am f0e62b7a: am 29039dee: Merge "Support another kind of iso mpeg4 file." into froyo
Merge commit 'f0e62b7a50e3f72a6e7bad510a2d605656b297ad' into kraken
* commit 'f0e62b7a50e3f72a6e7bad510a2d605656b297ad':
Support another kind of iso mpeg4 file.
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 41f070c..b8ba3f6 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -16,7 +16,7 @@
#include "installd.h"
-int install(const char *pkgname, uid_t uid, gid_t gid)
+int install(const char *pkgname, int encrypted_fs_flag, uid_t uid, gid_t gid)
{
char pkgdir[PKG_PATH_MAX];
char libdir[PKG_PATH_MAX];
@@ -27,11 +27,17 @@
}
- if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
- return -1;
- if (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX))
- return -1;
-
+ if (encrypted_fs_flag == USE_UNENCRYPTED_FS) {
+ if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
+ return -1;
+ if (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX))
+ return -1;
+ } else {
+ if (create_pkg_path(pkgdir, PKG_SEC_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
+ return -1;
+ if (create_pkg_path(libdir, PKG_SEC_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX))
+ return -1;
+ }
if (mkdir(pkgdir, 0751) < 0) {
LOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
@@ -56,27 +62,38 @@
return 0;
}
-int uninstall(const char *pkgname)
+int uninstall(const char *pkgname, int encrypted_fs_flag)
{
char pkgdir[PKG_PATH_MAX];
- if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
- return -1;
+ if (encrypted_fs_flag == USE_UNENCRYPTED_FS) {
+ if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
+ return -1;
+ } else {
+ if (create_pkg_path(pkgdir, PKG_SEC_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
+ return -1;
+ }
/* delete contents AND directory, no exceptions */
return delete_dir_contents(pkgdir, 1, 0);
}
-int renamepkg(const char *oldpkgname, const char *newpkgname)
+int renamepkg(const char *oldpkgname, const char *newpkgname, int encrypted_fs_flag)
{
char oldpkgdir[PKG_PATH_MAX];
char newpkgdir[PKG_PATH_MAX];
- if (create_pkg_path(oldpkgdir, PKG_DIR_PREFIX, oldpkgname, PKG_DIR_POSTFIX))
- return -1;
- if (create_pkg_path(newpkgdir, PKG_DIR_PREFIX, newpkgname, PKG_DIR_POSTFIX))
- return -1;
-
+ if (encrypted_fs_flag == USE_UNENCRYPTED_FS) {
+ if (create_pkg_path(oldpkgdir, PKG_DIR_PREFIX, oldpkgname, PKG_DIR_POSTFIX))
+ return -1;
+ if (create_pkg_path(newpkgdir, PKG_DIR_PREFIX, newpkgname, PKG_DIR_POSTFIX))
+ return -1;
+ } else {
+ if (create_pkg_path(oldpkgdir, PKG_SEC_DIR_PREFIX, oldpkgname, PKG_DIR_POSTFIX))
+ return -1;
+ if (create_pkg_path(newpkgdir, PKG_SEC_DIR_PREFIX, newpkgname, PKG_DIR_POSTFIX))
+ return -1;
+ }
if (rename(oldpkgdir, newpkgdir) < 0) {
LOGE("cannot rename dir '%s' to '%s': %s\n", oldpkgdir, newpkgdir, strerror(errno));
@@ -85,29 +102,41 @@
return 0;
}
-int delete_user_data(const char *pkgname)
+int delete_user_data(const char *pkgname, int encrypted_fs_flag)
{
char pkgdir[PKG_PATH_MAX];
- if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
- return -1;
+ if (encrypted_fs_flag == USE_UNENCRYPTED_FS) {
+ if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
+ return -1;
+ } else {
+ if (create_pkg_path(pkgdir, PKG_SEC_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
+ return -1;
+ }
/* delete contents, excluding "lib", but not the directory itself */
return delete_dir_contents(pkgdir, 0, "lib");
}
-int delete_cache(const char *pkgname)
+int delete_cache(const char *pkgname, int encrypted_fs_flag)
{
char cachedir[PKG_PATH_MAX];
- if (create_pkg_path(cachedir, CACHE_DIR_PREFIX, pkgname, CACHE_DIR_POSTFIX))
- return -1;
-
+ if (encrypted_fs_flag == USE_UNENCRYPTED_FS) {
+ if (create_pkg_path(cachedir, CACHE_DIR_PREFIX, pkgname, CACHE_DIR_POSTFIX))
+ return -1;
+ } else {
+ if (create_pkg_path(cachedir, CACHE_SEC_DIR_PREFIX, pkgname, CACHE_DIR_POSTFIX))
+ return -1;
+ }
/* delete contents, not the directory, no exceptions */
return delete_dir_contents(cachedir, 0, 0);
}
+/* TODO(oam): depending on use case (ecryptfs or dmcrypt)
+ * change implementation
+ */
static int disk_free()
{
struct statfs sfs;
@@ -139,6 +168,39 @@
LOGI("free_cache(%d) avail %d\n", free_size, avail);
if (avail >= free_size) return 0;
+ /* First try encrypted dir */
+ d = opendir(PKG_SEC_DIR_PREFIX);
+ if (d == NULL) {
+ LOGE("cannot open %s\n", PKG_SEC_DIR_PREFIX);
+ } else {
+ dfd = dirfd(d);
+
+ while ((de = readdir(d))) {
+ if (de->d_type != DT_DIR) continue;
+ name = de->d_name;
+
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+
+ subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
+ if (subfd < 0) continue;
+
+ delete_dir_contents_fd(subfd, "cache");
+ close(subfd);
+
+ avail = disk_free();
+ if (avail >= free_size) {
+ closedir(d);
+ return 0;
+ }
+ }
+ closedir(d);
+ }
+
+ /* Next try unencrypted dir... */
d = opendir(PKG_DIR_PREFIX);
if (d == NULL) {
LOGE("cannot open %s\n", PKG_DIR_PREFIX);
@@ -314,7 +376,7 @@
int get_size(const char *pkgname, const char *apkpath,
const char *fwdlock_apkpath,
- int *_codesize, int *_datasize, int *_cachesize)
+ int *_codesize, int *_datasize, int *_cachesize, int encrypted_fs_flag)
{
DIR *d;
int dfd;
@@ -349,8 +411,14 @@
}
}
- if (create_pkg_path(path, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) {
- goto done;
+ if (encrypted_fs_flag == 0) {
+ if (create_pkg_path(path, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) {
+ goto done;
+ }
+ } else {
+ if (create_pkg_path(path, PKG_SEC_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) {
+ goto done;
+ }
}
d = opendir(path);
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index f6ca998..882c493 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -29,7 +29,7 @@
static int do_install(char **arg, char reply[REPLY_MAX])
{
- return install(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */
+ return install(arg[0], atoi(arg[1]), atoi(arg[2]), atoi(arg[3])); /* pkgname, uid, gid */
}
static int do_dexopt(char **arg, char reply[REPLY_MAX])
@@ -50,12 +50,12 @@
static int do_remove(char **arg, char reply[REPLY_MAX])
{
- return uninstall(arg[0]); /* pkgname */
+ return uninstall(arg[0], atoi(arg[1])); /* pkgname */
}
static int do_rename(char **arg, char reply[REPLY_MAX])
{
- return renamepkg(arg[0], arg[1]); /* oldpkgname, newpkgname */
+ return renamepkg(arg[0], arg[1], atoi(arg[2])); /* oldpkgname, newpkgname */
}
static int do_free_cache(char **arg, char reply[REPLY_MAX]) /* TODO int:free_size */
@@ -65,7 +65,7 @@
static int do_rm_cache(char **arg, char reply[REPLY_MAX])
{
- return delete_cache(arg[0]); /* pkgname */
+ return delete_cache(arg[0], atoi(arg[1])); /* pkgname */
}
static int do_protect(char **arg, char reply[REPLY_MAX])
@@ -81,7 +81,7 @@
int res = 0;
/* pkgdir, apkpath */
- res = get_size(arg[0], arg[1], arg[2], &codesize, &datasize, &cachesize);
+ res = get_size(arg[0], arg[1], arg[2], &codesize, &datasize, &cachesize, atoi(arg[3]));
sprintf(reply,"%d %d %d", codesize, datasize, cachesize);
return res;
@@ -89,7 +89,7 @@
static int do_rm_user_data(char **arg, char reply[REPLY_MAX])
{
- return delete_user_data(arg[0]); /* pkgname */
+ return delete_user_data(arg[0], atoi(arg[1])); /* pkgname */
}
static int do_movefiles(char **arg, char reply[REPLY_MAX])
@@ -105,17 +105,17 @@
struct cmdinfo cmds[] = {
{ "ping", 0, do_ping },
- { "install", 3, do_install },
+ { "install", 4, do_install },
{ "dexopt", 3, do_dexopt },
{ "movedex", 2, do_move_dex },
{ "rmdex", 1, do_rm_dex },
- { "remove", 1, do_remove },
- { "rename", 2, do_rename },
+ { "remove", 2, do_remove },
+ { "rename", 3, do_rename },
{ "freecache", 1, do_free_cache },
- { "rmcache", 1, do_rm_cache },
+ { "rmcache", 2, do_rm_cache },
{ "protect", 2, do_protect },
- { "getsize", 3, do_get_size },
- { "rmuserdata", 1, do_rm_user_data },
+ { "getsize", 4, do_get_size },
+ { "rmuserdata", 2, do_rm_user_data },
{ "movefiles", 0, do_movefiles },
};
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index cfcdb98..8e4adb1 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -48,16 +48,23 @@
/* elements combined with a valid package name to form paths */
#define PKG_DIR_PREFIX "/data/data/"
+#define PKG_SEC_DIR_PREFIX "/data/secure/data/"
#define PKG_DIR_POSTFIX ""
#define PKG_LIB_PREFIX "/data/data/"
+#define PKG_SEC_LIB_PREFIX "/data/secure/data/"
#define PKG_LIB_POSTFIX "/lib"
#define CACHE_DIR_PREFIX "/data/data/"
+#define CACHE_SEC_DIR_PREFIX "/data/secure/data/"
#define CACHE_DIR_POSTFIX "/cache"
#define APK_DIR_PREFIX "/data/app/"
+/* Encrypted File SYstems constants */
+#define USE_ENCRYPTED_FS 1
+#define USE_UNENCRYPTED_FS 0
+
/* other handy constants */
#define PROTECTED_DIR_PREFIX "/data/app-private/"
@@ -89,16 +96,16 @@
/* commands.c */
-int install(const char *pkgname, uid_t uid, gid_t gid);
-int uninstall(const char *pkgname);
-int renamepkg(const char *oldpkgname, const char *newpkgname);
-int delete_user_data(const char *pkgname);
-int delete_cache(const char *pkgname);
+int install(const char *pkgname, int encrypted_fs_flag, uid_t uid, gid_t gid);
+int uninstall(const char *pkgname, int encrypted_fs_flag);
+int renamepkg(const char *oldpkgname, const char *newpkgname, int encrypted_fs_flag);
+int delete_user_data(const char *pkgname, int encrypted_fs_flag);
+int delete_cache(const char *pkgname, int encrypted_fs_flag);
int move_dex(const char *src, const char *dst);
int rm_dex(const char *path);
int protect(char *pkgname, gid_t gid);
int get_size(const char *pkgname, const char *apkpath, const char *fwdlock_apkpath,
- int *codesize, int *datasize, int *cachesize);
+ int *codesize, int *datasize, int *cachesize, int encrypted_fs_flag);
int free_cache(int free_size);
int dexopt(const char *apk_path, uid_t uid, int is_public);
int movefiles();
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 1cd7aa7..1d9e0f1 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1483,7 +1483,13 @@
}
private static String getDatabaseName() {
- return DATABASE_NAME;
+ if(Environment.isEncryptedFilesystemEnabled()) {
+ // Hard-coded path in case of encrypted file system
+ return Environment.getSystemSecureDirectory().getPath() + File.separator + DATABASE_NAME;
+ } else {
+ // Regular path in case of non-encrypted file system
+ return DATABASE_NAME;
+ }
}
private class DatabaseHelper extends SQLiteOpenHelper {
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 984c070..d81b2a3 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -317,7 +317,9 @@
if (sSyncStorageEngine != null) {
return;
}
- File dataDir = Environment.getDataDirectory();
+ // This call will return the correct directory whether Encrypted File Systems is
+ // enabled or not.
+ File dataDir = Environment.getSecureDataDirectory();
sSyncStorageEngine = new SyncStorageEngine(context, dataDir);
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 0a04e5b..023f9c4 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -252,6 +252,16 @@
public static final int FLAG_RESTORE_ANY_VERSION = 1<<17;
/**
+ * Value for {@link #flags}: this is true if the application has set
+ * its android:neverEncrypt to true, false otherwise. It is used to specify
+ * that this package specifically "opts-out" of a secured file system solution,
+ * and will always store its data in-the-clear.
+ *
+ * {@hide}
+ */
+ public static final int FLAG_NEVER_ENCRYPT = 1<<18;
+
+ /**
* Value for {@link #flags}: Set to true if the application has been
* installed using the forward lock option.
*
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 09a783d..fb52d2e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1539,6 +1539,12 @@
ai.flags |= ApplicationInfo.FLAG_TEST_ONLY;
}
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_neverEncrypt,
+ false)) {
+ ai.flags |= ApplicationInfo.FLAG_NEVER_ENCRYPT;
+ }
+
String str;
str = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestApplication_permission, 0);
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index f7e7d39..12487ff 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -28,6 +28,8 @@
private static final File ROOT_DIRECTORY
= getDirectory("ANDROID_ROOT", "/system");
+ private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
+
private static IMountService mMntSvc = null;
/**
@@ -37,9 +39,55 @@
return ROOT_DIRECTORY;
}
+ /**
+ * Gets the system directory available for secure storage.
+ * If Encrypted File system is enabled, it returns an encrypted directory (/data/secure/system).
+ * Otherwise, it returns the unencrypted /data/system directory.
+ * @return File object representing the secure storage system directory.
+ * @hide
+ */
+ public static File getSystemSecureDirectory() {
+ if (isEncryptedFilesystemEnabled()) {
+ return new File(SECURE_DATA_DIRECTORY, "system");
+ } else {
+ return new File(DATA_DIRECTORY, "system");
+ }
+ }
+
+ /**
+ * Gets the data directory for secure storage.
+ * If Encrypted File system is enabled, it returns an encrypted directory (/data/secure).
+ * Otherwise, it returns the unencrypted /data directory.
+ * @return File object representing the data directory for secure storage.
+ * @hide
+ */
+ public static File getSecureDataDirectory() {
+ if (isEncryptedFilesystemEnabled()) {
+ return SECURE_DATA_DIRECTORY;
+ } else {
+ return DATA_DIRECTORY;
+ }
+ }
+
+ /**
+ * Returns whether the Encrypted File System feature is enabled on the device or not.
+ * @return <code>true</code> if Encrypted File System feature is enabled, <code>false</code>
+ * if disabled.
+ * @hide
+ */
+ public static boolean isEncryptedFilesystemEnabled() {
+ return SystemProperties.getBoolean(SYSTEM_PROPERTY_EFS_ENABLED, false);
+ }
+
private static final File DATA_DIRECTORY
= getDirectory("ANDROID_DATA", "/data");
+ /**
+ * @hide
+ */
+ private static final File SECURE_DATA_DIRECTORY
+ = getDirectory("ANDROID_SECURE_DATA", "/data/secure");
+
private static final File EXTERNAL_STORAGE_DIRECTORY
= getDirectory("EXTERNAL_STORAGE", "/sdcard");
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index b3ec114..1b103aa 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -352,6 +352,23 @@
}
/**
+ * Reboot into the recovery system to wipe the /data partition and toggle
+ * Encrypted File Systems on/off.
+ * @param extras to add to the RECOVERY_COMPLETED intent after rebooting.
+ * @throws IOException if something goes wrong.
+ *
+ * @hide
+ */
+ public static void rebootToggleEFS(Context context, boolean efsEnabled)
+ throws IOException {
+ if (efsEnabled) {
+ bootCommand(context, "--set_encrypted_filesystem=on");
+ } else {
+ bootCommand(context, "--set_encrypted_filesystem=off");
+ }
+ }
+
+ /**
* Reboot into the recovery system with the supplied argument.
* @param arg to pass to the recovery utility.
* @throws IOException if something goes wrong.
diff --git a/core/java/com/android/internal/widget/DigitalClock.java b/core/java/com/android/internal/widget/DigitalClock.java
index 23e2277..fa47ff6 100644
--- a/core/java/com/android/internal/widget/DigitalClock.java
+++ b/core/java/com/android/internal/widget/DigitalClock.java
@@ -30,7 +30,7 @@
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.View;
-import android.widget.RelativeLayout;
+import android.widget.LinearLayout;
import android.widget.TextView;
import java.text.DateFormatSymbols;
@@ -39,7 +39,7 @@
/**
* Displays the time
*/
-public class DigitalClock extends RelativeLayout {
+public class DigitalClock extends LinearLayout {
private final static String M12 = "h:mm";
private final static String M24 = "kk:mm";
diff --git a/core/jni/android_location_GpsLocationProvider.cpp b/core/jni/android_location_GpsLocationProvider.cpp
index f60fe6d..a3be309 100755
--- a/core/jni/android_location_GpsLocationProvider.cpp
+++ b/core/jni/android_location_GpsLocationProvider.cpp
@@ -41,7 +41,6 @@
static const GpsInterface* sGpsInterface = NULL;
static const GpsXtraInterface* sGpsXtraInterface = NULL;
static const AGpsInterface* sAGpsInterface = NULL;
-static const GpsPrivacyInterface* sGpsPrivacyInterface = NULL;
static const GpsNiInterface* sGpsNiInterface = NULL;
static const GpsDebugInterface* sGpsDebugInterface = NULL;
@@ -224,15 +223,9 @@
sAGpsInterface->init(&sAGpsCallbacks);
if (!sGpsNiInterface)
- sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
+ sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
if (sGpsNiInterface)
- sGpsNiInterface->init(&sGpsNiCallbacks);
-
- // Clear privacy lock while enabled
- if (!sGpsPrivacyInterface)
- sGpsPrivacyInterface = (const GpsPrivacyInterface*)sGpsInterface->get_extension(GPS_PRIVACY_INTERFACE);
- if (sGpsPrivacyInterface)
- sGpsPrivacyInterface->set_privacy_lock(0);
+ sGpsNiInterface->init(&sGpsNiCallbacks);
if (!sGpsDebugInterface)
sGpsDebugInterface = (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
@@ -242,12 +235,6 @@
static void android_location_GpsLocationProvider_disable(JNIEnv* env, jobject obj)
{
- // Enable privacy lock while disabled
- if (!sGpsPrivacyInterface)
- sGpsPrivacyInterface = (const GpsPrivacyInterface*)sGpsInterface->get_extension(GPS_PRIVACY_INTERFACE);
- if (sGpsPrivacyInterface)
- sGpsPrivacyInterface->set_privacy_lock(1);
-
pthread_mutex_lock(&sEventMutex);
sPendingCallbacks |= kDisableRequest;
pthread_cond_signal(&sEventCond);
@@ -489,10 +476,12 @@
static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj,
jint notifId, jint response)
{
- if (!sGpsNiInterface)
+ if (!sGpsNiInterface) {
sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
- if (sGpsNiInterface)
+ }
+ if (sGpsNiInterface) {
sGpsNiInterface->respond(notifId, response);
+ }
}
static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj)
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index a4b2357..b404955 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -41,21 +41,20 @@
android:ellipsize="marquee"
android:gravity="right|bottom"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="22sp"
/>
- <!-- "emergency calls only" shown when sim is missing or PUKd -->
- <TextView
- android:id="@+id/emergencyCallText"
+ <!-- emergency call button shown when sim is missing or PUKd -->
+ <Button
+ android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_below="@id/carrier"
+ android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
- android:layout_marginTop="0dip"
+ android:layout_marginTop="10dip"
android:layout_marginRight="8dip"
- android:text="@string/emergency_calls_only"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/white"
+ android:drawableLeft="@drawable/ic_emergency"
+ style="@style/Widget.Button.Transparent"
+ android:drawablePadding="8dip"
/>
<!-- time and date -->
@@ -65,7 +64,6 @@
android:layout_below="@id/carrier"
android:layout_marginTop="52dip"
android:layout_marginLeft="20dip"
- android:layout_marginBottom="8dip"
>
<TextView android:id="@+id/timeDisplay"
@@ -73,6 +71,7 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
+ android:gravity="bottom"
android:textSize="72sp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:shadowColor="#C0000000"
@@ -85,9 +84,8 @@
<TextView android:id="@+id/am_pm"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/timeDisplay"
- android:layout_alignBaseline="@id/timeDisplay"
+ android:layout_height="match_parent"
+ android:gravity="bottom"
android:singleLine="true"
android:ellipsize="none"
android:textSize="22sp"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index e1c9772..6ee659c 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -46,19 +46,18 @@
android:ellipsize="marquee"
android:gravity="right|bottom"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:textSize="22sp"
/>
- <!-- "emergency calls only" shown when sim is missing or PUKd -->
- <TextView
- android:id="@+id/emergencyCallText"
+ <!-- emergency call button shown when sim is missing or PUKd -->
+ <Button
+ android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="20dip"
- android:text="@string/emergency_calls_only"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/white"
+ android:drawableLeft="@drawable/ic_emergency"
+ style="@style/Widget.Button.Transparent"
+ android:drawablePadding="8dip"
/>
<com.android.internal.widget.DigitalClock android:id="@+id/time"
@@ -66,12 +65,12 @@
android:layout_height="wrap_content"
android:layout_below="@id/carrier"
android:layout_marginTop="56dip"
- android:layout_marginBottom="8dip"
>
<TextView android:id="@+id/timeDisplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:gravity="bottom"
android:singleLine="true"
android:ellipsize="none"
android:textSize="72sp"
@@ -86,9 +85,8 @@
<TextView android:id="@+id/am_pm"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/timeDisplay"
- android:layout_alignBaseline="@id/timeDisplay"
+ android:layout_height="match_parent"
+ android:gravity="bottom"
android:singleLine="true"
android:ellipsize="none"
android:textSize="22sp"
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index 83381a1..c1b406f 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -58,19 +58,18 @@
android:ellipsize="marquee"
android:gravity="right|bottom"
/>
-
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginTop="8dip"
- android:layout_marginBottom="8dip"
>
<TextView android:id="@+id/timeDisplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:gravity="bottom"
android:singleLine="true"
android:ellipsize="none"
android:textSize="72sp"
@@ -85,9 +84,8 @@
<TextView android:id="@+id/am_pm"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/timeDisplay"
- android:layout_alignBaseline="@id/timeDisplay"
+ android:layout_height="match_parent"
+ android:gravity="bottom"
android:singleLine="true"
android:ellipsize="none"
android:textSize="22sp"
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 8dacfaf..74a0eee 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -55,12 +55,12 @@
android:layout_alignParentTop="true"
android:layout_marginTop="15dip"
android:layout_marginLeft="20dip"
- android:layout_marginBottom="8dip"
>
<TextView android:id="@+id/timeDisplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:gravity="bottom"
android:singleLine="true"
android:ellipsize="none"
android:textSize="56sp"
@@ -74,9 +74,8 @@
<TextView android:id="@+id/am_pm"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/timeDisplay"
- android:layout_alignBaseline="@id/timeDisplay"
+ android:layout_height="match_parent"
+ android:gravity="bottom"
android:singleLine="true"
android:ellipsize="none"
android:textSize="18sp"
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 959a9db..fc5edb3 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -79,6 +79,13 @@
by applications. -->
<attr name="allowClearUserData" format="boolean" />
+ <!-- Option to let applications specify that user data should
+ never be encrypted if an Encrypted File System solution
+ is enabled. Specifically, this is an "opt-out" feature, meaning
+ that, by default, user data will be encrypted if the EFS feature
+ is enabled. -->
+ <attr name="neverEncrypt" format="boolean" />
+
<!-- Option to indicate this application is only for testing purposes.
For example, it may expose functionality or data outside of itself
that would cause a security hole, but is useful for testing. This
@@ -712,6 +719,7 @@
<attr name="killAfterRestore" />
<attr name="restoreNeedsApplication" />
<attr name="restoreAnyVersion" />
+ <attr name="neverEncrypt" />
</declare-styleable>
<!-- The <code>permission</code> tag declares a security permission that can be
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index d057ab7..dd0d064 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -8,6 +8,8 @@
android:backupAgent="SettingsBackupAgent"
android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_settings">
+
+ <!-- todo add: android:neverEncrypt="true" -->
<provider android:name="SettingsProvider" android:authorities="settings"
android:multiprocess="false"
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
index 5672a01..eeafd5a 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
@@ -52,8 +52,11 @@
// The actual implementation is delegated to the VpnService class.
private VpnService<? extends VpnProfile> mService;
+ // TODO(oam): Test VPN when EFS is enabled (will do later)...
private static String getStateFilePath() {
- return Environment.getDataDirectory().getPath() + STATES_FILE_RELATIVE_PATH;
+ // This call will return the correcu directory whether Encrypted FS is enabled or not
+ // Disabled: /data/misc/vpn/.states Enabled: /data/secure/misc/vpn/.states
+ return Environment.getSecureDataDirectory().getPath() + STATES_FILE_RELATIVE_PATH;
}
private final IBinder mBinder = new IVpnService.Stub() {
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index ecf1a1d..818c785 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -421,7 +421,7 @@
Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;
// If Encrypted file systems is enabled or disabled, this call will return the
// correct directory.
- mBaseStateDir = new File(Environment.getDataDirectory(), "backup");
+ mBaseStateDir = new File(Environment.getSecureDataDirectory(), "backup");
mBaseStateDir.mkdirs();
mDataDir = Environment.getDownloadCacheDirectory();
diff --git a/services/java/com/android/server/Installer.java b/services/java/com/android/server/Installer.java
index 2eaa58c..1f34eba 100644
--- a/services/java/com/android/server/Installer.java
+++ b/services/java/com/android/server/Installer.java
@@ -166,11 +166,17 @@
}
}
- public int install(String name, int uid, int gid) {
+ public int install(String name, boolean useEncryptedFilesystem, int uid, int gid) {
StringBuilder builder = new StringBuilder("install");
builder.append(' ');
builder.append(name);
builder.append(' ');
+ if (useEncryptedFilesystem) {
+ builder.append('1');
+ } else {
+ builder.append('0');
+ }
+ builder.append(' ');
builder.append(uid);
builder.append(' ');
builder.append(gid);
@@ -203,33 +209,57 @@
return execute(builder.toString());
}
- public int remove(String name) {
+ public int remove(String name, boolean useEncryptedFilesystem) {
StringBuilder builder = new StringBuilder("remove");
builder.append(' ');
builder.append(name);
+ builder.append(' ');
+ if (useEncryptedFilesystem) {
+ builder.append('1');
+ } else {
+ builder.append('0');
+ }
return execute(builder.toString());
}
- public int rename(String oldname, String newname) {
+ public int rename(String oldname, String newname, boolean useEncryptedFilesystem) {
StringBuilder builder = new StringBuilder("rename");
builder.append(' ');
builder.append(oldname);
builder.append(' ');
builder.append(newname);
+ builder.append(' ');
+ if (useEncryptedFilesystem) {
+ builder.append('1');
+ } else {
+ builder.append('0');
+ }
return execute(builder.toString());
}
- public int deleteCacheFiles(String name) {
+ public int deleteCacheFiles(String name, boolean useEncryptedFilesystem) {
StringBuilder builder = new StringBuilder("rmcache");
builder.append(' ');
builder.append(name);
+ builder.append(' ');
+ if (useEncryptedFilesystem) {
+ builder.append('1');
+ } else {
+ builder.append('0');
+ }
return execute(builder.toString());
}
- public int clearUserData(String name) {
+ public int clearUserData(String name, boolean useEncryptedFilesystem) {
StringBuilder builder = new StringBuilder("rmuserdata");
builder.append(' ');
builder.append(name);
+ builder.append(' ');
+ if (useEncryptedFilesystem) {
+ builder.append('1');
+ } else {
+ builder.append('0');
+ }
return execute(builder.toString());
}
@@ -263,7 +293,7 @@
}
public int getSizeInfo(String pkgName, String apkPath,
- String fwdLockApkPath, PackageStats pStats) {
+ String fwdLockApkPath, PackageStats pStats, boolean useEncryptedFilesystem) {
StringBuilder builder = new StringBuilder("getsize");
builder.append(' ');
builder.append(pkgName);
@@ -271,6 +301,13 @@
builder.append(apkPath);
builder.append(' ');
builder.append(fwdLockApkPath != null ? fwdLockApkPath : "!");
+ builder.append(' ');
+ if (useEncryptedFilesystem) {
+ builder.append('1');
+ } else {
+ builder.append('0');
+ }
+
String s = transaction(builder.toString());
String res[] = s.split(" ");
diff --git a/services/java/com/android/server/MasterClearReceiver.java b/services/java/com/android/server/MasterClearReceiver.java
index 27a8a74..4d04cee 100644
--- a/services/java/com/android/server/MasterClearReceiver.java
+++ b/services/java/com/android/server/MasterClearReceiver.java
@@ -39,7 +39,11 @@
try {
Slog.w(TAG, "!!! FACTORY RESET !!!");
- RecoverySystem.rebootWipeUserData(context);
+ if (intent.hasExtra("enableEFS")) {
+ RecoverySystem.rebootToggleEFS(context, intent.getBooleanExtra("enableEFS", false));
+ } else {
+ RecoverySystem.rebootWipeUserData(context);
+ }
Log.wtf(TAG, "Still running after master clear?!");
} catch (IOException e) {
Slog.e(TAG, "Can't perform master clear/factory reset", e);
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index ef1738b..8c4bca9 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -147,6 +147,8 @@
private static final boolean GET_CERTIFICATES = true;
+ private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
+
private static final int REMOVE_EVENTS =
FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
private static final int ADD_EVENTS =
@@ -199,6 +201,10 @@
// This is where all application persistent data goes.
final File mAppDataDir;
+ // If Encrypted File System feature is enabled, all application persistent data
+ // should go here instead.
+ final File mSecureAppDataDir;
+
// This is the object monitoring the framework dir.
final FileObserver mFrameworkInstallObserver;
@@ -746,6 +752,7 @@
File dataDir = Environment.getDataDirectory();
mAppDataDir = new File(dataDir, "data");
+ mSecureAppDataDir = new File(dataDir, "secure/data");
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
if (mInstaller == null) {
@@ -755,6 +762,7 @@
File miscDir = new File(dataDir, "misc");
miscDir.mkdirs();
mAppDataDir.mkdirs();
+ mSecureAppDataDir.mkdirs();
mDrmAppPrivateInstallDir.mkdirs();
}
@@ -915,7 +923,9 @@
+ " no longer exists; wiping its data";
reportSettingsProblem(Log.WARN, msg);
if (mInstaller != null) {
- mInstaller.remove(ps.name);
+ // XXX how to set useEncryptedFSDir for packages that
+ // are not encrypted?
+ mInstaller.remove(ps.name, true);
}
}
}
@@ -985,7 +995,8 @@
void cleanupInstallFailedPackage(PackageSetting ps) {
Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
if (mInstaller != null) {
- int retCode = mInstaller.remove(ps.name);
+ boolean useSecureFS = useEncryptedFilesystemForPackage(ps.pkg);
+ int retCode = mInstaller.remove(ps.name, useSecureFS);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove app data directory for package: "
+ ps.name + ", retcode=" + retCode);
@@ -2692,6 +2703,11 @@
return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
}
+
+ private static boolean useEncryptedFilesystemForPackage(PackageParser.Package pkg) {
+ return Environment.isEncryptedFilesystemEnabled() &&
+ ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_NEVER_ENCRYPT) == 0);
+ }
private boolean verifyPackageUpdate(PackageSetting oldPkg, PackageParser.Package newPkg) {
if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
@@ -2709,7 +2725,14 @@
}
private File getDataPathForPackage(PackageParser.Package pkg) {
- return new File(mAppDataDir, pkg.packageName);
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
+ File dataPath;
+ if (useEncryptedFSDir) {
+ dataPath = new File(mSecureAppDataDir, pkg.packageName);
+ } else {
+ dataPath = new File(mAppDataDir, pkg.packageName);
+ }
+ return dataPath;
}
private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
@@ -3060,6 +3083,7 @@
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
// This is a normal package, need to make its data directory.
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
dataPath = getDataPathForPackage(pkg);
boolean uidError = false;
@@ -3076,7 +3100,7 @@
// If this is a system app, we can at least delete its
// current data so the application will still work.
if (mInstaller != null) {
- int ret = mInstaller.remove(pkgName);
+ int ret = mInstaller.remove(pkgName, useEncryptedFSDir);
if (ret >= 0) {
// Old data gone!
String msg = "System package " + pkg.packageName
@@ -3087,7 +3111,7 @@
recovered = true;
// And now re-install the app.
- ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+ ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if (ret == -1) {
// Ack should not happen!
@@ -3127,7 +3151,7 @@
Log.v(TAG, "Want this data dir: " + dataPath);
//invoke installer to do the actual installation
if (mInstaller != null) {
- int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
+ int ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if(ret < 0) {
// Error from installer
@@ -6089,8 +6113,9 @@
deletedPs = mSettings.mPackages.get(packageName);
}
if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
if (mInstaller != null) {
- int retCode = mInstaller.remove(packageName);
+ int retCode = mInstaller.remove(packageName, useEncryptedFSDir);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove app data or cache directory for package: "
+ packageName + ", retcode=" + retCode);
@@ -6329,6 +6354,7 @@
p = ps.pkg;
}
}
+ boolean useEncryptedFSDir = false;
if(!dataOnly) {
//need to check this only for fully installed applications
@@ -6341,9 +6367,10 @@
Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
+ useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
}
if (mInstaller != null) {
- int retCode = mInstaller.clearUserData(packageName);
+ int retCode = mInstaller.clearUserData(packageName, useEncryptedFSDir);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove cache files for package: "
+ packageName);
@@ -6394,8 +6421,9 @@
Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
if (mInstaller != null) {
- int retCode = mInstaller.deleteCacheFiles(packageName);
+ int retCode = mInstaller.deleteCacheFiles(packageName, useEncryptedFSDir);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove cache files for package: "
+ packageName);
@@ -6457,9 +6485,10 @@
}
publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null;
}
+ boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
if (mInstaller != null) {
int res = mInstaller.getSizeInfo(packageName, p.mPath,
- publicSrcDir, pStats);
+ publicSrcDir, pStats, useEncryptedFSDir);
if (res < 0) {
return false;
} else {
@@ -7509,7 +7538,8 @@
this.pkgFlags = pkgFlags & (
ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_FORWARD_LOCK |
- ApplicationInfo.FLAG_EXTERNAL_STORAGE);
+ ApplicationInfo.FLAG_EXTERNAL_STORAGE |
+ ApplicationInfo.FLAG_NEVER_ENCRYPT);
}
}
@@ -7770,11 +7800,17 @@
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
// TODO(oam): This secure dir creation needs to be moved somewhere else (later)
+ File systemSecureDir = new File(dataDir, "secure/system");
systemDir.mkdirs();
+ systemSecureDir.mkdirs();
FileUtils.setPermissions(systemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
+ FileUtils.setPermissions(systemSecureDir.toString(),
+ FileUtils.S_IRWXU|FileUtils.S_IRWXG
+ |FileUtils.S_IROTH|FileUtils.S_IXOTH,
+ -1, -1);
mSettingsFilename = new File(systemDir, "packages.xml");
mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
mPackageListFilename = new File(systemDir, "packages.list");
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce522c8..ce40b5d 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -85,7 +85,8 @@
// TODO(oam): Test VPN when EFS is enabled (will do later)...
public static String getProfilePath() {
- return Environment.getDataDirectory().getPath() + PROFILES_PATH;
+ // This call will return the correct path if Encrypted FS is enabled or not.
+ return Environment.getSecureDataDirectory().getPath() + PROFILES_PATH;
}
/**