summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/accounts/AccountManagerService.java8
-rw-r--r--core/java/android/app/ContextImpl.java33
-rw-r--r--core/java/android/app/NativeActivity.java141
-rw-r--r--core/java/android/content/SyncStorageEngine.java4
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java32
-rw-r--r--core/java/android/content/pm/ComponentInfo.java8
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java47
-rw-r--r--core/java/android/content/pm/PackageManager.java73
-rw-r--r--core/java/android/content/pm/PackageParser.java60
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java39
-rw-r--r--core/java/android/content/res/Configuration.java3
-rw-r--r--core/java/android/hardware/Camera.java107
-rw-r--r--core/java/android/os/Build.java4
-rw-r--r--core/java/android/os/Environment.java48
-rw-r--r--core/java/android/os/MessageQueue.java60
-rw-r--r--core/java/android/os/ParcelFileDescriptor.java4
-rw-r--r--core/java/android/os/RecoverySystem.java17
-rw-r--r--core/java/android/pim/vcard/VCardBuilder.java49
-rw-r--r--core/java/android/pim/vcard/VCardConfig.java31
-rw-r--r--core/java/android/pim/vcard/VCardEntry.java5
-rw-r--r--core/java/android/server/BluetoothA2dpService.java1
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java25
-rw-r--r--core/java/android/util/DisplayMetrics.java13
-rw-r--r--core/java/android/view/Surface.java10
-rw-r--r--core/java/android/view/SurfaceHolder.java1
-rw-r--r--core/java/android/view/ViewRoot.java308
-rw-r--r--core/java/android/view/Window.java8
-rw-r--r--core/java/com/android/internal/view/BaseSurfaceHolder.java31
-rw-r--r--core/java/com/android/internal/view/RootViewSurfaceTaker.java11
-rw-r--r--core/java/com/android/internal/widget/DigitalClock.java4
30 files changed, 1014 insertions, 171 deletions
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 @@ public class AccountManagerService
}
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/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f471f57..11b7b02 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2173,6 +2173,39 @@ class ContextImpl extends Context {
throws NameNotFoundException {
return getApplicationIcon(getApplicationInfo(packageName, 0));
}
+
+ @Override
+ public Drawable getActivityLogo(ComponentName activityName)
+ throws NameNotFoundException {
+ return getActivityInfo(activityName, 0).loadLogo(this);
+ }
+
+ @Override
+ public Drawable getActivityLogo(Intent intent)
+ throws NameNotFoundException {
+ if (intent.getComponent() != null) {
+ return getActivityLogo(intent.getComponent());
+ }
+
+ ResolveInfo info = resolveActivity(
+ intent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (info != null) {
+ return info.activityInfo.loadLogo(this);
+ }
+
+ throw new NameNotFoundException(intent.toUri(0));
+ }
+
+ @Override
+ public Drawable getApplicationLogo(ApplicationInfo info) {
+ return info.loadLogo(this);
+ }
+
+ @Override
+ public Drawable getApplicationLogo(String packageName)
+ throws NameNotFoundException {
+ return getApplicationLogo(getApplicationInfo(packageName, 0));
+ }
@Override public Resources getResourcesForActivity(
ComponentName activityName) throws NameNotFoundException {
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
new file mode 100644
index 0000000..fd20b71
--- /dev/null
+++ b/core/java/android/app/NativeActivity.java
@@ -0,0 +1,141 @@
+package android.app;
+
+import dalvik.system.PathClassLoader;
+
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.SurfaceHolder;
+
+import java.io.File;
+
+/**
+ * Convenience for implementing an activity that will be implemented
+ * purely in native code. That is, a game (or game-like thing).
+ */
+public class NativeActivity extends Activity implements SurfaceHolder.Callback {
+ public static final String META_DATA_LIB_NAME = "android.app.lib_name";
+
+ private int mNativeHandle;
+
+ private native int loadNativeCode(String path);
+ private native void unloadNativeCode(int handle);
+
+ private native void onStartNative(int handle);
+ private native void onResumeNative(int handle);
+ private native void onSaveInstanceStateNative(int handle);
+ private native void onPauseNative(int handle);
+ private native void onStopNative(int handle);
+ private native void onLowMemoryNative(int handle);
+ private native void onWindowFocusChangedNative(int handle, boolean focused);
+ private native void onSurfaceCreatedNative(int handle, SurfaceHolder holder);
+ private native void onSurfaceChangedNative(int handle, SurfaceHolder holder,
+ int format, int width, int height);
+ private native void onSurfaceDestroyedNative(int handle, SurfaceHolder holder);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ String libname = "main";
+ ActivityInfo ai;
+
+ getWindow().takeSurface(this);
+
+ try {
+ ai = getPackageManager().getActivityInfo(
+ getIntent().getComponent(), PackageManager.GET_META_DATA);
+ if (ai.metaData != null) {
+ String ln = ai.metaData.getString(META_DATA_LIB_NAME);
+ if (ln != null) libname = ln;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new RuntimeException("Error getting activity info", e);
+ }
+
+ String path = null;
+
+ if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) == 0) {
+ // If the application does not have (Java) code, then no ClassLoader
+ // has been set up for it. We will need to do our own search for
+ // the native code.
+ path = ai.applicationInfo.dataDir + "/lib/" + System.mapLibraryName(libname);
+ if (!(new File(path)).exists()) {
+ path = null;
+ }
+ }
+
+ if (path == null) {
+ path = ((PathClassLoader)getClassLoader()).findLibrary(libname);
+ }
+
+ if (path == null) {
+ throw new IllegalArgumentException("Unable to find native library: " + libname);
+ }
+
+ mNativeHandle = loadNativeCode(path);
+ if (mNativeHandle == 0) {
+ throw new IllegalArgumentException("Unable to load native library: " + path);
+ }
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ unloadNativeCode(mNativeHandle);
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ onPauseNative(mNativeHandle);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ onResumeNative(mNativeHandle);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ onSaveInstanceStateNative(mNativeHandle);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ onStartNative(mNativeHandle);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ onStopNative(mNativeHandle);
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ onLowMemoryNative(mNativeHandle);
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ onWindowFocusChangedNative(mNativeHandle, hasFocus);
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ onSurfaceCreatedNative(mNativeHandle, holder);
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ onSurfaceChangedNative(mNativeHandle, holder, format, width, height);
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ onSurfaceDestroyedNative(mNativeHandle, holder);
+ }
+}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 98a4993..6413cec 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -317,7 +317,9 @@ public class SyncStorageEngine extends Handler {
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 1577f9e..7047113 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -174,7 +174,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* Value for {@link #flags}: true when the application's window can be
* increased in size for larger screens. Corresponds to
* {@link android.R.styleable#AndroidManifestSupportsScreens_largeScreens
- * android:smallScreens}.
+ * android:largeScreens}.
*/
public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<11;
@@ -252,6 +252,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_RESTORE_ANY_VERSION = 1<<17;
/**
+ * Value for {@link #flags}: Set to true if the application has been
+ * installed using the forward lock option.
+ *
* Value for {@link #flags}: Set to true if the application is
* currently installed on external/removable/unprotected storage. Such
* applications may not be available if their storage is not currently
@@ -262,12 +265,30 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_EXTERNAL_STORAGE = 1<<18;
/**
+ * Value for {@link #flags}: true when the application's window can be
+ * increased in size for extra large screens. Corresponds to
+ * {@link android.R.styleable#AndroidManifestSupportsScreens_xlargeScreens
+ * android:xlargeScreens}.
+ */
+ public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1<<19;
+
+ /**
+ * 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<<30;
+
+ /**
* Value for {@link #flags}: Set to true if the application has been
* installed using the forward lock option.
*
* {@hide}
*/
- public static final int FLAG_FORWARD_LOCK = 1<<20;
+ public static final int FLAG_FORWARD_LOCK = 1<<29;
/**
* Value for {@link #flags}: Set to true if the application is
@@ -275,7 +296,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*
* {@hide}
*/
- public static final int FLAG_NATIVE_DEBUGGABLE = 1<<21;
+ public static final int FLAG_NATIVE_DEBUGGABLE = 1<<28;
/**
* Flags associated with the application. Any combination of
@@ -285,7 +306,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
* {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
* {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
- * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS},
+ * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_SUPPORTS_XLARGE_SCREENS},
+ * {@link #FLAG_RESIZEABLE_FOR_SCREENS},
* {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}, {@link #FLAG_VM_SAFE_MODE}
*/
public int flags = 0;
@@ -517,7 +539,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public void disableCompatibilityMode() {
flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS |
FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS |
- FLAG_SUPPORTS_SCREEN_DENSITIES);
+ FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
}
/**
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index cafe372..f16c4ef 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -157,6 +157,14 @@ public class ComponentInfo extends PackageItemInfo {
/**
* @hide
*/
+ @Override
+ protected Drawable loadDefaultLogo(PackageManager pm) {
+ return applicationInfo.loadLogo(pm);
+ }
+
+ /**
+ * @hide
+ */
@Override protected ApplicationInfo getApplicationInfo() {
return applicationInfo;
}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 14c0680..d73aaf6 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -67,6 +67,14 @@ public class PackageItemInfo {
public int icon;
/**
+ * A drawable resource identifier (in the package's resources) of this
+ * component's logo. Logos may be larger/wider than icons and are
+ * displayed by certain UI elements in place of a name or name/icon
+ * combination. From the "logo" attribute or, if not set, 0.
+ */
+ public int logo;
+
+ /**
* Additional meta-data associated with this component. This field
* will only be filled in if you set the
* {@link PackageManager#GET_META_DATA} flag when requesting the info.
@@ -84,6 +92,7 @@ public class PackageItemInfo {
nonLocalizedLabel = orig.nonLocalizedLabel;
if (nonLocalizedLabel != null) nonLocalizedLabel = nonLocalizedLabel.toString().trim();
icon = orig.icon;
+ logo = orig.logo;
metaData = orig.metaData;
}
@@ -152,6 +161,42 @@ public class PackageItemInfo {
}
/**
+ * Retrieve the current graphical logo associated with this item. This
+ * will call back on the given PackageManager to load the logo from
+ * the application.
+ *
+ * @param pm A PackageManager from which the logo can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a Drawable containing the item's logo. If the item
+ * does not have a logo, this method will return null.
+ */
+ public Drawable loadLogo(PackageManager pm) {
+ if (logo != 0) {
+ Drawable d = pm.getDrawable(packageName, logo, getApplicationInfo());
+ if (d != null) {
+ return d;
+ }
+ }
+ return loadDefaultLogo(pm);
+ }
+
+ /**
+ * Retrieve the default graphical logo associated with this item.
+ *
+ * @param pm A PackageManager from which the logo can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a Drawable containing the item's default logo
+ * or null if no default logo is available.
+ *
+ * @hide
+ */
+ protected Drawable loadDefaultLogo(PackageManager pm) {
+ return null;
+ }
+
+ /**
* Load an XML resource attached to the meta-data of this item. This will
* retrieved the name meta-data entry, and if defined call back on the
* given PackageManager to load its XML file from the application.
@@ -196,6 +241,7 @@ public class PackageItemInfo {
dest.writeInt(labelRes);
TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
dest.writeInt(icon);
+ dest.writeInt(logo);
dest.writeBundle(metaData);
}
@@ -206,6 +252,7 @@ public class PackageItemInfo {
nonLocalizedLabel
= TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
icon = source.readInt();
+ logo = source.readInt();
metaData = source.readBundle();
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 68b44e7..196f508 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1597,6 +1597,79 @@ public abstract class PackageManager {
throws NameNotFoundException;
/**
+ * Retrieve the logo associated with an activity. Given the full name of
+ * an activity, retrieves the information about it and calls
+ * {@link ComponentInfo#loadLogo ComponentInfo.loadLogo()} to return its logo.
+ * If the activity can not be found, NameNotFoundException is thrown.
+ *
+ * @param activityName Name of the activity whose logo is to be retrieved.
+ *
+ * @return Returns the image of the logo or null if the activity has no
+ * logo specified.
+ *
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * activity could not be loaded.
+ *
+ * @see #getActivityLogo(Intent)
+ */
+ public abstract Drawable getActivityLogo(ComponentName activityName)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve the logo associated with an Intent. If intent.getClassName() is
+ * set, this simply returns the result of
+ * getActivityLogo(intent.getClassName()). Otherwise it resolves the intent's
+ * component and returns the logo associated with the resolved component.
+ * If intent.getClassName() can not be found or the Intent can not be resolved
+ * to a component, NameNotFoundException is thrown.
+ *
+ * @param intent The intent for which you would like to retrieve a logo.
+ *
+ * @return Returns the image of the logo, or null if the activity has no
+ * logo specified.
+ *
+ * @throws NameNotFoundException Thrown if the resources for application
+ * matching the given intent could not be loaded.
+ *
+ * @see #getActivityLogo(ComponentName)
+ */
+ public abstract Drawable getActivityLogo(Intent intent)
+ throws NameNotFoundException;
+
+ /**
+ * Retrieve the logo associated with an application. If it has not specified
+ * a logo, this method returns null.
+ *
+ * @param info Information about application being queried.
+ *
+ * @return Returns the image of the logo, or null if no logo is specified
+ * by the application.
+ *
+ * @see #getApplicationLogo(String)
+ */
+ public abstract Drawable getApplicationLogo(ApplicationInfo info);
+
+ /**
+ * Retrieve the logo associated with an application. Given the name of the
+ * application's package, retrieves the information about it and calls
+ * getApplicationLogo() to return its logo. If the application can not be
+ * found, NameNotFoundException is thrown.
+ *
+ * @param packageName Name of the package whose application logo is to be
+ * retrieved.
+ *
+ * @return Returns the image of the logo, or null if no application logo
+ * has been specified.
+ *
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * application could not be loaded.
+ *
+ * @see #getApplicationLogo(ApplicationInfo)
+ */
+ public abstract Drawable getApplicationLogo(String packageName)
+ throws NameNotFoundException;
+
+ /**
* Retrieve text from a package. This is a low-level API used by
* the various package manager info structures (such as
* {@link ComponentInfo} to implement retrieval of their associated
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 2a20a2d..4ddc124 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -105,17 +105,19 @@ public class PackageParser {
final int nameRes;
final int labelRes;
final int iconRes;
+ final int logoRes;
String tag;
TypedArray sa;
ParsePackageItemArgs(Package _owner, String[] _outError,
- int _nameRes, int _labelRes, int _iconRes) {
+ int _nameRes, int _labelRes, int _iconRes, int _logoRes) {
owner = _owner;
outError = _outError;
nameRes = _nameRes;
labelRes = _labelRes;
iconRes = _iconRes;
+ logoRes = _logoRes;
}
}
@@ -127,10 +129,10 @@ public class PackageParser {
int flags;
ParseComponentArgs(Package _owner, String[] _outError,
- int _nameRes, int _labelRes, int _iconRes,
+ int _nameRes, int _labelRes, int _iconRes, int _logoRes,
String[] _sepProcesses, int _processRes,
int _descriptionRes, int _enabledRes) {
- super(_owner, _outError, _nameRes, _labelRes, _iconRes);
+ super(_owner, _outError, _nameRes, _labelRes, _iconRes, _logoRes);
sepProcesses = _sepProcesses;
processRes = _processRes;
descriptionRes = _descriptionRes;
@@ -789,6 +791,7 @@ public class PackageParser {
int supportsSmallScreens = 1;
int supportsNormalScreens = 1;
int supportsLargeScreens = 1;
+ int supportsXLargeScreens = 1;
int resizeable = 1;
int anyDensity = 1;
@@ -996,9 +999,12 @@ public class PackageParser {
supportsLargeScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
supportsLargeScreens);
+ supportsXLargeScreens = sa.getInteger(
+ com.android.internal.R.styleable.AndroidManifestSupportsScreens_xlargeScreens,
+ supportsXLargeScreens);
resizeable = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_resizeable,
- supportsLargeScreens);
+ resizeable);
anyDensity = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_anyDensity,
anyDensity);
@@ -1132,6 +1138,11 @@ public class PackageParser {
>= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
}
+ if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0
+ && pkg.applicationInfo.targetSdkVersion
+ >= android.os.Build.VERSION_CODES.GINGERBREAD)) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS;
+ }
if (resizeable < 0 || (resizeable > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.DONUT)) {
@@ -1241,7 +1252,8 @@ public class PackageParser {
"<permission-group>", sa,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_label,
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_icon)) {
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_icon,
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_logo)) {
sa.recycle();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
@@ -1276,7 +1288,8 @@ public class PackageParser {
"<permission>", sa,
com.android.internal.R.styleable.AndroidManifestPermission_name,
com.android.internal.R.styleable.AndroidManifestPermission_label,
- com.android.internal.R.styleable.AndroidManifestPermission_icon)) {
+ com.android.internal.R.styleable.AndroidManifestPermission_icon,
+ com.android.internal.R.styleable.AndroidManifestPermission_logo)) {
sa.recycle();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
@@ -1329,7 +1342,8 @@ public class PackageParser {
"<permission-tree>", sa,
com.android.internal.R.styleable.AndroidManifestPermissionTree_name,
com.android.internal.R.styleable.AndroidManifestPermissionTree_label,
- com.android.internal.R.styleable.AndroidManifestPermissionTree_icon)) {
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_icon,
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_logo)) {
sa.recycle();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
@@ -1373,7 +1387,8 @@ public class PackageParser {
mParseInstrumentationArgs = new ParsePackageItemArgs(owner, outError,
com.android.internal.R.styleable.AndroidManifestInstrumentation_name,
com.android.internal.R.styleable.AndroidManifestInstrumentation_label,
- com.android.internal.R.styleable.AndroidManifestInstrumentation_icon);
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_icon,
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_logo);
mParseInstrumentationArgs.tag = "<instrumentation>";
}
@@ -1485,6 +1500,8 @@ public class PackageParser {
ai.icon = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
+ ai.logo = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestApplication_logo, 0);
ai.theme = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
ai.descriptionRes = sa.getResourceId(
@@ -1542,6 +1559,12 @@ public class PackageParser {
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);
@@ -1705,7 +1728,7 @@ public class PackageParser {
private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
String[] outError, String tag, TypedArray sa,
- int nameRes, int labelRes, int iconRes) {
+ int nameRes, int labelRes, int iconRes, int logoRes) {
String name = sa.getNonConfigurationString(nameRes, 0);
if (name == null) {
outError[0] = tag + " does not specify android:name";
@@ -1723,6 +1746,11 @@ public class PackageParser {
outInfo.icon = iconVal;
outInfo.nonLocalizedLabel = null;
}
+
+ int logoVal = sa.getResourceId(logoRes, 0);
+ if (logoVal != 0) {
+ outInfo.logo = logoVal;
+ }
TypedValue v = sa.peekValue(labelRes);
if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
@@ -1745,6 +1773,7 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestActivity_name,
com.android.internal.R.styleable.AndroidManifestActivity_label,
com.android.internal.R.styleable.AndroidManifestActivity_icon,
+ com.android.internal.R.styleable.AndroidManifestActivity_logo,
mSeparateProcesses,
com.android.internal.R.styleable.AndroidManifestActivity_process,
com.android.internal.R.styleable.AndroidManifestActivity_description,
@@ -1947,6 +1976,7 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestActivityAlias_name,
com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_logo,
mSeparateProcesses,
0,
com.android.internal.R.styleable.AndroidManifestActivityAlias_description,
@@ -1980,6 +2010,7 @@ public class PackageParser {
info.configChanges = target.info.configChanges;
info.flags = target.info.flags;
info.icon = target.info.icon;
+ info.logo = target.info.logo;
info.labelRes = target.info.labelRes;
info.nonLocalizedLabel = target.info.nonLocalizedLabel;
info.launchMode = target.info.launchMode;
@@ -2074,6 +2105,7 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestProvider_name,
com.android.internal.R.styleable.AndroidManifestProvider_label,
com.android.internal.R.styleable.AndroidManifestProvider_icon,
+ com.android.internal.R.styleable.AndroidManifestProvider_logo,
mSeparateProcesses,
com.android.internal.R.styleable.AndroidManifestProvider_process,
com.android.internal.R.styleable.AndroidManifestProvider_description,
@@ -2337,6 +2369,7 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestService_name,
com.android.internal.R.styleable.AndroidManifestService_label,
com.android.internal.R.styleable.AndroidManifestService_icon,
+ com.android.internal.R.styleable.AndroidManifestService_logo,
mSeparateProcesses,
com.android.internal.R.styleable.AndroidManifestService_process,
com.android.internal.R.styleable.AndroidManifestService_description,
@@ -2540,6 +2573,9 @@ public class PackageParser {
outInfo.icon = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);
+
+ outInfo.logo = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0);
sa.recycle();
@@ -2801,6 +2837,11 @@ public class PackageParser {
outInfo.icon = iconVal;
outInfo.nonLocalizedLabel = null;
}
+
+ int logoVal = args.sa.getResourceId(args.logoRes, 0);
+ if (logoVal != 0) {
+ outInfo.logo = logoVal;
+ }
TypedValue v = args.sa.peekValue(args.labelRes);
if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
@@ -3135,6 +3176,7 @@ public class PackageParser {
public int labelRes;
public CharSequence nonLocalizedLabel;
public int icon;
+ public int logo;
}
public final static class ActivityIntentInfo extends IntentInfo {
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 11c67cc..d0ba590 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -99,7 +99,22 @@ public class CompatibilityInfo {
*/
private static final int CONFIGURED_LARGE_SCREENS = 16;
- private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE | LARGE_SCREENS;
+ /**
+ * A flag mask to indicates that the application supports xlarge screens.
+ * The flag is set to true if
+ * 1) Application declares it supports xlarge screens in manifest file using <supports-screens> or
+ * 2) The screen size is not xlarge
+ * {@see compatibilityFlag}
+ */
+ private static final int XLARGE_SCREENS = 32;
+
+ /**
+ * A flag mask to tell if the application supports xlarge screens. This differs
+ * from XLARGE_SCREENS in that the application that does not support xlarge
+ * screens will be marked as supporting them if the current screen is not
+ * xlarge.
+ */
+ private static final int CONFIGURED_XLARGE_SCREENS = 64;
/**
* The effective screen density we have selected for this application.
@@ -127,6 +142,9 @@ public class CompatibilityInfo {
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
mCompatibilityFlags |= LARGE_SCREENS | CONFIGURED_LARGE_SCREENS;
}
+ if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
+ mCompatibilityFlags |= XLARGE_SCREENS | CONFIGURED_XLARGE_SCREENS;
+ }
if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
mCompatibilityFlags |= EXPANDABLE | CONFIGURED_EXPANDABLE;
}
@@ -157,6 +175,7 @@ public class CompatibilityInfo {
this(ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
| ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
| ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS
| ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS,
EXPANDABLE | CONFIGURED_EXPANDABLE,
DisplayMetrics.DENSITY_DEVICE,
@@ -196,6 +215,17 @@ public class CompatibilityInfo {
}
/**
+ * Sets large screen bit in the compatibility flag.
+ */
+ public void setXLargeScreens(boolean expandable) {
+ if (expandable) {
+ mCompatibilityFlags |= CompatibilityInfo.XLARGE_SCREENS;
+ } else {
+ mCompatibilityFlags &= ~CompatibilityInfo.XLARGE_SCREENS;
+ }
+ }
+
+ /**
* @return true if the application is configured to be expandable.
*/
public boolean isConfiguredExpandable() {
@@ -210,6 +240,13 @@ public class CompatibilityInfo {
}
/**
+ * @return true if the application is configured to be expandable.
+ */
+ public boolean isConfiguredXLargeScreens() {
+ return (mCompatibilityFlags & CompatibilityInfo.CONFIGURED_XLARGE_SCREENS) != 0;
+ }
+
+ /**
* @return true if the scaling is required
*/
public boolean isScalingRequired() {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 1a0c867..02956ba 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -62,6 +62,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
public static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
public static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
+ public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;
public static final int SCREENLAYOUT_LONG_MASK = 0x30;
public static final int SCREENLAYOUT_LONG_UNDEFINED = 0x00;
@@ -82,7 +83,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
* <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
* of the screen. They may be one of
* {@link #SCREENLAYOUT_SIZE_SMALL}, {@link #SCREENLAYOUT_SIZE_NORMAL},
- * or {@link #SCREENLAYOUT_SIZE_LARGE}.
+ * {@link #SCREENLAYOUT_SIZE_LARGE}, or {@link #SCREENLAYOUT_SIZE_XLARGE}.
*
* <p>The {@link #SCREENLAYOUT_LONG_MASK} defines whether the screen
* is wider/taller than normal. They may be one of
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 8687a89..46c6cb8 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -84,13 +84,29 @@ public class Camera {
private boolean mWithBuffer;
/**
+ * Returns the number of Cameras available.
+ * @hide
+ */
+ public native static int getNumberOfCameras();
+
+ /**
* Returns a new Camera object.
+ * If {@link #getNumberOfCameras()} returns N, the valid is is 0 to N-1.
+ * The id 0 is the default camera.
+ * @hide
+ */
+ public static Camera open(int cameraId) {
+ return new Camera(cameraId);
+ }
+
+ /**
+ * Returns a new Camera object. This returns the default camera.
*/
public static Camera open() {
- return new Camera();
+ return new Camera(0);
}
- Camera() {
+ Camera(int cameraId) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
@@ -107,14 +123,14 @@ public class Camera {
mEventHandler = null;
}
- native_setup(new WeakReference<Camera>(this));
+ native_setup(new WeakReference<Camera>(this), cameraId);
}
protected void finalize() {
native_release();
}
- private native final void native_setup(Object camera_this);
+ private native final void native_setup(Object camera_this, int cameraId);
private native final void native_release();
@@ -746,6 +762,8 @@ public class Camera {
private static final String KEY_ZOOM_RATIOS = "zoom-ratios";
private static final String KEY_ZOOM_SUPPORTED = "zoom-supported";
private static final String KEY_SMOOTH_ZOOM_SUPPORTED = "smooth-zoom-supported";
+ private static final String KEY_FOCUS_DISTANCES = "focus-distances";
+
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -858,6 +876,36 @@ public class Camera {
*/
public static final String FOCUS_MODE_EDOF = "edof";
+ // Indices for focus distance array.
+ /**
+ * The array index of near focus distance for use with
+ * {@link #getFocusDistances(float[])}.
+ */
+ public static final int FOCUS_DISTANCE_NEAR_INDEX = 0;
+
+ /**
+ * The array index of optimal focus distance for use with
+ * {@link #getFocusDistances(float[])}.
+ */
+ public static final int FOCUS_DISTANCE_OPTIMAL_INDEX = 1;
+
+ /**
+ * The array index of far focus distance for use with
+ * {@link #getFocusDistances(float[])}.
+ */
+ public static final int FOCUS_DISTANCE_FAR_INDEX = 2;
+
+ /**
+ * Continuous focus mode. The camera continuously tries to focus. This
+ * is ideal for shooting video or shooting photo of moving object.
+ * Continuous focus starts when {@link #autoFocus(AutoFocusCallback)} is
+ * called. Continuous focus stops when {@link #cancelAutoFocus()} is
+ * called. AutoFocusCallback will be only called once as soon as the
+ * picture is in focus.
+ */
+ public static final String FOCUS_MODE_CONTINUOUS = "continuous";
+
+
// Formats for setPreviewFormat and setPictureFormat.
private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
@@ -1788,6 +1836,42 @@ public class Camera {
return TRUE.equals(str);
}
+ /**
+ * Gets the distances from the camera to where an object appears to be
+ * in focus. The object is sharpest at the optimal focus distance. The
+ * depth of field is the far focus distance minus near focus distance.
+ *
+ * Focus distances may change after calling {@link
+ * #autoFocus(AutoFocusCallback)}, {@link #cancelAutoFocus}, or {@link
+ * #startPreview()}. Applications can call {@link #getParameters()}
+ * and this method anytime to get the latest focus distances. If the
+ * focus mode is FOCUS_MODE_EDOF, the values may be all 0, which means
+ * focus distance is not applicable. If the focus mode is
+ * FOCUS_MODE_CONTINUOUS and autofocus has started, focus distances may
+ * change from time to time.
+ *
+ * Far focus distance > optimal focus distance > near focus distance. If
+ * the far focus distance is infinity, the value will be
+ * Float.POSITIVE_INFINITY.
+ *
+ * @param output focus distances in meters. output must be a float
+ * array with three elements. Near focus distance, optimal focus
+ * distance, and far focus distance will be filled in the array.
+ * @see #NEAR_FOCUS_DISTANCE_INDEX
+ * @see #OPTIMAL_FOCUS_DISTANCE_INDEX
+ * @see #FAR_FOCUS_DISTANCE_INDEX
+ */
+ public void getFocusDistances(float[] output) {
+ if (output == null || output.length != 3) {
+ throw new IllegalArgumentException(
+ "output must be an float array with three elements.");
+ }
+ List<Float> distances = splitFloat(get(KEY_FOCUS_DISTANCES));
+ output[0] = distances.get(0);
+ output[1] = distances.get(1);
+ output[2] = distances.get(2);
+ }
+
// Splits a comma delimited string to an ArrayList of String.
// Return null if the passing string is null or the size is 0.
private ArrayList<String> split(String str) {
@@ -1817,6 +1901,21 @@ public class Camera {
return substrings;
}
+ // Splits a comma delimited string to an ArrayList of Float.
+ // Return null if the passing string is null or the size is 0.
+ private ArrayList<Float> splitFloat(String str) {
+ if (str == null) return null;
+
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ ArrayList<Float> substrings = new ArrayList<Float>();
+ while (tokenizer.hasMoreElements()) {
+ String token = tokenizer.nextToken();
+ substrings.add(Float.parseFloat(token));
+ }
+ if (substrings.size() == 0) return null;
+ return substrings;
+ }
+
// Returns the value of a float parameter.
private float getFloat(String key, float defaultValue) {
try {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 3e9fd42..9d1a634 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -180,6 +180,10 @@ public class Build {
public static final int ECLAIR_MR1 = 7;
public static final int FROYO = 8;
+
+ public static final int KRAKEN = CUR_DEVELOPMENT;
+
+ public static final int GINGERBREAD = CUR_DEVELOPMENT;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 812391c..c7cbed6 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -28,6 +28,8 @@ public class Environment {
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 @@ public class Environment {
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/MessageQueue.java b/core/java/android/os/MessageQueue.java
index bc653d6..d394a46 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -36,8 +36,9 @@ public class MessageQueue {
Message mMessages;
private final ArrayList mIdleHandlers = new ArrayList();
private boolean mQuiting = false;
+ private int mObject = 0; // used by native code
boolean mQuitAllowed = true;
-
+
/**
* Callback interface for discovering when a thread is going to block
* waiting for more messages.
@@ -85,16 +86,49 @@ public class MessageQueue {
}
}
+ // Add an input pipe to the set being selected over. If token is
+ // negative, remove 'handler's entry from the current set and forget
+ // about it.
+ void setInputToken(int token, int region, Handler handler) {
+ if (token >= 0) nativeRegisterInputStream(token, region, handler);
+ else nativeUnregisterInputStream(token);
+ }
+
MessageQueue() {
+ nativeInit();
}
+ private native void nativeInit();
+
+ /**
+ * @param token fd of the readable end of the input stream
+ * @param region fd of the ashmem region used for data transport alongside the 'token' fd
+ * @param handler Handler from which to make input messages based on data read from the fd
+ */
+ private native void nativeRegisterInputStream(int token, int region, Handler handler);
+ private native void nativeUnregisterInputStream(int token);
+ private native void nativeSignal();
+
+ /**
+ * Wait until the designated time for new messages to arrive.
+ *
+ * @param when Timestamp in SystemClock.uptimeMillis() base of the next message in the queue.
+ * If 'when' is zero, the method will check for incoming messages without blocking. If
+ * 'when' is negative, the method will block forever waiting for the next message.
+ * @return
+ */
+ private native int nativeWaitForNext(long when);
final Message next() {
boolean tryIdle = true;
+ // when we start out, we'll just touch the input pipes and then go from there
+ long timeToNextEventMillis = 0;
while (true) {
long now;
Object[] idlers = null;
-
+
+ nativeWaitForNext(timeToNextEventMillis);
+
// Try to retrieve the next message, returning if found.
synchronized (this) {
now = SystemClock.uptimeMillis();
@@ -135,20 +169,17 @@ public class MessageQueue {
synchronized (this) {
// No messages, nobody to tell about it... time to wait!
- try {
- if (mMessages != null) {
- if (mMessages.when-now > 0) {
- Binder.flushPendingCommands();
- this.wait(mMessages.when-now);
- }
- } else {
+ if (mMessages != null) {
+ if (mMessages.when - now > 0) {
Binder.flushPendingCommands();
- this.wait();
+ timeToNextEventMillis = mMessages.when - now;
}
- }
- catch (InterruptedException e) {
+ } else {
+ Binder.flushPendingCommands();
+ timeToNextEventMillis = -1;
}
}
+ // loop to the while(true) and do the appropriate nativeWait(when)
}
}
@@ -190,7 +221,6 @@ public class MessageQueue {
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
- this.notify();
} else {
Message prev = null;
while (p != null && p.when <= when) {
@@ -199,8 +229,8 @@ public class MessageQueue {
}
msg.next = prev.next;
prev.next = msg;
- this.notify();
}
+ nativeSignal();
}
return true;
}
@@ -321,7 +351,7 @@ public class MessageQueue {
void poke()
{
synchronized (this) {
- this.notify();
+ nativeSignal();
}
}
}
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 0a3b2cf..d26f066 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -179,7 +179,7 @@ public class ParcelFileDescriptor implements Parcelable {
/**
* An InputStream you can create on a ParcelFileDescriptor, which will
* take care of calling {@link ParcelFileDescriptor#close
- * ParcelFileDescritor.close()} for you when the stream is closed.
+ * ParcelFileDescriptor.close()} for you when the stream is closed.
*/
public static class AutoCloseInputStream extends FileInputStream {
private final ParcelFileDescriptor mFd;
@@ -198,7 +198,7 @@ public class ParcelFileDescriptor implements Parcelable {
/**
* An OutputStream you can create on a ParcelFileDescriptor, which will
* take care of calling {@link ParcelFileDescriptor#close
- * ParcelFileDescritor.close()} for you when the stream is closed.
+ * ParcelFileDescriptor.close()} for you when the stream is closed.
*/
public static class AutoCloseOutputStream extends FileOutputStream {
private final ParcelFileDescriptor mFd;
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index b6dc1b5..5fea6fe 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -348,6 +348,23 @@ public class RecoverySystem {
}
/**
+ * 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/android/pim/vcard/VCardBuilder.java b/core/java/android/pim/vcard/VCardBuilder.java
index 0a6415d..1da6d7a 100644
--- a/core/java/android/pim/vcard/VCardBuilder.java
+++ b/core/java/android/pim/vcard/VCardBuilder.java
@@ -642,22 +642,18 @@ public class VCardBuilder {
if (TextUtils.isEmpty(phoneNumber)) {
continue;
}
- int type = (typeAsObject != null ? typeAsObject : DEFAULT_PHONE_TYPE);
- if (type == Phone.TYPE_PAGER) {
+
+ // PAGER number needs unformatted "phone number".
+ final int type = (typeAsObject != null ? typeAsObject : DEFAULT_PHONE_TYPE);
+ if (type == Phone.TYPE_PAGER ||
+ VCardConfig.refrainPhoneNumberFormatting(mVCardType)) {
phoneLineExists = true;
if (!phoneSet.contains(phoneNumber)) {
phoneSet.add(phoneNumber);
appendTelLine(type, label, phoneNumber, isPrimary);
}
} else {
- // The entry "may" have several phone numbers when the contact entry is
- // corrupted because of its original source.
- //
- // e.g. I encountered the entry like the following.
- // "111-222-3333 (Miami)\n444-555-6666 (Broward; 305-653-6796 (Miami); ..."
- // This kind of entry is not able to be inserted via Android devices, but
- // possible if the source of the data is already corrupted.
- List<String> phoneNumberList = splitIfSeveralPhoneNumbersExist(phoneNumber);
+ final List<String> phoneNumberList = splitAndTrimPhoneNumbers(phoneNumber);
if (phoneNumberList.isEmpty()) {
continue;
}
@@ -670,7 +666,7 @@ public class VCardBuilder {
phoneSet.add(actualPhoneNumber);
appendTelLine(type, label, formattedPhoneNumber, isPrimary);
}
- }
+ } // for (String actualPhoneNumber : phoneNumberList) {
}
}
}
@@ -682,15 +678,38 @@ public class VCardBuilder {
return this;
}
- private List<String> splitIfSeveralPhoneNumbersExist(final String phoneNumber) {
- List<String> phoneList = new ArrayList<String>();
+ /**
+ * <p>
+ * Splits a given string expressing phone numbers into several strings, and remove
+ * unnecessary characters inside them. The size of a returned list becomes 1 when
+ * no split is needed.
+ * </p>
+ * <p>
+ * The given number "may" have several phone numbers when the contact entry is corrupted
+ * because of its original source.
+ * e.g. "111-222-3333 (Miami)\n444-555-6666 (Broward; 305-653-6796 (Miami)"
+ * </p>
+ * <p>
+ * This kind of "phone numbers" will not be created with Android vCard implementation,
+ * but we may encounter them if the source of the input data has already corrupted
+ * implementation.
+ * </p>
+ * <p>
+ * To handle this case, this method first splits its input into multiple parts
+ * (e.g. "111-222-3333 (Miami)", "444-555-6666 (Broward", and 305653-6796 (Miami)") and
+ * removes unnecessary strings like "(Miami)".
+ * </p>
+ * <p>
+ * Do not call this method when trimming is inappropriate for its receivers.
+ * </p>
+ */
+ private List<String> splitAndTrimPhoneNumbers(final String phoneNumber) {
+ final List<String> phoneList = new ArrayList<String>();
StringBuilder builder = new StringBuilder();
final int length = phoneNumber.length();
for (int i = 0; i < length; i++) {
final char ch = phoneNumber.charAt(i);
- // TODO: add a test case for string with '+', and care the other possible issues
- // which may happen by ignoring non-digits other than '+'.
if (Character.isDigit(ch) || ch == '+') {
builder.append(ch);
} else if ((ch == ';' || ch == '\n') && builder.length() > 0) {
diff --git a/core/java/android/pim/vcard/VCardConfig.java b/core/java/android/pim/vcard/VCardConfig.java
index 3409be6..8219840 100644
--- a/core/java/android/pim/vcard/VCardConfig.java
+++ b/core/java/android/pim/vcard/VCardConfig.java
@@ -15,6 +15,7 @@
*/
package android.pim.vcard;
+import android.telephony.PhoneNumberUtils;
import android.util.Log;
import java.util.HashMap;
@@ -190,6 +191,30 @@ public class VCardConfig {
*/
public static final int FLAG_REFRAIN_IMAGE_EXPORT = 0x02000000;
+ /**
+ * <P>
+ * The flag indicating the vCard composer does touch nothing toward phone number Strings
+ * but leave it as is.
+ * </P>
+ * <P>
+ * The vCard specifications mention nothing toward phone numbers, while some devices
+ * do (wrongly, but with innevitable reasons).
+ * For example, there's a possibility Japanese mobile phones are expected to have
+ * just numbers, hypens, plus, etc. but not usual alphabets, while US mobile phones
+ * should get such characters. To make exported vCard simple for external parsers,
+ * we have used {@link PhoneNumberUtils#formatNumber(String)} during export, and
+ * removed unnecessary characters inside the number (e.g. "111-222-3333 (Miami)"
+ * becomes "111-222-3333").
+ * Unfortunate side effect of that use was some control characters used in the other
+ * areas may be badly affected by the formatting.
+ * </P>
+ * <P>
+ * This flag disables that formatting, affecting both importer and exporter.
+ * If the user is aware of some side effects due to the implicit formatting, use this flag.
+ * </P>
+ */
+ public static final int FLAG_REFRAIN_PHONE_NUMBER_FORMATTING = 0x02000000;
+
//// The followings are VCard types available from importer/exporter. ////
/**
@@ -431,6 +456,10 @@ public class VCardConfig {
return sJapaneseMobileTypeSet.contains(vcardType);
}
+ /* package */ static boolean refrainPhoneNumberFormatting(final int vcardType) {
+ return ((vcardType & FLAG_REFRAIN_PHONE_NUMBER_FORMATTING) != 0);
+ }
+
public static boolean needsToConvertPhoneticString(final int vcardType) {
return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0);
}
@@ -445,4 +474,4 @@ public class VCardConfig {
private VCardConfig() {
}
-} \ No newline at end of file
+}
diff --git a/core/java/android/pim/vcard/VCardEntry.java b/core/java/android/pim/vcard/VCardEntry.java
index 1327770..7c7e9b8 100644
--- a/core/java/android/pim/vcard/VCardEntry.java
+++ b/core/java/android/pim/vcard/VCardEntry.java
@@ -488,7 +488,7 @@ public class VCardEntry {
final StringBuilder builder = new StringBuilder();
final String trimed = data.trim();
final String formattedNumber;
- if (type == Phone.TYPE_PAGER) {
+ if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) {
formattedNumber = trimed;
} else {
final int length = trimed.length();
@@ -500,8 +500,7 @@ public class VCardEntry {
}
// Use NANP in default when there's no information about locale.
- final int formattingType = (VCardConfig.isJapaneseDevice(mVCardType) ?
- PhoneNumberUtils.FORMAT_JAPAN : PhoneNumberUtils.FORMAT_NANP);
+ final int formattingType = VCardUtils.getPhoneNumberFormat(mVCardType);
formattedNumber = PhoneNumberUtils.formatNumber(builder.toString(), formattingType);
}
PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary);
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 893db2e..ac89934 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -554,6 +554,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
if (!result) {
if (deviceObjectPath != null) {
String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+ if (address == null) return;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
int state = getSinkState(device);
handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED);
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 3d1d7d6..2ade44e 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -522,20 +522,14 @@ public abstract class WallpaperService extends Service {
}
try {
- SurfaceHolder.Callback callbacks[] = null;
- synchronized (mSurfaceHolder.mCallbacks) {
- final int N = mSurfaceHolder.mCallbacks.size();
- if (N > 0) {
- callbacks = new SurfaceHolder.Callback[N];
- mSurfaceHolder.mCallbacks.toArray(callbacks);
- }
- }
+ mSurfaceHolder.ungetCallbacks();
if (surfaceCreating) {
mIsCreating = true;
if (DEBUG) Log.v(TAG, "onSurfaceCreated("
+ mSurfaceHolder + "): " + this);
onSurfaceCreated(mSurfaceHolder);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
if (callbacks != null) {
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceCreated(mSurfaceHolder);
@@ -557,6 +551,7 @@ public abstract class WallpaperService extends Service {
+ "): " + this);
onSurfaceChanged(mSurfaceHolder, mFormat,
mCurWidth, mCurHeight);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
if (callbacks != null) {
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceChanged(mSurfaceHolder, mFormat,
@@ -698,14 +693,12 @@ public abstract class WallpaperService extends Service {
void reportSurfaceDestroyed() {
if (mSurfaceCreated) {
mSurfaceCreated = false;
- SurfaceHolder.Callback callbacks[];
- synchronized (mSurfaceHolder.mCallbacks) {
- callbacks = new SurfaceHolder.Callback[
- mSurfaceHolder.mCallbacks.size()];
- mSurfaceHolder.mCallbacks.toArray(callbacks);
- }
- for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceDestroyed(mSurfaceHolder);
+ mSurfaceHolder.ungetCallbacks();
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceDestroyed(mSurfaceHolder);
+ }
}
if (DEBUG) Log.v(TAG, "onSurfaceDestroyed("
+ mSurfaceHolder + "): " + this);
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 2628eb4..76d8106 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -135,6 +135,7 @@ public class DisplayMetrics {
int screenLayout) {
boolean expandable = compatibilityInfo.isConfiguredExpandable();
boolean largeScreens = compatibilityInfo.isConfiguredLargeScreens();
+ boolean xlargeScreens = compatibilityInfo.isConfiguredXLargeScreens();
// Note: this assume that configuration is updated before calling
// updateMetrics method.
@@ -157,8 +158,18 @@ public class DisplayMetrics {
compatibilityInfo.setLargeScreens(false);
}
}
+ if (!xlargeScreens) {
+ if ((screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
+ != Configuration.SCREENLAYOUT_SIZE_XLARGE) {
+ xlargeScreens = true;
+ // the current screen size is not large.
+ compatibilityInfo.setXLargeScreens(true);
+ } else {
+ compatibilityInfo.setXLargeScreens(false);
+ }
+ }
- if (!expandable || !largeScreens) {
+ if (!expandable || (!largeScreens && !xlargeScreens)) {
// This is a larger screen device and the app is not
// compatible with large screens, so diddle it.
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 83ef8ba..cd0ae3b 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -140,13 +140,13 @@ public class Surface implements Parcelable {
public static final int FLAGS_ORIENTATION_ANIMATION_DISABLE = 0x000000001;
@SuppressWarnings("unused")
- private int mSurface;
- @SuppressWarnings("unused")
private int mSurfaceControl;
@SuppressWarnings("unused")
private int mSaveCount;
@SuppressWarnings("unused")
private Canvas mCanvas;
+ @SuppressWarnings("unused")
+ private int mNativeSurface;
private String mName;
// The display metrics used to provide the pseudo canvas size for applications
@@ -422,13 +422,13 @@ public class Surface implements Parcelable {
/* no user serviceable parts here ... */
@Override
protected void finalize() throws Throwable {
- if (mSurface != 0 || mSurfaceControl != 0) {
+ if (mNativeSurface != 0 || mSurfaceControl != 0) {
if (DEBUG_RELEASE) {
Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() ("
- + mSurface + ", " + mSurfaceControl + ")", mCreationStack);
+ + mNativeSurface + ", " + mSurfaceControl + ")", mCreationStack);
} else {
Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() ("
- + mSurface + ", " + mSurfaceControl + ")");
+ + mNativeSurface + ", " + mSurfaceControl + ")");
}
}
release();
diff --git a/core/java/android/view/SurfaceHolder.java b/core/java/android/view/SurfaceHolder.java
index 64a10d1..34e4638 100644
--- a/core/java/android/view/SurfaceHolder.java
+++ b/core/java/android/view/SurfaceHolder.java
@@ -182,7 +182,6 @@ public interface SurfaceHolder {
/**
* Enable or disable option to keep the screen turned on while this
* surface is displayed. The default is false, allowing it to turn off.
- * Enabling the option effectivelty.
* This is safe to call from any thread.
*
* @param screenOn Supply to true to force the screen to stay on, false
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 03efea9..aa124e6 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -16,8 +16,10 @@
package android.view;
+import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
+import com.android.internal.view.RootViewSurfaceTaker;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
@@ -26,12 +28,12 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.*;
import android.os.Process;
-import android.os.SystemProperties;
import android.util.AndroidRuntimeException;
import android.util.Config;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.EventLog;
+import android.util.Slog;
import android.util.SparseArray;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
@@ -50,6 +52,7 @@ import android.Manifest;
import android.media.AudioManager;
import java.lang.ref.WeakReference;
+import java.io.FileDescriptor;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
@@ -76,6 +79,7 @@ public final class ViewRoot extends Handler implements ViewParent,
/** @noinspection PointlessBooleanExpression*/
private static final boolean DEBUG_DRAW = false || LOCAL_LOGV;
private static final boolean DEBUG_LAYOUT = false || LOCAL_LOGV;
+ private static final boolean DEBUG_INPUT = true || LOCAL_LOGV;
private static final boolean DEBUG_INPUT_RESIZE = false || LOCAL_LOGV;
private static final boolean DEBUG_ORIENTATION = false || LOCAL_LOGV;
private static final boolean DEBUG_TRACKBALL = false || LOCAL_LOGV;
@@ -133,6 +137,11 @@ public final class ViewRoot extends Handler implements ViewParent,
int mViewVisibility;
boolean mAppVisible = true;
+ SurfaceHolder.Callback mSurfaceHolderCallback;
+ BaseSurfaceHolder mSurfaceHolder;
+ boolean mIsCreating;
+ boolean mDrawingAllowed;
+
final Region mTransparentRegion;
final Region mPreviousTransparentRegion;
@@ -425,6 +434,9 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
+ // fd [0] is the receiver, [1] is the sender
+ private native int[] makeInputChannel();
+
/**
* We have one child
*/
@@ -435,6 +447,13 @@ public final class ViewRoot extends Handler implements ViewParent,
mView = view;
mWindowAttributes.copyFrom(attrs);
attrs = mWindowAttributes;
+ if (view instanceof RootViewSurfaceTaker) {
+ mSurfaceHolderCallback =
+ ((RootViewSurfaceTaker)view).willYouTakeTheSurface();
+ if (mSurfaceHolderCallback != null) {
+ mSurfaceHolder = new TakenSurfaceHolder();
+ }
+ }
Resources resources = mView.getContext().getResources();
CompatibilityInfo compatibilityInfo = resources.getCompatibilityInfo();
mTranslator = compatibilityInfo.getTranslator();
@@ -469,6 +488,14 @@ public final class ViewRoot extends Handler implements ViewParent,
mAdded = true;
int res; /* = WindowManagerImpl.ADD_OKAY; */
+ // Set up the input event channel
+ if (false) {
+ int[] fds = makeInputChannel();
+ if (DEBUG_INPUT) {
+ Log.v(TAG, "makeInputChannel() returned " + fds);
+ }
+ }
+
// Schedule the first layout -before- adding to the window
// manager, to make sure we do the relayout before receiving
// any other events from the system.
@@ -682,6 +709,7 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean windowResizesToFitContent = false;
boolean fullRedrawNeeded = mFullRedrawNeeded;
boolean newSurface = false;
+ boolean surfaceChanged = false;
WindowManager.LayoutParams lp = mWindowAttributes;
int desiredWindowWidth;
@@ -700,6 +728,7 @@ public final class ViewRoot extends Handler implements ViewParent,
WindowManager.LayoutParams params = null;
if (mWindowAttributesChanged) {
mWindowAttributesChanged = false;
+ surfaceChanged = true;
params = lp;
}
Rect frame = mWinFrame;
@@ -886,11 +915,18 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
+ if (mSurfaceHolder != null) {
+ mSurfaceHolder.mSurfaceLock.lock();
+ mDrawingAllowed = true;
+ lp.format = mSurfaceHolder.getRequestedFormat();
+ lp.type = mSurfaceHolder.getRequestedType();
+ }
+
boolean initialized = false;
boolean contentInsetsChanged = false;
boolean visibleInsetsChanged;
+ boolean hadSurface = mSurface.isValid();
try {
- boolean hadSurface = mSurface.isValid();
int fl = 0;
if (params != null) {
fl = params.flags;
@@ -965,6 +1001,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
} catch (RemoteException e) {
}
+
if (DEBUG_ORIENTATION) Log.v(
"ViewRoot", "Relayout returned: frame=" + frame + ", surface=" + mSurface);
@@ -977,6 +1014,57 @@ public final class ViewRoot extends Handler implements ViewParent,
mWidth = frame.width();
mHeight = frame.height();
+ if (mSurfaceHolder != null) {
+ // The app owns the surface; tell it about what is going on.
+ if (mSurface.isValid()) {
+ // XXX .copyFrom() doesn't work!
+ //mSurfaceHolder.mSurface.copyFrom(mSurface);
+ mSurfaceHolder.mSurface = mSurface;
+ }
+ mSurfaceHolder.mSurfaceLock.unlock();
+ if (mSurface.isValid()) {
+ if (!hadSurface) {
+ mSurfaceHolder.ungetCallbacks();
+
+ mIsCreating = true;
+ mSurfaceHolderCallback.surfaceCreated(mSurfaceHolder);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceCreated(mSurfaceHolder);
+ }
+ }
+ surfaceChanged = true;
+ }
+ if (surfaceChanged) {
+ mSurfaceHolderCallback.surfaceChanged(mSurfaceHolder,
+ lp.format, mWidth, mHeight);
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceChanged(mSurfaceHolder, lp.format,
+ mWidth, mHeight);
+ }
+ }
+ }
+ mIsCreating = false;
+ } else if (hadSurface) {
+ mSurfaceHolder.ungetCallbacks();
+ SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+ mSurfaceHolderCallback.surfaceDestroyed(mSurfaceHolder);
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceDestroyed(mSurfaceHolder);
+ }
+ }
+ mSurfaceHolder.mSurfaceLock.lock();
+ // Make surface invalid.
+ //mSurfaceHolder.mSurface.copyFrom(mSurface);
+ mSurfaceHolder.mSurface = new Surface();
+ mSurfaceHolder.mSurfaceLock.unlock();
+ }
+ }
+
if (initialized) {
mGlCanvas.setViewport((int) (mWidth * appScale + 0.5f),
(int) (mHeight * appScale + 0.5f));
@@ -1268,6 +1356,12 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean scalingRequired = mAttachInfo.mScalingRequired;
Rect dirty = mDirty;
+ if (mSurfaceHolder != null) {
+ // The app owns the surface, we won't draw.
+ dirty.setEmpty();
+ return;
+ }
+
if (mUseGL) {
if (!dirty.isEmpty()) {
Canvas canvas = mGlCanvas;
@@ -1332,103 +1426,105 @@ public final class ViewRoot extends Handler implements ViewParent,
appScale + ", width=" + mWidth + ", height=" + mHeight);
}
- Canvas canvas;
- try {
- int left = dirty.left;
- int top = dirty.top;
- int right = dirty.right;
- int bottom = dirty.bottom;
- canvas = surface.lockCanvas(dirty);
-
- if (left != dirty.left || top != dirty.top || right != dirty.right ||
- bottom != dirty.bottom) {
- mAttachInfo.mIgnoreDirtyState = true;
- }
-
- // TODO: Do this in native
- canvas.setDensity(mDensity);
- } catch (Surface.OutOfResourcesException e) {
- Log.e("ViewRoot", "OutOfResourcesException locking surface", e);
- // TODO: we should ask the window manager to do something!
- // for now we just do nothing
- return;
- } catch (IllegalArgumentException e) {
- Log.e("ViewRoot", "IllegalArgumentException locking surface", e);
- // TODO: we should ask the window manager to do something!
- // for now we just do nothing
- return;
- }
+ if (!dirty.isEmpty() || mIsAnimating) {
+ Canvas canvas;
+ try {
+ int left = dirty.left;
+ int top = dirty.top;
+ int right = dirty.right;
+ int bottom = dirty.bottom;
+ canvas = surface.lockCanvas(dirty);
+
+ if (left != dirty.left || top != dirty.top || right != dirty.right ||
+ bottom != dirty.bottom) {
+ mAttachInfo.mIgnoreDirtyState = true;
+ }
- try {
- if (!dirty.isEmpty() || mIsAnimating) {
- long startTime = 0L;
+ // TODO: Do this in native
+ canvas.setDensity(mDensity);
+ } catch (Surface.OutOfResourcesException e) {
+ Log.e("ViewRoot", "OutOfResourcesException locking surface", e);
+ // TODO: we should ask the window manager to do something!
+ // for now we just do nothing
+ return;
+ } catch (IllegalArgumentException e) {
+ Log.e("ViewRoot", "IllegalArgumentException locking surface", e);
+ // TODO: we should ask the window manager to do something!
+ // for now we just do nothing
+ return;
+ }
- if (DEBUG_ORIENTATION || DEBUG_DRAW) {
- Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w="
- + canvas.getWidth() + ", h=" + canvas.getHeight());
- //canvas.drawARGB(255, 255, 0, 0);
- }
+ try {
+ if (!dirty.isEmpty() || mIsAnimating) {
+ long startTime = 0L;
- if (Config.DEBUG && ViewDebug.profileDrawing) {
- startTime = SystemClock.elapsedRealtime();
- }
+ if (DEBUG_ORIENTATION || DEBUG_DRAW) {
+ Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w="
+ + canvas.getWidth() + ", h=" + canvas.getHeight());
+ //canvas.drawARGB(255, 255, 0, 0);
+ }
- // If this bitmap's format includes an alpha channel, we
- // need to clear it before drawing so that the child will
- // properly re-composite its drawing on a transparent
- // background. This automatically respects the clip/dirty region
- // or
- // If we are applying an offset, we need to clear the area
- // where the offset doesn't appear to avoid having garbage
- // left in the blank areas.
- if (!canvas.isOpaque() || yoff != 0) {
- canvas.drawColor(0, PorterDuff.Mode.CLEAR);
- }
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
+ startTime = SystemClock.elapsedRealtime();
+ }
- dirty.setEmpty();
- mIsAnimating = false;
- mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
- mView.mPrivateFlags |= View.DRAWN;
+ // If this bitmap's format includes an alpha channel, we
+ // need to clear it before drawing so that the child will
+ // properly re-composite its drawing on a transparent
+ // background. This automatically respects the clip/dirty region
+ // or
+ // If we are applying an offset, we need to clear the area
+ // where the offset doesn't appear to avoid having garbage
+ // left in the blank areas.
+ if (!canvas.isOpaque() || yoff != 0) {
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ }
- if (DEBUG_DRAW) {
- Context cxt = mView.getContext();
- Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
- ", metrics=" + cxt.getResources().getDisplayMetrics() +
- ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
- }
- int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
- try {
- canvas.translate(0, -yoff);
- if (mTranslator != null) {
- mTranslator.translateCanvas(canvas);
+ dirty.setEmpty();
+ mIsAnimating = false;
+ mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
+ mView.mPrivateFlags |= View.DRAWN;
+
+ if (DEBUG_DRAW) {
+ Context cxt = mView.getContext();
+ Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
+ ", metrics=" + cxt.getResources().getDisplayMetrics() +
+ ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
+ }
+ int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ try {
+ canvas.translate(0, -yoff);
+ if (mTranslator != null) {
+ mTranslator.translateCanvas(canvas);
+ }
+ canvas.setScreenDensity(scalingRequired
+ ? DisplayMetrics.DENSITY_DEVICE : 0);
+ mView.draw(canvas);
+ } finally {
+ mAttachInfo.mIgnoreDirtyState = false;
+ canvas.restoreToCount(saveCount);
}
- canvas.setScreenDensity(scalingRequired
- ? DisplayMetrics.DENSITY_DEVICE : 0);
- mView.draw(canvas);
- } finally {
- mAttachInfo.mIgnoreDirtyState = false;
- canvas.restoreToCount(saveCount);
- }
- if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
- mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
- }
+ if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
+ mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
+ }
- if (SHOW_FPS || Config.DEBUG && ViewDebug.showFps) {
- int now = (int)SystemClock.elapsedRealtime();
- if (sDrawTime != 0) {
- nativeShowFPS(canvas, now - sDrawTime);
+ if (SHOW_FPS || Config.DEBUG && ViewDebug.showFps) {
+ int now = (int)SystemClock.elapsedRealtime();
+ if (sDrawTime != 0) {
+ nativeShowFPS(canvas, now - sDrawTime);
+ }
+ sDrawTime = now;
}
- sDrawTime = now;
- }
- if (Config.DEBUG && ViewDebug.profileDrawing) {
- EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
+ EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
+ }
}
- }
- } finally {
- surface.unlockCanvasAndPost(canvas);
+ } finally {
+ surface.unlockCanvasAndPost(canvas);
+ }
}
if (LOCAL_LOGV) {
@@ -2813,6 +2909,46 @@ public final class ViewRoot extends Handler implements ViewParent,
return scrollToRectOrFocus(rectangle, immediate);
}
+ class TakenSurfaceHolder extends BaseSurfaceHolder {
+ @Override
+ public boolean onAllowLockCanvas() {
+ return mDrawingAllowed;
+ }
+
+ @Override
+ public void onRelayoutContainer() {
+ // Not currently interesting -- from changing between fixed and layout size.
+ }
+
+ public void setFormat(int format) {
+ ((RootViewSurfaceTaker)mView).setSurfaceFormat(format);
+ }
+
+ public void setType(int type) {
+ ((RootViewSurfaceTaker)mView).setSurfaceType(type);
+ }
+
+ @Override
+ public void onUpdateSurface() {
+ // We take care of format and type changes on our own.
+ throw new IllegalStateException("Shouldn't be here");
+ }
+
+ public boolean isCreating() {
+ return mIsCreating;
+ }
+
+ @Override
+ public void setFixedSize(int width, int height) {
+ throw new UnsupportedOperationException(
+ "Currently only support sizing from layout");
+ }
+
+ public void setKeepScreenOn(boolean screenOn) {
+ ((RootViewSurfaceTaker)mView).setSurfaceKeepScreenOn(screenOn);
+ }
+ }
+
static class InputMethodCallback extends IInputMethodCallback.Stub {
private WeakReference<ViewRoot> mViewRoot;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 7dd5085..234deba 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -473,6 +473,14 @@ public abstract class Window {
}
/**
+ * Take ownership of this window's surface. The window's view hierarchy
+ * will no longer draw into the surface, though it will otherwise continue
+ * to operate (such as for receiving input events). The given SurfaceHolder
+ * callback will be used to tell you about state changes to the surface.
+ */
+ public abstract void takeSurface(SurfaceHolder.Callback callback);
+
+ /**
* Return whether this window is being displayed with a floating style
* (based on the {@link android.R.attr#windowIsFloating} attribute in
* the style/theme).
diff --git a/core/java/com/android/internal/view/BaseSurfaceHolder.java b/core/java/com/android/internal/view/BaseSurfaceHolder.java
index e0d3a5f..3a04993 100644
--- a/core/java/com/android/internal/view/BaseSurfaceHolder.java
+++ b/core/java/com/android/internal/view/BaseSurfaceHolder.java
@@ -33,9 +33,11 @@ public abstract class BaseSurfaceHolder implements SurfaceHolder {
public final ArrayList<SurfaceHolder.Callback> mCallbacks
= new ArrayList<SurfaceHolder.Callback>();
-
+ SurfaceHolder.Callback[] mGottenCallbacks;
+ boolean mHaveGottenCallbacks;
+
public final ReentrantLock mSurfaceLock = new ReentrantLock();
- public final Surface mSurface = new Surface();
+ public Surface mSurface = new Surface();
int mRequestedWidth = -1;
int mRequestedHeight = -1;
@@ -83,6 +85,31 @@ public abstract class BaseSurfaceHolder implements SurfaceHolder {
}
}
+ public SurfaceHolder.Callback[] getCallbacks() {
+ if (mHaveGottenCallbacks) {
+ return mGottenCallbacks;
+ }
+
+ synchronized (mCallbacks) {
+ final int N = mCallbacks.size();
+ if (N > 0) {
+ if (mGottenCallbacks == null || mGottenCallbacks.length != N) {
+ mGottenCallbacks = new SurfaceHolder.Callback[N];
+ }
+ mCallbacks.toArray(mGottenCallbacks);
+ } else {
+ mGottenCallbacks = null;
+ }
+ mHaveGottenCallbacks = true;
+ }
+
+ return mGottenCallbacks;
+ }
+
+ public void ungetCallbacks() {
+ mHaveGottenCallbacks = false;
+ }
+
public void setFixedSize(int width, int height) {
if (mRequestedWidth != width || mRequestedHeight != height) {
mRequestedWidth = width;
diff --git a/core/java/com/android/internal/view/RootViewSurfaceTaker.java b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
new file mode 100644
index 0000000..fcb1645
--- /dev/null
+++ b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
@@ -0,0 +1,11 @@
+package com.android.internal.view;
+
+import android.view.SurfaceHolder;
+
+/** hahahah */
+public interface RootViewSurfaceTaker {
+ SurfaceHolder.Callback willYouTakeTheSurface();
+ void setSurfaceType(int type);
+ void setSurfaceFormat(int format);
+ void setSurfaceKeepScreenOn(boolean keepOn);
+}
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.provider.Settings;
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 @@ import java.util.Calendar;
/**
* 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";