Merge change 26323 into eclair
* changes:
Fix bug with ScrollView so that text entry fields are not hidden by virtual keyboard.
diff --git a/api/current.xml b/api/current.xml
index efeecb6..fa54a10 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2825,6 +2825,28 @@
visibility="public"
>
</field>
+<field name="detailColumn"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843427"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="detailSocialSummary"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843428"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dial"
type="int"
transient="false"
@@ -7522,6 +7544,17 @@
visibility="public"
>
</field>
+<field name="summaryColumn"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843426"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="summaryOff"
type="int"
transient="false"
@@ -36741,6 +36774,17 @@
visibility="public"
>
</field>
+<field name="FLAG_ACTIVITY_NO_ANIMATION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="65536"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="FLAG_ACTIVITY_NO_HISTORY"
type="int"
transient="false"
@@ -67644,6 +67688,17 @@
visibility="public"
>
</method>
+<method name="getFocusMode"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getInt"
return="int"
abstract="false"
@@ -67789,6 +67844,17 @@
visibility="public"
>
</method>
+<method name="getSupportedFocusModes"
+ return="java.util.List<java.lang.String>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getSupportedPictureFormats"
return="java.util.List<java.lang.Integer>"
abstract="false"
@@ -67970,6 +68036,19 @@
<parameter name="value" type="java.lang.String">
</parameter>
</method>
+<method name="setFocusMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
<method name="setGpsAltitude"
return="void"
abstract="false"
@@ -68371,6 +68450,61 @@
visibility="public"
>
</field>
+<field name="FLASH_MODE_VIDEO_LIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""video-light""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""auto""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_FIXED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""fixed""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_INFINITY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""infinity""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUS_MODE_MACRO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""macro""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SCENE_MODE_ACTION"
type="java.lang.String"
transient="false"
@@ -134730,6 +134864,21 @@
<parameter name="addr" type="int">
</parameter>
</method>
+<method name="formatShortFileSize"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="number" type="long">
+</parameter>
+</method>
</class>
<class name="Time"
extends="java.lang.Object"
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index ec4e2a2..ba74c78 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -291,7 +291,7 @@
return NO_ERROR;
}
-static int8_t scan()
+static int8_t saw()
{
DIR *dir = opendir(".");
struct dirent *file;
@@ -411,7 +411,7 @@
INSERT = 4,
DELETE = 8,
EXIST = 16,
- SCAN = 32,
+ SAW = 32,
RESET = 64,
PASSWORD = 128,
LOCK = 256,
@@ -430,7 +430,7 @@
{insert, 'i', NO_ERROR, INSERT, {KEY_SIZE, VALUE_SIZE}},
{delete, 'd', 0, DELETE, {KEY_SIZE}},
{exist, 'e', 0, EXIST, {KEY_SIZE}},
- {scan, 's', 0, SCAN, {KEY_SIZE}},
+ {saw, 's', 0, SAW, {KEY_SIZE}},
{reset, 'r', 0, RESET, {0}},
{password, 'p', 0, PASSWORD, {PASSWORD_SIZE, PASSWORD_SIZE}},
{lock, 'l', NO_ERROR, LOCK, {0}},
@@ -446,7 +446,7 @@
{AID_SYSTEM, 0, ~GET},
{AID_VPN, AID_SYSTEM, GET},
{AID_WIFI, AID_SYSTEM, GET},
- {0, 0, TEST | GET | INSERT | DELETE | EXIST | SCAN},
+ {0, 0, TEST | GET | INSERT | DELETE | EXIST | SAW},
};
static int8_t process(int8_t code) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a86fe90..4561899 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -790,8 +790,8 @@
* @see #onPostCreate
*/
protected void onCreate(Bundle savedInstanceState) {
- mVisibleFromClient = mWindow.getWindowStyle().getBoolean(
- com.android.internal.R.styleable.Window_windowNoDisplay, true);
+ mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
+ com.android.internal.R.styleable.Window_windowNoDisplay, false);
mCalled = true;
}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index caf72af..c0a0480 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -1144,7 +1144,7 @@
String query = mSearchAutoComplete.getText().toString();
String action = mGlobalSearchMode ? Intent.ACTION_WEB_SEARCH : Intent.ACTION_SEARCH;
Intent intent = createIntent(action, null, null, query, null,
- actionKey, actionMsg);
+ actionKey, actionMsg, null);
// Allow GlobalSearch to log and create shortcut for searches launched by
// the search button, enter key or an action key.
if (mGlobalSearchMode) {
@@ -1579,9 +1579,10 @@
String query = getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY);
String extraData = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA);
+ String mode = mGlobalSearchMode ? SearchManager.MODE_GLOBAL_SEARCH_SUGGESTION : null;
return createIntent(action, dataUri, extraData, query, componentName, actionKey,
- actionMsg);
+ actionMsg, mode);
} catch (RuntimeException e ) {
int rowNum;
try { // be really paranoid now
@@ -1607,10 +1608,12 @@
* or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
* @param actionMsg The message for the action key that was pressed,
* or <code>null</code> if none.
+ * @param mode The search mode, one of the acceptable values for
+ * {@link SearchManager#SEARCH_MODE}, or {@code null}.
* @return The intent.
*/
private Intent createIntent(String action, Uri data, String extraData, String query,
- String componentName, int actionKey, String actionMsg) {
+ String componentName, int actionKey, String actionMsg, String mode) {
// Now build the Intent
Intent intent = new Intent(action);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -1634,6 +1637,9 @@
intent.putExtra(SearchManager.ACTION_KEY, actionKey);
intent.putExtra(SearchManager.ACTION_MSG, actionMsg);
}
+ if (mode != null) {
+ intent.putExtra(SearchManager.SEARCH_MODE, mode);
+ }
// Only allow 3rd-party intents from GlobalSearch
if (!mGlobalSearchMode) {
intent.setComponent(mSearchable.getSearchActivity());
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 6a0285d..f0876f4 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1289,6 +1289,25 @@
public final static String SOURCE = "source";
/**
+ * Intent extra data key: Use {@link android.content.Intent#getBundleExtra
+ * content.Intent.getBundleExtra(SEARCH_MODE)} to get the search mode used
+ * to launch the intent.
+ * The only current value for this is {@link #MODE_GLOBAL_SEARCH_SUGGESTION}.
+ *
+ * @hide
+ */
+ public final static String SEARCH_MODE = "search_mode";
+
+ /**
+ * Value for the {@link #SEARCH_MODE} key.
+ * This is used if the intent was launched by clicking a suggestion in global search
+ * mode (Quick Search Box).
+ *
+ * @hide
+ */
+ public static final String MODE_GLOBAL_SEARCH_SUGGESTION = "global_search_suggestion";
+
+ /**
* Intent extra data key: Use this key with Intent.ACTION_SEARCH and
* {@link android.content.Intent#getIntExtra content.Intent.getIntExtra()}
* to obtain the keycode that the user used to trigger this query. It will be zero if the
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 409c744..24ad06a 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -83,6 +83,12 @@
* @param uuid
*/
public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) {
+ if ((uuidArray == null || uuidArray.length == 0) && uuid == null)
+ return true;
+
+ if (uuidArray == null)
+ return false;
+
for (ParcelUuid element: uuidArray) {
if (element.equals(uuid)) return true;
}
@@ -98,7 +104,14 @@
*/
public static boolean containsAnyUuid(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
- if (uuidA == null || uuidB == null) return false;
+
+ if (uuidA == null) {
+ return uuidB.length == 0 ? true : false;
+ }
+
+ if (uuidB == null) {
+ return uuidA.length == 0 ? true : false;
+ }
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
for (ParcelUuid uuid: uuidB) {
@@ -117,7 +130,12 @@
*/
public static boolean containsAllUuids(ParcelUuid[] uuidA, ParcelUuid[] uuidB) {
if (uuidA == null && uuidB == null) return true;
- if (uuidA == null || uuidB == null) return false;
+
+ if (uuidA == null) {
+ return uuidB.length == 0 ? true : false;
+ }
+
+ if (uuidB == null) return true;
HashSet<ParcelUuid> uuidSet = new HashSet<ParcelUuid> (Arrays.asList(uuidA));
for (ParcelUuid uuid: uuidB) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7366b8b..f6ca50d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2318,6 +2318,18 @@
*/
public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 0X00020000;
/**
+ * If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
+ * this flag will prevent the system from applying an activity transition
+ * animation to go to the next activity state. This doesn't mean an
+ * animation will never run -- if another activity change happens that doesn't
+ * specify this flag before the activity started here is displayed, then
+ * that transition will be used. This this flag can be put to good use
+ * when you are going to do a series of activity operations but the
+ * animation seen by the user shouldn't be driven by the first activity
+ * change but rather a later one.
+ */
+ public static final int FLAG_ACTIVITY_NO_ANIMATION = 0X00010000;
+ /**
* If set, when sending a broadcast only registered receivers will be
* called -- no BroadcastReceiver components will be launched.
*/
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 50faf57..11c67cc 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -274,6 +274,25 @@
* Apply translation to the canvas that is necessary to draw the content.
*/
public void translateCanvas(Canvas canvas) {
+ if (applicationScale == 1.5f) {
+ /* When we scale for compatibility, we can put our stretched
+ bitmaps and ninepatches on exacty 1/2 pixel boundaries,
+ which can give us inconsistent drawing due to imperfect
+ float precision in the graphics engine's inverse matrix.
+
+ As a work-around, we translate by a tiny amount to avoid
+ landing on exact pixel centers and boundaries, giving us
+ the slop we need to draw consistently.
+
+ This constant is meant to resolve to 1/255 after it is
+ scaled by 1.5 (applicationScale). Note, this is just a guess
+ as to what is small enough not to create its own artifacts,
+ and big enough to avoid the precision problems. Feel free
+ to experiment with smaller values as you choose.
+ */
+ final float tinyOffset = 2.0f / (3 * 255);
+ canvas.translate(tinyOffset, tinyOffset);
+ }
canvas.scale(applicationScale, applicationScale);
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index cc44400..5f1a3c5 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -357,10 +357,12 @@
/**
* Starts auto-focus function and registers a callback function to run when
- * camera is focused. Only valid after startPreview() has been called. If
- * the camera does not support auto-focus, it is a no-op and {@link
- * AutoFocusCallback#onAutoFocus(boolean, Camera)} callback will be called
- * immediately.
+ * camera is focused. Only valid after startPreview() has been called.
+ * Applications should call {@link
+ * android.hardware.Camera.Parameters#getFocusMode()} to determine if this
+ * method should be called. If the camera does not support auto-focus, it is
+ * a no-op and {@link AutoFocusCallback#onAutoFocus(boolean, Camera)}
+ * callback will be called immediately.
* <p>If your application should not be installed
* on devices without auto-focus, you must declare that your application
* uses auto-focus with the
@@ -598,6 +600,7 @@
private static final String KEY_ANTIBANDING = "antibanding";
private static final String KEY_SCENE_MODE = "scene-mode";
private static final String KEY_FLASH_MODE = "flash-mode";
+ private static final String KEY_FOCUS_MODE = "focus-mode";
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -646,6 +649,10 @@
* Flash will be fired in red-eye reduction mode.
*/
public static final String FLASH_MODE_RED_EYE = "red-eye";
+ /**
+ * Constant emission of light. This can be used for video recording.
+ */
+ public static final String FLASH_MODE_VIDEO_LIGHT = "video-light";
// Values for scene mode settings.
public static final String SCENE_MODE_AUTO = "auto";
@@ -664,6 +671,25 @@
public static final String SCENE_MODE_PARTY = "party";
public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
+ // Values for focus mode settings.
+ /**
+ * Auto-focus mode.
+ */
+ public static final String FOCUS_MODE_AUTO = "auto";
+ /**
+ * Focus is set at infinity. Applications should not call
+ * {@link #autoFocus(AutoFocusCallback)} in this mode.
+ */
+ public static final String FOCUS_MODE_INFINITY = "infinity";
+ public static final String FOCUS_MODE_MACRO = "macro";
+ /**
+ * Focus is fixed. The camera is always in this mode if the focus is not
+ * adjustable. If the camera has auto-focus, this mode can fix the
+ * focus, which is usually at hyperfocal distance. Applications should
+ * not call {@link #autoFocus(AutoFocusCallback)} in this mode.
+ */
+ public static final String FOCUS_MODE_FIXED = "fixed";
+
// Formats for setPreviewFormat and setPictureFormat.
private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
@@ -1295,6 +1321,39 @@
return split(str);
}
+ /**
+ * Gets the current focus mode setting.
+ *
+ * @return one of FOCUS_MODE_XXX string constant. If the camera does not
+ * support auto-focus, this should return {@link
+ * #FOCUS_MODE_FIXED}. If the focus mode is not FOCUS_MODE_FIXED
+ * or {@link #FOCUS_MODE_INFINITY}, applications should call
+ * {@link #autoFocus(AutoFocusCallback)} to start the focus.
+ */
+ public String getFocusMode() {
+ return get(KEY_FOCUS_MODE);
+ }
+
+ /**
+ * Sets the focus mode.
+ *
+ * @param value FOCUS_MODE_XXX string constants.
+ */
+ public void setFocusMode(String value) {
+ set(KEY_FOCUS_MODE, value);
+ }
+
+ /**
+ * Gets the supported focus modes.
+ *
+ * @return a List of FOCUS_MODE_XXX string constants. null if focus mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedFocusModes() {
+ String str = get(KEY_FOCUS_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
// Splits a comma delimited string to an ArrayList of String.
// Return null if the passing string is null or the size is 0.
private ArrayList<String> split(String str) {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 90c6328..3df228d 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -410,7 +410,8 @@
private AggregationSuggestions() {}
/**
- * The directory twig for this sub-table
+ * The directory twig for this sub-table. The URI can be followed by an optional
+ * type-to-filter, similar to {@link Contacts#CONTENT_FILTER_URI}.
*/
public static final String CONTENT_DIRECTORY = "suggestions";
}
@@ -900,32 +901,9 @@
public static final String PACKAGE_COMMON = "common";
/**
- * Columns common across the specific types.
- */
- private interface BaseCommonColumns {
- /**
- * The package name to use when creating {@link Resources} objects for
- * this data row. This value is only designed for use when building user
- * interfaces, and should not be used to infer the owner.
- */
- public static final String RES_PACKAGE = "res_package";
-
- /**
- * The MIME type of the item represented by this row.
- */
- public static final String MIMETYPE = "mimetype";
-
- /**
- * The {@link RawContacts#_ID} that this data belongs to.
- */
- public static final String RAW_CONTACT_ID = "raw_contact_id";
- }
-
- /**
* The base types that all "Typed" data kinds support.
*/
public interface BaseTypes {
-
/**
* A custom type. The custom label should be supplied by user.
*/
@@ -935,7 +913,7 @@
/**
* Columns common across the specific types.
*/
- private interface CommonColumns extends BaseTypes{
+ private interface CommonColumns extends BaseTypes {
/**
* The data for the contact method.
* <P>Type: TEXT</P>
@@ -1101,30 +1079,67 @@
*/
public static final String NUMBER = DATA;
+ /**
+ * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
+ */
+ @Deprecated
public static final CharSequence getDisplayLabel(Context context, int type,
CharSequence label, CharSequence[] labelArray) {
- CharSequence display = "";
-
- if (type != Phone.TYPE_CUSTOM) {
- CharSequence[] labels = labelArray != null? labelArray
- : context.getResources().getTextArray(
- com.android.internal.R.array.phoneTypes);
- try {
- display = labels[type - 1];
- } catch (ArrayIndexOutOfBoundsException e) {
- display = labels[Phone.TYPE_CUSTOM];
- }
- } else {
- if (!TextUtils.isEmpty(label)) {
- display = label;
- }
- }
- return display;
+ return getTypeLabel(context.getResources(), type, label);
}
+ /**
+ * @deprecated use {@link #getTypeLabel(Resources, int, CharSequence)} instead.
+ */
+ @Deprecated
public static final CharSequence getDisplayLabel(Context context, int type,
CharSequence label) {
- return getDisplayLabel(context, type, label, null);
+ return getTypeLabel(context.getResources(), type, label);
+ }
+
+ /**
+ * Return the string resource that best describes the given
+ * {@link CommonColumns#TYPE}. Will always return a valid resource.
+ */
+ public static final int getTypeLabelResource(int type) {
+ switch (type) {
+ case TYPE_HOME: return com.android.internal.R.string.phoneTypeHome;
+ case TYPE_MOBILE: return com.android.internal.R.string.phoneTypeMobile;
+ case TYPE_WORK: return com.android.internal.R.string.phoneTypeWork;
+ case TYPE_FAX_WORK: return com.android.internal.R.string.phoneTypeFaxWork;
+ case TYPE_FAX_HOME: return com.android.internal.R.string.phoneTypeFaxHome;
+ case TYPE_PAGER: return com.android.internal.R.string.phoneTypePager;
+ case TYPE_OTHER: return com.android.internal.R.string.phoneTypeOther;
+ case TYPE_CALLBACK: return com.android.internal.R.string.phoneTypeCallback;
+ case TYPE_CAR: return com.android.internal.R.string.phoneTypeCar;
+ case TYPE_COMPANY_MAIN: return com.android.internal.R.string.phoneTypeCompanyMain;
+ case TYPE_ISDN: return com.android.internal.R.string.phoneTypeIsdn;
+ case TYPE_MAIN: return com.android.internal.R.string.phoneTypeMain;
+ case TYPE_OTHER_FAX: return com.android.internal.R.string.phoneTypeOtherFax;
+ case TYPE_RADIO: return com.android.internal.R.string.phoneTypeRadio;
+ case TYPE_TELEX: return com.android.internal.R.string.phoneTypeTelex;
+ case TYPE_TTY_TDD: return com.android.internal.R.string.phoneTypeTtyTdd;
+ case TYPE_WORK_MOBILE: return com.android.internal.R.string.phoneTypeWorkMobile;
+ case TYPE_WORK_PAGER: return com.android.internal.R.string.phoneTypeWorkPager;
+ case TYPE_ASSISTANT: return com.android.internal.R.string.phoneTypeAssistant;
+ case TYPE_MMS: return com.android.internal.R.string.phoneTypeMms;
+ default: return com.android.internal.R.string.phoneTypeCustom;
+ }
+ }
+
+ /**
+ * Return a {@link CharSequence} that best describes the given type,
+ * possibly substituting the given {@link CommonColumns#LABEL} value
+ * for {@link BaseTypes#TYPE_CUSTOM}.
+ */
+ public static final CharSequence getTypeLabel(Resources res, int type,
+ CharSequence label) {
+ if ((type == TYPE_CUSTOM || type == TYPE_ASSISTANT) && !TextUtils.isEmpty(label)) {
+ return label;
+ } else {
+ final int labelRes = getTypeLabelResource(type);
+ return res.getText(labelRes);
+ }
}
}
@@ -1177,6 +1192,35 @@
* <P>Type: TEXT</P>
*/
public static final String DISPLAY_NAME = DATA4;
+
+ /**
+ * Return the string resource that best describes the given
+ * {@link CommonColumns#TYPE}. Will always return a valid resource.
+ */
+ public static final int getTypeLabelResource(int type) {
+ switch (type) {
+ case TYPE_HOME: return com.android.internal.R.string.emailTypeHome;
+ case TYPE_WORK: return com.android.internal.R.string.emailTypeWork;
+ case TYPE_OTHER: return com.android.internal.R.string.emailTypeOther;
+ case TYPE_MOBILE: return com.android.internal.R.string.emailTypeMobile;
+ default: return com.android.internal.R.string.emailTypeCustom;
+ }
+ }
+
+ /**
+ * Return a {@link CharSequence} that best describes the given type,
+ * possibly substituting the given {@link CommonColumns#LABEL} value
+ * for {@link BaseTypes#TYPE_CUSTOM}.
+ */
+ public static final CharSequence getTypeLabel(Resources res, int type,
+ CharSequence label) {
+ if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+ return label;
+ } else {
+ final int labelRes = getTypeLabelResource(type);
+ return res.getText(labelRes);
+ }
+ }
}
/**
@@ -1271,6 +1315,34 @@
* Type: TEXT
*/
public static final String COUNTRY = DATA10;
+
+ /**
+ * Return the string resource that best describes the given
+ * {@link CommonColumns#TYPE}. Will always return a valid resource.
+ */
+ public static final int getTypeLabelResource(int type) {
+ switch (type) {
+ case TYPE_HOME: return com.android.internal.R.string.postalTypeHome;
+ case TYPE_WORK: return com.android.internal.R.string.postalTypeWork;
+ case TYPE_OTHER: return com.android.internal.R.string.postalTypeOther;
+ default: return com.android.internal.R.string.postalTypeCustom;
+ }
+ }
+
+ /**
+ * Return a {@link CharSequence} that best describes the given type,
+ * possibly substituting the given {@link CommonColumns#LABEL} value
+ * for {@link BaseTypes#TYPE_CUSTOM}.
+ */
+ public static final CharSequence getTypeLabel(Resources res, int type,
+ CharSequence label) {
+ if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+ return label;
+ } else {
+ final int labelRes = getTypeLabelResource(type);
+ return res.getText(labelRes);
+ }
+ }
}
/**
@@ -1309,6 +1381,68 @@
public static final int PROTOCOL_ICQ = 6;
public static final int PROTOCOL_JABBER = 7;
public static final int PROTOCOL_NETMEETING = 8;
+
+ /**
+ * Return the string resource that best describes the given
+ * {@link CommonColumns#TYPE}. Will always return a valid resource.
+ */
+ public static final int getTypeLabelResource(int type) {
+ switch (type) {
+ case TYPE_HOME: return com.android.internal.R.string.imTypeHome;
+ case TYPE_WORK: return com.android.internal.R.string.imTypeWork;
+ case TYPE_OTHER: return com.android.internal.R.string.imTypeOther;
+ default: return com.android.internal.R.string.imTypeCustom;
+ }
+ }
+
+ /**
+ * Return a {@link CharSequence} that best describes the given type,
+ * possibly substituting the given {@link CommonColumns#LABEL} value
+ * for {@link BaseTypes#TYPE_CUSTOM}.
+ */
+ public static final CharSequence getTypeLabel(Resources res, int type,
+ CharSequence label) {
+ if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+ return label;
+ } else {
+ final int labelRes = getTypeLabelResource(type);
+ return res.getText(labelRes);
+ }
+ }
+
+ /**
+ * Return the string resource that best describes the given
+ * {@link Im#PROTOCOL}. Will always return a valid resource.
+ */
+ public static final int getProtocolLabelResource(int type) {
+ switch (type) {
+ case PROTOCOL_AIM: return com.android.internal.R.string.imProtocolAim;
+ case PROTOCOL_MSN: return com.android.internal.R.string.imProtocolMsn;
+ case PROTOCOL_YAHOO: return com.android.internal.R.string.imProtocolYahoo;
+ case PROTOCOL_SKYPE: return com.android.internal.R.string.imProtocolSkype;
+ case PROTOCOL_QQ: return com.android.internal.R.string.imProtocolQq;
+ case PROTOCOL_GOOGLE_TALK: return com.android.internal.R.string.imProtocolGoogleTalk;
+ case PROTOCOL_ICQ: return com.android.internal.R.string.imProtocolIcq;
+ case PROTOCOL_JABBER: return com.android.internal.R.string.imProtocolJabber;
+ case PROTOCOL_NETMEETING: return com.android.internal.R.string.imProtocolNetMeeting;
+ default: return com.android.internal.R.string.imProtocolCustom;
+ }
+ }
+
+ /**
+ * Return a {@link CharSequence} that best describes the given
+ * protocol, possibly substituting the given
+ * {@link #CUSTOM_PROTOCOL} value for {@link #PROTOCOL_CUSTOM}.
+ */
+ public static final CharSequence getProtocolLabel(Resources res, int type,
+ CharSequence label) {
+ if (type == PROTOCOL_CUSTOM && !TextUtils.isEmpty(label)) {
+ return label;
+ } else {
+ final int labelRes = getProtocolLabelResource(type);
+ return res.getText(labelRes);
+ }
+ }
}
/**
@@ -1358,6 +1492,33 @@
* <P>Type: TEXT</P>
*/
public static final String PHONETIC_NAME = DATA8;
+
+ /**
+ * Return the string resource that best describes the given
+ * {@link CommonColumns#TYPE}. Will always return a valid resource.
+ */
+ public static final int getTypeLabelResource(int type) {
+ switch (type) {
+ case TYPE_WORK: return com.android.internal.R.string.orgTypeWork;
+ case TYPE_OTHER: return com.android.internal.R.string.orgTypeOther;
+ default: return com.android.internal.R.string.orgTypeCustom;
+ }
+ }
+
+ /**
+ * Return a {@link CharSequence} that best describes the given type,
+ * possibly substituting the given {@link CommonColumns#LABEL} value
+ * for {@link BaseTypes#TYPE_CUSTOM}.
+ */
+ public static final CharSequence getTypeLabel(Resources res, int type,
+ CharSequence label) {
+ if (type == TYPE_CUSTOM && !TextUtils.isEmpty(label)) {
+ return label;
+ } else {
+ final int labelRes = getTypeLabelResource(type);
+ return res.getText(labelRes);
+ }
+ }
}
/**
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 34921f4..f9ab31c 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -369,6 +369,10 @@
uuid = str.toString();
}
mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
+
+ // UUIDs have changed, query remote service channel and update cache.
+ mBluetoothService.updateDeviceServiceChannelCache(address);
+
mBluetoothService.sendUuidIntent(address);
} else if (name.equals("Paired")) {
if (propValues[1].equals("true")) {
@@ -537,8 +541,7 @@
String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
// We don't parse the xml here, instead just query Bluez for the properties.
if (result) {
- String[] properties = mBluetoothService.getRemoteDeviceProperties(address);
- mBluetoothService.addRemoteDeviceProperties(address, properties);
+ mBluetoothService.updateRemoteDevicePropertiesCache(address);
}
mBluetoothService.sendUuidIntent(address);
}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 26007c5..e5b20bd 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -28,6 +28,7 @@
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetooth;
import android.bluetooth.ParcelUuid;
import android.content.BroadcastReceiver;
@@ -85,6 +86,7 @@
private final Map<String, String> mAdapterProperties;
private final HashMap <String, Map<String, String>> mDeviceProperties;
+ private final HashMap <String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
private final ArrayList <String> mUuidIntentTracker;
static {
@@ -111,6 +113,8 @@
mIsDiscovering = false;
mAdapterProperties = new HashMap<String, String>();
mDeviceProperties = new HashMap<String, Map<String,String>>();
+
+ mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>();
mUuidIntentTracker = new ArrayList<String>();
registerForAirplaneMode();
}
@@ -880,16 +884,22 @@
// Query for remote device properties, again.
// We will need to reload the cache when we switch Bluetooth on / off
// or if we crash.
- String[] propValues = getRemoteDeviceProperties(address);
- if (propValues != null) {
- addRemoteDeviceProperties(address, propValues);
+ if (updateRemoteDevicePropertiesCache(address))
return getRemoteDeviceProperty(address, property);
- }
}
Log.e(TAG, "getRemoteDeviceProperty: " + property + "not present:" + address);
return null;
}
+ /* package */ synchronized boolean updateRemoteDevicePropertiesCache(String address) {
+ String[] propValues = getRemoteDeviceProperties(address);
+ if (propValues != null) {
+ addRemoteDeviceProperties(address, propValues);
+ return true;
+ }
+ return false;
+ }
+
/* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) {
/*
* We get a DeviceFound signal every time RSSI changes or name changes.
@@ -924,6 +934,10 @@
propertyValues.put(name, newValue);
}
mDeviceProperties.put(address, propertyValues);
+
+ // We have added a new remote device or updated its properties.
+ // Also update the serviceChannel cache.
+ updateDeviceServiceChannelCache(address);
}
/* package */ void removeRemoteDeviceProperties(String address) {
@@ -1066,14 +1080,23 @@
* @param uuid ParcelUuid of the service attribute
*
* @return rfcomm channel associated with the service attribute
+ * -1 on error
*/
public int getRemoteServiceChannel(String address, ParcelUuid uuid) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
return BluetoothDevice.ERROR;
}
- return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(),
- 0x0004);
+ // Check if we are recovering from a crash.
+ if (mDeviceProperties.isEmpty()) {
+ if (!updateRemoteDevicePropertiesCache(address))
+ return -1;
+ }
+
+ Map<ParcelUuid, Integer> value = mDeviceServiceChannelCache.get(address);
+ if (value != null && value.containsKey(uuid))
+ return value.get(uuid);
+ return -1;
}
public synchronized boolean setPin(String address, byte[] pin) {
@@ -1152,6 +1175,27 @@
return cancelPairingUserInputNative(address, data.intValue());
}
+ public void updateDeviceServiceChannelCache(String address) {
+ ParcelUuid[] deviceUuids = getRemoteUuids(address);
+ // We are storing the rfcomm channel numbers only for the uuids
+ // we are interested in.
+ int channel;
+ ParcelUuid[] interestedUuids = {BluetoothUuid.Handsfree,
+ BluetoothUuid.HSP,
+ BluetoothUuid.ObexObjectPush};
+
+ Map <ParcelUuid, Integer> value = new HashMap<ParcelUuid, Integer>();
+ for (ParcelUuid uuid: interestedUuids) {
+ if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
+ channel =
+ getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(),
+ 0x0004);
+ value.put(uuid, channel);
+ }
+ }
+ mDeviceServiceChannelCache.put(address, value);
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1194,6 +1238,7 @@
/*package*/ synchronized void sendUuidIntent(String address) {
ParcelUuid[] uuid = getUuidFromCache(address);
Intent intent = new Intent(BluetoothDevice.ACTION_UUID);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
@@ -1366,4 +1411,5 @@
private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
private native boolean createDeviceNative(String address);
private native boolean discoverServicesNative(String objectPath, String pattern);
+
}
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 367b26c..baaa3ce 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -32,6 +32,18 @@
* @return formated string with the number
*/
public static String formatFileSize(Context context, long number) {
+ return formatFileSize(context, number, false);
+ }
+
+ /**
+ * Like {@link #formatFileSize}, but trying to generate shorter numbers
+ * (showing fewer digits of precisin).
+ */
+ public static String formatShortFileSize(Context context, long number) {
+ return formatFileSize(context, number, true);
+ }
+
+ private static String formatFileSize(Context context, long number, boolean shorter) {
if (context == null) {
return "";
}
@@ -58,13 +70,24 @@
suffix = com.android.internal.R.string.petabyteShort;
result = result / 1024;
}
- if (result < 100) {
- String value = String.format("%.2f", result);
- return context.getResources().
- getString(com.android.internal.R.string.fileSizeSuffix,
- value, context.getString(suffix));
+ String value;
+ if (result < 1) {
+ value = String.format("%.2f", result);
+ } else if (result < 10) {
+ if (shorter) {
+ value = String.format("%.1f", result);
+ } else {
+ value = String.format("%.2f", result);
+ }
+ } else if (result < 100) {
+ if (shorter) {
+ value = String.format("%.0f", result);
+ } else {
+ value = String.format("%.2f", result);
+ }
+ } else {
+ value = String.format("%.0f", result);
}
- String value = String.format("%.0f", result);
return context.getResources().
getString(com.android.internal.R.string.fileSizeSuffix,
value, context.getString(suffix));
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 45ff27e..cc5aeb1 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -314,7 +314,9 @@
public boolean showLw(boolean doAnimation);
}
- /** No transition happening. */
+ /** Not set up for a transition. */
+ public final int TRANSIT_UNSET = 0;
+ /** No animation for transition. */
public final int TRANSIT_NONE = 0;
/** Window has been added to the screen. */
public final int TRANSIT_ENTER = 1;
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index dbddb2e..e233a02 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -605,8 +605,8 @@
}
// Called by JNI when an apple-touch-icon attribute was found.
- private void didReceiveTouchIconUrl(String url) {
- mCallbackProxy.onReceivedTouchIconUrl(url);
+ private void didReceiveTouchIconUrl(String url, boolean precomposed) {
+ mCallbackProxy.onReceivedTouchIconUrl(url, precomposed);
}
/**
@@ -707,6 +707,10 @@
return value.string.toString();
}
+ private float density() {
+ return mContext.getResources().getDisplayMetrics().density;
+ }
+
//==========================================================================
// native functions
//==========================================================================
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index b051675..1ec769b 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -249,7 +249,7 @@
case RECEIVED_TOUCH_ICON_URL:
if (mWebChromeClient != null) {
mWebChromeClient.onReceivedTouchIconUrl(mWebView,
- (String) msg.obj);
+ (String) msg.obj, msg.arg1 == 1);
}
break;
@@ -1065,19 +1065,22 @@
sendMessage(obtainMessage(RECEIVED_ICON, icon));
}
- /* package */ void onReceivedTouchIconUrl(String url) {
+ /* package */ void onReceivedTouchIconUrl(String url, boolean precomposed) {
// We should have a current item but we do not want to crash so check
// for null.
WebHistoryItem i = mBackForwardList.getCurrentItem();
if (i != null) {
- i.setTouchIconUrl(url);
+ if (precomposed || i.getTouchIconUrl() != null) {
+ i.setTouchIconUrl(url);
+ }
}
// Do an unsynchronized quick check to avoid posting if no callback has
// been set.
if (mWebChromeClient == null) {
return;
}
- sendMessage(obtainMessage(RECEIVED_TOUCH_ICON_URL, url));
+ sendMessage(obtainMessage(RECEIVED_TOUCH_ICON_URL,
+ precomposed ? 1 : 0, 0, url));
}
public void onReceivedTitle(String title) {
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 0e08514..1ae1d85 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -48,9 +48,11 @@
* Notify the host application of the url for an apple-touch-icon.
* @param view The WebView that initiated the callback.
* @param url The icon url.
+ * @param precomposed True if the url is for a precomposed touch icon.
* @hide pending council approval
*/
- public void onReceivedTouchIconUrl(WebView view, String url) {}
+ public void onReceivedTouchIconUrl(WebView view, String url,
+ boolean precomposed) {}
/**
* A callback interface used by the host application to notify
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 39a2470..1a65ce8 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -448,8 +448,13 @@
int initialScrollX = Touch.getInitialScrollX(this, buffer);
int initialScrollY = Touch.getInitialScrollY(this, buffer);
super.onTouchEvent(event);
- if (Math.abs(mScrollX - initialScrollX) > slop
- || Math.abs(mScrollY - initialScrollY) > slop) {
+ int dx = Math.abs(mScrollX - initialScrollX);
+ int dy = Math.abs(mScrollY - initialScrollY);
+ // Use a smaller slop when checking to see if we've moved far enough
+ // to scroll the text, because experimentally, slop has shown to be
+ // to big for the case of a small textfield.
+ int smallerSlop = slop/2;
+ if (dx > smallerSlop || dy > smallerSlop) {
if (mWebView != null) {
mWebView.scrollFocusedTextInput(mScrollX, mScrollY);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9101578..113eac5 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1782,12 +1782,22 @@
}
/**
+ * Given a distance in view space, convert it to content space. Note: this
+ * does not reflect translation, just scaling, so this should not be called
+ * with coordinates, but should be called for dimensions like width or
+ * height.
+ */
+ private int viewToContentDimension(int d) {
+ return Math.round(d * mInvActualScale);
+ }
+
+ /**
* Given an x coordinate in view space, convert it to content space. Also
* may be used for absolute heights (such as for the WebTextView's
* textSize, which is unaffected by the height of the title bar).
*/
/*package*/ int viewToContentX(int x) {
- return Math.round(x * mInvActualScale);
+ return viewToContentDimension(x);
}
/**
@@ -1796,7 +1806,7 @@
* embedded into the WebView.
*/
/*package*/ int viewToContentY(int y) {
- return viewToContentX(y - getTitleHeight());
+ return viewToContentDimension(y - getTitleHeight());
}
/**
@@ -1811,7 +1821,7 @@
/**
* Given an x coordinate in content space, convert it to view
- * space. Also used for absolute heights.
+ * space.
*/
/*package*/ int contentToViewX(int x) {
return contentToViewDimension(x);
@@ -2505,16 +2515,26 @@
// saved scroll position, it is ok to skip this.
return false;
}
- int vx = contentToViewX(cx);
- int vy = contentToViewY(cy);
+ int vx;
+ int vy;
+ if ((cx | cy) == 0) {
+ // If the page is being scrolled to (0,0), do not add in the title
+ // bar's height, and simply scroll to (0,0). (The only other work
+ // in contentToView_ is to multiply, so this would not change 0.)
+ vx = 0;
+ vy = 0;
+ } else {
+ vx = contentToViewX(cx);
+ vy = contentToViewY(cy);
+ }
// Log.d(LOGTAG, "content scrollTo [" + cx + " " + cy + "] view=[" +
// vx + " " + vy + "]");
// Some mobile sites attempt to scroll the title bar off the page by
- // scrolling to (0,0) or (0,1). If we are at the top left corner of the
+ // scrolling to (0,1). If we are at the top left corner of the
// page, assume this is an attempt to scroll off the title bar, and
// animate the title bar off screen slowly enough that the user can see
// it.
- if (cx == 0 && cy <= 1 && mScrollX == 0 && mScrollY == 0) {
+ if (cx == 0 && cy == 1 && mScrollX == 0 && mScrollY == 0) {
pinScrollTo(vx, vy, true, SLIDE_TITLE_DURATION);
// Since we are animating, we have not yet reached the desired
// scroll position. Do not return true to request another attempt
@@ -4435,7 +4455,10 @@
return;
}
mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, viewToContentX(x),
- viewToContentY(y));
+ // Since this position is relative to the top of the text input
+ // field, we do not need to take the title bar's height into
+ // consideration.
+ viewToContentDimension(y));
}
/**
@@ -4845,7 +4868,7 @@
/ draw.mMinPrefWidth;
mMinZoomScaleFixed = false;
} else {
- mMinZoomScale = mDefaultScale;
+ mMinZoomScale = restoreState.mDefaultScale;
mMinZoomScaleFixed = true;
}
} else {
@@ -4862,22 +4885,13 @@
mMaxZoomScale = restoreState.mMaxScale;
}
setNewZoomScale(mLastScale, false);
- if (getTitleHeight() != 0 && restoreState.mScrollX == 0
- && restoreState.mScrollY == 0) {
- // If there is a title bar, and the page is being
- // restored to (0,0), do not scroll the title bar
- // off the page.
- abortAnimation();
- scrollTo(0,0);
- } else {
- setContentScrollTo(restoreState.mScrollX,
- restoreState.mScrollY);
- }
+ setContentScrollTo(restoreState.mScrollX,
+ restoreState.mScrollY);
if (useWideViewport
&& settings.getLoadWithOverviewMode()) {
if (restoreState.mViewScale == 0
|| (restoreState.mMobileSite
- && mMinZoomScale < mDefaultScale)) {
+ && mMinZoomScale < restoreState.mDefaultScale)) {
mInZoomOverview = true;
}
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index d4142bb..e734444 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -100,6 +100,15 @@
private boolean mViewportUserScalable = true;
+ /*
+ * range is from 70 to 400.
+ * 0 is a special value means device-dpi. The default scale factor will be
+ * always 100.
+ * -1 means undefined. The default scale factor will be
+ * WebView.DEFAULT_SCALE_PERCENT.
+ */
+ private int mViewportDensityDpi = -1;
+
private int mRestoredScale = 0;
private int mRestoredScreenWidthScale = 0;
private int mRestoredX = 0;
@@ -1539,6 +1548,7 @@
float mMaxScale;
float mViewScale;
float mTextWrapScale;
+ float mDefaultScale;
int mScrollX;
int mScrollY;
boolean mMobileSite;
@@ -1842,47 +1852,48 @@
// set the viewport settings from WebKit
setViewportSettingsFromNative();
- // adjust the default scale to match the density
- if (WebView.DEFAULT_SCALE_PERCENT != 100) {
- float adjust = (float) WebView.DEFAULT_SCALE_PERCENT / 100.0f;
- if (mViewportInitialScale > 0) {
- mViewportInitialScale *= adjust;
+ // adjust the default scale to match the densityDpi
+ float adjust = 1.0f;
+ if (mViewportDensityDpi == -1) {
+ if (WebView.DEFAULT_SCALE_PERCENT != 100) {
+ adjust = WebView.DEFAULT_SCALE_PERCENT / 100.0f;
}
- if (mViewportMinimumScale > 0) {
- mViewportMinimumScale *= adjust;
- }
- if (mViewportMaximumScale > 0) {
- mViewportMaximumScale *= adjust;
- }
+ } else if (mViewportDensityDpi > 0) {
+ adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi
+ / mViewportDensityDpi;
+ }
+ int defaultScale = (int) (adjust * 100);
+
+ if (mViewportInitialScale > 0) {
+ mViewportInitialScale *= adjust;
+ }
+ if (mViewportMinimumScale > 0) {
+ mViewportMinimumScale *= adjust;
+ }
+ if (mViewportMaximumScale > 0) {
+ mViewportMaximumScale *= adjust;
}
// infer the values if they are not defined.
if (mViewportWidth == 0) {
if (mViewportInitialScale == 0) {
- mViewportInitialScale = WebView.DEFAULT_SCALE_PERCENT;
+ mViewportInitialScale = defaultScale;
}
}
if (mViewportUserScalable == false) {
- mViewportInitialScale = WebView.DEFAULT_SCALE_PERCENT;
- mViewportMinimumScale = WebView.DEFAULT_SCALE_PERCENT;
- mViewportMaximumScale = WebView.DEFAULT_SCALE_PERCENT;
+ mViewportInitialScale = defaultScale;
+ mViewportMinimumScale = defaultScale;
+ mViewportMaximumScale = defaultScale;
}
- if (mViewportMinimumScale > mViewportInitialScale) {
- if (mViewportInitialScale == 0) {
- mViewportInitialScale = mViewportMinimumScale;
- } else {
- mViewportMinimumScale = mViewportInitialScale;
- }
+ if (mViewportMinimumScale > mViewportInitialScale
+ && mViewportInitialScale != 0) {
+ mViewportMinimumScale = mViewportInitialScale;
}
- if (mViewportMaximumScale > 0) {
- if (mViewportMaximumScale < mViewportInitialScale) {
- mViewportMaximumScale = mViewportInitialScale;
- } else if (mViewportInitialScale == 0) {
- mViewportInitialScale = mViewportMaximumScale;
- }
+ if (mViewportMaximumScale > 0
+ && mViewportMaximumScale < mViewportInitialScale) {
+ mViewportMaximumScale = mViewportInitialScale;
}
- if (mViewportWidth < 0
- && mViewportInitialScale == WebView.DEFAULT_SCALE_PERCENT) {
+ if (mViewportWidth < 0 && mViewportInitialScale == defaultScale) {
mViewportWidth = 0;
}
@@ -1899,7 +1910,7 @@
// we call WebView method from WebCore thread. But not perfect
// reference is better than no reference.
webViewWidth = mWebView.getViewWidth();
- viewportWidth = webViewWidth * 100 / WebView.DEFAULT_SCALE_PERCENT;
+ viewportWidth = (int) (webViewWidth / adjust);
if (viewportWidth == 0) {
Log.w(LOGTAG, "Can't get the viewWidth after the first layout");
}
@@ -1909,6 +1920,7 @@
mRestoreState = new RestoreState();
mRestoreState.mMinScale = mViewportMinimumScale / 100.0f;
mRestoreState.mMaxScale = mViewportMaximumScale / 100.0f;
+ mRestoreState.mDefaultScale = adjust;
mRestoreState.mScrollX = mRestoredX;
mRestoreState.mScrollY = mRestoredY;
mRestoreState.mMobileSite = (0 == mViewportWidth);
@@ -1930,8 +1942,7 @@
mRestoreState.mViewScale = mRestoreState.mTextWrapScale =
(float) webViewWidth / mViewportWidth;
} else {
- mRestoreState.mTextWrapScale =
- WebView.DEFAULT_SCALE_PERCENT / 100.0f;
+ mRestoreState.mTextWrapScale = adjust;
// 0 will trigger WebView to turn on zoom overview mode
mRestoreState.mViewScale = 0;
}
diff --git a/core/java/com/android/internal/backup/BackupConstants.java b/core/java/com/android/internal/backup/BackupConstants.java
new file mode 100644
index 0000000..3ee11bd
--- /dev/null
+++ b/core/java/com/android/internal/backup/BackupConstants.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.backup;
+
+/**
+ * Constants used internally between the backup manager and its transports
+ */
+public class BackupConstants {
+ public static final int TRANSPORT_OK = 0;
+ public static final int TRANSPORT_ERROR = 1;
+ public static final int TRANSPORT_NOT_INITIALIZED = 2;
+}
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index 250bc91..a830ebd 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -22,24 +22,6 @@
/** {@hide} */
interface IBackupTransport {
-/* STOPSHIP - don't ship with this comment in place
- Things the transport interface has to do:
- 1. set up the connection to the destination
- - set up encryption
- - for Google cloud, log in using the user's gaia credential or whatever
- - for adb, just set up the all-in-one destination file
- 2. send each app's backup transaction
- - parse the data file for key/value pointers etc
- - send key/blobsize set to the Google cloud, get back quota ok/rejected response
- - sd/adb doesn't preflight; no per-app quota
- - app's entire change is essentially atomic
- - cloud transaction encrypts then sends each key/value pair separately; we already
- parsed the data when preflighting so we don't have to again here
- - sd target streams raw data into encryption envelope then to sd?
- 3. shut down connection to destination
- - cloud: tear down connection etc
- - adb: close the file
-*/
/**
* Ask the transport where, on local device storage, to keep backup state blobs.
* This is per-transport so that mock transports used for testing can coexist with
@@ -68,6 +50,17 @@
long requestBackupTime();
/**
+ * Initialize the server side storage for this device, erasing all stored data.
+ * The transport may send the request immediately, or may buffer it. After
+ * this is called, {@link #finishBackup} must be called to ensure the request
+ * is sent and received successfully.
+ *
+ * @return One of {@link BackupConstants#TRANSPORT_OK} (OK so far) or
+ * {@link BackupConstants#TRANSPORT_ERROR} (on network error or other failure).
+ */
+ int initializeDevice();
+
+ /**
* Send one application's data to the backup destination. The transport may send
* the data immediately, or may buffer it. After this is called, {@link #finishBackup}
* must be called to ensure the data is sent and recorded successfully.
@@ -81,11 +74,12 @@
* will be erased prior to the storage of the data provided here. The purpose of this
* is to provide a guarantee that no stale data exists in the restore set when the
* device begins providing backups.
- * @return false if errors occurred (the backup should be aborted and rescheduled),
- * true if everything is OK so far (but {@link #finishBackup} must be called).
+ * @return one of {@link BackupConstants#TRANSPORT_OK} (OK so far),
+ * {@link BackupConstants#TRANSPORT_ERROR} (on network error or other failure), or
+ * {@link BackupConstants#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has
+ * become lost due to inactive expiry or some other reason and needs re-initializing)
*/
- boolean performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd,
- boolean wipeAllFirst);
+ int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd);
/**
* Erase the give application's data from the backup destination. This clears
@@ -93,10 +87,9 @@
* the app had never yet been backed up. After this is called, {@link finishBackup}
* must be called to ensure that the operation is recorded successfully.
*
- * @return false if errors occurred (the backup should be aborted and rescheduled),
- * true if everything is OK so far (but {@link #finishBackup} must be called).
+ * @return the same error codes as {@link #performBackup}.
*/
- boolean clearBackupData(in PackageInfo packageInfo);
+ int clearBackupData(in PackageInfo packageInfo);
/**
* Finish sending application data to the backup destination. This must be
@@ -104,10 +97,9 @@
* all data is sent. Only when this method returns true can a backup be assumed
* to have succeeded.
*
- * @return false if errors occurred (the backup should be aborted and rescheduled),
- * true if everything is OK.
+ * @return the same error codes as {@link #performBackup}.
*/
- boolean finishBackup();
+ int finishBackup();
/**
* Get the set of backups currently available over this transport.
@@ -125,10 +117,11 @@
* @param token A backup token as returned by {@link #getAvailableRestoreSets}.
* @param packages List of applications to restore (if data is available).
* Application data will be restored in the order given.
- * @return false if errors occurred (the restore should be aborted and rescheduled),
- * true if everything is OK so far (go ahead and call {@link #nextRestorePackage}).
+ * @return One of {@link BackupConstants#TRANSPORT_OK} (OK so far, call
+ * {@link #nextRestorePackage}) or {@link BackupConstants#TRANSPORT_ERROR}
+ * (an error occurred, the restore should be aborted and rescheduled).
*/
- boolean startRestore(long token, in PackageInfo[] packages);
+ int startRestore(long token, in PackageInfo[] packages);
/**
* Get the package name of the next application with data in the backup store.
@@ -141,10 +134,9 @@
/**
* Get the data for the application returned by {@link #nextRestorePackage}.
* @param data An open, writable file into which the backup data should be stored.
- * @return false if errors occurred (the restore should be aborted and rescheduled),
- * true if everything is OK so far (go ahead and call {@link #nextRestorePackage}).
+ * @return the same error codes as {@link #nextRestorePackage}.
*/
- boolean getRestoreData(in ParcelFileDescriptor outFd);
+ int getRestoreData(in ParcelFileDescriptor outFd);
/**
* End a restore session (aborting any in-process data transfer as necessary),
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 981ea82..4fc3edc 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -47,25 +47,26 @@
}
- public String transportDirName() throws RemoteException {
+ public String transportDirName() {
return TRANSPORT_DIR_NAME;
}
- public long requestBackupTime() throws RemoteException {
+ public long requestBackupTime() {
// any time is a good time for local backup
return 0;
}
- public boolean performBackup(PackageInfo packageInfo, ParcelFileDescriptor data,
- boolean wipeAllFirst) throws RemoteException {
+ public int initializeDevice() {
+ if (DEBUG) Log.v(TAG, "wiping all data");
+ deleteContents(mDataDir);
+ return BackupConstants.TRANSPORT_OK;
+ }
+
+ public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName);
File packageDir = new File(mDataDir, packageInfo.packageName);
packageDir.mkdirs();
- if (wipeAllFirst) {
- if (DEBUG) Log.v(TAG, "wiping all data first");
- deleteContents(mDataDir);
- }
// Each 'record' in the restore set is kept in its own file, named by
// the record key. Wind through the data file, extracting individual
@@ -99,7 +100,7 @@
entity.write(buf, 0, dataSize);
} catch (IOException e) {
Log.e(TAG, "Unable to update key file " + entityFile.getAbsolutePath());
- return false;
+ return BackupConstants.TRANSPORT_ERROR;
} finally {
entity.close();
}
@@ -107,11 +108,11 @@
entityFile.delete();
}
}
- return true;
+ return BackupConstants.TRANSPORT_OK;
} catch (IOException e) {
// oops, something went wrong. abort the operation and return error.
Log.v(TAG, "Exception reading backup input:", e);
- return false;
+ return BackupConstants.TRANSPORT_ERROR;
}
}
@@ -130,7 +131,7 @@
}
}
- public boolean clearBackupData(PackageInfo packageInfo) {
+ public int clearBackupData(PackageInfo packageInfo) {
if (DEBUG) Log.v(TAG, "clearBackupData() pkg=" + packageInfo.packageName);
File packageDir = new File(mDataDir, packageInfo.packageName);
@@ -138,12 +139,12 @@
f.delete();
}
packageDir.delete();
- return true;
+ return BackupConstants.TRANSPORT_OK;
}
- public boolean finishBackup() throws RemoteException {
+ public int finishBackup() {
if (DEBUG) Log.v(TAG, "finishBackup()");
- return true;
+ return BackupConstants.TRANSPORT_OK;
}
// Restore handling
@@ -154,11 +155,11 @@
return array;
}
- public boolean startRestore(long token, PackageInfo[] packages) {
+ public int startRestore(long token, PackageInfo[] packages) {
if (DEBUG) Log.v(TAG, "start restore " + token);
mRestorePackages = packages;
mRestorePackage = -1;
- return true;
+ return BackupConstants.TRANSPORT_OK;
}
public String nextRestorePackage() {
@@ -175,7 +176,7 @@
return "";
}
- public boolean getRestoreData(ParcelFileDescriptor outFd) {
+ public int getRestoreData(ParcelFileDescriptor outFd) {
if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
if (mRestorePackage < 0) throw new IllegalStateException("nextRestorePackage not called");
File packageDir = new File(mDataDir, mRestorePackages[mRestorePackage].packageName);
@@ -183,9 +184,9 @@
// The restore set is the concatenation of the individual record blobs,
// each of which is a file in the package's directory
File[] blobs = packageDir.listFiles();
- if (blobs == null) {
+ if (blobs == null) { // nextRestorePackage() ensures the dir exists, so this is an error
Log.e(TAG, "Error listing directory: " + packageDir);
- return false; // nextRestorePackage() ensures the dir exists, so this is an error
+ return BackupConstants.TRANSPORT_ERROR;
}
// We expect at least some data if the directory exists in the first place
@@ -206,10 +207,10 @@
in.close();
}
}
- return true;
+ return BackupConstants.TRANSPORT_OK;
} catch (IOException e) {
Log.e(TAG, "Unable to read backup records", e);
- return false;
+ return BackupConstants.TRANSPORT_ERROR;
}
}
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 4987775..35d637d 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -63,6 +63,7 @@
private static final String TAG = "ContactHeaderWidget";
private TextView mDisplayNameView;
+ private View mAggregateBadge;
private TextView mPhoneticNameView;
private CheckBox mStarredView;
private FasttrackBadgeWidget mPhotoView;
@@ -159,6 +160,8 @@
mDisplayNameView = (TextView) findViewById(R.id.name);
mDisplayNameView.setOnLongClickListener(this);
+ mAggregateBadge = findViewById(R.id.aggregate_badge);
+ mAggregateBadge.setVisibility(View.GONE);
mPhoneticNameView = (TextView) findViewById(R.id.phonetic_name);
@@ -284,6 +287,13 @@
}
/**
+ * Turn on/off showing of the aggregate bage element.
+ */
+ public void showAggregateBadge(boolean showBagde) {
+ mAggregateBadge.setVisibility(showBagde ? View.VISIBLE : View.GONE);
+ }
+
+ /**
* Turn on/off showing of the star element.
*/
public void showStar(boolean showStar) {
@@ -310,6 +320,7 @@
*/
public void setContactUri(Uri uri) {
mContactUri = uri;
+ mPhotoView.assignContactUri(uri);
}
/**
diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml
index 9d1ef53..f1258e8 100644
--- a/core/res/res/anim/activity_close_enter.xml
+++ b/core/res/res/anim/activity_close_enter.xml
@@ -21,5 +21,5 @@
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
<translate android:fromXDelta="-100%" android:toXDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml
index 47cb6d6..bf3d8cd3 100644
--- a/core/res/res/anim/activity_close_exit.xml
+++ b/core/res/res/anim/activity_close_exit.xml
@@ -20,5 +20,5 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator">
<translate android:fromXDelta="0%" android:toXDelta="33%"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml
index e4c7e9b..a9ea381 100644
--- a/core/res/res/anim/activity_open_enter.xml
+++ b/core/res/res/anim/activity_open_enter.xml
@@ -20,5 +20,5 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator">
<translate android:fromXDelta="33%" android:toXDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml
index 9d47b7f..b04b79e 100644
--- a/core/res/res/anim/activity_open_exit.xml
+++ b/core/res/res/anim/activity_open_exit.xml
@@ -21,5 +21,5 @@
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
<translate android:fromXDelta="0%" android:toXDelta="-100%"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/dialog_enter.xml b/core/res/res/anim/dialog_enter.xml
index cc409e8..d4983c6 100644
--- a/core/res/res/anim/dialog_enter.xml
+++ b/core/res/res/anim/dialog_enter.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/fade_in.xml
-**
+/*
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/core/res/res/anim/dialog_exit.xml b/core/res/res/anim/dialog_exit.xml
index 8bf8082..2aa629a 100644
--- a/core/res/res/anim/dialog_exit.xml
+++ b/core/res/res/anim/dialog_exit.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/res/anim/fade_out.xml
-**
+/*
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +16,7 @@
** limitations under the License.
*/
-->
+
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/accelerate_interpolator">
<scale android:fromXScale="1.0" android:toXScale="0.9"
diff --git a/core/res/res/anim/recent_enter.xml b/core/res/res/anim/recent_enter.xml
index 54ae73b..8faa2c1 100644
--- a/core/res/res/anim/recent_enter.xml
+++ b/core/res/res/anim/recent_enter.xml
@@ -19,10 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator">
- <scale android:fromXScale="2.0" android:toXScale="1.0"
- android:fromYScale="2.0" android:toYScale="1.0"
+ <scale android:fromXScale="0.9" android:toXScale="1.0"
+ android:fromYScale="0.9" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="50%"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_shortAnimTime" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime" />
</set>
diff --git a/core/res/res/anim/recent_exit.xml b/core/res/res/anim/recent_exit.xml
index 32d64a4..9399329 100644
--- a/core/res/res/anim/recent_exit.xml
+++ b/core/res/res/anim/recent_exit.xml
@@ -18,12 +18,11 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/decelerate_interpolator"
- android:zAdjustment="top">
- <scale android:fromXScale="1.0" android:toXScale="2.0"
- android:fromYScale="1.0" android:toYScale="2.0"
+ android:interpolator="@anim/accelerate_interpolator">
+ <scale android:fromXScale="1.0" android:toXScale="0.9"
+ android:fromYScale="1.0" android:toYScale="0.9"
android:pivotX="50%" android:pivotY="50%"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime" />
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index 98975fb..db331b1 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -18,8 +18,7 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/decelerate_interpolator"
- android:zAdjustment="top">
+ android:interpolator="@anim/decelerate_interpolator">
<scale android:fromXScale="1.0" android:toXScale="2.0"
android:fromYScale="1.0" android:toYScale="2.0"
android:pivotX="50%p" android:pivotY="50%p"
diff --git a/core/res/res/anim/translucent_enter.xml b/core/res/res/anim/translucent_enter.xml
index fb4c1c3..04852a8 100644
--- a/core/res/res/anim/translucent_enter.xml
+++ b/core/res/res/anim/translucent_enter.xml
@@ -20,7 +20,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator">
<translate android:fromXDelta="75%" android:toXDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/translucent_exit.xml b/core/res/res/anim/translucent_exit.xml
index 1d424e1..adaf3d1 100644
--- a/core/res/res/anim/translucent_exit.xml
+++ b/core/res/res/anim/translucent_exit.xml
@@ -20,7 +20,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/accelerate_interpolator">
<translate android:fromXDelta="0%" android:toXDelta="75%"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="@android:integer/config_shortAnimTime"/>
</set>
diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml
index e4c7e9b..0d13009 100644
--- a/core/res/res/anim/wallpaper_close_enter.xml
+++ b/core/res/res/anim/wallpaper_close_enter.xml
@@ -17,8 +17,22 @@
*/
-->
+<!-- This version zooms the new non-wallpaper down on top of the
+ wallpaper. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_interpolator">
+ <scale android:fromXScale="2.0" android:toXScale="1.0"
+ android:fromYScale="2.0" android:toYScale="1.0"
+ android:pivotX="50%p" android:pivotY="50%p"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+ also scales the wallpaper. -->
+<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator">
<translate android:fromXDelta="33%" android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
+-->
diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml
index 16edec1..5d91e30 100644
--- a/core/res/res/anim/wallpaper_close_exit.xml
+++ b/core/res/res/anim/wallpaper_close_exit.xml
@@ -17,6 +17,22 @@
*/
-->
+<!-- This version zooms the new non-wallpaper down on top of the
+ wallpaper. The wallpaper here just stays fixed behind. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_interpolator"
+ android:zAdjustment="top">
+ <scale android:fromXScale="1.0" android:toXScale=".5"
+ android:fromYScale="1.0" android:toYScale=".5"
+ android:pivotX="50%p" android:pivotY="50%p"
+ android:duration="@android:integer/config_mediumAnimTime" />
+ <alpha android:fromAlpha="1.0" android:toAlpha="0"
+ android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+ also scales the wallpaper. -->
+<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
@@ -27,3 +43,4 @@
<translate android:fromXDelta="0%" android:toXDelta="-100%"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
+-->
diff --git a/core/res/res/anim/wallpaper_open_enter.xml b/core/res/res/anim/wallpaper_open_enter.xml
index af22b47..cf27cf0 100644
--- a/core/res/res/anim/wallpaper_open_enter.xml
+++ b/core/res/res/anim/wallpaper_open_enter.xml
@@ -17,6 +17,22 @@
*/
-->
+<!-- This version zooms the new non-wallpaper up off the wallpaper the
+ wallpaper. The wallpaper here just stays fixed behind. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_interpolator"
+ android:zAdjustment="top">
+ <scale android:fromXScale=".5" android:toXScale="1.0"
+ android:fromYScale=".5" android:toYScale="1.0"
+ android:pivotX="50%p" android:pivotY="50%p"
+ android:duration="@android:integer/config_mediumAnimTime" />
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+ also scales the wallpaper. -->
+<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
@@ -27,3 +43,4 @@
<translate android:fromXDelta="-100%" android:toXDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
+-->
diff --git a/core/res/res/anim/wallpaper_open_exit.xml b/core/res/res/anim/wallpaper_open_exit.xml
index 47cb6d6..b7a539c 100644
--- a/core/res/res/anim/wallpaper_open_exit.xml
+++ b/core/res/res/anim/wallpaper_open_exit.xml
@@ -17,8 +17,22 @@
*/
-->
+<!-- This version zooms the new non-wallpaper down on top of the
+ wallpaper. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_interpolator">
+ <scale android:fromXScale="1.0" android:toXScale="2.0"
+ android:fromYScale="1.0" android:toYScale="2.0"
+ android:pivotX="50%p" android:pivotY="50%p"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
+<!-- This version is a variation on the inter-activity slide that
+ also scales the wallpaper. -->
+<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator">
<translate android:fromXDelta="0%" android:toXDelta="33%"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
+-->
diff --git a/core/res/res/drawable-hdpi/ic_aggregated.png b/core/res/res/drawable-hdpi/ic_aggregated.png
new file mode 100644
index 0000000..7ca15b1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_aggregated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_aggregated.png b/core/res/res/drawable-mdpi/ic_aggregated.png
new file mode 100644
index 0000000..7c2e2b0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_aggregated.png
Binary files differ
diff --git a/core/res/res/layout/contact_header.xml b/core/res/res/layout/contact_header.xml
index e800dfa..d19bb04 100644
--- a/core/res/res/layout/contact_header.xml
+++ b/core/res/res/layout/contact_header.xml
@@ -38,8 +38,24 @@
android:layout_marginTop="5dip"
android:orientation="vertical">
- <!-- "Name" field is locale-specific. -->
- <include layout="@layout/contact_header_name"/>
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/aggregate_badge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="3dip"
+ android:paddingTop="3dip"
+ android:src="@drawable/ic_aggregated"
+ />
+
+ <!-- "Name" field is locale-specific. -->
+ <include layout="@layout/contact_header_name"/>
+
+ </LinearLayout>
<TextView android:id="@+id/status"
android:layout_width="fill_parent"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e7b379a..c3b7a2c 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3486,13 +3486,29 @@
<!-- Contacts meta-data attributes -->
<!-- =============================== -->
+ <!-- TODO: remove this deprecated styleable -->
<declare-styleable name="Icon">
<attr name="icon" />
<attr name="mimeType" />
</declare-styleable>
+ <!-- TODO: remove this deprecated styleable -->
<declare-styleable name="IconDefault">
<attr name="icon" />
</declare-styleable>
+ <!-- Maps a specific contact data MIME-type to styling information -->
+ <declare-styleable name="ContactsDataKind">
+ <!-- Mime-type handled by this mapping -->
+ <attr name="mimeType" />
+ <!-- Icon used to represent data of this kind -->
+ <attr name="icon" />
+ <!-- Column in data table that summarizes this data -->
+ <attr name="summaryColumn" format="string" />
+ <!-- Column in data table that contains details for this data -->
+ <attr name="detailColumn" format="string" />
+ <!-- Flag indicating that detail should be built from SocialProvider -->
+ <attr name="detailSocialSummary" format="boolean" />
+ </declare-styleable>
+
</resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 2f09aca..15841a8 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -19,7 +19,7 @@
-->
<resources>
<drawable name="screen_background_light">#ffffffff</drawable>
- <drawable name="screen_background_dark">#ff1a1a1a</drawable>
+ <drawable name="screen_background_dark">#ff000000</drawable>
<drawable name="status_bar_closed_default_background">#ff000000</drawable>
<drawable name="status_bar_opened_default_background">#ff000000</drawable>
<drawable name="search_bar_default_color">#ff000000</drawable>
@@ -36,7 +36,7 @@
<color name="white">#ffffffff</color>
<color name="black">#ff000000</color>
<color name="transparent">#00000000</color>
- <color name="background_dark">#ff1a1a1a</color>
+ <color name="background_dark">#ff000000</color>
<color name="bright_foreground_dark">#ffffffff</color>
<color name="bright_foreground_dark_disabled">#80ffffff</color>
<color name="bright_foreground_dark_inverse">#ff000000</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7695503..7aeaec4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -27,13 +27,13 @@
<bool name="config_sf_limitedAlpha">false</bool>
<!-- The duration (in milliseconds) of a short animation. -->
- <integer name="config_shortAnimTime">100</integer>
+ <integer name="config_shortAnimTime">150</integer>
<!-- The duration (in milliseconds) of a medium-length animation. -->
- <integer name="config_mediumAnimTime">150</integer>
+ <integer name="config_mediumAnimTime">250</integer>
<!-- The duration (in milliseconds) of a long animation. -->
- <integer name="config_longAnimTime">300</integer>
+ <integer name="config_longAnimTime">400</integer>
<!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
Please don't copy them, copy anything else. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 89581e6..b08a58a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1166,6 +1166,9 @@
<public type="attr" name="accountPreferences" />
<public type="attr" name="textAppearanceSearchResultSubtitle" />
<public type="attr" name="textAppearanceSearchResultTitle" />
+ <public type="attr" name="summaryColumn" />
+ <public type="attr" name="detailColumn" />
+ <public type="attr" name="detailSocialSummary" />
<public type="style" name="Theme.Wallpaper" />
<public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a1a0102..e2f6981 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1200,6 +1200,106 @@
<item>Jabber</item>
</string-array>
+ <!-- Custom phone number type -->
+ <string name="phoneTypeCustom">Custom</string>
+ <!-- Home phone number type -->
+ <string name="phoneTypeHome">Home</string>
+ <!-- Mobile phone number type -->
+ <string name="phoneTypeMobile">Mobile</string>
+ <!-- Work phone number type -->
+ <string name="phoneTypeWork">Work</string>
+ <!-- Work fax phone number type -->
+ <string name="phoneTypeFaxWork">Work Fax</string>
+ <!-- Home fax phone number type -->
+ <string name="phoneTypeFaxHome">Home Fax</string>
+ <!-- Pager phone number type -->
+ <string name="phoneTypePager">Pager</string>
+ <!-- Other phone number type -->
+ <string name="phoneTypeOther">Other</string>
+ <!-- Callback phone number type -->
+ <string name="phoneTypeCallback">Callback</string>
+ <!-- Car phone number type -->
+ <string name="phoneTypeCar">Car</string>
+ <!-- Company main phone number type -->
+ <string name="phoneTypeCompanyMain">Company Main</string>
+ <!-- ISDN phone number type -->
+ <string name="phoneTypeIsdn">ISDN</string>
+ <!-- Main phone number type -->
+ <string name="phoneTypeMain">Main</string>
+ <!-- Other fax phone number type -->
+ <string name="phoneTypeOtherFax">Other Fax</string>
+ <!-- Radio phone number type -->
+ <string name="phoneTypeRadio">Radio</string>
+ <!-- Telex phone number type -->
+ <string name="phoneTypeTelex">Telex</string>
+ <!-- TTY TDD phone number type -->
+ <string name="phoneTypeTtyTdd">TTY TDD</string>
+ <!-- Work mobile phone number type -->
+ <string name="phoneTypeWorkMobile">Work Mobile</string>
+ <!-- Work pager phone number type -->
+ <string name="phoneTypeWorkPager">Work Pager</string>
+ <!-- Assistant phone number type -->
+ <string name="phoneTypeAssistant">Assistant</string>
+ <!-- MMS phone number type -->
+ <string name="phoneTypeMms">MMS</string>
+
+ <!-- Custom email type -->
+ <string name="emailTypeCustom">Custom</string>
+ <!-- Home email type -->
+ <string name="emailTypeHome">Home</string>
+ <!-- Work email type -->
+ <string name="emailTypeWork">Work</string>
+ <!-- Other email type -->
+ <string name="emailTypeOther">Other</string>
+ <!-- Mobile email type -->
+ <string name="emailTypeMobile">Mobile</string>
+
+ <!-- Custom postal address type -->
+ <string name="postalTypeCustom">Custom</string>
+ <!-- Home postal address type -->
+ <string name="postalTypeHome">Home</string>
+ <!-- Work postal address type -->
+ <string name="postalTypeWork">Work</string>
+ <!-- Other postal address type -->
+ <string name="postalTypeOther">Other</string>
+
+ <!-- Custom IM address type -->
+ <string name="imTypeCustom">Custom</string>
+ <!-- Home IM address type -->
+ <string name="imTypeHome">Home</string>
+ <!-- Work IM address type -->
+ <string name="imTypeWork">Work</string>
+ <!-- Other IM address type -->
+ <string name="imTypeOther">Other</string>
+
+ <!-- Custom IM address type -->
+ <string name="imProtocolCustom">Custom</string>
+ <!-- AIM IM protocol type -->
+ <string name="imProtocolAim">AIM</string>
+ <!-- MSN IM protocol type -->
+ <string name="imProtocolMsn">Windows Live</string>
+ <!-- Yahoo IM protocol type -->
+ <string name="imProtocolYahoo">Yahoo</string>
+ <!-- Skype IM protocol type -->
+ <string name="imProtocolSkype">Skype</string>
+ <!-- QQ IM protocol type -->
+ <string name="imProtocolQq">QQ</string>
+ <!-- Google Talk IM protocol type -->
+ <string name="imProtocolGoogleTalk">Google Talk</string>
+ <!-- ICQ IM protocol type -->
+ <string name="imProtocolIcq">ICQ</string>
+ <!-- Jabber IM protocol type -->
+ <string name="imProtocolJabber">Jabber</string>
+ <!-- NetMeeting IM protocol type -->
+ <string name="imProtocolNetMeeting">NetMeeting</string>
+
+ <!-- Work organization type -->
+ <string name="orgTypeWork">Work</string>
+ <!-- Other organization type -->
+ <string name="orgTypeOther">Other</string>
+ <!-- Custom organization type -->
+ <string name="orgTypeCustom">Custom</string>
+
<!-- Instructions telling the user to enter their pin to unlock the keyguard.
Displayed in one line in a large font. -->
<string name="keyguard_password_enter_pin_code">Enter PIN code</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 35db8ee..bc8ec45 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -58,6 +58,19 @@
<item name="activityOpenExitAnimation">@anim/activity_open_exit</item>
<item name="activityCloseEnterAnimation">@anim/activity_close_enter</item>
<item name="activityCloseExitAnimation">@anim/activity_close_exit</item>
+ <item name="taskOpenEnterAnimation">@anim/activity_open_enter</item>
+ <item name="taskOpenExitAnimation">@anim/activity_open_exit</item>
+ <item name="taskCloseEnterAnimation">@anim/activity_close_enter</item>
+ <item name="taskCloseExitAnimation">@anim/activity_close_exit</item>
+ <item name="taskToFrontEnterAnimation">@anim/activity_open_enter</item>
+ <item name="taskToFrontExitAnimation">@anim/activity_open_exit</item>
+ <item name="taskToBackEnterAnimation">@anim/activity_close_enter</item>
+ <item name="taskToBackExitAnimation">@anim/activity_close_exit</item>
+ <!-- There is a good argument to be made that the user shouldn't
+ be aware of task transitions, so we are going to use the same
+ animation for them as we do for regular activity transitions. -->
+ <!-- These provide an alternative animation for task transitions. -->
+ <!--
<item name="taskOpenEnterAnimation">@anim/task_open_enter</item>
<item name="taskOpenExitAnimation">@anim/task_open_exit</item>
<item name="taskCloseEnterAnimation">@anim/task_close_enter</item>
@@ -66,6 +79,7 @@
<item name="taskToFrontExitAnimation">@anim/task_open_exit</item>
<item name="taskToBackEnterAnimation">@anim/task_close_enter</item>
<item name="taskToBackExitAnimation">@anim/task_close_exit</item>
+ -->
<item name="wallpaperOpenEnterAnimation">@anim/wallpaper_open_enter</item>
<item name="wallpaperOpenExitAnimation">@anim/wallpaper_open_exit</item>
<item name="wallpaperCloseEnterAnimation">@anim/wallpaper_close_enter</item>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b29e571..fbdd247 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -354,7 +354,7 @@
<style name="Theme.NoDisplay">
<item name="android:windowBackground">@null</item>
<item name="android:windowContentOverlay">@null</item>
- <item name="android:windowIsTranslucent">false</item>
+ <item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowNoDisplay">true</item>
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 30c81ab..957f2dd 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -48,50 +48,49 @@
}
public void data(int[] d) {
- int size;
- if(mType != null && mType.mElement != null) {
- size = mType.mElement.mSize;
- for(int ct=0; ct < mType.mValues.length; ct++) {
- if(mType.mValues[ct] != 0) {
- size *= mType.mValues[ct];
- }
- }
- if((d.length * 4) < size) {
- throw new IllegalArgumentException("Array too small for allocation type.");
- }
- Log.e("rs", "Alloc data size=" + size);
- mRS.nAllocationData(mID, d, size);
- return;
- }
- mRS.nAllocationData(mID, d, d.length * 4);
+ subData1D(0, mType.getElementCount(), d);
+ }
+ public void data(short[] d) {
+ subData1D(0, mType.getElementCount(), d);
+ }
+ public void data(byte[] d) {
+ subData1D(0, mType.getElementCount(), d);
+ }
+ public void data(float[] d) {
+ subData1D(0, mType.getElementCount(), d);
}
- public void data(float[] d) {
- int size;
- if(mType != null && mType.mElement != null) {
- size = mType.mElement.mSize;
- for(int ct=0; ct < mType.mValues.length; ct++) {
- if(mType.mValues[ct] != 0) {
- size *= mType.mValues[ct];
- }
- }
- if((d.length * 4) < size) {
- throw new IllegalArgumentException("Array too small for allocation type.");
- }
- Log.e("rs", "Alloc data size=" + size);
- mRS.nAllocationData(mID, d, size);
- return;
+ private void data1DChecks(int off, int count, int len, int dataSize) {
+ if((off < 0) || (count < 1) || ((off + count) > mType.getElementCount())) {
+ throw new IllegalArgumentException("Offset or Count out of bounds.");
}
- mRS.nAllocationData(mID, d, d.length * 4);
+ if((len) < dataSize) {
+ throw new IllegalArgumentException("Array too small for allocation type.");
+ }
}
public void subData1D(int off, int count, int[] d) {
- mRS.nAllocationSubData1D(mID, off, count, d, count * 4);
+ int dataSize = mType.mElement.getSizeBytes() * count;
+ data1DChecks(off, count, d.length * 4, dataSize);
+ mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ }
+ public void subData1D(int off, int count, short[] d) {
+ int dataSize = mType.mElement.getSizeBytes() * count;
+ data1DChecks(off, count, d.length * 2, dataSize);
+ mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ }
+ public void subData1D(int off, int count, byte[] d) {
+ int dataSize = mType.mElement.getSizeBytes() * count;
+ data1DChecks(off, count, d.length, dataSize);
+ mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ }
+ public void subData1D(int off, int count, float[] d) {
+ int dataSize = mType.mElement.getSizeBytes() * count;
+ data1DChecks(off, count, d.length * 4, dataSize);
+ mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
}
- public void subData1D(int off, int count, float[] d) {
- mRS.nAllocationSubData1D(mID, off, count, d, d.length * 4);
- }
+
public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
@@ -213,11 +212,15 @@
static public Allocation createSized(RenderScript rs, Element e, int count)
throws IllegalArgumentException {
- int id = rs.nAllocationCreateSized(e.mID, count);
+ Type.Builder b = new Type.Builder(rs, e);
+ b.add(Dimension.X, count);
+ Type t = b.create();
+
+ int id = rs.nAllocationCreateTyped(t.mID);
if(id == 0) {
throw new IllegalStateException("Bad element.");
}
- return new Allocation(id, rs, null);
+ return new Allocation(id, rs, t);
}
static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 04c36fd..0a586c4 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -26,18 +26,40 @@
int mSize;
Entry[] mEntries;
+ int getSizeBytes() {
+ return mSize;
+ }
+ int getComponentCount() {
+ return mEntries.length;
+ }
+ Element.DataType getComponentDataType(int num) {
+ return mEntries[num].mType;
+ }
+ Element.DataKind getComponentDataKind(int num) {
+ return mEntries[num].mKind;
+ }
+ boolean getComponentIsNormalized(int num) {
+ return mEntries[num].mIsNormalized;
+ }
+ int getComponentBits(int num) {
+ return mEntries[num].mBits;
+ }
+ String getComponentName(int num) {
+ return mEntries[num].mName;
+ }
+
static class Entry {
- Element mElement;
+ //Element mElement;
Element.DataType mType;
Element.DataKind mKind;
boolean mIsNormalized;
int mBits;
String mName;
- Entry(Element e, int bits) {
- mElement = e;
- int mBits = bits;
- }
+ //Entry(Element e, int bits) {
+ //mElement = e;
+ //int mBits = bits;
+ //}
Entry(DataType dt, DataKind dk, boolean isNorm, int bits, String name) {
mType = dt;
@@ -266,14 +288,11 @@
int bits = 0;
for (int ct=0; ct < e.mEntries.length; ct++) {
Entry en = e.mEntries[ct];
- if(en.mElement != null) {
+ //if(en.mElement != null) {
//rs.nElementAdd(en.mElement.mID);
- } else {
- int norm = 0;
- if (en.mIsNormalized) {
- norm = 1;
- }
- rs.nElementAdd(en.mKind.mID, en.mType.mID, norm, en.mBits, en.mName);
+ //} else
+ {
+ rs.nElementAdd(en.mKind.mID, en.mType.mID, en.mIsNormalized, en.mBits, en.mName);
bits += en.mBits;
}
}
@@ -308,11 +327,11 @@
mEntryCount++;
}
- public Builder add(Element e) throws IllegalArgumentException {
- Entry en = new Entry(e, e.mSize * 8);
- addEntry(en);
- return this;
- }
+ //public Builder add(Element e) throws IllegalArgumentException {
+ //Entry en = new Entry(e, e.mSize * 8);
+ //addEntry(en);
+ //return this;
+ //}
public Builder add(Element.DataType dt, Element.DataKind dk, boolean isNormalized, int bits, String name) {
Entry en = new Entry(dt, dk, isNormalized, bits, name);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index d35c5e3..5831d13 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -80,7 +80,7 @@
native int nFileOpen(byte[] name);
native void nElementBegin();
- native void nElementAdd(int kind, int type, int norm, int bits, String s);
+ native void nElementAdd(int kind, int type, boolean norm, int bits, String s);
native int nElementCreate();
native void nTypeBegin(int elementID);
@@ -90,17 +90,19 @@
native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs);
native int nAllocationCreateTyped(int type);
- native int nAllocationCreateSized(int elem, int count);
+ //native int nAllocationCreateSized(int elem, int count);
native int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp);
native int nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp);
native int nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream);
native void nAllocationUploadToTexture(int alloc, int baseMioLevel);
native void nAllocationUploadToBufferObject(int alloc);
- native void nAllocationData(int id, int[] d, int sizeBytes);
- native void nAllocationData(int id, float[] d, int sizeBytes);
+
native void nAllocationSubData1D(int id, int off, int count, int[] d, int sizeBytes);
+ native void nAllocationSubData1D(int id, int off, int count, short[] d, int sizeBytes);
+ native void nAllocationSubData1D(int id, int off, int count, byte[] d, int sizeBytes);
native void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes);
+
native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d, int sizeBytes);
native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d, int sizeBytes);
native void nAllocationRead(int id, int[] d);
diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java
index 5d87654..dc74c61 100644
--- a/graphics/java/android/renderscript/SimpleMesh.java
+++ b/graphics/java/android/renderscript/SimpleMesh.java
@@ -162,7 +162,6 @@
}
public SimpleMesh create() {
- Log.e("rs", "SimpleMesh create");
SimpleMesh sm = internalCreate(mRS, this);
sm.mVertexTypes = new Type[mVertexTypeCount];
for(int ct=0; ct < mVertexTypeCount; ct++) {
@@ -177,7 +176,7 @@
public static class TriangleMeshBuilder {
float mVtxData[];
int mVtxCount;
- int mIndexData[];
+ short mIndexData[];
int mIndexCount;
RenderScript mRS;
Element mElement;
@@ -191,7 +190,7 @@
mVtxCount = 0;
mIndexCount = 0;
mVtxData = new float[128];
- mIndexData = new int[128];
+ mIndexData = new short[128];
mVtxSize = vtxSize;
mNorm = norm;
mTex = tex;
@@ -268,13 +267,13 @@
public void addTriangle(int idx1, int idx2, int idx3) {
if((mIndexCount + 3) >= mIndexData.length) {
- int t[] = new int[mIndexData.length * 2];
+ short t[] = new short[mIndexData.length * 2];
System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
mIndexData = t;
}
- mIndexData[mIndexCount++] = idx1;
- mIndexData[mIndexCount++] = idx2;
- mIndexData[mIndexCount++] = idx3;
+ mIndexData[mIndexCount++] = (short)idx1;
+ mIndexData[mIndexCount++] = (short)idx2;
+ mIndexData[mIndexCount++] = (short)idx3;
}
public SimpleMesh create() {
@@ -309,10 +308,6 @@
vertexAlloc.data(mVtxData);
vertexAlloc.uploadToBufferObject();
- // This is safe because length is a pow2
- for(int ct=0; ct < (mIndexCount+1); ct += 2) {
- mIndexData[ct >> 1] = mIndexData[ct] | (mIndexData[ct+1] << 16);
- }
indexAlloc.data(mIndexData);
indexAlloc.uploadToBufferObject();
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index b6b7adf..df60990 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -23,13 +23,74 @@
*
**/
public class Type extends BaseObj {
- Dimension[] mDimensions;
- int[] mValues;
+ int mDimX;
+ int mDimY;
+ int mDimZ;
+ boolean mDimLOD;
+ boolean mDimFaces;
+ int mElementCount;
Element mElement;
+
private int mNativeCache;
Class mJavaClass;
+ public int getX() {
+ return mDimX;
+ }
+ public int getY() {
+ return mDimY;
+ }
+ public int getZ() {
+ return mDimZ;
+ }
+ public boolean getLOD() {
+ return mDimLOD;
+ }
+ public boolean getFaces() {
+ return mDimFaces;
+ }
+ public int getElementCount() {
+ return mElementCount;
+ }
+
+ void calcElementCount() {
+ boolean hasLod = getLOD();
+ int x = getX();
+ int y = getY();
+ int z = getZ();
+ int faces = 1;
+ if(getFaces()) {
+ faces = 6;
+ }
+ if(x == 0) {
+ x = 1;
+ }
+ if(y == 0) {
+ y = 1;
+ }
+ if(z == 0) {
+ z = 1;
+ }
+
+ int count = x * y * z * faces;
+ if(hasLod && (x > 1) && (y > 1) && (z > 1)) {
+ if(x > 1) {
+ x >>= 1;
+ }
+ if(y > 1) {
+ y >>= 1;
+ }
+ if(z > 1) {
+ z >>= 1;
+ }
+
+ count += x * y * z * faces;
+ }
+ mElementCount = count;
+ }
+
+
Type(int id, RenderScript rs) {
super(rs);
mID = id;
@@ -131,12 +192,25 @@
public Type create() {
Type t = internalCreate(mRS, this);
t.mElement = mElement;
- t.mDimensions = new Dimension[mEntryCount];
- t.mValues = new int[mEntryCount];
+
for(int ct=0; ct < mEntryCount; ct++) {
- t.mDimensions[ct] = mEntries[ct].mDim;
- t.mValues[ct] = mEntries[ct].mValue;
+ if(mEntries[ct].mDim == Dimension.X) {
+ t.mDimX = mEntries[ct].mValue;
+ }
+ if(mEntries[ct].mDim == Dimension.Y) {
+ t.mDimY = mEntries[ct].mValue;
+ }
+ if(mEntries[ct].mDim == Dimension.Z) {
+ t.mDimZ = mEntries[ct].mValue;
+ }
+ if(mEntries[ct].mDim == Dimension.LOD) {
+ t.mDimLOD = mEntries[ct].mValue != 0;
+ }
+ if(mEntries[ct].mDim == Dimension.FACE) {
+ t.mDimFaces = mEntries[ct].mValue != 0;
+ }
}
+ t.calcElementCount();
return t;
}
}
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index c7b5448..56a4223 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -181,7 +181,7 @@
static void
-nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jint norm, jint bits, jstring name)
+nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jboolean norm, jint bits, jstring name)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
const char* n = NULL;
@@ -359,14 +359,6 @@
return (jint) rsAllocationCreateTyped(con, (RsElement)e);
}
-static jint
-nAllocationCreateSized(JNIEnv *_env, jobject _this, jint e, jint count)
-{
- RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
- LOG_API("nAllocationCreateSized, con(%p), e(%p), count(%i)", con, (RsElement)e, count);
- return (jint) rsAllocationCreateSized(con, (RsElement)e, count);
-}
-
static void
nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip)
{
@@ -476,44 +468,44 @@
static void
-nAllocationData_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data, int sizeBytes)
-{
- RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
- jint len = _env->GetArrayLength(data);
- LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
- jint *ptr = _env->GetIntArrayElements(data, NULL);
- rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes);
- _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
-nAllocationData_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data, int sizeBytes)
-{
- RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
- jint len = _env->GetArrayLength(data);
- LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
- jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
- rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes);
- _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
-}
-
-static void
nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data, int sizeBytes)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
jint len = _env->GetArrayLength(data);
- LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
+ LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
jint *ptr = _env->GetIntArrayElements(data, NULL);
rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
_env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
}
static void
+nAllocationSubData1D_s(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jshortArray data, int sizeBytes)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ jint len = _env->GetArrayLength(data);
+ LOG_API("nAllocation1DSubData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
+ jshort *ptr = _env->GetShortArrayElements(data, NULL);
+ rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
+ _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationSubData1D_b(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jbyteArray data, int sizeBytes)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ jint len = _env->GetArrayLength(data);
+ LOG_API("nAllocation1DSubData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
+ jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+ rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
+ _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data, int sizeBytes)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
jint len = _env->GetArrayLength(data);
- LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
+ LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
_env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
@@ -1323,7 +1315,7 @@
{"nFileOpen", "([B)I", (void*)nFileOpen },
{"nElementBegin", "()V", (void*)nElementBegin },
-{"nElementAdd", "(IIIILjava/lang/String;)V", (void*)nElementAdd },
+{"nElementAdd", "(IIZILjava/lang/String;)V", (void*)nElementAdd },
{"nElementCreate", "()I", (void*)nElementCreate },
{"nTypeBegin", "(I)V", (void*)nTypeBegin },
@@ -1333,15 +1325,14 @@
{"nTypeSetupFields", "(Landroid/renderscript/Type;[I[I[Ljava/lang/reflect/Field;)V", (void*)nTypeSetupFields },
{"nAllocationCreateTyped", "(I)I", (void*)nAllocationCreateTyped },
-{"nAllocationCreateSized", "(II)I", (void*)nAllocationCreateSized },
{"nAllocationCreateFromBitmap", "(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap },
{"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmapBoxed },
{"nAllocationCreateFromAssetStream","(IZI)I", (void*)nAllocationCreateFromAssetStream },
{"nAllocationUploadToTexture", "(II)V", (void*)nAllocationUploadToTexture },
{"nAllocationUploadToBufferObject","(I)V", (void*)nAllocationUploadToBufferObject },
-{"nAllocationData", "(I[II)V", (void*)nAllocationData_i },
-{"nAllocationData", "(I[FI)V", (void*)nAllocationData_f },
{"nAllocationSubData1D", "(III[II)V", (void*)nAllocationSubData1D_i },
+{"nAllocationSubData1D", "(III[SI)V", (void*)nAllocationSubData1D_s },
+{"nAllocationSubData1D", "(III[BI)V", (void*)nAllocationSubData1D_b },
{"nAllocationSubData1D", "(III[FI)V", (void*)nAllocationSubData1D_f },
{"nAllocationSubData2D", "(IIIII[II)V", (void*)nAllocationSubData2D_i },
{"nAllocationSubData2D", "(IIIII[FI)V", (void*)nAllocationSubData2D_f },
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index b47e399..a47534b 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -92,12 +92,12 @@
return contains(key.getBytes());
}
- public byte[][] scan(byte[] prefix) {
+ public byte[][] saw(byte[] prefix) {
return execute('s', prefix);
}
- public String[] scan(String prefix) {
- byte[][] values = scan(prefix.getBytes());
+ public String[] saw(String prefix) {
+ byte[][] values = saw(prefix.getBytes());
if (values == null) {
return null;
}
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index e534447..6500791 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1227,44 +1227,46 @@
enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
}
-
- // output audio to hardware
- if (mSuspended) {
- usleep(kMaxBufferRecoveryInUsecs);
+ if (LIKELY(enabledTracks)) {
+ // mix buffers...
+ mAudioMixer->process(curBuf);
+ sleepTime = 0;
+ standbyTime = systemTime() + kStandbyTimeInNsecs;
} else {
- if (LIKELY(enabledTracks)) {
- // mix buffers...
- mAudioMixer->process(curBuf);
+ sleepTime += kBufferRecoveryInUsecs;
+ if (sleepTime > kMaxBufferRecoveryInUsecs) {
+ sleepTime = kMaxBufferRecoveryInUsecs;
+ }
+ // There was nothing to mix this round, which means all
+ // active tracks were late. Sleep a little bit to give
+ // them another chance. If we're too late, write 0s to audio
+ // hardware to avoid underrun.
+ if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
+ memset (curBuf, 0, mixBufferSize);
sleepTime = 0;
- standbyTime = systemTime() + kStandbyTimeInNsecs;
- } else {
- sleepTime += kBufferRecoveryInUsecs;
- // There was nothing to mix this round, which means all
- // active tracks were late. Sleep a little bit to give
- // them another chance. If we're too late, write 0s to audio
- // hardware to avoid underrun.
- if (mBytesWritten == 0 || sleepTime < kMaxBufferRecoveryInUsecs) {
- usleep(kBufferRecoveryInUsecs);
- } else {
- memset (curBuf, 0, mixBufferSize);
- sleepTime = 0;
- }
}
- // sleepTime == 0 means PCM data were written to mMixBuffer[]
- if (sleepTime == 0) {
- mLastWriteTime = systemTime();
- mInWrite = true;
- int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
- if (bytesWritten > 0) mBytesWritten += bytesWritten;
- mNumWrites++;
- mInWrite = false;
- mStandby = false;
- nsecs_t delta = systemTime() - mLastWriteTime;
- if (delta > maxPeriod) {
- LOGW("write blocked for %llu msecs", ns2ms(delta));
- mNumDelayedWrites++;
- }
+ }
+
+ if (mSuspended) {
+ sleepTime = kMaxBufferRecoveryInUsecs;
+ }
+ // sleepTime == 0 means we must write to audio hardware
+ if (sleepTime == 0) {
+ mLastWriteTime = systemTime();
+ mInWrite = true;
+ LOGV("mOutput->write() thread %p frames %d", this, mFrameCount);
+ int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
+ if (bytesWritten > 0) mBytesWritten += bytesWritten;
+ mNumWrites++;
+ mInWrite = false;
+ mStandby = false;
+ nsecs_t delta = systemTime() - mLastWriteTime;
+ if (delta > maxPeriod) {
+ LOGW("write blocked for %llu msecs, thread %p", ns2ms(delta), this);
+ mNumDelayedWrites++;
}
+ } else {
+ usleep(sleepTime);
}
// finally let go of all our tracks, without the lock held
@@ -1718,50 +1720,55 @@
}
}
- // output audio to hardware
- if (mSuspended) {
- usleep(kMaxBufferRecoveryInUsecs);
+ if (activeTrack != 0) {
+ AudioBufferProvider::Buffer buffer;
+ size_t frameCount = mFrameCount;
+ curBuf = (int8_t *)mMixBuffer;
+ // output audio to hardware
+ while(frameCount) {
+ buffer.frameCount = frameCount;
+ activeTrack->getNextBuffer(&buffer);
+ if (UNLIKELY(buffer.raw == 0)) {
+ memset(curBuf, 0, frameCount * mFrameSize);
+ break;
+ }
+ memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
+ frameCount -= buffer.frameCount;
+ curBuf += buffer.frameCount * mFrameSize;
+ activeTrack->releaseBuffer(&buffer);
+ }
+ sleepTime = 0;
+ standbyTime = systemTime() + kStandbyTimeInNsecs;
} else {
- if (activeTrack != 0) {
- AudioBufferProvider::Buffer buffer;
- size_t frameCount = mFrameCount;
- curBuf = (int8_t *)mMixBuffer;
- // output audio to hardware
- while(frameCount) {
- buffer.frameCount = frameCount;
- activeTrack->getNextBuffer(&buffer);
- if (UNLIKELY(buffer.raw == 0)) {
- memset(curBuf, 0, frameCount * mFrameSize);
- break;
- }
- memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
- frameCount -= buffer.frameCount;
- curBuf += buffer.frameCount * mFrameSize;
- activeTrack->releaseBuffer(&buffer);
- }
+ sleepTime += kBufferRecoveryInUsecs;
+ if (sleepTime > kMaxBufferRecoveryInUsecs) {
+ sleepTime = kMaxBufferRecoveryInUsecs;
+ }
+ // There was nothing to mix this round, which means all
+ // active tracks were late. Sleep a little bit to give
+ // them another chance. If we're too late, write 0s to audio
+ // hardware to avoid underrun.
+ if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs &&
+ AudioSystem::isLinearPCM(mFormat)) {
+ memset (mMixBuffer, 0, mFrameCount * mFrameSize);
sleepTime = 0;
- standbyTime = systemTime() + kStandbyTimeInNsecs;
- } else {
- sleepTime += kBufferRecoveryInUsecs;
- if (mBytesWritten == 0 || !AudioSystem::isLinearPCM(mFormat) ||
- sleepTime < kMaxBufferRecoveryInUsecs) {
- usleep(kBufferRecoveryInUsecs);
- } else {
- memset (mMixBuffer, 0, mFrameCount * mFrameSize);
- sleepTime = 0;
- }
}
+ }
- // sleepTime == 0 means PCM data were written to mMixBuffer[]
- if (sleepTime == 0) {
- mLastWriteTime = systemTime();
- mInWrite = true;
- int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
- if (bytesWritten) mBytesWritten += bytesWritten;
- mNumWrites++;
- mInWrite = false;
- mStandby = false;
- }
+ if (mSuspended) {
+ sleepTime = kMaxBufferRecoveryInUsecs;
+ }
+ // sleepTime == 0 means we must write to audio hardware
+ if (sleepTime == 0) {
+ mLastWriteTime = systemTime();
+ mInWrite = true;
+ int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
+ if (bytesWritten) mBytesWritten += bytesWritten;
+ mNumWrites++;
+ mInWrite = false;
+ mStandby = false;
+ } else {
+ usleep(sleepTime);
}
// finally let go of removed track, without the lock held
@@ -1913,38 +1920,40 @@
}
enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
- }
+ }
- bool mustSleep = true;
if (LIKELY(enabledTracks)) {
// mix buffers...
mAudioMixer->process(curBuf);
- if (!mSuspended) {
- for (size_t i = 0; i < outputTracks.size(); i++) {
- outputTracks[i]->write(curBuf, mFrameCount);
- mustSleep = false;
- }
- mStandby = false;
- mBytesWritten += mixBufferSize;
- }
+ sleepTime = 0;
+ standbyTime = systemTime() + kStandbyTimeInNsecs;
} else {
- // flush remaining overflow buffers in output tracks
- for (size_t i = 0; i < outputTracks.size(); i++) {
- if (outputTracks[i]->isActive()) {
- outputTracks[i]->write(curBuf, 0);
- standbyTime = systemTime() + kStandbyTimeInNsecs;
- mustSleep = false;
- }
+ sleepTime += kBufferRecoveryInUsecs;
+ if (sleepTime > kMaxBufferRecoveryInUsecs) {
+ sleepTime = kMaxBufferRecoveryInUsecs;
+ }
+ // There was nothing to mix this round, which means all
+ // active tracks were late. Sleep a little bit to give
+ // them another chance. If we're too late, write 0s to audio
+ // hardware to avoid underrun.
+ if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
+ memset (curBuf, 0, mixBufferSize);
+ sleepTime = 0;
}
}
- if (mustSleep) {
-// LOGV("threadLoop() sleeping %d", sleepTime);
- usleep(sleepTime);
- if (sleepTime < kMaxBufferRecoveryInUsecs) {
- sleepTime += kBufferRecoveryInUsecs;
+
+ if (mSuspended) {
+ sleepTime = kMaxBufferRecoveryInUsecs;
+ }
+ // sleepTime == 0 means we must write to audio hardware
+ if (sleepTime == 0) {
+ for (size_t i = 0; i < outputTracks.size(); i++) {
+ outputTracks[i]->write(curBuf, mFrameCount);
}
+ mStandby = false;
+ mBytesWritten += mixBufferSize;
} else {
- sleepTime = kBufferRecoveryInUsecs;
+ usleep(sleepTime);
}
// finally let go of all our tracks, without the lock held
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index a34889a..493e777 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -250,7 +250,9 @@
GraphicPlane& graphicPlane(int dpy);
void waitForEvent();
+public: // hack to work around gcc 4.0.3 bug
void signalEvent();
+private:
void signalDelayedEvent(nsecs_t delay);
void handleConsoleEvents();
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 37a3bd5..3ac5df5 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -736,6 +736,28 @@
if (time != -1) {
values.put(Images.Media.DATE_TAKEN, time);
}
+
+ int orientation = exif.getAttributeInt(
+ ExifInterface.TAG_ORIENTATION, -1);
+ if (orientation != -1) {
+ // We only recognize a subset of orientation tag values.
+ int degree;
+ switch(orientation) {
+ case ExifInterface.ORIENTATION_ROTATE_90:
+ degree = 90;
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_180:
+ degree = 180;
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_270:
+ degree = 270;
+ break;
+ default:
+ degree = 0;
+ break;
+ }
+ values.put(Images.Media.ORIENTATION, degree);
+ }
}
}
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 022da0c..b3a19e3 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -271,18 +271,52 @@
* @param renderer the renderer to use to perform OpenGL drawing.
*/
public void setRenderer(Renderer renderer) {
- if (mGLThread != null) {
- throw new IllegalStateException(
- "setRenderer has already been called for this instance.");
- }
+ checkRenderThreadState();
if (mEGLConfigChooser == null) {
mEGLConfigChooser = new SimpleEGLConfigChooser(true);
}
+ if (mEGLContextFactory == null) {
+ mEGLContextFactory = new DefaultContextFactory();
+ }
+ if (mEGLWindowSurfaceFactory == null) {
+ mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
+ }
mGLThread = new GLThread(renderer);
mGLThread.start();
}
/**
+ * @hide
+ * Install a custom EGLContextFactory.
+ * <p>If this method is
+ * called, it must be called before {@link #setRenderer(Renderer)}
+ * is called.
+ * <p>
+ * If this method is not called, then by default
+ * a context will be created with no shared context and
+ * with a null attribute list.
+ */
+ public void setContextFactory(EGLContextFactory factory) {
+ checkRenderThreadState();
+ mEGLContextFactory = factory;
+ }
+
+ /**
+ * @hide
+ * Install a custom EGLWindowSurfaceFactory.
+ * <p>If this method is
+ * called, it must be called before {@link #setRenderer(Renderer)}
+ * is called.
+ * <p>
+ * If this method is not called, then by default
+ * a window surface will be created with a null attribute list.
+ */
+ public void setWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
+ checkRenderThreadState();
+ mEGLWindowSurfaceFactory = factory;
+ }
+
+ /**
* Install a custom EGLConfigChooser.
* <p>If this method is
* called, it must be called before {@link #setRenderer(Renderer)}
@@ -294,10 +328,7 @@
* @param configChooser
*/
public void setEGLConfigChooser(EGLConfigChooser configChooser) {
- if (mGLThread != null) {
- throw new IllegalStateException(
- "setRenderer has already been called for this instance.");
- }
+ checkRenderThreadState();
mEGLConfigChooser = configChooser;
}
@@ -578,6 +609,56 @@
}
/**
+ * @hide
+ * An interface for customizing the eglCreateContext and eglDestroyContext calls.
+ * <p>
+ * This interface must be implemented by clients wishing to call
+ * {@link GLSurfaceView#setEGLContextFactory(EGLContextFactory)}
+ */
+ public interface EGLContextFactory {
+ EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig);
+ void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context);
+ }
+
+ private static class DefaultContextFactory implements EGLContextFactory {
+
+ public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
+ return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);
+ }
+
+ public void destroyContext(EGL10 egl, EGLDisplay display,
+ EGLContext context) {
+ egl.eglDestroyContext(display, context);
+ }
+ }
+
+ /**
+ * @hide
+ * An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls.
+ * <p>
+ * This interface must be implemented by clients wishing to call
+ * {@link GLSurfaceView#setEGLContextCreator(EGLContextCreator)}
+ */
+ public interface EGLWindowSurfaceFactory {
+ EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig config,
+ Object nativeWindow);
+ void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface);
+ }
+
+ private static class DefaultWindowSurfaceFactory implements EGLWindowSurfaceFactory {
+
+ public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
+ EGLConfig config, Object nativeWindow) {
+ return egl.eglCreateWindowSurface(display, config, nativeWindow, null);
+ }
+
+ public void destroySurface(EGL10 egl, EGLDisplay display,
+ EGLSurface surface) {
+ egl.eglDestroySurface(display, surface);
+ }
+ }
+
+ /**
* An interface for choosing an EGLConfig configuration from a list of
* potential configurations.
* <p>
@@ -751,8 +832,7 @@
* Create an OpenGL ES context. This must be done only once, an
* OpenGL context is a somewhat heavy object.
*/
- mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig,
- EGL10.EGL_NO_CONTEXT, null);
+ mEglContext = mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig);
mEglSurface = null;
}
@@ -774,14 +854,14 @@
*/
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
- mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+ mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay, mEglSurface);
}
/*
* Create an EGL surface we can render into.
*/
- mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,
- mEglConfig, holder, null);
+ mEglSurface = mEGLWindowSurfaceFactory.createWindowSurface(mEgl,
+ mEglDisplay, mEglConfig, holder);
/*
* Before we can issue GL commands, we need to make sure
@@ -790,7 +870,6 @@
mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
mEglContext);
-
GL gl = mEglContext.getGL();
if (mGLWrapper != null) {
gl = mGLWrapper.wrap(gl);
@@ -826,16 +905,19 @@
return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
}
- public void finish() {
+ public void destroySurface() {
if (mEglSurface != null) {
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_CONTEXT);
- mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+ mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay, mEglSurface);
mEglSurface = null;
}
+ }
+
+ public void finish() {
if (mEglContext != null) {
- mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+ mEGLContextFactory.destroyContext(mEgl, mEglDisplay, mEglContext);
mEglContext = null;
}
if (mEglDisplay != null) {
@@ -895,78 +977,93 @@
private void guardedRun() throws InterruptedException {
mEglHelper = new EglHelper();
- mEglHelper.start();
+ try {
+ mEglHelper.start();
- GL10 gl = null;
- boolean tellRendererSurfaceCreated = true;
- boolean tellRendererSurfaceChanged = true;
-
- /*
- * This is our main activity thread's loop, we go until
- * asked to quit.
- */
- while (!mDone) {
+ GL10 gl = null;
+ boolean tellRendererSurfaceCreated = true;
+ boolean tellRendererSurfaceChanged = true;
/*
- * Update the asynchronous state (window size)
+ * This is our main activity thread's loop, we go until
+ * asked to quit.
*/
- int w, h;
- boolean changed;
- boolean needStart = false;
- synchronized (this) {
- Runnable r;
- while ((r = getEvent()) != null) {
- r.run();
- }
- if (mPaused) {
- mEglHelper.finish();
- needStart = true;
- }
- while (needToWait()) {
- wait();
- }
- if (mDone) {
- break;
- }
- changed = mSizeChanged;
- w = mWidth;
- h = mHeight;
- mSizeChanged = false;
- mRequestRender = false;
- }
- if (needStart) {
- mEglHelper.start();
- tellRendererSurfaceCreated = true;
- changed = true;
- }
- if (changed) {
- gl = (GL10) mEglHelper.createSurface(getHolder());
- tellRendererSurfaceChanged = true;
- }
- if (tellRendererSurfaceCreated) {
- mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
- tellRendererSurfaceCreated = false;
- }
- if (tellRendererSurfaceChanged) {
- mRenderer.onSurfaceChanged(gl, w, h);
- tellRendererSurfaceChanged = false;
- }
- if ((w > 0) && (h > 0)) {
- /* draw a frame here */
- mRenderer.onDrawFrame(gl);
+ while (!mDone) {
/*
- * Once we're done with GL, we need to call swapBuffers()
- * to instruct the system to display the rendered frame
+ * Update the asynchronous state (window size)
*/
- mEglHelper.swap();
- }
- }
+ int w, h;
+ boolean changed;
+ boolean needStart = false;
+ synchronized (this) {
+ Runnable r;
+ while ((r = getEvent()) != null) {
+ r.run();
+ }
+ if (mPaused) {
+ mEglHelper.destroySurface();
+ mEglHelper.finish();
+ needStart = true;
+ }
+ while (needToWait()) {
+ if (!mHasSurface) {
+ if (!mWaitingForSurface) {
+ mEglHelper.destroySurface();
+ mWaitingForSurface = true;
+ notify();
+ }
+ }
+ wait();
+ }
+ if (mDone) {
+ break;
+ }
+ changed = mSizeChanged;
+ w = mWidth;
+ h = mHeight;
+ mSizeChanged = false;
+ mRequestRender = false;
+ if (mHasSurface && mWaitingForSurface) {
+ changed = true;
+ mWaitingForSurface = false;
+ }
+ }
+ if (needStart) {
+ mEglHelper.start();
+ tellRendererSurfaceCreated = true;
+ changed = true;
+ }
+ if (changed) {
+ gl = (GL10) mEglHelper.createSurface(getHolder());
+ tellRendererSurfaceChanged = true;
+ }
+ if (tellRendererSurfaceCreated) {
+ mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
+ tellRendererSurfaceCreated = false;
+ }
+ if (tellRendererSurfaceChanged) {
+ mRenderer.onSurfaceChanged(gl, w, h);
+ tellRendererSurfaceChanged = false;
+ }
+ if ((w > 0) && (h > 0)) {
+ /* draw a frame here */
+ mRenderer.onDrawFrame(gl);
- /*
- * clean-up everything...
- */
- mEglHelper.finish();
+ /*
+ * Once we're done with GL, we need to call swapBuffers()
+ * to instruct the system to display the rendered frame
+ */
+ mEglHelper.swap();
+ }
+ }
+ } finally {
+ /*
+ * clean-up everything...
+ */
+ mEglHelper.destroySurface();
+ mEglHelper.finish();
+ }
}
private boolean needToWait() {
@@ -1021,6 +1118,13 @@
synchronized(this) {
mHasSurface = false;
notify();
+ while(!mWaitingForSurface && isAlive()) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
}
}
@@ -1083,6 +1187,7 @@
private boolean mDone;
private boolean mPaused;
private boolean mHasSurface;
+ private boolean mWaitingForSurface;
private int mWidth;
private int mHeight;
private int mRenderMode;
@@ -1124,11 +1229,21 @@
private StringBuilder mBuilder = new StringBuilder();
}
+
+ private void checkRenderThreadState() {
+ if (mGLThread != null) {
+ throw new IllegalStateException(
+ "setRenderer has already been called for this instance.");
+ }
+ }
+
private static final Semaphore sEglSemaphore = new Semaphore(1);
private boolean mSizeChanged = true;
private GLThread mGLThread;
private EGLConfigChooser mEGLConfigChooser;
+ private EGLContextFactory mEGLContextFactory;
+ private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
private GLWrapper mGLWrapper;
private int mDebugFlags;
}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index d5f1c61..db1b5f1 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -29,7 +29,7 @@
<integer name="def_screen_brightness">102</integer>
<bool name="def_screen_brightness_automatic_mode">false</bool>
<fraction name="def_window_animation_scale">100%</fraction>
- <fraction name="def_window_transition_scale">0%</fraction>
+ <fraction name="def_window_transition_scale">100%</fraction>
<bool name="def_bluetooth_on">false</bool>
<bool name="def_install_non_market_apps">false</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index f99eb58..c561078 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 40;
+ private static final int DATABASE_VERSION = 41;
private Context mContext;
@@ -481,6 +481,27 @@
upgradeVersion = 40;
}
+ if (upgradeVersion == 40) {
+ /*
+ * All animations are now turned on by default!
+ */
+ db.beginTransaction();
+ try {
+ db.execSQL("DELETE FROM system WHERE name='"
+ + Settings.System.WINDOW_ANIMATION_SCALE + "'");
+ db.execSQL("DELETE FROM system WHERE name='"
+ + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
+ SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadDefaultAnimationSettings(stmt);
+ stmt.close();
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ upgradeVersion = 41;
+ }
+
if (upgradeVersion != currentVersion) {
Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
+ ", must wipe the settings provider");
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
index 13b4952..9909905 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
@@ -17,7 +17,7 @@
package com.android.server.vpn;
import android.net.vpn.L2tpIpsecProfile;
-import android.security.CertTool;
+import android.security.Credentials;
import java.io.IOException;
@@ -30,16 +30,18 @@
@Override
protected void connect(String serverIp, String username, String password)
throws IOException {
+ L2tpIpsecProfile p = getProfile();
// IPSEC
DaemonProxy ipsec = startDaemon(IPSEC);
ipsec.sendCommand(serverIp, L2tpService.L2TP_PORT,
- getUserkeyPath(), getUserCertPath(), getCaCertPath());
+ Credentials.USER_PRIVATE_KEY + p.getUserCertificate(),
+ Credentials.USER_CERTIFICATE + p.getUserCertificate(),
+ Credentials.CA_CERTIFICATE + p.getCaCertificate());
ipsec.closeControlSocket();
sleep(2000); // 2 seconds
// L2TP
- L2tpIpsecProfile p = getProfile();
MtpdHelper.sendCommand(this, L2tpService.L2TP_DAEMON, serverIp,
L2tpService.L2TP_PORT,
(p.isSecretEnabled() ? p.getSecretString() : null),
@@ -51,19 +53,4 @@
stopDaemon(IPSEC);
stopDaemon(MtpdHelper.MTPD);
}
-
- private String getCaCertPath() {
- return CertTool.getInstance().getCaCertificate(
- getProfile().getCaCertificate());
- }
-
- private String getUserCertPath() {
- return CertTool.getInstance().getUserCertificate(
- getProfile().getUserCertificate());
- }
-
- private String getUserkeyPath() {
- return CertTool.getInstance().getUserPrivateKey(
- getProfile().getUserCertificate());
- }
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 854a6f9..1dc51c8 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -57,6 +57,7 @@
import android.backup.IRestoreSession;
import android.backup.RestoreSet;
+import com.android.internal.backup.BackupConstants;
import com.android.internal.backup.LocalTransport;
import com.android.internal.backup.IBackupTransport;
@@ -101,6 +102,7 @@
private static final int BACKUP_AGENT_FAILURE_EVENT = 2823;
private static final int BACKUP_PACKAGE_EVENT = 2824;
private static final int BACKUP_SUCCESS_EVENT = 2825;
+ private static final int BACKUP_RESET_EVENT = 2826;
private static final int RESTORE_START_EVENT = 2830;
private static final int RESTORE_TRANSPORT_FAILURE_EVENT = 2831;
@@ -406,6 +408,47 @@
}
}
+ // Reset all of our bookkeeping, in response to having been told that
+ // the backend data has been wiped [due to idle expiry, for example],
+ // so we must re-upload all saved settings.
+ void resetBackupState(File stateFileDir) {
+ synchronized (mQueueLock) {
+ // Wipe the "what we've ever backed up" tracking
+ try {
+ // close the ever-stored journal...
+ if (mEverStoredStream != null) {
+ mEverStoredStream.close();
+ }
+ // ... so we can delete it and start over
+ mEverStored.delete();
+ mEverStoredStream = new RandomAccessFile(mEverStored, "rwd");
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to open known-stored file!");
+ mEverStoredStream = null;
+ }
+ mEverStoredApps.clear();
+
+ // Remove all the state files
+ for (File sf : stateFileDir.listFiles()) {
+ sf.delete();
+ }
+
+ // Enqueue a new backup of every participant
+ int N = mBackupParticipants.size();
+ for (int i=0; i<N; i++) {
+ int uid = mBackupParticipants.keyAt(i);
+ HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i);
+ for (ApplicationInfo app: participants) {
+ try {
+ dataChanged(app.packageName);
+ } catch (RemoteException e) {
+ // can't happen; we're in the same process
+ }
+ }
+ }
+ }
+ }
+
// Add a transport to our set of available backends
private void registerTransport(String name, IBackupTransport transport) {
synchronized (mTransports) {
@@ -877,39 +920,57 @@
try {
EventLog.writeEvent(BACKUP_START_EVENT, mTransport.transportDirName());
+ int status = BackupConstants.TRANSPORT_OK;
+
+ // If we haven't stored anything yet, we need to do an init operation.
+ if (status == BackupConstants.TRANSPORT_OK && mEverStoredApps.size() == 0) {
+ status = mTransport.initializeDevice();
+ }
// The package manager doesn't have a proper <application> etc, but since
// it's running here in the system process we can just set up its agent
// directly and use a synthetic BackupRequest. We always run this pass
// because it's cheap and this way we guarantee that we don't get out of
// step even if we're selecting among various transports at run time.
- PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
- mPackageManager, allAgentPackages());
- BackupRequest pmRequest = new BackupRequest(new ApplicationInfo(), false);
- pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL;
-
- // If we haven't stored anything yet, we need to do an init
- // operation along with recording the metadata blob.
- boolean needInit = (mEverStoredApps.size() == 0);
- processOneBackup(pmRequest, IBackupAgent.Stub.asInterface(pmAgent.onBind()),
- mTransport, needInit);
-
- // Now run all the backups in our queue
- int count = mQueue.size();
- doQueuedBackups(mTransport);
-
- // Finally, tear down the transport
- if (mTransport.finishBackup()) {
- int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
- EventLog.writeEvent(BACKUP_SUCCESS_EVENT, count, millis);
- } else {
- EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, "");
- Log.e(TAG, "Transport error in finishBackup()");
+ if (status == BackupConstants.TRANSPORT_OK) {
+ PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
+ mPackageManager, allAgentPackages());
+ BackupRequest pmRequest = new BackupRequest(new ApplicationInfo(), false);
+ pmRequest.appInfo.packageName = PACKAGE_MANAGER_SENTINEL;
+ status = processOneBackup(pmRequest,
+ IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
}
- if (!mJournal.delete()) {
+ if (status == BackupConstants.TRANSPORT_OK) {
+ // Now run all the backups in our queue
+ status = doQueuedBackups(mTransport);
+ }
+
+ if (status == BackupConstants.TRANSPORT_OK) {
+ // Tell the transport to finish everything it has buffered
+ status = mTransport.finishBackup();
+ if (status == BackupConstants.TRANSPORT_OK) {
+ int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
+ EventLog.writeEvent(BACKUP_SUCCESS_EVENT, mQueue.size(), millis);
+ } else {
+ EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, "");
+ Log.e(TAG, "Transport error in finishBackup()");
+ }
+ }
+
+ // When we succeed at everything, we can remove the journal
+ if (status == BackupConstants.TRANSPORT_OK && !mJournal.delete()) {
Log.e(TAG, "Unable to remove backup journal file " + mJournal);
}
+
+ if (status == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
+ // The backend reports that our dataset has been wiped. We need to
+ // reset all of our bookkeeping and instead run a new backup pass for
+ // everything.
+ EventLog.writeEvent(BACKUP_RESET_EVENT, mTransport.transportDirName());
+ resetBackupState(mStateDir);
+ backupNow();
+ }
} catch (Exception e) {
Log.e(TAG, "Error in backup thread", e);
} finally {
@@ -918,7 +979,7 @@
}
}
- private void doQueuedBackups(IBackupTransport transport) {
+ private int doQueuedBackups(IBackupTransport transport) {
for (BackupRequest request : mQueue) {
Log.d(TAG, "starting agent for backup of " + request);
@@ -938,25 +999,26 @@
try {
agent = bindToAgentSynchronous(request.appInfo, mode);
if (agent != null) {
- processOneBackup(request, agent, transport, false);
+ int result = processOneBackup(request, agent, transport);
+ if (result != BackupConstants.TRANSPORT_OK) return result;
}
-
- // unbind even on timeout, just in case
- mActivityManager.unbindBackupAgent(request.appInfo);
} catch (SecurityException ex) {
// Try for the next one.
Log.d(TAG, "error in bind/backup", ex);
- } catch (RemoteException e) {
- Log.v(TAG, "bind/backup threw");
- e.printStackTrace();
+ } finally {
+ try { // unbind even on timeout, just in case
+ mActivityManager.unbindBackupAgent(request.appInfo);
+ } catch (RemoteException e) {}
}
}
+
+ return BackupConstants.TRANSPORT_OK;
}
- void processOneBackup(BackupRequest request, IBackupAgent agent,
- IBackupTransport transport, boolean doInit) {
+ private int processOneBackup(BackupRequest request, IBackupAgent agent,
+ IBackupTransport transport) {
final String packageName = request.appInfo.packageName;
- if (DEBUG) Log.d(TAG, "processOneBackup doBackup(" + doInit + ") on " + packageName);
+ if (DEBUG) Log.d(TAG, "processOneBackup doBackup() on " + packageName);
File savedStateName = new File(mStateDir, packageName);
File backupDataName = new File(mDataDir, packageName + ".data");
@@ -1007,7 +1069,7 @@
EventLog.writeEvent(BACKUP_AGENT_FAILURE_EVENT, packageName, e.toString());
backupDataName.delete();
newStateName.delete();
- return;
+ return BackupConstants.TRANSPORT_ERROR;
} finally {
try { if (savedState != null) savedState.close(); } catch (IOException e) {}
try { if (backupData != null) backupData.close(); } catch (IOException e) {}
@@ -1016,20 +1078,23 @@
}
// Now propagate the newly-backed-up data to the transport
+ int result = BackupConstants.TRANSPORT_OK;
try {
int size = (int) backupDataName.length();
if (size > 0) {
- backupData = ParcelFileDescriptor.open(backupDataName,
- ParcelFileDescriptor.MODE_READ_ONLY);
+ if (result == BackupConstants.TRANSPORT_OK) {
+ backupData = ParcelFileDescriptor.open(backupDataName,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ result = transport.performBackup(packInfo, backupData);
+ }
// TODO - We call finishBackup() for each application backed up, because
// we need to know now whether it succeeded or failed. Instead, we should
// hold off on finishBackup() until the end, which implies holding off on
// renaming *all* the output state files (see below) until that happens.
- if (!transport.performBackup(packInfo, backupData, doInit) ||
- !transport.finishBackup()) {
- throw new Exception("Backup transport failed");
+ if (result == BackupConstants.TRANSPORT_OK) {
+ result = transport.finishBackup();
}
} else {
if (DEBUG) Log.i(TAG, "no backup data written; not calling transport");
@@ -1038,16 +1103,22 @@
// After successful transport, delete the now-stale data
// and juggle the files so that next time we supply the agent
// with the new state file it just created.
- backupDataName.delete();
- newStateName.renameTo(savedStateName);
- EventLog.writeEvent(BACKUP_PACKAGE_EVENT, packageName, size);
+ if (result == BackupConstants.TRANSPORT_OK) {
+ backupDataName.delete();
+ newStateName.renameTo(savedStateName);
+ EventLog.writeEvent(BACKUP_PACKAGE_EVENT, packageName, size);
+ } else {
+ EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, packageName);
+ }
} catch (Exception e) {
Log.e(TAG, "Transport error backing up " + packageName, e);
EventLog.writeEvent(BACKUP_TRANSPORT_FAILURE_EVENT, packageName);
- return;
+ result = BackupConstants.TRANSPORT_ERROR;
} finally {
try { if (backupData != null) backupData.close(); } catch (IOException e) {}
}
+
+ return result;
}
}
@@ -1172,7 +1243,8 @@
}
}
- if (!mTransport.startRestore(mToken, restorePackages.toArray(new PackageInfo[0]))) {
+ if (mTransport.startRestore(mToken, restorePackages.toArray(new PackageInfo[0])) !=
+ BackupConstants.TRANSPORT_OK) {
Log.e(TAG, "Error starting restore operation");
EventLog.writeEvent(RESTORE_TRANSPORT_FAILURE_EVENT);
return;
@@ -1372,7 +1444,7 @@
ParcelFileDescriptor.MODE_CREATE |
ParcelFileDescriptor.MODE_TRUNCATE);
- if (!mTransport.getRestoreData(backupData)) {
+ if (mTransport.getRestoreData(backupData) != BackupConstants.TRANSPORT_OK) {
Log.e(TAG, "Error getting restore data for " + packageName);
EventLog.writeEvent(RESTORE_TRANSPORT_FAILURE_EVENT);
return;
@@ -1590,7 +1662,6 @@
if (DEBUG) Log.v(TAG, "Scheduling immediate backup pass");
synchronized (mQueueLock) {
try {
- if (DEBUG) Log.v(TAG, "sending immediate backup broadcast");
mRunBackupIntent.send();
} catch (PendingIntent.CanceledException e) {
// should never happen
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 656d6ba..b2e3a8c 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1862,9 +1862,10 @@
Log.d(TAG, "setKeyboardVisibility: " + visible);
}
mKeyboardVisible = visible;
- // don't signal user activity when closing keyboard if the screen is off.
- // otherwise, we want to make sure the backlights are adjusted.
- if (visible || (mPowerState & SCREEN_ON_BIT) != 0) {
+ // don't signal user activity if the screen is off; other code
+ // will take care of turning on due to a true change to the lid
+ // switch and synchronized with the lock screen.
+ if ((mPowerState & SCREEN_ON_BIT) != 0) {
userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
}
}
@@ -2130,7 +2131,9 @@
long milliseconds = event.timestamp / 1000000;
synchronized (mLocks) {
float distance = event.values[0];
- if (distance >= 0.0 && distance < PROXIMITY_THRESHOLD) {
+ // compare against getMaximumRange to support sensors that only return 0 or 1
+ if (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
+ distance < mProximitySensor.getMaximumRange()) {
if (mSpew) {
Log.d(TAG, "onSensorChanged: proximity active, distance: " + distance);
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index bbf2a24..3c76cf2 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -372,7 +372,7 @@
// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
// mOpeningApps and mClosingApps are the lists of tokens that will be
// made visible or hidden at the next transition.
- int mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
+ int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
boolean mAppTransitionReady = false;
boolean mAppTransitionRunning = false;
boolean mAppTransitionTimeout = false;
@@ -932,7 +932,7 @@
+ " layer=" + highestTarget.mAnimLayer
+ " new layer=" + w.mAnimLayer);
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
// If we are currently setting up for an animation,
// hold everything until we can find out what will happen.
mInputMethodTargetWaitingAnim = true;
@@ -1270,7 +1270,7 @@
}
}
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
// If we are currently waiting for an app transition, and either
// the current target or the next target are involved with it,
// then hold off on doing anything with the wallpaper.
@@ -2542,7 +2542,7 @@
: com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
break;
}
- a = loadAnimation(lp, animAttr);
+ a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
if (DEBUG_ANIM) Log.v(TAG, "applyAnimation: wtoken=" + wtoken
+ " anim=" + a
+ " animAttr=0x" + Integer.toHexString(animAttr)
@@ -2990,7 +2990,8 @@
TAG, "Prepare app transition: transit=" + transit
+ " mNextAppTransition=" + mNextAppTransition);
if (!mDisplayFrozen) {
- if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
+ || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
mNextAppTransition = transit;
} else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
&& mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
@@ -3025,7 +3026,7 @@
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Execute app transition: mNextAppTransition=" + mNextAppTransition);
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mAppTransitionReady = true;
final long origId = Binder.clearCallingIdentity();
performLayoutAndPlaceSurfacesLocked();
@@ -3228,7 +3229,7 @@
boolean runningAppAnimation = false;
- if (transit != WindowManagerPolicy.TRANSIT_NONE) {
+ if (transit != WindowManagerPolicy.TRANSIT_UNSET) {
if (wtoken.animation == sDummyAnimation) {
wtoken.animation = null;
}
@@ -3328,7 +3329,7 @@
// If we are preparing an app transition, then delay changing
// the visibility of this token until we execute that transition.
- if (!mDisplayFrozen && mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ if (!mDisplayFrozen && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
// Already in requested state, don't do anything more.
if (wtoken.hiddenRequested != visible) {
return;
@@ -3367,7 +3368,7 @@
}
final long origId = Binder.clearCallingIdentity();
- setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_NONE, true);
+ setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_UNSET, true);
wtoken.updateReportedVisibilityLocked();
Binder.restoreCallingIdentity(origId);
}
@@ -3493,13 +3494,13 @@
mTokenList.remove(basewtoken);
if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "Removing app token: " + wtoken);
- delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_NONE, true);
+ delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_UNSET, true);
wtoken.inPendingTransaction = false;
mOpeningApps.remove(wtoken);
wtoken.waitingToShow = false;
if (mClosingApps.contains(wtoken)) {
delayed = true;
- } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mClosingApps.add(wtoken);
wtoken.waitingToHide = true;
delayed = true;
@@ -3781,7 +3782,7 @@
AppWindowToken wt = findAppWindowToken(tokens.get(i));
if (wt != null) {
mAppTokens.add(wt);
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mToTopApps.remove(wt);
mToBottomApps.remove(wt);
mToTopApps.add(wt);
@@ -3791,7 +3792,7 @@
}
}
- if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
moveAppWindowsLocked(tokens, mAppTokens.size());
}
}
@@ -3813,7 +3814,7 @@
AppWindowToken wt = findAppWindowToken(tokens.get(i));
if (wt != null) {
mAppTokens.add(pos, wt);
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mToTopApps.remove(wt);
mToBottomApps.remove(wt);
mToBottomApps.add(i, wt);
@@ -3824,7 +3825,7 @@
}
}
- if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET) {
moveAppWindowsLocked(tokens, 0);
}
}
@@ -7459,7 +7460,7 @@
*/
boolean isReadyForDisplay() {
if (mRootToken.waitingToShow &&
- mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
return false;
}
final AppWindowToken atoken = mAppToken;
@@ -8530,7 +8531,7 @@
case APP_TRANSITION_TIMEOUT: {
synchronized (mWindowMap) {
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
"*** APP TRANSITION TIMEOUT");
mAppTransitionReady = true;
@@ -9074,9 +9075,9 @@
if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "**** GOOD TO GO");
int transit = mNextAppTransition;
if (mSkipAppTransitionAnimation) {
- transit = WindowManagerPolicy.TRANSIT_NONE;
+ transit = WindowManagerPolicy.TRANSIT_UNSET;
}
- mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
+ mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
mAppTransitionReady = false;
mAppTransitionRunning = true;
mAppTransitionTimeout = false;
@@ -10092,8 +10093,8 @@
}
mDisplayFrozen = true;
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
- mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
+ mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
mAppTransitionReady = true;
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d4f7207e..82664eb 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -458,6 +458,13 @@
= new ArrayList<HistoryRecord>();
/**
+ * Animations that for the current transition have requested not to
+ * be considered for the transition animation.
+ */
+ final ArrayList<HistoryRecord> mNoAnimActivities
+ = new ArrayList<HistoryRecord>();
+
+ /**
* List of intents that were used to start the most recent tasks.
*/
final ArrayList<TaskRecord> mRecentTasks
@@ -2249,6 +2256,7 @@
next.resumeKeyDispatchingLocked();
ensureActivitiesVisibleLocked(null, 0);
mWindowManager.executeAppTransition();
+ mNoAnimActivities.clear();
// Mark the point when the activity is resuming
// TODO: To be more accurate, the mark should be before the onCreate,
@@ -2565,6 +2573,7 @@
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
+ mNoAnimActivities.clear();
return false;
}
@@ -2575,6 +2584,7 @@
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
+ mNoAnimActivities.clear();
return false;
}
@@ -2637,17 +2647,25 @@
if (prev.finishing) {
if (DEBUG_TRANSITION) Log.v(TAG,
"Prepare close transition: prev=" + prev);
- mWindowManager.prepareAppTransition(prev.task == next.task
- ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
- : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
+ if (mNoAnimActivities.contains(prev)) {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+ } else {
+ mWindowManager.prepareAppTransition(prev.task == next.task
+ ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
+ : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
+ }
mWindowManager.setAppWillBeHidden(prev);
mWindowManager.setAppVisibility(prev, false);
} else {
if (DEBUG_TRANSITION) Log.v(TAG,
"Prepare open transition: prev=" + prev);
- mWindowManager.prepareAppTransition(prev.task == next.task
- ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
- : WindowManagerPolicy.TRANSIT_TASK_OPEN);
+ if (mNoAnimActivities.contains(next)) {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+ } else {
+ mWindowManager.prepareAppTransition(prev.task == next.task
+ ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
+ : WindowManagerPolicy.TRANSIT_TASK_OPEN);
+ }
}
if (false) {
mWindowManager.setAppWillBeHidden(prev);
@@ -2656,7 +2674,11 @@
} else if (mHistory.size() > 1) {
if (DEBUG_TRANSITION) Log.v(TAG,
"Prepare open transition: no previous");
- mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+ if (mNoAnimActivities.contains(next)) {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+ } else {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+ }
}
if (next.app != null && next.app.thread != null) {
@@ -2699,6 +2721,7 @@
mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
}
mWindowManager.executeAppTransition();
+ mNoAnimActivities.clear();
return true;
}
@@ -2859,9 +2882,18 @@
}
if (DEBUG_TRANSITION) Log.v(TAG,
"Prepare open transition: starting " + r);
- mWindowManager.prepareAppTransition(newTask
- ? WindowManagerPolicy.TRANSIT_TASK_OPEN
- : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+ if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+ mNoAnimActivities.add(r);
+ } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
+ mNoAnimActivities.remove(r);
+ } else {
+ mWindowManager.prepareAppTransition(newTask
+ ? WindowManagerPolicy.TRANSIT_TASK_OPEN
+ : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
+ mNoAnimActivities.remove(r);
+ }
mWindowManager.addAppToken(
addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
boolean doShow = true;
@@ -3336,7 +3368,7 @@
if (callerAtFront) {
// We really do want to push this one into the
// user's face, right now.
- moveTaskToFrontLocked(taskTop.task);
+ moveTaskToFrontLocked(taskTop.task, r);
}
}
// If the caller has requested that the target task be
@@ -6922,14 +6954,14 @@
for (int i=0; i<N; i++) {
TaskRecord tr = mRecentTasks.get(i);
if (tr.taskId == task) {
- moveTaskToFrontLocked(tr);
+ moveTaskToFrontLocked(tr, null);
return;
}
}
for (int i=mHistory.size()-1; i>=0; i--) {
HistoryRecord hr = (HistoryRecord)mHistory.get(i);
if (hr.task.taskId == task) {
- moveTaskToFrontLocked(hr.task);
+ moveTaskToFrontLocked(hr.task, null);
return;
}
}
@@ -6939,7 +6971,7 @@
}
}
- private final void moveTaskToFrontLocked(TaskRecord tr) {
+ private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
final int task = tr.taskId;
@@ -6950,10 +6982,6 @@
return;
}
- if (DEBUG_TRANSITION) Log.v(TAG,
- "Prepare to front transition: task=" + tr);
- mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
-
ArrayList moved = new ArrayList();
// Applying the affinities may have removed entries from the history,
@@ -6982,6 +7010,19 @@
pos--;
}
+ if (DEBUG_TRANSITION) Log.v(TAG,
+ "Prepare to front transition: task=" + tr);
+ if (reason != null &&
+ (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+ HistoryRecord r = topRunningActivityLocked(null);
+ if (r != null) {
+ mNoAnimActivities.add(r);
+ }
+ } else {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
+ }
+
mWindowManager.moveAppTokensToTop(moved);
if (VALIDATE_TOKENS) {
mWindowManager.validateAppTokens(mHistory);
@@ -7007,7 +7048,7 @@
}
}
final long origId = Binder.clearCallingIdentity();
- moveTaskToBackLocked(task);
+ moveTaskToBackLocked(task, null);
Binder.restoreCallingIdentity(origId);
}
}
@@ -7026,7 +7067,7 @@
final long origId = Binder.clearCallingIdentity();
int taskId = getTaskForActivityLocked(token, !nonRoot);
if (taskId >= 0) {
- return moveTaskToBackLocked(taskId);
+ return moveTaskToBackLocked(taskId, null);
}
Binder.restoreCallingIdentity(origId);
}
@@ -7044,7 +7085,7 @@
* @param task The taskId to collect and move to the bottom.
* @return Returns true if the move completed, false if not.
*/
- private final boolean moveTaskToBackLocked(int task) {
+ private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
Log.i(TAG, "moveTaskToBack: " + task);
// If we have a watcher, preflight the move before committing to it. First check
@@ -7095,6 +7136,16 @@
pos++;
}
+ if (reason != null &&
+ (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
+ HistoryRecord r = topRunningActivityLocked(null);
+ if (r != null) {
+ mNoAnimActivities.add(r);
+ }
+ } else {
+ mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
+ }
mWindowManager.moveAppTokensToBottom(moved);
if (VALIDATE_TOKENS) {
mWindowManager.validateAppTokens(mHistory);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 9ac78eb..a410f0e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -538,12 +538,15 @@
if (!mPendingRadioPowerOffAfterDataOff) {
DataConnectionTracker.State currentState = dcTracker.getState();
if (currentState != DataConnectionTracker.State.CONNECTED
- && currentState != DataConnectionTracker.State.DISCONNECTING) {
+ && currentState != DataConnectionTracker.State.DISCONNECTING
+ && currentState != DataConnectionTracker.State.INITING) {
if (DBG) log("Data disconnected, turn off radio right away.");
cm.setRadioPower(false, null);
}
- else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 5000)) {
- if (DBG) log("Wait 5 sec for data to be disconnected, then turn off radio.");
+ else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
+ if (DBG) {
+ log("Wait up to 30 sec for data to disconnect, then turn off radio.");
+ }
mPendingRadioPowerOffAfterDataOff = true;
} else {
Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
index 74ac865f..861e37b 100644
--- a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
+++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
@@ -12,7 +12,8 @@
private static final String LOGTAG = "PowerMeasurement";
private static final String PKG_NAME = "com.android.browserpowertest";
- private static final String TESTING_URL = "http://www.espn.com";
+ private static final String TESTING_URL =
+ "http://75.17.48.204:10088/nyt/index.html";
private static final int TIME_OUT = 2 * 60 * 1000;
private static final int DELAY = 0;
@@ -46,6 +47,24 @@
pageErrorFlag);
Log.v(LOGTAG, "Page is loaded in " + activity.getPageLoadTime() + " ms.");
+ // Force to clean up the cache dir so that it get back to the clean
+ // state
+ Runtime fileRemoval = Runtime.getRuntime();
+ String cmdBecomeSu = "su";
+ boolean clearCacheSuccess = false;
+ try{
+ Process runsum = fileRemoval.exec(cmdBecomeSu);
+ int exitVal = runsum.waitFor();
+ String rmfile = "rm -r /data/data/com.android.browserpowertest/cache";
+ Process removal = fileRemoval.exec(rmfile);
+ exitVal = removal.waitFor();
+ if (exitVal == 0) {
+ clearCacheSuccess = true;
+ }
+ } catch ( Exception e){
+ assertTrue("Fails to clear the cahche", false);
+ }
+ assertTrue("Fails to clear the cahche", clearCacheSuccess);
activity.finish();
}
}
diff --git a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
index 7426d33..20ea4d7 100644
--- a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -257,19 +257,19 @@
@SmallTest
public void testToCallerIDIndexable() throws Exception {
- assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
- assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
- assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
- assertEquals("14145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
+ assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
+ assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
+ assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
+ assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
//this seems wrong, or at least useless
- assertEquals("NN145", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
+ assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
//<shrug> -- these are all not useful, but not terribly wrong
assertEquals("", PhoneNumberUtils.toCallerIDMinMatch(""));
assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300"));
assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300"));
- assertEquals("#130#", PhoneNumberUtils.toCallerIDMinMatch("*#031#"));
+ assertEquals("#130#*", PhoneNumberUtils.toCallerIDMinMatch("*#031#"));
}
@SmallTest
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 954930e..01bc919 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -71,7 +71,7 @@
/** {@hide} */
public EnterpriseField phase2 = new EnterpriseField("phase2");
/** {@hide} */
- public EnterpriseField identity = new EnterpriseField("anonymous_identity");
+ public EnterpriseField identity = new EnterpriseField("identity");
/** {@hide} */
public EnterpriseField anonymous_identity = new EnterpriseField("anonymous_identity");
/** {@hide} */
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index e3d8bf4..5638480 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -907,6 +907,7 @@
}
}
} else if (newState == SupplicantState.DISCONNECTED) {
+ mHaveIpAddress = false;
if (isDriverStopped() || mDisconnectExpected) {
handleDisconnectedState(DetailedState.DISCONNECTED);
} else {
@@ -1007,20 +1008,17 @@
setNotificationVisible(false, 0, false, 0);
boolean wasDisconnectPending = mDisconnectPending;
cancelDisconnect();
- if (!TextUtils.equals(mWifiInfo.getSSID(), mLastSsid)) {
- /*
- * The connection is fully configured as far as link-level
- * connectivity is concerned, but we may still need to obtain
- * an IP address. But do this only if we are connecting to
- * a different network than we were connected to previously.
- */
- if (wasDisconnectPending) {
- DetailedState saveState = getNetworkInfo().getDetailedState();
- handleDisconnectedState(DetailedState.DISCONNECTED);
- setDetailedStateInternal(saveState);
- }
- configureInterface();
+ /*
+ * The connection is fully configured as far as link-level
+ * connectivity is concerned, but we may still need to obtain
+ * an IP address.
+ */
+ if (wasDisconnectPending) {
+ DetailedState saveState = getNetworkInfo().getDetailedState();
+ handleDisconnectedState(DetailedState.DISCONNECTED);
+ setDetailedStateInternal(saveState);
}
+ configureInterface();
mLastBssid = result.BSSID;
mLastSsid = mWifiInfo.getSSID();
mLastNetworkId = result.networkId;