diff options
| -rw-r--r-- | core/java/android/net/http/Request.java | 26 | ||||
| -rw-r--r-- | core/java/android/webkit/LoadListener.java | 12 | ||||
| -rw-r--r-- | core/java/android/webkit/WebTextView.java | 17 | ||||
| -rw-r--r-- | core/java/android/webkit/WebView.java | 4 | ||||
| -rw-r--r-- | docs/html/guide/developing/tools/bmgr.jd | 165 | ||||
| -rw-r--r-- | docs/html/guide/guide_toc.cs | 1 |
6 files changed, 221 insertions, 4 deletions
diff --git a/core/java/android/net/http/Request.java b/core/java/android/net/http/Request.java index 6dbf32593a8d..f1ebb4793ac1 100644 --- a/core/java/android/net/http/Request.java +++ b/core/java/android/net/http/Request.java @@ -34,6 +34,7 @@ import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; import org.apache.http.ParseException; import org.apache.http.ProtocolVersion; @@ -72,6 +73,10 @@ class Request { int mFailCount = 0; + // This will be used to set the Range field if we retry a connection. This + // is http/1.1 feature. + private int mReceivedBytes = 0; + private InputStream mBodyProvider; private int mBodyLength; @@ -241,7 +246,6 @@ class Request { StatusLine statusLine = null; boolean hasBody = false; - boolean reuse = false; httpClientConnection.flush(); int statusCode = 0; @@ -264,6 +268,8 @@ class Request { if (hasBody) entity = httpClientConnection.receiveResponseEntity(header); + boolean supportPartialContent = v.greaterEquals(HttpVersion.HTTP_1_1); + if (entity != null) { InputStream is = entity.getContent(); @@ -306,6 +312,7 @@ class Request { if (len != -1) { count += len; + if (supportPartialContent) mReceivedBytes += len; } if (len == -1 || count >= lowWater) { if (HttpLog.LOGV) HttpLog.v("Request.readResponse() " + count); @@ -324,7 +331,13 @@ class Request { if (HttpLog.LOGV) HttpLog.v( "readResponse() handling " + e); } catch(IOException e) { // don't throw if we have a non-OK status code - if (statusCode == HttpStatus.SC_OK) { + if (statusCode == HttpStatus.SC_OK + || statusCode == HttpStatus.SC_PARTIAL_CONTENT) { + if (supportPartialContent && count > 0) { + // if there is uncommited content, we should commit them + // as we will continue the request + mEventHandler.data(buf, count); + } throw e; } } finally { @@ -411,6 +424,15 @@ class Request { } setBodyProvider(mBodyProvider, mBodyLength); } + + if (mReceivedBytes > 0) { + // reset the fail count as we continue the request + mFailCount = 0; + // set the "Range" header to indicate that the retry will continue + // instead of restarting the request + HttpLog.v("*** Request.reset() to range:" + mReceivedBytes); + mHttpRequest.setHeader("Range", "bytes=" + mReceivedBytes + "-"); + } } /** diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index e0f8bc0bd404..e6fa405b11ce 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -64,6 +64,7 @@ class LoadListener extends Handler implements EventHandler { // Standard HTTP status codes in a more representative format private static final int HTTP_OK = 200; + private static final int HTTP_PARTIAL_CONTENT = 206; private static final int HTTP_MOVED_PERMANENTLY = 301; private static final int HTTP_FOUND = 302; private static final int HTTP_SEE_OTHER = 303; @@ -328,6 +329,17 @@ class LoadListener extends Handler implements EventHandler { // Does the header parsing work on the WebCore thread. private void handleHeaders(Headers headers) { if (mCancelled) return; + + // Note: the headers we care in LoadListeners, like + // content-type/content-length, should not be updated for partial + // content. Just skip here and go ahead with adding data. + if (mStatusCode == HTTP_PARTIAL_CONTENT) { + // we don't support cache for partial content yet + WebViewWorker.getHandler().obtainMessage( + WebViewWorker.MSG_REMOVE_CACHE, this).sendToTarget(); + return; + } + mHeaders = headers; long contentLength = headers.getContentLength(); diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java index dc952e6408af..19abec1a5907 100644 --- a/core/java/android/webkit/WebTextView.java +++ b/core/java/android/webkit/WebTextView.java @@ -301,6 +301,23 @@ import java.util.ArrayList; } @Override + protected void onDraw(Canvas canvas) { + // onDraw should only be called for password fields. If WebTextView is + // still drawing, but is no longer corresponding to a password field, + // remove it. + if (mWebView == null || !mWebView.nativeFocusCandidateIsPassword() + || !isSameTextField(mWebView.nativeFocusCandidatePointer())) { + // Although calling remove() would seem to make more sense here, + // changing it to not be a password field will make it not draw. + // Other code will make sure that it is removed completely, but this + // way the user will not see it. + setInPassword(false); + } else { + super.onDraw(canvas); + } + } + + @Override public void onEditorAction(int actionCode) { switch (actionCode) { case EditorInfo.IME_ACTION_NEXT: diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index e2f5de4be743..66dad0bc107b 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -7256,13 +7256,13 @@ public class WebView extends AbsoluteLayout private native void nativeFindNext(boolean forward); /* package */ native int nativeFocusCandidateFramePointer(); /* package */ native boolean nativeFocusCandidateHasNextTextfield(); - private native boolean nativeFocusCandidateIsPassword(); + /* package */ native boolean nativeFocusCandidateIsPassword(); private native boolean nativeFocusCandidateIsRtlText(); private native boolean nativeFocusCandidateIsTextInput(); /* package */ native int nativeFocusCandidateMaxLength(); /* package */ native String nativeFocusCandidateName(); private native Rect nativeFocusCandidateNodeBounds(); - private native int nativeFocusCandidatePointer(); + /* package */ native int nativeFocusCandidatePointer(); private native String nativeFocusCandidateText(); private native int nativeFocusCandidateTextSize(); /** diff --git a/docs/html/guide/developing/tools/bmgr.jd b/docs/html/guide/developing/tools/bmgr.jd new file mode 100644 index 000000000000..0353b77237f5 --- /dev/null +++ b/docs/html/guide/developing/tools/bmgr.jd @@ -0,0 +1,165 @@ +page.title=bmgr +@jd:body + +<!-- quickview box content here --> + +<div id="qv-wrapper"> +<div id="qv"> + <h2>bmgr quickview</h2> +<p><code>bmgr</code> lets you inspect and control the backup/restore system on an Android device. + + <h2>In this document</h2> + <ol> +<li><a href="#transports">About backup transports</a></li> +<li><a href="#restoresets">About restore sets</a></li> +<li><a href="#backup">Forcing a backup operation</a></li> +<li><a href="#restore">Forcing a restore operation</a></li> +<li><a href="#other">Other commands</a></li> + </ol> + +</div> +</div> + +<!-- normal page content here --> + +<p><code>bmgr</code> is a shell tool that developers can use to interact with the Backup Manager +on Android devices supporting API version 8 or later. It provides commands for inducing backup +and restore operations on demand so that you do not need to repeatedly wipe data or take similar +intrusive steps to test the operation of an application's backup agent. These commands are +accessed via the <a href="{@docRoot}guide/developing/tools/adb.html">adb</a> shell. + +<p>There are a couple of basic concepts used by the Backup Manager that are built into the way +that <code>bmgr</code> operates. These are <a href="#transports">backup transports</a> and +<a href="#restoresets">restore sets</a>. + + +<a name="transports"></a> +<h2>About backup transports</h2> + +<p>A <em>backup transport</em> is the code module responsible for moving backup and restore data +to and from some storage location. A device can have multipe transports installed, though only +one is active at any given time. Transports are identified by name. You can see what +transports are available on your device or emulator by running the +<code>bmgr list transports</code> command: + + <pre>adb shell bmgr list transports</pre> + +<p>The output of this command is a list of the transports available on the device. The currently +active transport is flagged with a <code>*</code> character. Transport names may look like +component names -- for example, <code>android/com.android.internal.backup.LocalTransport</code> -- +but they need not be, and the strings are never used as direct class references. The use of +a component-like naming scheme is simply for purposes of preventing name collisions. + +<p>You can change which transport is currently active from the command line as well: + + <pre>adb shell bmgr transport NAME</pre> + +<p>where <code>NAME</code> is one of the names as printed by the <code>bmgr list transports</code> +command. From this point forward, backup and restore operations will be directed through the +newly-selected transport. Backup state tracking is managed separately for each transport, so +switching back and forth between them will not corrupt the saved state. + + +<a name="restoresets"></a> +<h2>About restore sets</h2> + +<p>All of the application data that a device has written to a given backup transport is tracked +together, and is collectively sometimes called a <em>restore set,</em> because the typical use +of the data set is during restore operations. Each time a device is initially provisioned, a +new data set is established. The user can get a listing of all the data sets that can be +restored through the current transport by running this shell command: + + <pre>adb shell bmgr list sets</pre> + +<p>The output is listing of available restore sets, one per line. The first item on each line is +a <em>token,</em> a number in hexadecimal that identifies the restore set to the transport. After +that is a string that may provide some brief identifying information about the restore set. Only +the token is actually used within the backup and restore mechanism. + + +<a name="backup"></a> +<h2>Forcing a backup operation</h2> + +<p>Normally, applications notify the backup manager directly that their data has changed, in +response to which the backup manager will make sure to invoke that application's agent when the +next backup operation is run. You can simulate this manually from the command line if you wish, +by running this shell command: + + <pre>adb shell bmgr backup PACKAGE</pre> + +<p><code>PACKAGE</code> is the formal package name of the application you wish to schedule for +backup. At this point you know that the application's agent will be invoked for backup at some +point in the future, though there is no hard guarantee of when that will occur. You can force +all pending backup operations to run immediately by using the following command: + + <pre>adb shell bmgr run</pre> + +<p>This causes a backup pass to execute immediately, invoking the agents of all applications that +had called <code>BackupManager.dataChanged()</code> since the time of the last backup operation, +plus any applications which had been manually scheduled for backup via +<code>bmgr backup PACKAGE</code>. + + +<a name="restore"></a> +<h2>Forcing a restore operation</h2> + +<p>Unlike backup operations, which are batched together and run on an occasional basis, restore +operations execute immediately. The backup manager currently provides two kinds of restore +operations. The first restores an entire device with the data from a given restore set. This +is typically only performed when a device is first provisioned, to replicate settings and other +such saved state from the user's previous device. The second kind of restore operation restores +a single application from the <em>active</em> data set; that is, from the data set currently +being written to by backup operations. This second form is available as part of the public API. +It allows applications to abandon their current data and revert to the last-known-good data as +represented in their current backup image. + +<p>A full-system restore operation can be initiated with this shell command: + + <pre>adb shell bmgr restore TOKEN</pre> + +<p>where <code>TOKEN</code> is the desired restore set's token as printed out by the <code>bmgr +list sets</code> command. <strong>Warning!</strong> This operation will <em>replace</em> the +data of all backup-enabled applications with the contents of the given restore set. Be careful, +and be aware of the potential consequences. + +<p>A single-application restore operation does not reference a restore set token; it always uses +the data from the currently active data set. You can induce such an operation from the command +line like this: + + <pre>adb shell bmgr restore PACKAGE</pre> + +<p><code>PACKAGE</code> is the formal package name of an application that is participating in the +backup/restore mechanism. The backup manager will immediately instantiate the application's +agent and invoke it for restore. + +<a name="other"></a> +<h2>Other commands</h2> + +<p>The data for a single application can be erased from the active data set on demand. This is +very useful during development of backup agents, in case bugs lead you to write corrupt data +or saved state information. The shell command for wiping an application's data is this: + + <pre>adb shell bmgr wipe PACKAGE</pre> + +<p><code>PACKAGE</code> is the formal package name of the application whose data you wish to +erase. The next backup operation that the application's agent processes will look as +though the application had never backed anything up before. + +<p>You can see whether the backup manager is operational at all by running this command: + + <pre>adb shell bmgr enabled</pre> + +<p>This might be useful if your application's agent is never being invoked for backup, to verify +whether the operating system thinks it should be performing such operations at all. You can also +directly disable or enable the backup manager with this command: + + <pre>adb shell bmgr enable BOOLEAN</pre> + +<p>where <code>BOOLEAN</code> is either <code>true</code> or <code>false</code>. This is +equivalent to disabling or enabling backup in the device's main Settings UI. +<strong>Warning!</strong> When backup is disabled, the current transport will explicitly wipe +the entire active data set from its backend storage. This is so that when a user says that no, +they do not want their data backed up, the backup manager respects that wish. No further data +will be saved from the device, and no restore operations will be possible, unless the backup +manager is re-enabled (either through Settings or through the above <code>bmgr</code> command). + diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index fd163f6b2ba2..269e807d8c70 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -282,6 +282,7 @@ <!--<li><a href="<?cs var:toroot ?>guide/developing/tools/adt.html">ADT Plugin</a></li>--> <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">aidl</a></li> <li><a href="<?cs var:toroot ?>guide/developing/tools/avd.html">AVDs</a></li> + <li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a></li> <li><a href="<?cs var:toroot ?>guide/developing/tools/ddms.html">ddms</a></li> <li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#dx">dx</a></li> <li><a href="<?cs var:toroot ?>guide/developing/tools/draw9patch.html">Draw 9-Patch</a></li> |