Merge change 5595 into donut
* changes:
We might try to close the Vorbis file twice under certain circumstances. This fix nulls the mFile member so we don't try to close it twice. Bug 1904783.
diff --git a/api/current.xml b/api/current.xml
index 66bdb28..673d053 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3452,39 +3452,6 @@
visibility="public"
>
</field>
-<field name="donut_resource_pad26"
- type="int"
- transient="false"
- volatile="false"
- value="16843398"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad27"
- type="int"
- transient="false"
- volatile="false"
- value="16843397"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad28"
- type="int"
- transient="false"
- volatile="false"
- value="16843396"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="donut_resource_pad3"
type="int"
transient="false"
@@ -5311,6 +5278,17 @@
visibility="public"
>
</field>
+<field name="largeScreens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843398"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="launchMode"
type="int"
transient="false"
@@ -6191,6 +6169,17 @@
visibility="public"
>
</field>
+<field name="normalScreens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843397"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="numColumns"
type="int"
transient="false"
@@ -7577,6 +7566,17 @@
visibility="public"
>
</field>
+<field name="smallScreens"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843396"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="smoothScrollbar"
type="int"
transient="false"
@@ -34821,6 +34821,17 @@
visibility="public"
>
</field>
+<field name="CONFIG_SCREEN_LAYOUT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="256"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="CONFIG_TOUCHSCREEN"
type="int"
transient="false"
@@ -35289,6 +35300,28 @@
type="int"
transient="false"
volatile="false"
+ value="2048"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_SUPPORTS_NORMAL_SCREENS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_SUPPORTS_SMALL_SCREENS"
+ type="int"
+ transient="false"
+ volatile="false"
value="512"
static="true"
final="true"
@@ -39488,6 +39521,50 @@
visibility="public"
>
</field>
+<field name="SCREENLAYOUT_LARGE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREENLAYOUT_NORMAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREENLAYOUT_SMALL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREENLAYOUT_UNDEFINED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="TOUCHSCREEN_FINGER"
type="int"
transient="false"
@@ -39622,6 +39699,16 @@
visibility="public"
>
</field>
+<field name="screenLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="touchscreen"
type="int"
transient="false"
@@ -139401,6 +139488,19 @@
visibility="public"
>
</method>
+<method name="buildDrawingCache"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoScale" type="boolean">
+</parameter>
+</method>
<method name="cancelLongPress"
return="void"
abstract="false"
@@ -139977,6 +140077,19 @@
visibility="public"
>
</method>
+<method name="getDrawingCache"
+ return="android.graphics.Bitmap"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoScale" type="boolean">
+</parameter>
+</method>
<method name="getDrawingCacheBackgroundColor"
return="int"
abstract="false"
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 01083f1..c299bff 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -171,9 +171,7 @@
if (sets == null || sets.length == 0) {
System.out.println("No restore sets available");
} else {
- for (RestoreSet s : sets) {
- System.out.println(" " + s.token + " : " + s.name);
- }
+ printRestoreSets(sets);
}
} catch (RemoteException e) {
System.err.println(e.toString());
@@ -181,6 +179,12 @@
}
}
+ private void printRestoreSets(RestoreSet[] sets) {
+ for (RestoreSet s : sets) {
+ System.out.println(" " + s.token + " : " + s.name);
+ }
+ }
+
class RestoreObserver extends IRestoreObserver.Stub {
boolean done;
public void restoreStarting(int numPackages) {
@@ -201,9 +205,9 @@
}
private void doRestore() {
- int token;
+ long token;
try {
- token = Integer.parseInt(nextArg());
+ token = Long.parseLong(nextArg());
} catch (NumberFormatException e) {
showUsage();
return;
@@ -212,6 +216,7 @@
RestoreObserver observer = new RestoreObserver();
try {
+ boolean didRestore = false;
int curTransport = mBmgr.getCurrentTransport();
mRestore = mBmgr.beginRestoreSession(curTransport);
if (mRestore == null) {
@@ -223,9 +228,18 @@
if (s.token == token) {
System.out.println("Scheduling restore: " + s.name);
mRestore.performRestore(token, observer);
+ didRestore = true;
break;
}
}
+ if (!didRestore) {
+ if (sets == null || sets.length == 0) {
+ System.out.println("No available restore sets; no restore performed");
+ } else {
+ System.out.println("No matching restore set token. Available sets:");
+ printRestoreSets(sets);
+ }
+ }
mRestore.endRestoreSession();
} catch (RemoteException e) {
System.err.println(e.toString());
diff --git a/core/java/android/backup/BackupManager.java b/core/java/android/backup/BackupManager.java
index 8df7eae..79e2c03 100644
--- a/core/java/android/backup/BackupManager.java
+++ b/core/java/android/backup/BackupManager.java
@@ -68,9 +68,11 @@
* {@link android.app.BackupAgent} subclass will be scheduled when you call this method.
*/
public void dataChanged() {
- try {
- mService.dataChanged(mContext.getPackageName());
- } catch (RemoteException e) {
+ if (mService != null) {
+ try {
+ mService.dataChanged(mContext.getPackageName());
+ } catch (RemoteException e) {
+ }
}
}
@@ -83,9 +85,11 @@
*/
public IRestoreSession beginRestoreSession(int transportID) {
IRestoreSession binder = null;
- try {
- binder = mService.beginRestoreSession(transportID);
- } catch (RemoteException e) {
+ if (mService != null) {
+ try {
+ binder = mService.beginRestoreSession(transportID);
+ } catch (RemoteException e) {
+ }
}
return binder;
}
diff --git a/core/java/android/backup/IRestoreSession.aidl b/core/java/android/backup/IRestoreSession.aidl
index ac01c2d..2a1fbc1 100644
--- a/core/java/android/backup/IRestoreSession.aidl
+++ b/core/java/android/backup/IRestoreSession.aidl
@@ -45,7 +45,7 @@
* @param observer If non-null, this binder points to an object that will receive
* progress callbacks during the restore operation.
*/
- int performRestore(int token, IRestoreObserver observer);
+ int performRestore(long token, IRestoreObserver observer);
/**
* End this restore session. After this method is called, the IRestoreSession binder
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index f492629..4a7b399 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -30,7 +30,7 @@
private Context mContext;
private String[] mPrefGroups;
- public SharedPreferencesBackupHelper(Context context, String[] prefGroups) {
+ public SharedPreferencesBackupHelper(Context context, String... prefGroups) {
super(context);
mContext = context;
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 85d877a..27783ef 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -235,6 +235,12 @@
public static final int CONFIG_ORIENTATION = 0x0080;
/**
* Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle changes to the screen layout. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_SCREEN_LAYOUT = 0x0100;
+ /**
+ * Bit in {@link #configChanges} that indicates that the activity
* can itself handle changes to the font scaling factor. Set from the
* {@link android.R.attr#configChanges} attribute. This is
* not a core resource configutation, but a higher-level value, so its
@@ -248,8 +254,8 @@
* Contains any combination of {@link #CONFIG_FONT_SCALE},
* {@link #CONFIG_MCC}, {@link #CONFIG_MNC},
* {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN},
- * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION}, and
- * {@link #CONFIG_ORIENTATION}. Set from the
+ * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION},
+ * {@link #CONFIG_ORIENTATION}, and {@link #CONFIG_SCREEN_LAYOUT}. Set from the
* {@link android.R.attr#configChanges} attribute.
*/
public int configChanges;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 2a2cf93..bcf95b6 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -138,10 +138,27 @@
/**
* Value for {@link #flags}: true when the application's window can be
- * expanded over default window size in target density (320x480 for
- * 1.0 density, 480x720 for 1.5 density etc)
+ * reduced in size for smaller screens. Corresponds to
+ * {@link android.R.styleable#AndroidManifestSupportsScreens_smallScreens
+ * android:smallScreens}.
*/
- public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<9;
+ public static final int FLAG_SUPPORTS_SMALL_SCREENS = 1<<9;
+
+ /**
+ * Value for {@link #flags}: true when the application's window can be
+ * displayed on normal screens. Corresponds to
+ * {@link android.R.styleable#AndroidManifestSupportsScreens_normalScreens
+ * android:normalScreens}.
+ */
+ public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1<<10;
+
+ /**
+ * 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}.
+ */
+ public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<11;
/**
* Value for {@link #flags}: this is false if the application has set
@@ -149,7 +166,7 @@
*
* {@hide}
*/
- public static final int FLAG_ALLOW_BACKUP = 1<<10;
+ public static final int FLAG_ALLOW_BACKUP = 1<<12;
/**
* Indicates that the application supports any densities;
@@ -164,7 +181,9 @@
* {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
* {@link #FLAG_ALLOW_TASK_REPARENTING}
* {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
- * {@link #FLAG_TEST_ONLY}.
+ * {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
+ * {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
+ * {@link #FLAG_SUPPORTS_LARGE_SCREENS}.
*/
public int flags = 0;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ab9518e..558b0c3 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -668,6 +668,11 @@
}
sa.recycle();
+ // Resource boolean are -1, so 1 means we don't know the value.
+ int supportsSmallScreens = 1;
+ int supportsNormalScreens = 1;
+ int supportsLargeScreens = 1;
+
int outerDepth = parser.getDepth();
while ((type=parser.next()) != parser.END_DOCUMENT
&& (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -876,8 +881,24 @@
XmlUtils.skipCurrentTag(parser);
- } else if (tagName.equals("expandable")) {
- pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
+ } else if (tagName.equals("supports-screens")) {
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestSupportsScreens);
+
+ // This is a trick to get a boolean and still able to detect
+ // if a value was actually set.
+ supportsSmallScreens = sa.getInteger(
+ com.android.internal.R.styleable.AndroidManifestSupportsScreens_smallScreens,
+ supportsSmallScreens);
+ supportsNormalScreens = sa.getInteger(
+ com.android.internal.R.styleable.AndroidManifestSupportsScreens_normalScreens,
+ supportsNormalScreens);
+ supportsLargeScreens = sa.getInteger(
+ com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
+ supportsLargeScreens);
+
+ sa.recycle();
+
XmlUtils.skipCurrentTag(parser);
} else {
Log.w(TAG, "Bad element under <manifest>: "
@@ -910,7 +931,20 @@
pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
}
- // TODO: enable all density & expandable if target sdk is higher than donut
+
+ if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
+ && pkg.applicationInfo.targetSdkVersion
+ >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
+ }
+ if (supportsNormalScreens != 0) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
+ }
+ if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
+ && pkg.applicationInfo.targetSdkVersion
+ >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
+ }
int size = pkg.supportsDensityList.size();
if (size > 0) {
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 1c91736..5c7b01f 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -601,7 +601,7 @@
public native final void setConfiguration(int mcc, int mnc, String locale,
int orientation, int touchscreen, int density, int keyboard,
int keyboardHidden, int navigation, int screenWidth, int screenHeight,
- int majorVersion);
+ int screenLayout, int majorVersion);
/**
* Retrieve the resource identifier for the given resource name.
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 179b9bd..4e6fe07 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -65,7 +65,7 @@
/**
* A compatibility flags
*/
- private int compatibilityFlags;
+ private int mCompatibilityFlags;
/**
* A flag mask to tell if the application needs scaling (when mApplicationScale != 1.0f)
@@ -101,7 +101,11 @@
*/
public final float applicationInvertedScale;
-
+ /**
+ * The flags from ApplicationInfo.
+ */
+ public final int appFlags;
+
/**
* Window size in Compatibility Mode, in real pixels. This is updated by
* {@link DisplayMetrics#updateMetrics}.
@@ -117,8 +121,10 @@
private int mXOffset;
public CompatibilityInfo(ApplicationInfo appInfo) {
+ appFlags = appInfo.flags;
+
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
- compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
+ mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
}
float packageDensityScale = -1.0f;
@@ -149,13 +155,16 @@
}
applicationInvertedScale = 1.0f / applicationScale;
if (applicationScale != 1.0f) {
- compatibilityFlags |= SCALING_REQUIRED;
+ mCompatibilityFlags |= SCALING_REQUIRED;
}
}
private CompatibilityInfo() {
+ appFlags = ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
applicationScale = applicationInvertedScale = 1.0f;
- compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
+ mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
}
/**
@@ -175,9 +184,9 @@
*/
public void setExpandable(boolean expandable) {
if (expandable) {
- compatibilityFlags |= CompatibilityInfo.EXPANDABLE;
+ mCompatibilityFlags |= CompatibilityInfo.EXPANDABLE;
} else {
- compatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
+ mCompatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
}
}
@@ -185,20 +194,20 @@
* @return true if the application is configured to be expandable.
*/
public boolean isConfiguredExpandable() {
- return (compatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
+ return (mCompatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
}
/**
* @return true if the scaling is required
*/
public boolean isScalingRequired() {
- return (compatibilityFlags & SCALING_REQUIRED) != 0;
+ return (mCompatibilityFlags & SCALING_REQUIRED) != 0;
}
@Override
public String toString() {
return "CompatibilityInfo{scale=" + applicationScale +
- ", compatibility flag=" + compatibilityFlags + "}";
+ ", compatibility flag=" + mCompatibilityFlags + "}";
}
/**
@@ -222,13 +231,13 @@
* @param params the window's parameter
*/
public Translator getTranslator(WindowManager.LayoutParams params) {
- if ( (compatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
+ if ( (mCompatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
== CompatibilityInfo.EXPANDABLE) {
if (DBG) Log.d(TAG, "no translation required");
return null;
}
- if ((compatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
+ if ((mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
if ((params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
if (DBG) Log.d(TAG, "translation for surface view selected");
return new Translator(X_SHIFT_WINDOW, false, 1.0f, 1.0f);
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index bb3486c..577aa60 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -116,6 +116,18 @@
*/
public int orientation;
+ public static final int SCREENLAYOUT_UNDEFINED = 0;
+ public static final int SCREENLAYOUT_SMALL = 1;
+ public static final int SCREENLAYOUT_NORMAL = 2;
+ public static final int SCREENLAYOUT_LARGE = 3;
+
+ /**
+ * Overall layout of the screen. May be one of
+ * {@link #SCREENLAYOUT_SMALL}, {@link #SCREENLAYOUT_NORMAL},
+ * or {@link #SCREENLAYOUT_LARGE}.
+ */
+ public int screenLayout;
+
/**
* Construct an invalid Configuration. You must call {@link #setToDefaults}
* for this object to be valid. {@more}
@@ -141,6 +153,7 @@
hardKeyboardHidden = o.hardKeyboardHidden;
navigation = o.navigation;
orientation = o.orientation;
+ screenLayout = o.screenLayout;
}
public String toString() {
@@ -165,6 +178,8 @@
sb.append(navigation);
sb.append(" orien=");
sb.append(orientation);
+ sb.append(" layout=");
+ sb.append(screenLayout);
sb.append('}');
return sb.toString();
}
@@ -183,6 +198,7 @@
hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
navigation = NAVIGATION_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
+ screenLayout = SCREENLAYOUT_UNDEFINED;
}
/** {@hide} */
@@ -253,6 +269,11 @@
changed |= ActivityInfo.CONFIG_ORIENTATION;
orientation = delta.orientation;
}
+ if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
+ && screenLayout != delta.screenLayout) {
+ changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
+ screenLayout = delta.screenLayout;
+ }
return changed;
}
@@ -276,9 +297,11 @@
* {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD
* PackageManager.ActivityInfo.CONFIG_KEYBOARD},
* {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
- * PackageManager.ActivityInfo.CONFIG_NAVIGATION}, or
+ * PackageManager.ActivityInfo.CONFIG_NAVIGATION},
* {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
- * PackageManager.ActivityInfo.CONFIG_ORIENTATION}.
+ * PackageManager.ActivityInfo.CONFIG_ORIENTATION}, or
+ * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
+ * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}.
*/
public int diff(Configuration delta) {
int changed = 0;
@@ -319,6 +342,10 @@
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
}
+ if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
+ && screenLayout != delta.screenLayout) {
+ changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
+ }
return changed;
}
@@ -368,6 +395,7 @@
dest.writeInt(hardKeyboardHidden);
dest.writeInt(navigation);
dest.writeInt(orientation);
+ dest.writeInt(screenLayout);
}
public static final Parcelable.Creator<Configuration> CREATOR
@@ -399,6 +427,7 @@
hardKeyboardHidden = source.readInt();
navigation = source.readInt();
orientation = source.readInt();
+ screenLayout = source.readInt();
}
public int compareTo(Configuration that) {
@@ -428,6 +457,8 @@
n = this.navigation - that.navigation;
if (n != 0) return n;
n = this.orientation - that.orientation;
+ if (n != 0) return n;
+ n = this.screenLayout - that.screenLayout;
//if (n != 0) return n;
return n;
}
@@ -450,6 +481,6 @@
return ((int)this.fontScale) + this.mcc + this.mnc
+ this.locale.hashCode() + this.touchscreen
+ this.keyboard + this.keyboardHidden + this.hardKeyboardHidden
- + this.navigation + this.orientation;
+ + this.navigation + this.orientation + this.screenLayout;
}
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index cb9d46e..d7512bb 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1267,7 +1267,8 @@
}
if (metrics != null) {
mMetrics.setTo(metrics);
- mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration.orientation);
+ mMetrics.updateMetrics(mCompatibilityInfo,
+ mConfiguration.orientation, mConfiguration.screenLayout);
}
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
@@ -1299,7 +1300,7 @@
mConfiguration.touchscreen,
(int)(mMetrics.density*160), mConfiguration.keyboard,
keyboardHidden, mConfiguration.navigation, width, height,
- sSdkVersion);
+ mConfiguration.screenLayout, sSdkVersion);
int N = mDrawableCache.size();
if (DEBUG_CONFIG) {
Log.d(TAG, "Cleaning up drawables config changes: 0x"
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index ca579b6..09fbc97 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -39,13 +39,16 @@
public class Camera {
private static final String TAG = "Camera";
- // These match the enum in libs/android_runtime/android_hardware_Camera.cpp
- private static final int SHUTTER_CALLBACK = 0;
- private static final int RAW_PICTURE_CALLBACK = 1;
- private static final int JPEG_PICTURE_CALLBACK = 2;
- private static final int PREVIEW_CALLBACK = 3;
- private static final int AUTOFOCUS_CALLBACK = 4;
- private static final int ERROR_CALLBACK = 5;
+ // These match the enums in frameworks/base/include/ui/Camera.h
+ private static final int CAMERA_MSG_ERROR = 0;
+ private static final int CAMERA_MSG_SHUTTER = 1;
+ private static final int CAMERA_MSG_FOCUS = 2;
+ private static final int CAMERA_MSG_ZOOM = 3;
+ private static final int CAMERA_MSG_PREVIEW_FRAME = 4;
+ private static final int CAMERA_MSG_VIDEO_FRAME = 5;
+ private static final int CAMERA_MSG_POSTVIEW_FRAME = 6;
+ private static final int CAMERA_MSG_RAW_IMAGE = 7;
+ private static final int CAMERA_MSG_COMPRESSED_IMAGE = 8;
private int mNativeContext; // accessed by native methods
private EventHandler mEventHandler;
@@ -231,22 +234,23 @@
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
- case SHUTTER_CALLBACK:
+ case CAMERA_MSG_SHUTTER:
if (mShutterCallback != null) {
mShutterCallback.onShutter();
}
return;
- case RAW_PICTURE_CALLBACK:
+
+ case CAMERA_MSG_RAW_IMAGE:
if (mRawImageCallback != null)
mRawImageCallback.onPictureTaken((byte[])msg.obj, mCamera);
return;
- case JPEG_PICTURE_CALLBACK:
+ case CAMERA_MSG_COMPRESSED_IMAGE:
if (mJpegCallback != null)
mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);
return;
- case PREVIEW_CALLBACK:
+ case CAMERA_MSG_PREVIEW_FRAME:
if (mPreviewCallback != null) {
mPreviewCallback.onPreviewFrame((byte[])msg.obj, mCamera);
if (mOneShot) {
@@ -255,12 +259,12 @@
}
return;
- case AUTOFOCUS_CALLBACK:
+ case CAMERA_MSG_FOCUS:
if (mAutoFocusCallback != null)
mAutoFocusCallback.onAutoFocus(msg.arg1 == 0 ? false : true, mCamera);
return;
- case ERROR_CALLBACK:
+ case CAMERA_MSG_ERROR :
Log.e(TAG, "Error " + msg.arg1);
if (mErrorCallback != null)
mErrorCallback.onError(msg.arg1, mCamera);
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 6c13582..abfb274 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -127,12 +127,12 @@
public abstract class AsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = "AsyncTask";
- private static final int CORE_POOL_SIZE = 1;
- private static final int MAXIMUM_POOL_SIZE = 10;
+ private static final int CORE_POOL_SIZE = 5;
+ private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 10;
private static final BlockingQueue<Runnable> sWorkQueue =
- new LinkedBlockingQueue<Runnable>(MAXIMUM_POOL_SIZE);
+ new LinkedBlockingQueue<Runnable>(10);
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index 6ea2528..95e54324 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -150,7 +150,7 @@
// Set the title bar if title is available, else no title bar
final CharSequence title = getTitle();
- Dialog dialog = mDialog = new Dialog(context, !TextUtils.isEmpty(title)
+ Dialog dialog = mDialog = new Dialog(context, TextUtils.isEmpty(title)
? com.android.internal.R.style.Theme_NoTitleBar
: com.android.internal.R.style.Theme);
dialog.setContentView(listView);
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index 789fdff..1ba5e25e 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -91,6 +91,17 @@
*/
public static final String EXTRA_APPEND_LOCATION = "com.android.browser.append_location";
+ /**
+ * The name of the extra data in the VIEW intent. The data is in the format of
+ * a byte array.
+ * <p>
+ * Any value sent here will be passed in the http request to the provided url as post data.
+ * <p>
+ * pending api approval
+ * @hide
+ */
+ public static final String EXTRA_POST_DATA = "com.android.browser.post_data";
+
/* if you change column order you must also change indices
below */
public static final String[] HISTORY_PROJECTION = new String[] {
diff --git a/core/java/android/speech/tts/ITts.aidl b/core/java/android/speech/tts/ITts.aidl
index 75c3b30..47976e5 100755
--- a/core/java/android/speech/tts/ITts.aidl
+++ b/core/java/android/speech/tts/ITts.aidl
@@ -33,6 +33,8 @@
void speak(in String text, in int queueMode, in String[] params);
+ void speakIpa(in String ipaText, in int queueMode, in String[] params);
+
boolean isSpeaking();
void stop();
@@ -43,7 +45,9 @@
void setLanguage(in String language, in String country, in String variant);
- boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
+ boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
+
+ boolean synthesizeIpaToFile(in String ipaText, in String[] params, in String outputDirectory);
void playEarcon(in String earcon, in int queueMode, in String[] params);
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 1502d98..8fa06fa 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -369,7 +369,28 @@
*/
public void speakIpa(String ipaText, int queueMode, HashMap<String,String> params)
{
- //TODO: Implement speakIpa
+ synchronized (mStartLock) {
+ Log.i("TTS received: ", ipaText);
+ if (!mStarted) {
+ return;
+ }
+ try {
+ // TODO support extra parameters, passing cache of current parameters for the moment
+ mITts.speakIpa(ipaText, queueMode, mCachedParams);
+ } catch (RemoteException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ } catch (NullPointerException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ } catch (IllegalStateException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ }
+ }
}
@@ -410,7 +431,27 @@
public void playSilence(long durationInMs, int queueMode) {
- // TODO implement, already present in TTS service
+ synchronized (mStartLock) {
+ if (!mStarted) {
+ return;
+ }
+ try {
+ // TODO support extra parameters, passing cache of current parameters for the moment
+ mITts.playSilence(durationInMs, queueMode, mCachedParams);
+ } catch (RemoteException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ } catch (NullPointerException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ } catch (IllegalStateException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ }
+ }
}
@@ -580,7 +621,7 @@
/**
- * Speaks the given text using the specified queueing mode and parameters.
+ * Synthesizes the given text to a file using the specified parameters.
*
* @param text
* The String of text that should be synthesized
@@ -617,5 +658,42 @@
}
}
+ /**
+ * Synthesizes the given IPA text to a file using the specified parameters.
+ *
+ * @param text
+ * The String of text that should be synthesized
+ * @param params
+ * A hashmap of parameters.
+ * @param filename
+ * The string that gives the full output filename; it should be
+ * something like "/sdcard/myappsounds/mysound.wav".
+ * @return A boolean that indicates if the synthesis succeeded
+ */
+ public boolean synthesizeIpaToFile(String ipaText,
+ HashMap<String,String> params, String filename) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
+ return false;
+ }
+ try {
+ // TODO support extra parameters, passing null for the moment
+ return mITts.synthesizeIpaToFile(ipaText, null, filename);
+ } catch (RemoteException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ } catch (NullPointerException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ } catch (IllegalStateException e) {
+ // TTS died; restart it.
+ mStarted = false;
+ initTts();
+ }
+ return false;
+ }
+ }
}
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index d89ada0..4179edb 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -103,40 +103,43 @@
/**
* Update the display metrics based on the compatibility info and orientation
+ * NOTE: DO NOT EXPOSE THIS API! It is introducing a circular dependency
+ * with the higher-level android.res package.
* {@hide}
*/
- public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) {
+ public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation,
+ int screenLayout) {
int xOffset = 0;
if (!compatibilityInfo.isConfiguredExpandable()) {
// Note: this assume that configuration is updated before calling
// updateMetrics method.
- int defaultWidth;
- int defaultHeight;
- switch (orientation) {
- case Configuration.ORIENTATION_LANDSCAPE: {
- defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
- defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
- break;
- }
- case Configuration.ORIENTATION_PORTRAIT:
- case Configuration.ORIENTATION_SQUARE:
- default: {
- defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
- defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
- break;
- }
- case Configuration.ORIENTATION_UNDEFINED: {
- // don't change
- return;
- }
- }
-
- if (defaultWidth == widthPixels && defaultHeight == heightPixels) {
- // the screen size is same as expected size. make it expandable
- compatibilityInfo.setExpandable(true);
- } else {
+ if (screenLayout == Configuration.SCREENLAYOUT_LARGE) {
+ // This is a large screen device and the app is not
+ // compatible with large screens, to diddle it.
+
compatibilityInfo.setExpandable(false);
- // adjust the size only when the device's screen is bigger.
+ // Figure out the compatibility width and height of the screen.
+ int defaultWidth;
+ int defaultHeight;
+ switch (orientation) {
+ case Configuration.ORIENTATION_LANDSCAPE: {
+ defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
+ defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
+ break;
+ }
+ case Configuration.ORIENTATION_PORTRAIT:
+ case Configuration.ORIENTATION_SQUARE:
+ default: {
+ defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
+ defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
+ break;
+ }
+ case Configuration.ORIENTATION_UNDEFINED: {
+ // don't change
+ return;
+ }
+ }
+
if (defaultWidth < widthPixels) {
// content/window's x offset in original pixels
xOffset = ((widthPixels - defaultWidth) / 2);
@@ -145,6 +148,10 @@
if (defaultHeight < heightPixels) {
heightPixels = defaultHeight;
}
+
+ } else {
+ // the screen size is same as expected size. make it expandable
+ compatibilityInfo.setExpandable(true);
}
}
compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3bfdde8..c9a785c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1690,6 +1690,7 @@
private int[] mDrawableState = null;
private SoftReference<Bitmap> mDrawingCache;
+ private SoftReference<Bitmap> mUnscaledDrawingCache;
/**
* When this view has focus and the next focus is {@link #FOCUS_LEFT},
@@ -5783,28 +5784,52 @@
}
/**
+ * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
+ *
+ * @return A non-scaled bitmap representing this view or null if cache is disabled.
+ *
+ * @see #getDrawingCache(boolean)
+ */
+ public Bitmap getDrawingCache() {
+ return getDrawingCache(false);
+ }
+
+ /**
* <p>Returns the bitmap in which this view drawing is cached. The returned bitmap
* is null when caching is disabled. If caching is enabled and the cache is not ready,
* this method will create it. Calling {@link #draw(android.graphics.Canvas)} will not
* draw from the cache when the cache is enabled. To benefit from the cache, you must
* request the drawing cache by calling this method and draw it on screen if the
* returned bitmap is not null.</p>
+ *
+ * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
+ * this method will create a bitmap of the same size as this view. Because this bitmap
+ * will be drawn scaled by the parent ViewGroup, the result on screen might show
+ * scaling artifacts. To avoid such artifacts, you should call this method by setting
+ * the auto scaling to true. Doing so, however, will generate a bitmap of a different
+ * size than the view. This implies that your application must be able to handle this
+ * size.</p>
+ *
+ * @param autoScale Indicates whether the generated bitmap should be scaled based on
+ * the current density of the screen when the application is in compatibility
+ * mode.
*
- * @return a bitmap representing this view or null if cache is disabled
- *
+ * @return A bitmap representing this view or null if cache is disabled.
+ *
* @see #setDrawingCacheEnabled(boolean)
* @see #isDrawingCacheEnabled()
- * @see #buildDrawingCache()
+ * @see #buildDrawingCache(boolean)
* @see #destroyDrawingCache()
*/
- public Bitmap getDrawingCache() {
+ public Bitmap getDrawingCache(boolean autoScale) {
if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
return null;
}
if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
- buildDrawingCache();
+ buildDrawingCache(autoScale);
}
- return mDrawingCache == null ? null : mDrawingCache.get();
+ return autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) :
+ (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
}
/**
@@ -5823,6 +5848,11 @@
if (bitmap != null) bitmap.recycle();
mDrawingCache = null;
}
+ if (mUnscaledDrawingCache != null) {
+ final Bitmap bitmap = mUnscaledDrawingCache.get();
+ if (bitmap != null) bitmap.recycle();
+ mUnscaledDrawingCache = null;
+ }
}
/**
@@ -5850,18 +5880,36 @@
}
/**
+ * <p>Calling this method is equivalent to calling <code>buildDrawingCache(false)</code>.</p>
+ *
+ * @see #buildDrawingCache(boolean)
+ */
+ public void buildDrawingCache() {
+ buildDrawingCache(false);
+ }
+
+ /**
* <p>Forces the drawing cache to be built if the drawing cache is invalid.</p>
*
* <p>If you call {@link #buildDrawingCache()} manually without calling
* {@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you
* should cleanup the cache by calling {@link #destroyDrawingCache()} afterwards.</p>
+ *
+ * <p>Note about auto scaling in compatibility mode: When auto scaling is not enabled,
+ * this method will create a bitmap of the same size as this view. Because this bitmap
+ * will be drawn scaled by the parent ViewGroup, the result on screen might show
+ * scaling artifacts. To avoid such artifacts, you should call this method by setting
+ * the auto scaling to true. Doing so, however, will generate a bitmap of a different
+ * size than the view. This implies that your application must be able to handle this
+ * size.</p>
*
* @see #getDrawingCache()
* @see #destroyDrawingCache()
*/
- public void buildDrawingCache() {
- if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mDrawingCache == null ||
- mDrawingCache.get() == null) {
+ public void buildDrawingCache(boolean autoScale) {
+ if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ?
+ (mDrawingCache == null || mDrawingCache.get() == null) :
+ (mUnscaledDrawingCache == null || mUnscaledDrawingCache.get() == null))) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);
@@ -5874,12 +5922,10 @@
int height = mBottom - mTop;
final AttachInfo attachInfo = mAttachInfo;
- if (attachInfo != null) {
- final boolean scalingRequired = attachInfo.mScalingRequired;
- if (scalingRequired) {
- width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
- height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
- }
+
+ if (autoScale && attachInfo != null && attachInfo.mScalingRequired) {
+ width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
+ height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
}
final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
@@ -5894,7 +5940,8 @@
}
boolean clear = true;
- Bitmap bitmap = mDrawingCache == null ? null : mDrawingCache.get();
+ Bitmap bitmap = autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) :
+ (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
@@ -5923,12 +5970,20 @@
try {
bitmap = Bitmap.createBitmap(width, height, quality);
- mDrawingCache = new SoftReference<Bitmap>(bitmap);
+ if (autoScale) {
+ mDrawingCache = new SoftReference<Bitmap>(bitmap);
+ } else {
+ mUnscaledDrawingCache = new SoftReference<Bitmap>(bitmap);
+ }
} catch (OutOfMemoryError e) {
// If there is not enough memory to create the bitmap cache, just
// ignore the issue as bitmap caches are not required to draw the
// view hierarchy
- mDrawingCache = null;
+ if (autoScale) {
+ mDrawingCache = null;
+ } else {
+ mUnscaledDrawingCache = null;
+ }
return;
}
@@ -5940,13 +5995,6 @@
canvas = attachInfo.mCanvas;
if (canvas == null) {
canvas = new Canvas();
-
- // NOTE: This should have to happen only once since compatibility
- // mode should not change at runtime
- if (attachInfo.mScalingRequired) {
- final float scale = attachInfo.mApplicationScale;
- canvas.scale(scale, scale);
- }
}
canvas.setBitmap(bitmap);
// Temporarily clobber the cached Canvas in case one of our children
@@ -5965,6 +6013,12 @@
computeScroll();
final int restoreCount = canvas.save();
+
+ if (autoScale && attachInfo.mScalingRequired) {
+ final float scale = attachInfo.mApplicationScale;
+ canvas.scale(scale, scale);
+ }
+
canvas.translate(-mScrollX, -mScrollY);
mPrivateFlags |= DRAWN;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f803b5a..f7b7f02 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1166,7 +1166,7 @@
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
child.setDrawingCacheEnabled(true);
- child.buildDrawingCache();
+ child.buildDrawingCache(true);
}
}
@@ -1208,7 +1208,7 @@
bindLayoutAnimation(child);
if (cache) {
child.setDrawingCacheEnabled(true);
- child.buildDrawingCache();
+ child.buildDrawingCache(true);
}
}
}
@@ -1448,7 +1448,7 @@
Bitmap cache = null;
if ((flags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE ||
(flags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE) {
- cache = child.getDrawingCache();
+ cache = child.getDrawingCache(true);
if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
}
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 70749d1..e84e5b0 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1202,7 +1202,11 @@
int position, long id) {
if (position != -1) {
- mDropDownList.mListSelectionHidden = false;
+ DropDownListView dropDownList = mDropDownList;
+
+ if (dropDownList != null) {
+ dropDownList.mListSelectionHidden = false;
+ }
}
}
diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java
index 4757919..031abdd 100644
--- a/core/java/com/android/internal/util/BitwiseInputStream.java
+++ b/core/java/com/android/internal/util/BitwiseInputStream.java
@@ -69,19 +69,19 @@
*
* @return byte of read data (possibly partially filled, from lsb)
*/
- public byte read(int bits) throws AccessException {
+ public int read(int bits) throws AccessException {
int index = mPos >>> 3;
int offset = 16 - (mPos & 0x07) - bits; // &7==%8
if ((bits < 0) || (bits > 8) || ((mPos + bits) > mEnd)) {
throw new AccessException("illegal read " +
"(pos " + mPos + ", end " + mEnd + ", bits " + bits + ")");
}
- int data = (mBuf[index] & 0x00FF) << 8;
- if (offset < 8) data |= (mBuf[index + 1] & 0xFF);
+ int data = (mBuf[index] & 0xFF) << 8;
+ if (offset < 8) data |= mBuf[index + 1] & 0xFF;
data >>>= offset;
data &= (-1 >>> (32 - bits));
mPos += bits;
- return (byte)data;
+ return data;
}
/**
diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java
index 1b974ce..ab8a7f3 100644
--- a/core/java/com/android/internal/util/BitwiseOutputStream.java
+++ b/core/java/com/android/internal/util/BitwiseOutputStream.java
@@ -95,8 +95,8 @@
int offset = 16 - (mPos & 0x07) - bits; // &7==%8
data <<= offset;
mPos += bits;
- mBuf[index] |= (data >>> 8);
- if (offset < 8) mBuf[index + 1] |= (data & 0x00FF);
+ mBuf[index] |= data >>> 8;
+ if (offset < 8) mBuf[index + 1] |= data & 0xFF;
}
/**
diff --git a/core/jni/android_backup_BackupHelperDispatcher.cpp b/core/jni/android_backup_BackupHelperDispatcher.cpp
index 24d529b..2e3f0b9 100644
--- a/core/jni/android_backup_BackupHelperDispatcher.cpp
+++ b/core/jni/android_backup_BackupHelperDispatcher.cpp
@@ -87,6 +87,14 @@
}
}
+#if 0
+ LOGD("chunk header:");
+ LOGD(" headerSize=%d", flattenedHeader.headerSize);
+ LOGD(" version=0x%08x", flattenedHeader.version);
+ LOGD(" dataSize=%d", flattenedHeader.dataSize);
+ LOGD(" nameLength=%d", flattenedHeader.nameLength);
+#endif
+
if (flattenedHeader.dataSize < 0 || flattenedHeader.nameLength < 0 ||
remainingHeader < flattenedHeader.nameLength) {
LOGW("Malformed V1 header remainingHeader=%d dataSize=%d nameLength=%d", remainingHeader,
@@ -101,13 +109,12 @@
}
amt = read(fd, buf, flattenedHeader.nameLength);
+ buf[flattenedHeader.nameLength] = 0;
keyPrefix.unlockBuffer(flattenedHeader.nameLength);
remainingHeader -= flattenedHeader.nameLength;
- LOGD("remainingHeader=%d", remainingHeader);
-
if (remainingHeader > 0) {
lseek(fd, remainingHeader, SEEK_CUR);
}
@@ -183,6 +190,7 @@
header.headerSize = sizeof(chunk_header_v1) + header.nameLength + namePadding;
header.version = VERSION_1_HEADER;
+ header.dataSize = prevPos - (pos + header.headerSize);
lseek(fd, pos, SEEK_SET);
err = write(fd, &header, sizeof(chunk_header_v1));
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index b07ba7d..8e48b38 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -125,37 +125,8 @@
return;
}
JNIEnv *env = AndroidRuntime::getJNIEnv();
-
- // parse message
- switch (msgType) {
- case CAMERA_MSG_ERROR:
- LOGV("errorCallback");
- int error;
- switch (ext1) {
- case DEAD_OBJECT:
- error = kCameraErrorMediaServer;
- break;
- default:
- error = kCameraErrorUnknown;
- break;
- }
- env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kErrorCallback, error, 0, NULL);
- break;
- case CAMERA_MSG_FOCUS:
- LOGV("autoFocusCallback");
- env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kAutoFocusCallback, ext1, 0, NULL);
- break;
- case CAMERA_MSG_SHUTTER:
- LOGV("shutterCallback");
- env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kShutterCallback, 0, 0, NULL);
- break;
- default:
- LOGV("notifyCallback(%d, %d, %d)", msgType, ext1, ext2);
- break;
- }
+ env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
+ mCameraJObjectWeak, msgType, ext1, ext2);
}
void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType)
@@ -203,27 +174,20 @@
// return data based on callback type
switch(msgType) {
- case CAMERA_MSG_PREVIEW_FRAME:
- LOGV("previewCallback");
- copyAndPost(env, dataPtr, kPreviewCallback);
- break;
case CAMERA_MSG_VIDEO_FRAME:
- LOGV("recordingCallback");
+ // should never happen
break;
+ // don't return raw data to Java
case CAMERA_MSG_RAW_IMAGE:
LOGV("rawCallback");
env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kRawCallback, 0, 0, NULL);
- break;
- case CAMERA_MSG_COMPRESSED_IMAGE:
- LOGV("jpegCallback");
- copyAndPost(env, dataPtr, kJpegCallback);
+ mCameraJObjectWeak, msgType, 0, 0, NULL);
break;
default:
LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
+ copyAndPost(env, dataPtr, msgType);
break;
}
-
}
// connect to camera service
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index d147bcc..2d90ba4 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -535,7 +535,7 @@
jint keyboard, jint keyboardHidden,
jint navigation,
jint screenWidth, jint screenHeight,
- jint sdkVersion)
+ jint screenLayout, jint sdkVersion)
{
AssetManager* am = assetManagerForJavaObject(env, clazz);
if (am == NULL) {
@@ -557,6 +557,7 @@
config.navigation = (uint8_t)navigation;
config.screenWidth = (uint16_t)screenWidth;
config.screenHeight = (uint16_t)screenHeight;
+ config.screenLayout = (uint8_t)screenLayout;
config.sdkVersion = (uint16_t)sdkVersion;
config.minorVersion = 0;
am->setConfiguration(config, locale8);
@@ -1567,7 +1568,7 @@
(void*) android_content_AssetManager_setLocale },
{ "getLocales", "()[Ljava/lang/String;",
(void*) android_content_AssetManager_getLocales },
- { "setConfiguration", "(IILjava/lang/String;IIIIIIIII)V",
+ { "setConfiguration", "(IILjava/lang/String;IIIIIIIIII)V",
(void*) android_content_AssetManager_setConfiguration },
{ "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void*) android_content_AssetManager_getResourceIdentifier },
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 91cd9fd..7571e24 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -512,6 +512,9 @@
<!-- The screen orientation has changed, that is the user has
rotated the device. -->
<flag name="orientation" value="0x0080" />
+ <!-- The screen orientation has changed, that is the user has
+ rotated the device. -->
+ <flag name="screenLayout" value="0x0100" />
<!-- The font scaling factor has changed, that is the user has
selected a new global font size. -->
<flag name="fontScale" value="0x40000000" />
@@ -829,8 +832,59 @@
<p>This appears as a child tag of the
{@link #AndroidManifest manifest} tag. -->
<declare-styleable name="AndroidManifestSupportsDensity" parent="AndroidManifest">
- <!-- Required value of the density in dip (device independent pixel). -->
- <attr name="density" format="integer" />
+ <!-- Required value of the density in dip (device independent pixel).
+ You should use one of the pre-defined constants for the standard
+ screen densities defined here.
+ -->
+ <attr name="density" format="integer">
+ <!-- A low density screen, such as a QVGA or WQVGA screen in a
+ typical hand-held phone. The constant for this is 120. -->
+ <enum name="low" value="120" />
+ <!-- A medium density screen, such as an HVGA screen in a
+ typical hand-held phone. The constant for this is 160. -->
+ <enum name="medium" value="160" />
+ <!-- A high density screen, such as a VGA or WVGA screen in a
+ typical hand-held phone. The constant for this is 240. -->
+ <enum name="high" value="240" />
+ </attr>
+ </declare-styleable>
+
+ <!-- The <code>supports-screens</code> specifies the screen dimensions an
+ application supports. By default a modern application supports all
+ screen sizes and must explicitly disable certain screen sizes here;
+ older applications are assumed to only support the traditional normal
+ (HVGA) screen size. Note that screen size is a separate axis from
+ density, and is determined as the available pixels to an application
+ after density scaling has been applied.
+
+ <p>This appears as a child tag of the
+ {@link #AndroidManifest manifest} tag. -->
+ <declare-styleable name="AndroidManifestSupportsScreens" parent="AndroidManifest">
+ <!-- Indicates whether the application supports smaller screen form-factors.
+ A small screen is defined as one with a smaller aspect ratio than
+ the traditional HVGA screen; that is, for a portrait screen, less
+ tall than an HVGA screen. In practice, this means a QVGA low
+ density or VGA high density screen. An application that does
+ not support small screens <em>will not be available</em> for
+ small screen devices, since there is little the platform can do
+ to make such an application work on a smaller screen. -->
+ <attr name="smallScreens" format="boolean" />
+ <!-- Indicates whether an application supports the normal screen
+ form-factors. Traditionally this is an HVGA normal density
+ screen, but WQVGA low density and WVGA high density are also
+ considered to be normal. This attribute is true by default,
+ and applications currently should leave it that way. -->
+ <attr name="normalScreens" format="boolean" />
+ <!-- Indicates whether the application supports larger screen form-factors.
+ A large screen is defined as a screen that is significantly larger
+ than a normal phone screen, and thus may require some special care
+ on the application's part to make good use of it. An example would
+ be a VGA <em>normal density</em> screen, though even larger screens
+ are certainly possible. An application that does not support
+ large screens will be placed as a postage stamp on such a
+ screen, so that it retains the dimensions it was originally
+ designed for. -->
+ <attr name="largeScreens" format="boolean" />
</declare-styleable>
<!-- The <code>expandable</code> specifies if this package supports screen metrics
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4634b50..14d8dbe 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1117,6 +1117,9 @@
<public type="attr" name="glEsVersion" />
<public type="attr" name="queryAfterZeroResults" />
<public type="attr" name="dropDownHeight" />
+ <public type="attr" name="smallScreens" />
+ <public type="attr" name="normalScreens" />
+ <public type="attr" name="largeScreens" />
<public-padding type="attr" name="donut_resource_pad" end="0x0101029f" />
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index 8486532..ca50a5e 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -69,6 +69,14 @@
TTS_MISSING_RESOURCES = -6
};
+enum tts_support_result {
+ TTS_LANG_COUNTRY_VAR_AVAILABLE = 2,
+ TTS_LANG_COUNTRY_AVAILABLE = 1,
+ TTS_LANG_AVAILABLE = 0,
+ TTS_LANG_MISSING_DATA = -1,
+ TTS_LANG_NOT_SUPPORTED = -2
+};
+
class TtsEngine
{
public:
@@ -86,19 +94,32 @@
// @return TTS_SUCCESS, or TTS_FAILURE
virtual tts_result stop();
+ // Returns the level of support for the language, country and variant.
+ // @return TTS_LANG_COUNTRY_VAR_AVAILABLE if the language, country and variant are supported,
+ // and the corresponding resources are correctly installed
+ // TTS_LANG_COUNTRY_AVAILABLE if the language and country are supported and the
+ // corresponding resources are correctly installed, but there is no match for
+ // the specified variant
+ // TTS_LANG_AVAILABLE if the language is supported and the
+ // corresponding resources are correctly installed, but there is no match for
+ // the specified country and variant
+ // TTS_LANG_MISSING_DATA if the required resources to provide any level of support
+ // for the language are not correctly installed
+ // TTS_LANG_NOT_SUPPORTED if the language is not supported by the TTS engine.
+ virtual tts_support_result isLanguageAvailable(const char *lang, const char *country,
+ const char *variant);
+
// Load the resources associated with the specified language. The loaded
// language will only be used once a call to setLanguage() with the same
- // language value is issued. Language values are based on the Android
- // conventions for localization as described in the Android platform
- // documentation on internationalization. This implies that language
- // data is specified in the format xx-rYY, where xx is a two letter
- // ISO 639-1 language code in lowercase and rYY is a two letter
- // ISO 3166-1-alpha-2 language code in uppercase preceded by a
- // lowercase "r".
- // @param value pointer to the language value
- // @param size length of the language value
+ // language value is issued. Language and country values are coded according to the ISO three
+ // letter codes for languages and countries, as can be retrieved from a java.util.Locale
+ // instance. The variant value is encoded as the variant string retrieved from a
+ // java.util.Locale instance built with that variant data.
+ // @param lang pointer to the ISO three letter code for the language
+ // @param country pointer to the ISO three letter code for the country
+ // @param variant pointer to the variant code
// @return TTS_SUCCESS, or TTS_FAILURE
- virtual tts_result loadLanguage(const char *value, const size_t size);
+ virtual tts_result loadLanguage(const char *lang, const char *country, const char *variant);
// Load the resources associated with the specified language, country and Locale variant.
// The loaded language will only be used once a call to setLanguageFromLocale() with the same
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
index bbc21c4..97e0e90 100644
--- a/include/ui/Camera.h
+++ b/include/ui/Camera.h
@@ -63,16 +63,12 @@
#define FRAME_CALLBACK_FLAG_CAMERA 0x05
#define FRAME_CALLBACK_FLAG_BARCODE_SCANNER 0x07
-// msgType in notifyCallback function
+// msgType in notifyCallback and dataCallback functions
enum {
- CAMERA_MSG_ERROR,
+ CAMERA_MSG_ERROR = 0,
CAMERA_MSG_SHUTTER,
CAMERA_MSG_FOCUS,
- CAMERA_MSG_ZOOM
-};
-
-// msgType in dataCallback function
-enum {
+ CAMERA_MSG_ZOOM,
CAMERA_MSG_PREVIEW_FRAME,
CAMERA_MSG_VIDEO_FRAME,
CAMERA_MSG_POSTVIEW_FRAME,
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index f1029b7..5c41ead 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -866,7 +866,7 @@
uint8_t keyboard;
uint8_t navigation;
uint8_t inputFlags;
- uint8_t pad0;
+ uint8_t inputPad0;
};
uint32_t input;
};
@@ -905,6 +905,23 @@
uint32_t version;
};
+ enum {
+ SCREENLAYOUT_ANY = 0x0000,
+ SCREENLAYOUT_SMALL = 0x0001,
+ SCREENLAYOUT_NORMAL = 0x0002,
+ SCREENLAYOUT_LARGE = 0x0003,
+ };
+
+ union {
+ struct {
+ uint8_t screenLayout;
+ uint8_t screenConfigPad0;
+ uint8_t screenConfigPad1;
+ uint8_t screenConfigPad2;
+ };
+ uint32_t screenConfig;
+ };
+
inline void copyFromDeviceNoSwap(const ResTable_config& o) {
const size_t size = dtohl(o.size);
if (size >= sizeof(ResTable_config)) {
@@ -950,6 +967,8 @@
diff = (int32_t)(screenSize - o.screenSize);
if (diff != 0) return diff;
diff = (int32_t)(version - o.version);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenLayout - o.screenLayout);
return (int)diff;
}
@@ -967,7 +986,8 @@
CONFIG_ORIENTATION = 0x0080,
CONFIG_DENSITY = 0x0100,
CONFIG_SCREEN_SIZE = 0x0200,
- CONFIG_VERSION = 0x0400
+ CONFIG_VERSION = 0x0400,
+ CONFIG_SCREEN_LAYOUT = 0x0800
};
// Compare two configuration, returning CONFIG_* flags set for each value
@@ -985,6 +1005,7 @@
if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
if (version != o.version) diffs |= CONFIG_VERSION;
+ if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
return diffs;
}
@@ -1062,6 +1083,13 @@
}
}
+ if (screenConfig || o.screenConfig) {
+ if (screenLayout != o.screenLayout) {
+ if (!screenLayout) return false;
+ if (!o.screenLayout) return true;
+ }
+ }
+
if (version || o.version) {
if (sdkVersion != o.sdkVersion) {
if (!sdkVersion) return false;
@@ -1191,6 +1219,12 @@
}
}
+ if (screenConfig || o.screenConfig) {
+ if ((screenLayout != o.screenLayout) && requested->screenLayout) {
+ return (screenLayout);
+ }
+ }
+
if (version || o.version) {
if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
return (sdkVersion);
@@ -1282,6 +1316,12 @@
return false;
}
}
+ if (screenConfig != 0) {
+ if (settings.screenLayout != 0 && screenLayout != 0
+ && screenLayout != settings.screenLayout) {
+ return false;
+ }
+ }
if (version != 0) {
if (settings.sdkVersion != 0 && sdkVersion != 0
&& sdkVersion != settings.sdkVersion) {
@@ -1310,13 +1350,13 @@
String8 toString() const {
char buf[200];
- sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=0x%02x touch=0x%02x dens=0x%02x "
- "kbd=0x%02x nav=0x%02x input=0x%02x screenW=0x%04x screenH=0x%04x vers=%d.%d",
+ sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
+ "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d layout=%d vers=%d.%d",
mcc, mnc,
language[0] ? language[0] : '-', language[1] ? language[1] : '-',
country[0] ? country[0] : '-', country[1] ? country[1] : '-',
orientation, touchscreen, density, keyboard, navigation, inputFlags,
- screenWidth, screenHeight, sdkVersion, minorVersion);
+ screenWidth, screenHeight, screenLayout, sdkVersion, minorVersion);
return String8(buf);
}
};
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index 0868cff..cce754a 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -107,7 +107,10 @@
} else {
k = key;
}
- LOGD("m_keyPrefix=%s key=%s k=%s", m_keyPrefix.string(), key.string(), k.string());
+ if (true) {
+ LOGD("Writing entity: prefix='%s' key='%s' dataSize=%d", m_keyPrefix.string(), key.string(),
+ dataSize);
+ }
entity_header_v1 header;
ssize_t keyLen;
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index 99a4abc..4ad9b51 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -68,11 +68,15 @@
const static int CURRENT_METADATA_VERSION = 1;
-#if 1 // TEST_BACKUP_HELPERS
+#if 1
+#define LOGP(f, x...)
+#else
+#if TEST_BACKUP_HELPERS
#define LOGP(f, x...) printf(f "\n", x)
#else
#define LOGP(x...) LOGD(x)
#endif
+#endif
const static int ROUND_UP[4] = { 0, 3, 2, 1 };
@@ -349,7 +353,6 @@
err = stat(file, &st);
if (err != 0) {
- LOGW("Error stating file %s", file);
r.deleted = true;
} else {
r.deleted = false;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index e4f9f0f..7a33220 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3919,7 +3919,7 @@
printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type);
continue;
}
- printf(" config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n",
+ printf(" config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d lyt=%d\n",
(int)configIndex,
type->config.language[0] ? type->config.language[0] : '-',
type->config.language[1] ? type->config.language[1] : '-',
@@ -3932,7 +3932,8 @@
type->config.inputFlags,
type->config.navigation,
dtohs(type->config.screenWidth),
- dtohs(type->config.screenHeight));
+ dtohs(type->config.screenHeight),
+ type->config.screenLayout);
size_t entryCount = dtohl(type->entryCount);
uint32_t entriesStart = dtohl(type->entriesStart);
if ((entriesStart&0x3) != 0) {
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index c356acb..8537cae 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -297,8 +297,32 @@
variantNativeString);
}
env->ReleaseStringUTFChars(language, langNativeString);
- env->ReleaseStringUTFChars(language, countryNativeString);
- env->ReleaseStringUTFChars(language, variantNativeString);
+ env->ReleaseStringUTFChars(country, countryNativeString);
+ env->ReleaseStringUTFChars(variant, variantNativeString);
+}
+
+
+static void
+android_tts_SynthProxy_loadLanguage(JNIEnv *env, jobject thiz, jint jniData,
+ jstring language, jstring country, jstring variant)
+{
+ if (jniData == 0) {
+ LOGE("android_tts_SynthProxy_loadLanguage(): invalid JNI data");
+ return;
+ }
+
+ SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+ const char *langNativeString = env->GetStringUTFChars(language, 0);
+ const char *countryNativeString = env->GetStringUTFChars(country, 0);
+ const char *variantNativeString = env->GetStringUTFChars(variant, 0);
+ // TODO check return codes
+ if (pSynthData->mNativeSynthInterface) {
+ pSynthData->mNativeSynthInterface->loadLanguage(langNativeString, countryNativeString,
+ variantNativeString);
+ }
+ env->ReleaseStringUTFChars(language, langNativeString);
+ env->ReleaseStringUTFChars(country, countryNativeString);
+ env->ReleaseStringUTFChars(variant, variantNativeString);
}
@@ -567,6 +591,10 @@
"(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
(void*)android_tts_SynthProxy_setLanguage
},
+ { "native_loadLanguage",
+ "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
+ (void*)android_tts_SynthProxy_loadLanguage
+ },
{ "native_setSpeechRate",
"(II)V",
(void*)android_tts_SynthProxy_setSpeechRate
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index 3bdff37..a8eaaa43 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -73,6 +73,13 @@
public void setLanguage(String language, String country, String variant) {
native_setLanguage(mJniData, language, country, variant);
}
+
+ /**
+ * Loads the language: it's not set, but prepared for use later.
+ */
+ public void loadLanguage(String language, String country, String variant) {
+ native_loadLanguage(mJniData, language, country, variant);
+ }
/**
* Sets the speech rate
@@ -149,6 +156,9 @@
private native final void native_setLanguage(int jniData, String language, String country,
String variant);
+
+ private native final void native_loadLanguage(int jniData, String language, String country,
+ String variant);
private native final void native_setSpeechRate(int jniData, int speechRate);
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 3c931b8..421b2ca 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -47,12 +47,13 @@
public class TtsService extends Service implements OnCompletionListener {
private static class SpeechItem {
- public static final int SPEECH = 0;
- public static final int EARCON = 1;
- public static final int SILENCE = 2;
+ public static final int TEXT = 0;
+ public static final int IPA = 1;
+ public static final int EARCON = 2;
+ public static final int SILENCE = 3;
public String mText = null;
public ArrayList<String> mParams = null;
- public int mType = SPEECH;
+ public int mType = TEXT;
public long mDuration = 0;
public SpeechItem(String text, ArrayList<String> params, int itemType) {
@@ -297,7 +298,29 @@
if (queueMode == 0) {
stop();
}
- mSpeechQueue.add(new SpeechItem(text, params, SpeechItem.SPEECH));
+ mSpeechQueue.add(new SpeechItem(text, params, SpeechItem.TEXT));
+ if (!mIsSpeaking) {
+ processSpeechQueue();
+ }
+ }
+
+ /**
+ * Speaks the given IPA text using the specified queueing mode and parameters.
+ *
+ * @param ipaText
+ * The IPA text that should be spoken
+ * @param queueMode
+ * 0 for no queue (interrupts all previous utterances), 1 for
+ * queued
+ * @param params
+ * An ArrayList of parameters. This is not implemented for all
+ * engines.
+ */
+ private void speakIpa(String ipaText, int queueMode, ArrayList<String> params) {
+ if (queueMode == 0) {
+ stop();
+ }
+ mSpeechQueue.add(new SpeechItem(ipaText, params, SpeechItem.IPA));
if (!mIsSpeaking) {
processSpeechQueue();
}
@@ -455,13 +478,13 @@
SpeechItem splitItem;
while (end < currentSpeechItem.mText.length()){
splitText = currentSpeechItem.mText.substring(start, end);
- splitItem = new SpeechItem(splitText, null, SpeechItem.SPEECH);
+ splitItem = new SpeechItem(splitText, null, SpeechItem.TEXT);
splitItems.add(splitItem);
start = end;
end = start + MAX_SPEECH_ITEM_CHAR_LENGTH - 1;
}
splitText = currentSpeechItem.mText.substring(start);
- splitItem = new SpeechItem(splitText, null, SpeechItem.SPEECH);
+ splitItem = new SpeechItem(splitText, null, SpeechItem.TEXT);
splitItems.add(splitItem);
mSpeechQueue.remove(0);
for (int i = splitItems.size() - 1; i >= 0; i--){
@@ -491,10 +514,12 @@
// processSpeechQueue to continue running the queue
Log.i("TTS processing: ", currentSpeechItem.mText);
if (sr == null) {
- if (currentSpeechItem.mType == SpeechItem.SPEECH) {
+ if (currentSpeechItem.mType == SpeechItem.TEXT) {
currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem);
speakInternalOnly(currentSpeechItem.mText,
currentSpeechItem.mParams);
+ } else if (currentSpeechItem.mType == SpeechItem.IPA) {
+ // TODO Implement IPA support
} else {
// This is either silence or an earcon that was missing
silence(currentSpeechItem.mDuration);
@@ -560,8 +585,7 @@
}
/**
- * Synthesizes the given text using the specified queuing mode and
- * parameters.
+ * Synthesizes the given text to a file using the specified parameters.
*
* @param text
* The String of text that should be synthesized
@@ -606,6 +630,52 @@
return true;
}
+ /**
+ * Synthesizes the given IPA text to a file using the specified parameters.
+ *
+ * @param ipaText
+ * The String of IPA text that should be synthesized
+ * @param params
+ * An ArrayList of parameters. The first element of this array
+ * controls the type of voice to use.
+ * @param filename
+ * The string that gives the full output filename; it should be
+ * something like "/sdcard/myappsounds/mysound.wav".
+ * @return A boolean that indicates if the synthesis succeeded
+ */
+ private boolean synthesizeIpaToFile(String ipaText, ArrayList<String> params,
+ String filename, boolean calledFromApi) {
+ // Only stop everything if this is a call made by an outside app trying
+ // to
+ // use the API. Do NOT stop if this is a call from within the service as
+ // clearing the speech queue here would be a mistake.
+ if (calledFromApi) {
+ stop();
+ }
+ Log.i("TTS", "Synthesizing IPA to " + filename);
+ boolean synthAvailable = false;
+ try {
+ synthAvailable = synthesizerLock.tryLock();
+ if (!synthAvailable) {
+ return false;
+ }
+ // Don't allow a filename that is too long
+ // TODO use platform constant
+ if (filename.length() > 250) {
+ return false;
+ }
+ // TODO: Add nativeSynth.synthesizeIpaToFile(text, filename);
+ } finally {
+ // This check is needed because finally will always run; even if the
+ // method returns somewhere in the try block.
+ if (synthAvailable) {
+ synthesizerLock.unlock();
+ }
+ }
+ Log.i("TTS", "Completed synthesis for " + filename);
+ return true;
+ }
+
@Override
public IBinder onBind(Intent intent) {
if (ACTION.equals(intent.getAction())) {
@@ -652,6 +722,27 @@
}
/**
+ * Speaks the given IPA text using the specified queueing mode and
+ * parameters.
+ *
+ * @param ipaText
+ * The IPA text that should be spoken
+ * @param queueMode
+ * 0 for no queue (interrupts all previous utterances), 1 for
+ * queued
+ * @param params
+ * An ArrayList of parameters. The first element of this
+ * array controls the type of voice to use.
+ */
+ public void speakIpa(String ipaText, int queueMode, String[] params) {
+ ArrayList<String> speakingParams = new ArrayList<String>();
+ if (params != null) {
+ speakingParams = new ArrayList<String>(Arrays.asList(params));
+ }
+ mSelf.speakIpa(ipaText, queueMode, speakingParams);
+ }
+
+ /**
* Plays the earcon using the specified queueing mode and parameters.
*
* @param earcon
@@ -794,7 +885,7 @@
}
/**
- * Speaks the given text using the specified queueing mode and
+ * Synthesizes the given text to a file using the specified
* parameters.
*
* @param text
@@ -815,6 +906,29 @@
}
return mSelf.synthesizeToFile(text, speakingParams, filename, true);
}
+
+ /**
+ * Synthesizes the given IPA text to a file using the specified
+ * parameters.
+ *
+ * @param ipaText
+ * The String of IPA text that should be synthesized
+ * @param params
+ * An ArrayList of parameters. The first element of this
+ * array controls the type of voice to use.
+ * @param filename
+ * The string that gives the full output filename; it should
+ * be something like "/sdcard/myappsounds/mysound.wav".
+ * @return A boolean that indicates if the synthesis succeeded
+ */
+ public boolean synthesizeIpaToFile(String ipaText, String[] params,
+ String filename) {
+ ArrayList<String> speakingParams = new ArrayList<String>();
+ if (params != null) {
+ speakingParams = new ArrayList<String>(Arrays.asList(params));
+ }
+ return mSelf.synthesizeIpaToFile(ipaText, speakingParams, filename, true);
+ }
};
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index bc2eaed..c0f0d74 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -34,7 +34,6 @@
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Binder;
-import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -61,7 +60,6 @@
import java.io.EOFException;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
@@ -69,7 +67,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
class BackupManagerService extends IBackupManager.Stub {
@@ -138,10 +135,12 @@
private class RestoreParams {
public IBackupTransport transport;
public IRestoreObserver observer;
+ public long token;
- RestoreParams(IBackupTransport _transport, IRestoreObserver _obs) {
+ RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token) {
transport = _transport;
observer = _obs;
+ token = _token;
}
}
@@ -347,9 +346,8 @@
case MSG_RUN_RESTORE:
{
- int token = msg.arg1;
RestoreParams params = (RestoreParams)msg.obj;
- (new PerformRestoreThread(params.transport, params.observer, token)).start();
+ (new PerformRestoreThread(params.transport, params.observer, params.token)).start();
break;
}
}
@@ -531,6 +529,19 @@
// clear an application's data, blocking until the operation completes or times out
void clearApplicationDataSynchronous(String packageName) {
+ // Don't wipe packages marked allowClearUserData=false
+ try {
+ PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
+ if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
+ if (DEBUG) Log.i(TAG, "allowClearUserData=false so not wiping "
+ + packageName);
+ return;
+ }
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Tried to clear data for " + packageName + " but not found");
+ return;
+ }
+
ClearDataObserver observer = new ClearDataObserver();
synchronized(mClearDataLock) {
@@ -761,7 +772,7 @@
class PerformRestoreThread extends Thread {
private IBackupTransport mTransport;
private IRestoreObserver mObserver;
- private int mToken;
+ private long mToken;
private RestoreSet mImage;
private File mStateDir;
@@ -776,7 +787,7 @@
}
PerformRestoreThread(IBackupTransport transport, IRestoreObserver observer,
- int restoreSetToken) {
+ long restoreSetToken) {
mTransport = transport;
mObserver = observer;
mToken = restoreSetToken;
@@ -847,9 +858,7 @@
}
}
- // STOPSHIP TODO: pick out the set for this token (instead of images[0])
- long token = images[0].token;
- if (!mTransport.startRestore(token, restorePackages.toArray(new PackageInfo[0]))) {
+ if (!mTransport.startRestore(mToken, restorePackages.toArray(new PackageInfo[0]))) {
// STOPSHIP TODO: Handle the failure somehow?
Log.e(TAG, "Error starting restore operation");
return;
@@ -1198,7 +1207,7 @@
}
}
- public int performRestore(int token, IRestoreObserver observer)
+ public int performRestore(long token, IRestoreObserver observer)
throws android.os.RemoteException {
mContext.enforceCallingPermission("android.permission.BACKUP", "performRestore");
@@ -1206,8 +1215,7 @@
for (int i = 0; i < mRestoreSets.length; i++) {
if (token == mRestoreSets[i].token) {
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
- msg.obj = new RestoreParams(mRestoreTransport, observer);
- msg.arg1 = token;
+ msg.obj = new RestoreParams(mRestoreTransport, observer, token);
mBackupHandler.sendMessage(msg);
return 0;
}
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index fef3598..68bf4fb 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -504,6 +504,7 @@
if (mPhoneMemMonitor.checkLocked(curTime, mPhonePid,
mPhonePss)) {
// Just kill the phone process and let it restart.
+ Log.i(TAG, "Watchdog is killing the phone process");
Process.killProcess(mPhonePid);
}
} else {
@@ -848,6 +849,7 @@
// Only kill the process if the debugger is not attached.
if (!Debug.isDebuggerConnected()) {
+ Log.i(TAG, "Watchdog is killing the system process");
Process.killProcess(Process.myPid());
}
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3b47ae7..5ea7504 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -77,6 +77,7 @@
import android.os.SystemProperties;
import android.os.TokenWatcher;
import android.provider.Settings;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.SparseIntArray;
@@ -415,7 +416,8 @@
final Rect mTempRect = new Rect();
final Configuration mTempConfiguration = new Configuration();
-
+ int screenLayout = Configuration.SCREENLAYOUT_UNDEFINED;
+
public static WindowManagerService main(Context context,
PowerManagerService pm, boolean haveInputMethods) {
WMThread thr = new WMThread(context, pm, haveInputMethods);
@@ -3724,6 +3726,40 @@
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
config.orientation = orientation;
+
+ if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
+ // Note we only do this once because at this point we don't
+ // expect the screen to change in this way at runtime, and want
+ // to avoid all of this computation for every config change.
+ DisplayMetrics dm = new DisplayMetrics();
+ mDisplay.getMetrics(dm);
+ int longSize = dw;
+ int shortSize = dh;
+ if (longSize < shortSize) {
+ int tmp = longSize;
+ longSize = shortSize;
+ shortSize = tmp;
+ }
+ longSize = (int)(longSize/dm.density);
+ shortSize = (int)(shortSize/dm.density);
+
+ // These semi-magic numbers define our compatibility modes for
+ // applications with different screens. Don't change unless you
+ // make sure to test lots and lots of apps!
+ if (longSize < 470) {
+ // This is shorter than an HVGA normal density screen (which
+ // is 480 pixels on its long side).
+ screenLayout = Configuration.SCREENLAYOUT_SMALL;
+ } else if (longSize > 490 && shortSize > 330) {
+ // This is larger than an HVGA normal density screen (which
+ // is 480x320 pixels).
+ screenLayout = Configuration.SCREENLAYOUT_LARGE;
+ } else {
+ screenLayout = Configuration.SCREENLAYOUT_NORMAL;
+ }
+ }
+ config.screenLayout = screenLayout;
+
config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
mPolicy.adjustConfigurationLw(config);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index fd1dfc83..6d04b6b 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -10472,8 +10472,17 @@
// done with this agent
public void unbindBackupAgent(ApplicationInfo appInfo) {
if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
+ if (appInfo == null) {
+ Log.w(TAG, "unbind backup agent for null app");
+ return;
+ }
synchronized(this) {
+ if (mBackupAppName == null) {
+ Log.w(TAG, "Unbinding backup agent with no active backup");
+ return;
+ }
+
if (!mBackupAppName.equals(appInfo.packageName)) {
Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
return;
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index a835dee..03bdbda 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -789,7 +789,7 @@
if (inStream.read(8) != 3) {
throw new CodingException("MESSAGE_IDENTIFIER subparam size incorrect");
}
- bData.messageType = inStream.read(4);
+ bData.messageType = (byte)inStream.read(4);
bData.messageId = inStream.read(8) << 8;
bData.messageId |= inStream.read(8);
bData.hasUserDataHeader = (inStream.read(1) == 1);
@@ -799,7 +799,7 @@
private static void decodeUserData(BearerData bData, BitwiseInputStream inStream)
throws BitwiseInputStream.AccessException
{
- byte paramBytes = inStream.read(8);
+ int paramBytes = inStream.read(8);
bData.userData = new UserData();
bData.userData.msgEncoding = inStream.read(5);
bData.userData.msgEncodingSet = true;
@@ -867,7 +867,7 @@
inStream.skip(offset);
byte[] expandedData = new byte[numFields];
for (int i = 0; i < numFields; i++) {
- expandedData[i] = inStream.read(7);
+ expandedData[i] = (byte)inStream.read(7);
}
return new String(expandedData, 0, numFields, "US-ASCII");
} catch (java.io.UnsupportedEncodingException ex) {
@@ -922,7 +922,7 @@
private static void decodeReplyOption(BearerData bData, BitwiseInputStream inStream)
throws BitwiseInputStream.AccessException, CodingException
{
- byte paramBytes = inStream.read(8);
+ int paramBytes = inStream.read(8);
if (paramBytes != 1) {
throw new CodingException("REPLY_OPTION subparam size incorrect");
}
@@ -985,18 +985,18 @@
private static void decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream)
throws BitwiseInputStream.AccessException, CodingException
{
- byte paramBytes = inStream.read(8);
+ int paramBytes = inStream.read(8);
CdmaSmsAddress addr = new CdmaSmsAddress();
- addr.digitMode = inStream.read(1);
+ addr.digitMode = (byte)inStream.read(1);
byte fieldBits = 4;
byte consumedBits = 1;
if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
addr.ton = inStream.read(3);
- addr.numberPlan = inStream.read(4);
+ addr.numberPlan = (byte)inStream.read(4);
fieldBits = 8;
consumedBits += 7;
}
- addr.numberOfDigits = inStream.read(8);
+ addr.numberOfDigits = (byte)inStream.read(8);
consumedBits += 8;
int remainingBits = (paramBytes * 8) - consumedBits;
int dataBits = addr.numberOfDigits * fieldBits;
@@ -1076,7 +1076,7 @@
if (inStream.read(8) != 1) {
throw new CodingException("PRIVACY_INDICATOR subparam size incorrect");
}
- bData.privacy = inStream.read(2);
+ bData.privacy = (byte)inStream.read(2);
inStream.skip(6);
bData.privacyIndicatorSet = true;
}
@@ -1097,7 +1097,7 @@
if (inStream.read(8) != 1) {
throw new CodingException("DISPLAY_MODE subparam size incorrect");
}
- bData.displayMode = inStream.read(2);
+ bData.displayMode = (byte)inStream.read(2);
inStream.skip(6);
bData.displayModeSet = true;
}
@@ -1108,7 +1108,7 @@
if (inStream.read(8) != 1) {
throw new CodingException("PRIORITY_INDICATOR subparam size incorrect");
}
- bData.priority = inStream.read(2);
+ bData.priority = (byte)inStream.read(2);
inStream.skip(6);
bData.priorityIndicatorSet = true;
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
index a935247..c5562b3 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java
@@ -25,6 +25,8 @@
import android.util.Log;
+import java.util.Random;
+
public class BitwiseStreamsTest extends AndroidTestCase {
private final static String LOG_TAG = "BitwiseStreamsTest";
@@ -39,7 +41,7 @@
BitwiseInputStream inStream = new BitwiseInputStream(outBuf);
byte[] inBufDup = new byte[inBuf.length];
inStream.skip(offset);
- for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+ for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
}
@@ -53,7 +55,7 @@
BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
inStream.skip(offset);
byte[] inBufDup = new byte[inBuf.length];
- for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+ for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
}
@@ -67,7 +69,7 @@
BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
inStream.skip(offset);
byte[] inBufDup = new byte[inBuf.length];
- for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+ for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
}
@@ -84,12 +86,33 @@
BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
inStream.skip(offset);
byte[] inBufDup = new byte[inBuf.length];
- for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+ for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
}
@SmallTest
public void testFive() throws Exception {
+ Random random = new Random();
+ int iterations = 10000;
+ int[] sizeArr = new int[iterations];
+ int[] valueArr = new int[iterations];
+ BitwiseOutputStream outStream = new BitwiseOutputStream(iterations * 4);
+ for (int i = 0; i < iterations; i++) {
+ int x = random.nextInt();
+ int size = (x & 0x07) + 1;
+ int value = x & (-1 >>> (32 - size));
+ sizeArr[i] = size;
+ valueArr[i] = value;
+ outStream.write(size, value);
+ }
+ BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
+ for (int i = 0; i < iterations; i++) {
+ assertEquals(valueArr[i], inStream.read(sizeArr[i]));
+ }
+ }
+
+ @SmallTest
+ public void testSix() throws Exception {
int num_runs = 10;
long start = android.os.SystemClock.elapsedRealtime();
for (int run = 0; run < num_runs; run++) {
@@ -104,7 +127,7 @@
BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray());
inStream.skip(offset);
byte[] inBufDup = new byte[inBuf.length];
- for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8);
+ for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8);
assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup));
}
long end = android.os.SystemClock.elapsedRealtime();
diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
index b2529811..9188e04b 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
@@ -171,14 +171,14 @@
assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
assertEquals(bearerData.msgCenterTimeStamp.second, 59);
assertEquals(bearerData.validityPeriodAbsolute, null);
- assertEquals(bearerData.validityPeriodRelative, -63);
+ assertEquals(bearerData.validityPeriodRelative, 193);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
- assertEquals(bearerData.deferredDeliveryTimeRelative, -57);
+ assertEquals(bearerData.deferredDeliveryTimeRelative, 199);
assertEquals(bearerData.hasUserDataHeader, false);
assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
assertEquals(bearerData.userData.numFields, 2);
@@ -225,7 +225,7 @@
assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
- assertEquals(bearerData.deferredDeliveryTimeRelative, -110);
+ assertEquals(bearerData.deferredDeliveryTimeRelative, 146);
assertEquals(bearerData.hasUserDataHeader, false);
assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
assertEquals(bearerData.userData.numFields, 2);
diff --git a/tests/DpiTest/AndroidManifest.xml b/tests/DpiTest/AndroidManifest.xml
index f71cff2..64ad7be 100644
--- a/tests/DpiTest/AndroidManifest.xml
+++ b/tests/DpiTest/AndroidManifest.xml
@@ -16,6 +16,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.test.dpi">
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="3" />
+ <supports-screens android:smallScreens="true" />
<application android:label="DpiTest">
<activity android:name="DpiTestActivity" android:label="DpiTest">
<intent-filter>
diff --git a/tests/DpiTest/res/values-largeScreen/strings.xml b/tests/DpiTest/res/values-largeScreen/strings.xml
new file mode 100644
index 0000000..f4dd543
--- /dev/null
+++ b/tests/DpiTest/res/values-largeScreen/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="act_title">DpiTest: Large Screen</string>
+</resources>
diff --git a/tests/DpiTest/res/values-normalScreen/strings.xml b/tests/DpiTest/res/values-normalScreen/strings.xml
new file mode 100644
index 0000000..256d696
--- /dev/null
+++ b/tests/DpiTest/res/values-normalScreen/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="act_title">DpiTest: Normal Screen</string>
+</resources>
diff --git a/tests/DpiTest/res/values-smallScreen/strings.xml b/tests/DpiTest/res/values-smallScreen/strings.xml
new file mode 100644
index 0000000..cdb4ac9
--- /dev/null
+++ b/tests/DpiTest/res/values-smallScreen/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="act_title">DpiTest: Small Screen</string>
+</resources>
diff --git a/tests/DpiTest/res/values/strings.xml b/tests/DpiTest/res/values/strings.xml
new file mode 100644
index 0000000..ef924ac
--- /dev/null
+++ b/tests/DpiTest/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="act_title">DpiTest: Unknown Screen</string>
+</resources>
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
index 3759622..5a9f3f5 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -34,6 +34,7 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ this.setTitle(R.string.act_title);
LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
diff --git a/tests/backup/src/com/android/backuptest/BackupTestAgent.java b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
index 6acd90c..8e4fd39 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestAgent.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
@@ -18,6 +18,7 @@
import android.backup.BackupHelperAgent;
import android.backup.FileBackupHelper;
+import android.backup.SharedPreferencesBackupHelper;
public class BackupTestAgent extends BackupHelperAgent
{
@@ -25,6 +26,7 @@
addHelper("data_files", new FileBackupHelper(this, BackupTestActivity.FILE_NAME));
addHelper("more_data_files", new FileBackupHelper(this, "another_file.txt", "3.txt",
"empty.txt"));
+ addHelper("shared_prefs", new SharedPreferencesBackupHelper(this, "settings", "raw"));
}
}
diff --git a/tests/backup/test_backup.sh b/tests/backup/test_backup.sh
index 6ef5dff..dbf9ed2 100755
--- a/tests/backup/test_backup.sh
+++ b/tests/backup/test_backup.sh
@@ -9,6 +9,8 @@
adb shell "rm /data/data/com.android.backuptest/files/* ; \
mkdir /data/data/com.android.backuptest ; \
mkdir /data/data/com.android.backuptest/files ; \
+ mkdir /data/data/com.android.backuptest/shared_prefs ; \
+ echo -n \"<map><int name=\\\"pref\\\" value=\\\"1\\\" /></map>\" > /data/data/com.android.backuptest/shared_prefs/raw.xml ; \
echo -n first file > /data/data/com.android.backuptest/files/file.txt ; \
echo -n asdf > /data/data/com.android.backuptest/files/another_file.txt ; \
echo -n 3 > /data/data/com.android.backuptest/files/3.txt ; \
@@ -20,3 +22,6 @@
# run the backup
adb shell bmgr run
+
+
+
diff --git a/tests/backup/test_restore.sh b/tests/backup/test_restore.sh
index f3d581e..ccf29cf 100755
--- a/tests/backup/test_restore.sh
+++ b/tests/backup/test_restore.sh
@@ -2,7 +2,7 @@
function check_file
{
- data=$(adb shell cat /data/data/com.android.backuptest/files/$1)
+ data=$(adb shell cat /data/data/com.android.backuptest/$1)
if [ "$data" = "$2" ] ; then
echo "$1 has correct value [$2]"
else
@@ -16,8 +16,12 @@
echo --- Previous files
adb shell "ls -l /data/data/com.android.backuptest/files"
adb shell "rm /data/data/com.android.backuptest/files/*"
-echo --- Erased files
+echo --- Previous shared_prefs
+adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
+adb shell "rm /data/data/com.android.backuptest/shared_prefs/*"
+echo --- Erased files and shared_prefs
adb shell "ls -l /data/data/com.android.backuptest/files"
+adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
echo ---
echo
@@ -32,15 +36,18 @@
echo
# check the results
-check_file file.txt "first file"
-check_file another_file.txt "asdf"
-check_file 3.txt "3"
-check_file empty.txt ""
+check_file files/file.txt "first file"
+check_file files/another_file.txt "asdf"
+check_file files/3.txt "3"
+check_file files/empty.txt ""
+check_file shared_prefs/raw.xml '<map><int name="pref" value="1" /></map>'
echo
echo
echo
echo --- Restored files
adb shell "ls -l /data/data/com.android.backuptest/files"
+echo --- Restored shared_prefs
+adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
echo ---
echo
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 6bc1ee6..67af116 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -187,6 +187,13 @@
return 0;
}
+ // screen layout
+ if (getScreenLayoutName(part.string(), &config)) {
+ *axis = AXIS_SCREENLAYOUT;
+ *value = config.screenLayout;
+ return 0;
+ }
+
// version
if (getVersionName(part.string(), &config)) {
*axis = AXIS_VERSION;
@@ -202,7 +209,7 @@
{
Vector<String8> parts;
- String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, vers;
+ String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, layout, vers;
const char *p = dir;
const char *q;
@@ -378,6 +385,18 @@
//printf("not screen size: %s\n", part.string());
}
+ if (getScreenLayoutName(part.string())) {
+ layout = part;
+
+ index++;
+ if (index == N) {
+ goto success;
+ }
+ part = parts[index];
+ } else {
+ //printf("not screen layout: %s\n", part.string());
+ }
+
if (getVersionName(part.string())) {
vers = part;
@@ -404,6 +423,7 @@
this->keyboard = key;
this->navigation = nav;
this->screenSize = size;
+ this->screenLayout = layout;
this->version = vers;
// what is this anyway?
@@ -435,6 +455,8 @@
s += ",";
s += screenSize;
s += ",";
+ s += screenLayout;
+ s += ",";
s += version;
return s;
}
@@ -483,6 +505,10 @@
s += "-";
s += screenSize;
}
+ if (this->screenLayout != "") {
+ s += "-";
+ s += screenLayout;
+ }
if (this->version != "") {
s += "-";
s += version;
@@ -786,6 +812,26 @@
return true;
}
+bool AaptGroupEntry::getScreenLayoutName(const char* name,
+ ResTable_config* out)
+{
+ if (strcmp(name, kWildcardName) == 0) {
+ if (out) out->screenLayout = out->SCREENLAYOUT_ANY;
+ return true;
+ } else if (strcmp(name, "smallscreen") == 0) {
+ if (out) out->screenLayout = out->SCREENLAYOUT_SMALL;
+ return true;
+ } else if (strcmp(name, "normalscreen") == 0) {
+ if (out) out->screenLayout = out->SCREENLAYOUT_NORMAL;
+ return true;
+ } else if (strcmp(name, "largescreen") == 0) {
+ if (out) out->screenLayout = out->SCREENLAYOUT_LARGE;
+ return true;
+ }
+
+ return false;
+}
+
bool AaptGroupEntry::getVersionName(const char* name,
ResTable_config* out)
{
@@ -828,6 +874,7 @@
if (v == 0) v = keyboard.compare(o.keyboard);
if (v == 0) v = navigation.compare(o.navigation);
if (v == 0) v = screenSize.compare(o.screenSize);
+ if (v == 0) v = screenLayout.compare(o.screenLayout);
if (v == 0) v = version.compare(o.version);
return v;
}
@@ -846,6 +893,7 @@
getKeyboardName(keyboard.string(), ¶ms);
getNavigationName(navigation.string(), ¶ms);
getScreenSizeName(screenSize.string(), ¶ms);
+ getScreenLayoutName(screenLayout.string(), ¶ms);
getVersionName(version.string(), ¶ms);
return params;
}
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 01c8140..3b96412 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -37,6 +37,7 @@
AXIS_KEYBOARD,
AXIS_NAVIGATION,
AXIS_SCREENSIZE,
+ AXIS_SCREENLAYOUT,
AXIS_VERSION
};
@@ -62,6 +63,7 @@
String8 keyboard;
String8 navigation;
String8 screenSize;
+ String8 screenLayout;
String8 version;
bool initFromDirName(const char* dir, String8* resType);
@@ -78,6 +80,7 @@
static bool getKeyboardName(const char* name, ResTable_config* out = NULL);
static bool getNavigationName(const char* name, ResTable_config* out = NULL);
static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
+ static bool getScreenLayoutName(const char* name, ResTable_config* out = NULL);
static bool getVersionName(const char* name, ResTable_config* out = NULL);
int compare(const AaptGroupEntry& o) const;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 503f661..e04491d 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -329,6 +329,9 @@
TARGET_SDK_VERSION_ATTR = 0x01010270,
TEST_ONLY_ATTR = 0x01010272,
DENSITY_ATTR = 0x0101026c,
+ SMALL_SCREEN_ATTR = 0x01010284,
+ NORMAL_SCREEN_ATTR = 0x01010285,
+ LARGE_SCREEN_ATTR = 0x01010286,
};
const char *getComponentName(String8 &pkgName, String8 &componentName) {
@@ -499,6 +502,10 @@
bool isLauncherActivity = false;
bool withinApplication = false;
bool withinReceiver = false;
+ int targetSdk = 0;
+ int smallScreen = 1;
+ int normalScreen = 1;
+ int largeScreen = 1;
String8 pkg;
String8 activityName;
String8 activityLabel;
@@ -572,8 +579,10 @@
error.string());
goto bail;
}
+ if (name == "Donut") targetSdk = 4;
printf("sdkVersion:'%s'\n", name.string());
} else if (code != -1) {
+ targetSdk = code;
printf("sdkVersion:'%d'\n", code);
}
code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error);
@@ -585,8 +594,12 @@
error.string());
goto bail;
}
+ if (name == "Donut" && targetSdk < 4) targetSdk = 4;
printf("targetSdkVersion:'%s'\n", name.string());
} else if (code != -1) {
+ if (targetSdk < code) {
+ targetSdk = code;
+ }
printf("targetSdkVersion:'%d'\n", code);
}
} else if (tag == "uses-configuration") {
@@ -625,6 +638,13 @@
goto bail;
}
printf("supports-density:'%d'\n", dens);
+ } else if (tag == "supports-screens") {
+ smallScreen = getIntegerAttribute(tree,
+ SMALL_SCREEN_ATTR, NULL, 1);
+ normalScreen = getIntegerAttribute(tree,
+ NORMAL_SCREEN_ATTR, NULL, 1);
+ largeScreen = getIntegerAttribute(tree,
+ LARGE_SCREEN_ATTR, NULL, 1);
}
} else if (depth == 3 && withinApplication) {
withinActivity = false;
@@ -733,6 +753,25 @@
}
}
+ // Determine default values for any unspecified screen sizes,
+ // based on the target SDK of the package. As of 4 (donut)
+ // the screen size support was introduced, so all default to
+ // enabled.
+ if (smallScreen > 0) {
+ smallScreen = targetSdk >= 4 ? -1 : 0;
+ }
+ if (normalScreen > 0) {
+ normalScreen = -1;
+ }
+ if (largeScreen > 0) {
+ largeScreen = targetSdk >= 4 ? -1 : 0;
+ }
+ printf("supports-screens:");
+ if (smallScreen != 0) printf(" 'small'");
+ if (normalScreen != 0) printf(" 'normal'");
+ if (largeScreen != 0) printf(" 'large'");
+ printf("\n");
+
printf("locales:");
Vector<String8> locales;
res.getLocales(&locales);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
index 1fa11af..06dd96f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
@@ -59,7 +59,7 @@
public void setConfiguration(int mcc, int mnc, String locale,
int orientation, int touchscreen, int density, int keyboard,
int keyboardHidden, int navigation, int screenWidth, int screenHeight,
- int version) {
+ int screenLayout, int version) {
Configuration c = new Configuration();
c.mcc = mcc;
@@ -70,5 +70,6 @@
c.keyboardHidden = keyboardHidden;
c.navigation = navigation;
c.orientation = orientation;
+ c.screenLayout = screenLayout;
}
}