Merge change 1674 into donut
* changes:
gps: Time out after 1 minute if we are unable to get a fix and our fix interval is long.
diff --git a/api/current.xml b/api/current.xml
index 623b986..56e2309 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -21839,219 +21839,6 @@
</field>
</class>
</package>
-<package name="android.backup"
->
-<class name="BackupDataOutput"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BackupDataOutput"
- type="android.backup.BackupDataOutput"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="fd" type="java.io.FileDescriptor">
-</parameter>
-</constructor>
-<method name="close"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="flush"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="write"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="buffer" type="byte[]">
-</parameter>
-</method>
-<method name="write"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="oneByte" type="int">
-</parameter>
-</method>
-<method name="write"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="buffer" type="byte[]">
-</parameter>
-<parameter name="offset" type="int">
-</parameter>
-<parameter name="count" type="int">
-</parameter>
-</method>
-<method name="writeKey"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="key" type="java.lang.String">
-</parameter>
-</method>
-<method name="writeOperation"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="op" type="int">
-</parameter>
-</method>
-<field name="OP_DELETE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="OP_UPDATE"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="FileBackupHelper"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="FileBackupHelper"
- type="android.backup.FileBackupHelper"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="performBackup"
- return="void"
- 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="oldSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="newSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="data" type="android.backup.BackupDataOutput">
-</parameter>
-<parameter name="files" type="java.lang.String[]">
-</parameter>
-</method>
-</class>
-<class name="SharedPreferencesBackupHelper"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="SharedPreferencesBackupHelper"
- type="android.backup.SharedPreferencesBackupHelper"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="performBackup"
- return="void"
- 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="oldSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="newSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="data" type="android.backup.BackupDataOutput">
-</parameter>
-<parameter name="prefGroups" type="java.lang.String[]">
-</parameter>
-</method>
-</class>
-</package>
<package name="android.content"
>
<class name="ActivityNotFoundException"
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index 7871fb6..26712a1 100755
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -22,7 +22,7 @@
import android.os.Bundle;
/**
- * A conveience class to aid in implementing an AppWidget provider.
+ * A convenience class to aid in implementing an AppWidget provider.
* Everything you can do with AppWidgetProvider, you can do with a regular {@link BroadcastReceiver}.
* AppWidgetProvider merely parses the relevant fields out of the Intent that is received in
* {@link #onReceive(Context,Intent) onReceive(Context,Intent)}, and calls hook methods
diff --git a/core/java/android/backup/BackupDataOutput.java b/core/java/android/backup/BackupDataOutput.java
index 6c47f7e..555494e 100644
--- a/core/java/android/backup/BackupDataOutput.java
+++ b/core/java/android/backup/BackupDataOutput.java
@@ -20,6 +20,7 @@
import java.io.FileDescriptor;
+/** @hide */
public class BackupDataOutput {
/* package */ FileDescriptor fd;
diff --git a/core/java/android/backup/BackupService.java b/core/java/android/backup/BackupService.java
index 6ac703a..50a5921 100644
--- a/core/java/android/backup/BackupService.java
+++ b/core/java/android/backup/BackupService.java
@@ -75,9 +75,8 @@
* file. The application should record the final backup state
* here after writing the requested data to dataFd.
*/
- public abstract void onBackup(ParcelFileDescriptor oldState,
- ParcelFileDescriptor data,
- ParcelFileDescriptor newState);
+ public abstract void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState);
/**
* The application is being restored from backup, and should replace any
@@ -92,7 +91,7 @@
* file. The application should record the final backup state
* here after restoring its data from dataFd.
*/
- public abstract void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState);
+ public abstract void onRestore(ParcelFileDescriptor /* TODO: BackupDataInput */ data, ParcelFileDescriptor newState);
// ----- Core implementation -----
@@ -117,7 +116,15 @@
ParcelFileDescriptor newState) throws RemoteException {
// !!! TODO - real implementation; for now just invoke the callbacks directly
Log.v("BackupServiceBinder", "doBackup() invoked");
- BackupService.this.onBackup(oldState, data, newState);
+ BackupDataOutput output = new BackupDataOutput(BackupService.this,
+ data.getFileDescriptor());
+ try {
+ BackupService.this.onBackup(oldState, output, newState);
+ } catch (RuntimeException ex) {
+ Log.d("BackupService", "onBackup ("
+ + BackupService.this.getClass().getName() + ") threw", ex);
+ throw ex;
+ }
}
public void doRestore(ParcelFileDescriptor data,
diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java
index 3b2122c..2762f22 100644
--- a/core/java/android/backup/FileBackupHelper.java
+++ b/core/java/android/backup/FileBackupHelper.java
@@ -18,20 +18,24 @@
import android.content.Context;
import android.os.ParcelFileDescriptor;
+import android.util.Log;
import java.io.FileDescriptor;
+/** @hide */
public class FileBackupHelper {
+ private static final String TAG = "FileBackupHelper";
+
/**
- * Based on oldSnapshot, determine which of the files from the application's data directory
- * need to be backed up, write them to the data stream, and fill in newSnapshot with the
+ * Based on oldState, determine which of the files from the application's data directory
+ * need to be backed up, write them to the data stream, and fill in newState with the
* state as it exists now.
*/
public static void performBackup(Context context,
- ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
- BackupDataOutput data, String[] files) {
+ ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState, String[] files) {
String basePath = context.getFilesDir().getAbsolutePath();
- performBackup_checked(basePath, oldSnapshot, newSnapshot, data, files);
+ performBackup_checked(basePath, oldState, data, newState, files);
}
/**
@@ -39,30 +43,34 @@
* since it's easier to do that from java.
*/
static void performBackup_checked(String basePath,
- ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
- BackupDataOutput data, String[] files) {
- if (newSnapshot == null) {
- throw new NullPointerException("newSnapshot==null");
+ ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState, String[] files) {
+ if (files.length == 0) {
+ return;
}
- if (data == null) {
- throw new NullPointerException("data==null");
+ if (basePath == null) {
+ throw new NullPointerException();
}
+ // oldStateFd can be null
+ FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null;
if (data.fd == null) {
- throw new NullPointerException("data.fd==null");
+ throw new NullPointerException();
+ }
+ FileDescriptor newStateFd = newState.getFileDescriptor();
+ if (newStateFd == null) {
+ throw new NullPointerException();
}
if (files == null) {
- throw new NullPointerException("files==null");
+ throw new NullPointerException();
}
- int err = performBackup_native(basePath, oldSnapshot.getFileDescriptor(),
- newSnapshot.getFileDescriptor(), data.fd, files);
+ int err = performBackup_native(basePath, oldStateFd, data.fd, newStateFd, files);
if (err != 0) {
throw new RuntimeException("Backup failed"); // TODO: more here
}
}
- native private static int performBackup_native(String basePath,
- FileDescriptor oldSnapshot, FileDescriptor newSnapshot,
- FileDescriptor data, String[] files);
+ native private static int performBackup_native(String basePath, FileDescriptor oldState,
+ FileDescriptor data, FileDescriptor newState, String[] files);
}
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index e839bb4..8627f08 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -21,6 +21,7 @@
import java.io.FileDescriptor;
+/** @hide */
public class SharedPreferencesBackupHelper {
public static void performBackup(Context context,
ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
@@ -34,7 +35,7 @@
files[i] = prefGroups[i] + ".xml";
}
- FileBackupHelper.performBackup_checked(basePath, oldSnapshot, newSnapshot, data, files);
+ FileBackupHelper.performBackup_checked(basePath, oldSnapshot, data, newSnapshot, files);
}
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 9cf7a22..8fcb4d7 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -30,6 +30,10 @@
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
@@ -857,6 +861,17 @@
/**
+ * Equivalent to <code>setFieldsOn(cl, false)</code>.
+ *
+ * @see #setFieldsOn(Class, boolean)
+ *
+ * @hide
+ */
+ public static void setFieldsOn(Class<?> cl) {
+ setFieldsOn(cl, false);
+ }
+
+ /**
* Reflectively sets static fields of a class based on internal debugging
* properties. This method is a no-op if android.util.Config.DEBUG is
* false.
@@ -868,7 +883,7 @@
* Class setup: define a class whose only fields are non-final, static
* primitive types (except for "char") or Strings. In a static block
* after the field definitions/initializations, pass the class to
- * this method, Debug.setFieldsOn(). Example:
+ * this method, Debug.setFieldsOn(). Example:
* <pre>
* package com.example;
*
@@ -880,12 +895,18 @@
* public static String ns = null;
* public static boolean b = false;
* public static int i = 5;
+ * @Debug.DebugProperty
* public static float f = 0.1f;
+ * @@Debug.DebugProperty
* public static double d = 0.5d;
*
* // This MUST appear AFTER all fields are defined and initialized!
* static {
+ * // Sets all the fields
* Debug.setFieldsOn(MyDebugVars.class);
+ *
+ * // Sets only the fields annotated with @Debug.DebugProperty
+ * // Debug.setFieldsOn(MyDebugVars.class, true);
* }
* }
* </pre>
@@ -898,25 +919,31 @@
* {@hide}
*
* @param cl The class to (possibly) modify
+ * @param partial If false, sets all static fields, otherwise, only set
+ * fields with the {@link android.os.Debug.DebugProperty}
+ * annotation
* @throws IllegalArgumentException if any fields are final or non-static,
* or if the type of the field does not match the type of
* the internal debugging property value.
*/
- public static void setFieldsOn(Class<?> cl) {
+ public static void setFieldsOn(Class<?> cl, boolean partial) {
if (Config.DEBUG) {
if (debugProperties != null) {
/* Only look for fields declared directly by the class,
* so we don't mysteriously change static fields in superclasses.
*/
for (Field field : cl.getDeclaredFields()) {
- final String propertyName = cl.getName() + "." + field.getName();
- boolean isStatic = Modifier.isStatic(field.getModifiers());
- boolean isFinal = Modifier.isFinal(field.getModifiers());
- if (!isStatic || isFinal) {
- throw new IllegalArgumentException(propertyName +
- " must be static and non-final");
+ if (!partial || field.getAnnotation(DebugProperty.class) != null) {
+ final String propertyName = cl.getName() + "." + field.getName();
+ boolean isStatic = Modifier.isStatic(field.getModifiers());
+ boolean isFinal = Modifier.isFinal(field.getModifiers());
+
+ if (!isStatic || isFinal) {
+ throw new IllegalArgumentException(propertyName +
+ " must be static and non-final");
+ }
+ modifyFieldIfSet(field, debugProperties, propertyName);
}
- modifyFieldIfSet(field, debugProperties, propertyName);
}
}
} else {
@@ -925,4 +952,15 @@
") called in non-DEBUG build");
}
}
+
+ /**
+ * Annotation to put on fields you want to set with
+ * {@link Debug#setFieldsOn(Class, boolean)}.
+ *
+ * @hide
+ */
+ @Target({ ElementType.FIELD })
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface DebugProperty {
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 335b43c..af5dca6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -49,6 +49,7 @@
import android.util.Pool;
import android.util.Pools;
import android.util.PoolableManager;
+import android.util.Config;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.animation.Animation;
import android.view.inputmethod.InputConnection;
@@ -5641,7 +5642,7 @@
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);
}
- if (ViewRoot.PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
EventLog.writeEvent(60002, hashCode());
}
@@ -7166,6 +7167,60 @@
}
/**
+ * @param consistency The type of consistency. See ViewDebug for more information.
+ *
+ * @hide
+ */
+ protected boolean dispatchConsistencyCheck(int consistency) {
+ return onConsistencyCheck(consistency);
+ }
+
+ /**
+ * Method that subclasses should implement to check their consistency. The type of
+ * consistency check is indicated by the bit field passed as a parameter.
+ *
+ * @param consistency The type of consistency. See ViewDebug for more information.
+ *
+ * @throws IllegalStateException if the view is in an inconsistent state.
+ *
+ * @hide
+ */
+ protected boolean onConsistencyCheck(int consistency) {
+ boolean result = true;
+
+ final boolean checkLayout = (consistency & ViewDebug.CONSISTENCY_LAYOUT) != 0;
+ final boolean checkDrawing = (consistency & ViewDebug.CONSISTENCY_DRAWING) != 0;
+
+ if (checkLayout) {
+ if (getParent() == null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + this + " does not have a parent.");
+ }
+
+ if (mAttachInfo == null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + this + " is not attached to a window.");
+ }
+ }
+
+ if (checkDrawing) {
+ // Do not check the DIRTY/DRAWN flags because views can call invalidate()
+ // from their draw() method
+
+ if ((mPrivateFlags & DRAWN) != DRAWN &&
+ (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + this + " was invalidated but its drawing cache is valid.");
+ }
+ }
+
+ return result;
+ }
+
+ /**
* Prints information about this view in the log output, with the tag
* {@link #VIEW_LOG_TAG}.
*
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 367c9a2..4436f4b 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -54,6 +54,27 @@
*/
public class ViewDebug {
/**
+ * Log tag used to log errors related to the consistency of the view hierarchy.
+ *
+ * @hide
+ */
+ public static final String CONSISTENCY_LOG_TAG = "ViewConsistency";
+
+ /**
+ * Flag indicating the consistency check should check layout-related properties.
+ *
+ * @hide
+ */
+ public static final int CONSISTENCY_LAYOUT = 0x1;
+
+ /**
+ * Flag indicating the consistency check should check drawing-related properties.
+ *
+ * @hide
+ */
+ public static final int CONSISTENCY_DRAWING = 0x2;
+
+ /**
* Enables or disables view hierarchy tracing. Any invoker of
* {@link #trace(View, android.view.ViewDebug.HierarchyTraceType)} should first
* check that this value is set to true as not to affect performance.
@@ -80,6 +101,49 @@
static final String SYSTEM_PROPERTY_CAPTURE_EVENT = "debug.captureevent";
/**
+ * Profiles drawing times in the events log.
+ *
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean profileDrawing = false;
+
+ /**
+ * Profiles layout times in the events log.
+ *
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean profileLayout = false;
+
+ /**
+ * Profiles real fps (times between draws) and displays the result.
+ *
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean showFps = false;
+
+ /**
+ * <p>Enables or disables views consistency check. Even when this property is enabled,
+ * view consistency checks happen only if {@link android.util.Config#DEBUG} is set
+ * to true. The value of this property can be configured externally in one of the
+ * following files:</p>
+ * <ul>
+ * <li>/system/debug.prop</li>
+ * <li>/debug.prop</li>
+ * <li>/data/debug.prop</li>
+ * </ul>
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean consistencyCheckEnabled = false;
+
+ static {
+ Debug.setFieldsOn(ViewDebug.class, true);
+ }
+
+ /**
* This annotation can be used to mark fields and methods to be dumped by
* the view server. Only non-void methods with no arguments can be annotated
* by this annotation.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 31159d7..26fe776 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -32,6 +32,7 @@
import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
+import android.util.Config;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
@@ -1404,7 +1405,7 @@
// Clear the flag as early as possible to allow draw() implementations
// to call invalidate() successfully when doing animations
- child.mPrivateFlags |= DRAWN;
+ child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK) | DRAWN;
if (!concatMatrix && canvas.quickReject(cl, ct, cr, cb, Canvas.EdgeType.BW) &&
(child.mPrivateFlags & DRAW_ANIMATION) == 0) {
@@ -1494,7 +1495,7 @@
cachePaint.setAlpha(255);
mGroupFlags &= ~FLAG_ALPHA_LOWER_THAN_ONE;
}
- if (ViewRoot.PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
EventLog.writeEvent(60003, hashCode());
}
canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
@@ -2750,6 +2751,61 @@
}
/**
+ * @hide
+ */
+ @Override
+ protected boolean dispatchConsistencyCheck(int consistency) {
+ boolean result = super.dispatchConsistencyCheck(consistency);
+
+ final int count = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i = 0; i < count; i++) {
+ if (!children[i].dispatchConsistencyCheck(consistency)) result = false;
+ }
+
+ return result;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ protected boolean onConsistencyCheck(int consistency) {
+ boolean result = super.onConsistencyCheck(consistency);
+
+ final boolean checkLayout = (consistency & ViewDebug.CONSISTENCY_LAYOUT) != 0;
+ final boolean checkDrawing = (consistency & ViewDebug.CONSISTENCY_DRAWING) != 0;
+
+ if (checkLayout) {
+ final int count = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i = 0; i < count; i++) {
+ if (children[i].getParent() != this) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + children[i] + " has no parent/a parent that is not " + this);
+ }
+ }
+ }
+
+ if (checkDrawing) {
+ // If this group is dirty, check that the parent is dirty as well
+ if ((mPrivateFlags & DIRTY_MASK) != 0) {
+ final ViewParent parent = getParent();
+ if (parent != null && !(parent instanceof ViewRoot)) {
+ if ((((View) parent).mPrivateFlags & DIRTY_MASK) == 0) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "ViewGroup " + this + " is dirty but its parent is not: " + this);
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 8494d5e..90453ba 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -75,13 +75,6 @@
private static final boolean DEBUG_IMF = false || LOCAL_LOGV;
private static final boolean WATCH_POINTER = false;
- static final boolean PROFILE_DRAWING = false;
- private static final boolean PROFILE_LAYOUT = false;
- // profiles real fps (times between draws) and displays the result
- private static final boolean SHOW_FPS = false;
- // used by SHOW_FPS
- private static int sDrawTime;
-
/**
* Maximum time we allow the user to roll the trackball enough to generate
* a key event, before resetting the counters.
@@ -97,6 +90,8 @@
static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<RunQueue>();
+ private static int sDrawTime;
+
long mLastTrackballTime = 0;
final TrackballAxis mTrackballAxisX = new TrackballAxis();
final TrackballAxis mTrackballAxisY = new TrackballAxis();
@@ -796,7 +791,7 @@
final Rect frame = mWinFrame;
boolean initialized = false;
boolean contentInsetsChanged = false;
- boolean visibleInsetsChanged = false;
+ boolean visibleInsetsChanged;
try {
boolean hadSurface = mSurface.isValid();
int fl = 0;
@@ -937,14 +932,22 @@
if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v(
"ViewRoot", "Laying out " + host + " to (" +
host.mMeasuredWidth + ", " + host.mMeasuredHeight + ")");
- long startTime;
- if (PROFILE_LAYOUT) {
+ long startTime = 0L;
+ if (Config.DEBUG && ViewDebug.profileLayout) {
startTime = SystemClock.elapsedRealtime();
}
host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight);
- if (PROFILE_LAYOUT) {
+ if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
+ if (!host.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_LAYOUT)) {
+ throw new IllegalStateException("The view hierarchy is an inconsistent state,"
+ + "please refer to the logs with the tag "
+ + ViewDebug.CONSISTENCY_LOG_TAG + " for more infomation.");
+ }
+ }
+
+ if (Config.DEBUG && ViewDebug.profileLayout) {
EventLog.writeEvent(60001, SystemClock.elapsedRealtime() - startTime);
}
@@ -960,10 +963,11 @@
mTmpLocation[1] + host.mBottom - host.mTop);
host.gatherTransparentRegion(mTransparentRegion);
- if (mAppScale != 1.0f) {
- mTransparentRegion.scale(mAppScale);
- }
+ // TODO: scale the region, like:
+ // Region uses native methods. We probabl should have ScalableRegion class.
+
+ // Region does not have equals method ?
if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
mPreviousTransparentRegion.set(mTransparentRegion);
// reconfigure window manager
@@ -1168,6 +1172,9 @@
canvas.scale(scale, scale);
}
mView.draw(canvas);
+ if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
+ mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
+ }
} finally {
canvas.restoreToCount(saveCount);
}
@@ -1175,7 +1182,7 @@
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
checkEglErrors();
- if (SHOW_FPS) {
+ if (Config.DEBUG && ViewDebug.showFps) {
int now = (int)SystemClock.elapsedRealtime();
if (sDrawTime != 0) {
nativeShowFPS(canvas, now - sDrawTime);
@@ -1216,7 +1223,7 @@
try {
if (!dirty.isEmpty() || mIsAnimating) {
- long startTime;
+ long startTime = 0L;
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w="
@@ -1224,7 +1231,7 @@
//canvas.drawARGB(255, 255, 0, 0);
}
- if (PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
startTime = SystemClock.elapsedRealtime();
}
@@ -1259,11 +1266,15 @@
canvas.scale(scale, scale);
}
mView.draw(canvas);
+
+ if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
+ mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
+ }
} finally {
canvas.restoreToCount(saveCount);
}
- if (SHOW_FPS) {
+ if (Config.DEBUG && ViewDebug.showFps) {
int now = (int)SystemClock.elapsedRealtime();
if (sDrawTime != 0) {
nativeShowFPS(canvas, now - sDrawTime);
@@ -1271,7 +1282,7 @@
sDrawTime = now;
}
- if (PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
}
}
@@ -1878,6 +1889,9 @@
} else {
didFinish = false;
}
+ if (event != null) {
+ event.scale(mAppScaleInverted);
+ }
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4f503b4..1ca59b2 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3190,7 +3190,7 @@
// Reclaim views on screen
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
- AbsListView.LayoutParams lp = (AbsListView.LayoutParams)child.getLayoutParams();
+ AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
// Don't reclaim header or footer views, or views that should be ignored
if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
views.add(child);
@@ -3205,6 +3205,63 @@
}
/**
+ * @hide
+ */
+ @Override
+ protected boolean onConsistencyCheck(int consistency) {
+ boolean result = super.onConsistencyCheck(consistency);
+
+ final boolean checkLayout = (consistency & ViewDebug.CONSISTENCY_LAYOUT) != 0;
+
+ if (checkLayout) {
+ // The active recycler must be empty
+ final View[] activeViews = mRecycler.mActiveViews;
+ int count = activeViews.length;
+ for (int i = 0; i < count; i++) {
+ if (activeViews[i] != null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "AbsListView " + this + " has a view in its active recycler: " +
+ activeViews[i]);
+ }
+ }
+
+ // All views in the recycler must NOT be on screen and must NOT have a parent
+ final ArrayList<View> scrap = mRecycler.mCurrentScrap;
+ if (!checkScrap(scrap)) result = false;
+ final ArrayList<View>[] scraps = mRecycler.mScrapViews;
+ count = scraps.length;
+ for (int i = 0; i < count; i++) {
+ if (!checkScrap(scraps[i])) result = false;
+ }
+ }
+
+ return result;
+ }
+
+ private boolean checkScrap(ArrayList<View> scrap) {
+ if (scrap == null) return true;
+ boolean result = true;
+
+ final int count = scrap.size();
+ for (int i = 0; i < count; i++) {
+ final View view = scrap.get(i);
+ if (view.getParent() != null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, "AbsListView " + this +
+ " has a view in its scrap heap still attached to a parent: " + view);
+ }
+ if (indexOfChild(view) >= 0) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, "AbsListView " + this +
+ " has a view in its scrap heap that is also a direct child: " + view);
+ }
+ }
+
+ return result;
+ }
+
+ /**
* Sets the recycler listener to be notified whenever a View is set aside in
* the recycler for later reuse. This listener can be used to free resources
* associated to the View.
diff --git a/core/jni/android_backup_FileBackupHelper.cpp b/core/jni/android_backup_FileBackupHelper.cpp
index e8d60a0..c6de3a5 100644
--- a/core/jni/android_backup_FileBackupHelper.cpp
+++ b/core/jni/android_backup_FileBackupHelper.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "FileBackupHelper_native"
+#include <utils/Log.h>
+
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
@@ -22,29 +25,29 @@
namespace android
{
-static jfieldID s_descriptorField;
+static jfieldID s_descriptorField = 0;
static int
-performBackup_native(JNIEnv* env, jstring basePath,
- jobject oldSnapshot, jobject newSnapshot,
- jobject data, jobjectArray files)
+performBackup_native(JNIEnv* env, jobject clazz, jstring basePath, jobject oldState, jobject data,
+ jobject newState, jobjectArray files)
{
int err;
// all parameters have already been checked against null
-
- int oldSnapshotFD = env->GetIntField(oldSnapshot, s_descriptorField);
- int newSnapshotFD = env->GetIntField(newSnapshot, s_descriptorField);
+ LOGD("oldState=%p newState=%p data=%p\n", oldState, newState, data);
+ int oldStateFD = oldState != NULL ? env->GetIntField(oldState, s_descriptorField) : -1;
+ int newStateFD = env->GetIntField(newState, s_descriptorField);
int dataFD = env->GetIntField(data, s_descriptorField);
char const* basePathUTF = env->GetStringUTFChars(basePath, NULL);
+ LOGD("basePathUTF=\"%s\"\n", basePathUTF);
const int fileCount = env->GetArrayLength(files);
char const** filesUTF = (char const**)malloc(sizeof(char*)*fileCount);
for (int i=0; i<fileCount; i++) {
filesUTF[i] = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(files, i), NULL);
}
- err = back_up_files(oldSnapshotFD, newSnapshotFD, dataFD, basePathUTF, filesUTF, fileCount);
+ err = back_up_files(oldStateFD, dataFD, newStateFD, basePathUTF, filesUTF, fileCount);
for (int i=0; i<fileCount; i++) {
env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(files, i), filesUTF[i]);
@@ -64,6 +67,8 @@
int register_android_backup_FileBackupHelper(JNIEnv* env)
{
+ LOGD("register_android_backup_FileBackupHelper");
+
jclass clazz;
clazz = env->FindClass("java/io/FileDescriptor");
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 0b398bc..fda584d 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -400,7 +400,7 @@
* @param y The y coordinate of the first pixel in source
* @param width The number of pixels in each row
* @param height The number of rows
- * @param m Option matrix to be applied to the pixels
+ * @param m Optional matrix to be applied to the pixels
* @param filter true if the source should be filtered.
* Only applies if the matrix contains more than just
* translation.
diff --git a/include/utils/backup_helpers.h b/include/utils/backup_helpers.h
index 61bee340..137c5f1 100644
--- a/include/utils/backup_helpers.h
+++ b/include/utils/backup_helpers.h
@@ -1,7 +1,7 @@
#ifndef _UTILS_BACKUP_HELPERS_H
#define _UTILS_BACKUP_HELPERS_H
-int back_up_files(int oldSnapshotFD, int newSnapshotFD, int oldDataStream,
+int back_up_files(int oldSnapshotFD, int oldDataStream, int newSnapshotFD,
char const* fileBase, char const* const* files, int fileCount);
#define TEST_BACKUP_HELPERS 0
diff --git a/libs/utils/file_backup_helper.cpp b/libs/utils/file_backup_helper.cpp
index 111f88d..453084a 100644
--- a/libs/utils/file_backup_helper.cpp
+++ b/libs/utils/file_backup_helper.cpp
@@ -24,6 +24,9 @@
#define MAGIC0 0x70616e53 // Snap
#define MAGIC1 0x656c6946 // File
+#define LOGP(x...) LOGD(x)
+//#define LOGP(x...) printf(x)
+
struct SnapshotHeader {
int magic0;
int fileCount;
@@ -159,14 +162,14 @@
static int
write_delete_file(const String8& key)
{
- printf("write_delete_file %s\n", key.string());
+ LOGP("write_delete_file %s\n", key.string());
return 0;
}
static int
write_update_file(const String8& realFilename, const String8& key)
{
- printf("write_update_file %s (%s)\n", realFilename.string(), key.string());
+ LOGP("write_update_file %s (%s)\n", realFilename.string(), key.string());
return 0;
}
@@ -195,7 +198,7 @@
}
int
-back_up_files(int oldSnapshotFD, int newSnapshotFD, int oldDataStream,
+back_up_files(int oldSnapshotFD, int oldDataStream, int newSnapshotFD,
char const* fileBase, char const* const* files, int fileCount)
{
int err;
@@ -260,10 +263,10 @@
const FileState& f = oldSnapshot.valueAt(n);
const FileState& g = newSnapshot.valueAt(m);
- printf("%s\n", q.string());
- printf(" new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+ LOGP("%s\n", q.string());
+ LOGP(" new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
f.modTime_sec, f.modTime_nsec, f.size, f.crc32);
- printf(" old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+ LOGP(" old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
g.modTime_sec, g.modTime_nsec, g.size, g.crc32);
if (f.modTime_sec != g.modTime_sec || f.modTime_nsec != g.modTime_nsec
|| f.size != g.size || f.crc32 != g.crc32) {
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index db1deae..983329b 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -220,6 +220,9 @@
BackupRequest request;
synchronized (mQueueLock) {
+ if (mBackupQueue == null) {
+ Log.d(TAG, "mBackupQueue is null. WHY?");
+ }
request = mBackupQueue.get(0);
}
diff --git a/services/java/com/android/server/status/IconMerger.java b/services/java/com/android/server/status/IconMerger.java
index 37fdbfb..5b80638 100644
--- a/services/java/com/android/server/status/IconMerger.java
+++ b/services/java/com/android/server/status/IconMerger.java
@@ -8,8 +8,6 @@
public class IconMerger extends LinearLayout {
- private static final boolean SPEW = false;
-
StatusBarService service;
StatusBarIcon moreIcon;
@@ -29,7 +27,7 @@
int fitRight = -1;
for (i=N-1; i>=0; i--) {
final View child = getChildAt(i);
- if (child != null && child.getVisibility() != GONE) {
+ if (child.getVisibility() != GONE) {
fitRight = child.getRight();
break;
}
@@ -45,7 +43,7 @@
moreView = child;
startIndex = i+1;
}
- else if (child != null && child.getVisibility() != GONE) {
+ else if (child.getVisibility() != GONE) {
fitLeft = child.getLeft();
break;
}
@@ -71,7 +69,7 @@
int number = 0;
for (i=startIndex; i<N; i++) {
final View child = getChildAt(i);
- if (child != null && child.getVisibility() != GONE) {
+ if (child.getVisibility() != GONE) {
int childLeft = child.getLeft();
int childRight = child.getRight();
if (childLeft < breakingPoint) {
diff --git a/tests/backup/src/com/android/backuptest/BackupTestActivity.java b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
index de68cb7..af7dfd4 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestActivity.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
@@ -83,6 +83,27 @@
bm.dataChanged();
}
},
+ new Test("Clear File") {
+ void run() {
+ PrintStream output = null;
+ try {
+ output = new PrintStream(openFileOutput(FILE_NAME, MODE_PRIVATE));
+ output.close();
+ } catch (IOException ex) {
+ if (output != null) {
+ output.close();
+ }
+ }
+ BackupManager bm = new BackupManager(BackupTestActivity.this);
+ bm.dataChanged();
+ }
+ },
+ new Test("Poke") {
+ void run() {
+ BackupManager bm = new BackupManager(BackupTestActivity.this);
+ bm.dataChanged();
+ }
+ },
new Test("Show Shared Pref") {
void run() {
SharedPreferences prefs = getSharedPreferences(PREF_GROUP_SETTINGS, MODE_PRIVATE);
diff --git a/tests/backup/src/com/android/backuptest/BackupTestService.java b/tests/backup/src/com/android/backuptest/BackupTestService.java
index c58c98b..00eb86e 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestService.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestService.java
@@ -17,6 +17,8 @@
package com.android.backuptest;
import android.backup.BackupService;
+import android.backup.BackupDataOutput;
+import android.backup.FileBackupHelper;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -25,10 +27,12 @@
static final String TAG = "BackupTestService";
@Override
- public void onBackup(ParcelFileDescriptor oldState,
- ParcelFileDescriptor data,
- ParcelFileDescriptor newState) {
+ public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
Log.d(TAG, "onBackup");
+ FileBackupHelper.performBackup(this, oldState, data, newState, new String[] {
+ BackupTestActivity.FILE_NAME
+ });
}
@Override