diff options
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | core/java/android/print/IPrintDocumentAdapter.aidl | 2 | ||||
-rw-r--r-- | core/java/android/print/IPrintDocumentAdapterObserver.aidl | 26 | ||||
-rw-r--r-- | core/java/android/print/PrintManager.java | 269 | ||||
-rw-r--r-- | core/java/android/view/accessibility/AccessibilityNodeInfo.java | 2 | ||||
-rw-r--r-- | core/java/android/webkit/CacheManager.java | 341 | ||||
-rw-r--r-- | core/java/android/webkit/PluginData.java | 141 | ||||
-rw-r--r-- | core/java/android/webkit/UrlInterceptHandler.java | 60 | ||||
-rw-r--r-- | core/java/android/webkit/UrlInterceptRegistry.java | 167 | ||||
-rw-r--r-- | packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java | 25 | ||||
-rw-r--r-- | packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java | 1 | ||||
-rw-r--r-- | packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java | 71 |
12 files changed, 1002 insertions, 104 deletions
diff --git a/Android.mk b/Android.mk index 166db4ee016b..4e5427adab33 100644 --- a/Android.mk +++ b/Android.mk @@ -165,6 +165,7 @@ LOCAL_SRC_FILES += \ core/java/android/print/ILayoutResultCallback.aidl \ core/java/android/print/IPrinterDiscoveryObserver.aidl \ core/java/android/print/IPrintDocumentAdapter.aidl \ + core/java/android/print/IPrintDocumentAdapterObserver.aidl \ core/java/android/print/IPrintJobStateChangeListener.aidl \ core/java/android/print/IPrintManager.aidl \ core/java/android/print/IPrintSpooler.aidl \ diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl index b12c922cca6e..9d384fba874d 100644 --- a/core/java/android/print/IPrintDocumentAdapter.aidl +++ b/core/java/android/print/IPrintDocumentAdapter.aidl @@ -19,6 +19,7 @@ package android.print; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.print.ILayoutResultCallback; +import android.print.IPrintDocumentAdapterObserver; import android.print.IWriteResultCallback; import android.print.PageRange; import android.print.PrintAttributes; @@ -29,6 +30,7 @@ import android.print.PrintAttributes; * @hide */ oneway interface IPrintDocumentAdapter { + void setObserver(in IPrintDocumentAdapterObserver observer); void start(); void layout(in PrintAttributes oldAttributes, in PrintAttributes newAttributes, ILayoutResultCallback callback, in Bundle metadata, int sequence); diff --git a/core/java/android/print/IPrintDocumentAdapterObserver.aidl b/core/java/android/print/IPrintDocumentAdapterObserver.aidl new file mode 100644 index 000000000000..4443df09ae38 --- /dev/null +++ b/core/java/android/print/IPrintDocumentAdapterObserver.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2013 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 android.print; + +/** + * Interface for observing the state of a print document adapter. + * + * @hide + */ +oneway interface IPrintDocumentAdapterObserver { + void onDestroy(); +} diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index dbd8278d3a1f..955b4d8f457b 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -16,6 +16,8 @@ package android.print; +import android.app.Activity; +import android.app.Application.ActivityLifecycleCallbacks; import android.content.Context; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; @@ -302,8 +304,8 @@ public final class PrintManager { if (TextUtils.isEmpty(printJobName)) { throw new IllegalArgumentException("priintJobName cannot be empty"); } - PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate(documentAdapter, - mContext.getMainLooper()); + PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate( + mContext, documentAdapter); try { Bundle result = mService.print(printJobName, delegate, attributes, mContext.getPackageName(), mAppId, mUserId); @@ -369,17 +371,21 @@ public final class PrintManager { return new PrinterDiscoverySession(mService, mContext, mUserId); } - private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub { + private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub + implements ActivityLifecycleCallbacks { private final Object mLock = new Object(); private CancellationSignal mLayoutOrWriteCancellation; - private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - - // cleared in finish() + private Activity mActivity; // Strong reference OK - cleared in finish() + + private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - cleared in finish private Handler mHandler; // Strong reference OK - cleared in finish() + private IPrintDocumentAdapterObserver mObserver; // Strong reference OK - cleared in finish + private LayoutSpec mLastLayoutSpec; private WriteSpec mLastWriteSpec; @@ -390,16 +396,42 @@ public final class PrintManager { private boolean mFinishRequested; private boolean mFinished; - public PrintDocumentAdapterDelegate(PrintDocumentAdapter documentAdapter, Looper looper) { + private boolean mDestroyed; + + public PrintDocumentAdapterDelegate(Context context, + PrintDocumentAdapter documentAdapter) { + if (!(context instanceof Activity)) { + throw new IllegalStateException("Can print only from an activity"); + } + mActivity = (Activity) context; mDocumentAdapter = documentAdapter; - mHandler = new MyHandler(looper); + mHandler = new MyHandler(mActivity.getMainLooper()); + mActivity.getApplication().registerActivityLifecycleCallbacks(this); + } + + @Override + public void setObserver(IPrintDocumentAdapterObserver observer) { + final boolean destroyed; + synchronized (mLock) { + if (!mDestroyed) { + mObserver = observer; + } + destroyed = mDestroyed; + } + if (destroyed) { + try { + observer.onDestroy(); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error announcing destroyed state", re); + } + } } @Override public void start() { synchronized (mLock) { - // Started or finished - nothing to do. - if (mStartReqeusted || mFinishRequested) { + // Started called or finish called or destroyed - nothing to do. + if (mStartReqeusted || mFinishRequested || mDestroyed) { return; } @@ -412,71 +444,85 @@ public final class PrintManager { @Override public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes, ILayoutResultCallback callback, Bundle metadata, int sequence) { + final boolean destroyed; synchronized (mLock) { - // Start not called or finish called - nothing to do. - if (!mStartReqeusted || mFinishRequested) { - return; - } - - // Layout cancels write and overrides layout. - if (mLastWriteSpec != null) { - IoUtils.closeQuietly(mLastWriteSpec.fd); - mLastWriteSpec = null; - } + destroyed = mDestroyed; + // If start called and not finished called and not destroyed - do some work. + if (mStartReqeusted && !mFinishRequested && !mDestroyed) { + // Layout cancels write and overrides layout. + if (mLastWriteSpec != null) { + IoUtils.closeQuietly(mLastWriteSpec.fd); + mLastWriteSpec = null; + } - mLastLayoutSpec = new LayoutSpec(); - mLastLayoutSpec.callback = callback; - mLastLayoutSpec.oldAttributes = oldAttributes; - mLastLayoutSpec.newAttributes = newAttributes; - mLastLayoutSpec.metadata = metadata; - mLastLayoutSpec.sequence = sequence; + mLastLayoutSpec = new LayoutSpec(); + mLastLayoutSpec.callback = callback; + mLastLayoutSpec.oldAttributes = oldAttributes; + mLastLayoutSpec.newAttributes = newAttributes; + mLastLayoutSpec.metadata = metadata; + mLastLayoutSpec.sequence = sequence; + + // Cancel the previous cancellable operation.When the + // cancellation completes we will do the pending work. + if (cancelPreviousCancellableOperationLocked()) { + return; + } - // Cancel the previous cancellable operation.When the - // cancellation completes we will do the pending work. - if (cancelPreviousCancellableOperationLocked()) { - return; + doPendingWorkLocked(); + } + } + if (destroyed) { + try { + callback.onLayoutFailed(null, sequence); + } catch (RemoteException re) { + Log.i(LOG_TAG, "Error notifying for cancelled layout", re); } - - doPendingWorkLocked(); } } @Override public void write(PageRange[] pages, ParcelFileDescriptor fd, IWriteResultCallback callback, int sequence) { + final boolean destroyed; synchronized (mLock) { - // Start not called or finish called - nothing to do. - if (!mStartReqeusted || mFinishRequested) { - return; - } + destroyed = mDestroyed; + // If start called and not finished called and not destroyed - do some work. + if (mStartReqeusted && !mFinishRequested && !mDestroyed) { + // Write cancels previous writes. + if (mLastWriteSpec != null) { + IoUtils.closeQuietly(mLastWriteSpec.fd); + mLastWriteSpec = null; + } - // Write cancels previous writes. - if (mLastWriteSpec != null) { - IoUtils.closeQuietly(mLastWriteSpec.fd); - mLastWriteSpec = null; - } + mLastWriteSpec = new WriteSpec(); + mLastWriteSpec.callback = callback; + mLastWriteSpec.pages = pages; + mLastWriteSpec.fd = fd; + mLastWriteSpec.sequence = sequence; - mLastWriteSpec = new WriteSpec(); - mLastWriteSpec.callback = callback; - mLastWriteSpec.pages = pages; - mLastWriteSpec.fd = fd; - mLastWriteSpec.sequence = sequence; + // Cancel the previous cancellable operation.When the + // cancellation completes we will do the pending work. + if (cancelPreviousCancellableOperationLocked()) { + return; + } - // Cancel the previous cancellable operation.When the - // cancellation completes we will do the pending work. - if (cancelPreviousCancellableOperationLocked()) { - return; + doPendingWorkLocked(); + } + } + if (destroyed) { + try { + callback.onWriteFailed(null, sequence); + } catch (RemoteException re) { + Log.i(LOG_TAG, "Error notifying for cancelled write", re); } - - doPendingWorkLocked(); } } @Override public void finish() { synchronized (mLock) { - // Start not called or finish called - nothing to do. - if (!mStartReqeusted || mFinishRequested) { + // Start not called or finish called or destroyed - nothing to do. + if (!mStartReqeusted || mFinishRequested || mDestroyed) { return; } @@ -495,15 +541,78 @@ public final class PrintManager { } } + @Override + public void onActivityPaused(Activity activity) { + /* do nothing */ + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + /* do nothing */ + } + + @Override + public void onActivityStarted(Activity activity) { + /* do nothing */ + } + + @Override + public void onActivityResumed(Activity activity) { + /* do nothing */ + } + + @Override + public void onActivityStopped(Activity activity) { + /* do nothing */ + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + /* do nothing */ + } + + @Override + public void onActivityDestroyed(Activity activity) { + // We really care only if the activity is being destroyed to + // notify the the print spooler so it can close the print dialog. + // Note the the spooler has a death recipient that observes if + // this process gets killed so we cover the case of onDestroy not + // being called due to this process being killed to reclaim memory. + final IPrintDocumentAdapterObserver observer; + synchronized (mLock) { + if (activity == mActivity) { + mDestroyed = true; + observer = mObserver; + clearLocked(); + } else { + observer = null; + activity = null; + } + } + if (observer != null) { + activity.getApplication().unregisterActivityLifecycleCallbacks( + PrintDocumentAdapterDelegate.this); + try { + observer.onDestroy(); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error announcing destroyed state", re); + } + } + } + private boolean isFinished() { return mDocumentAdapter == null; } - private void doFinish() { + private void clearLocked() { + mActivity = null; mDocumentAdapter = null; mHandler = null; - synchronized (mLock) { - mLayoutOrWriteCancellation = null; + mLayoutOrWriteCancellation = null; + mLastLayoutSpec = null; + if (mLastWriteSpec != null) { + IoUtils.closeQuietly(mLastWriteSpec.fd); + mLastWriteSpec = null; } } @@ -564,63 +673,81 @@ public final class PrintManager { } switch (message.what) { case MSG_START: { - mDocumentAdapter.onStart(); - } - break; + final PrintDocumentAdapter adapter; + synchronized (mLock) { + adapter = mDocumentAdapter; + } + if (adapter != null) { + adapter.onStart(); + } + } break; case MSG_LAYOUT: { + final PrintDocumentAdapter adapter; final CancellationSignal cancellation; final LayoutSpec layoutSpec; synchronized (mLock) { + adapter = mDocumentAdapter; layoutSpec = mLastLayoutSpec; mLastLayoutSpec = null; cancellation = new CancellationSignal(); mLayoutOrWriteCancellation = cancellation; } - if (layoutSpec != null) { + if (layoutSpec != null && adapter != null) { if (DEBUG) { Log.i(LOG_TAG, "Performing layout"); } - mDocumentAdapter.onLayout(layoutSpec.oldAttributes, + adapter.onLayout(layoutSpec.oldAttributes, layoutSpec.newAttributes, cancellation, new MyLayoutResultCallback(layoutSpec.callback, layoutSpec.sequence), layoutSpec.metadata); } - } - break; + } break; case MSG_WRITE: { + final PrintDocumentAdapter adapter; final CancellationSignal cancellation; final WriteSpec writeSpec; synchronized (mLock) { + adapter = mDocumentAdapter; writeSpec = mLastWriteSpec; mLastWriteSpec = null; cancellation = new CancellationSignal(); mLayoutOrWriteCancellation = cancellation; } - if (writeSpec != null) { + if (writeSpec != null && adapter != null) { if (DEBUG) { Log.i(LOG_TAG, "Performing write"); } - mDocumentAdapter.onWrite(writeSpec.pages, writeSpec.fd, + adapter.onWrite(writeSpec.pages, writeSpec.fd, cancellation, new MyWriteResultCallback(writeSpec.callback, writeSpec.fd, writeSpec.sequence)); } - } - break; + } break; case MSG_FINISH: { if (DEBUG) { Log.i(LOG_TAG, "Performing finish"); } - mDocumentAdapter.onFinish(); - doFinish(); - } - break; + final PrintDocumentAdapter adapter; + final Activity activity; + synchronized (mLock) { + adapter = mDocumentAdapter; + activity = mActivity; + clearLocked(); + } + if (adapter != null) { + adapter.onFinish(); + } + if (activity != null) { + activity.getApplication().unregisterActivityLifecycleCallbacks( + PrintDocumentAdapterDelegate.this); + } + } break; default: { throw new IllegalArgumentException("Unknown message: " diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 9fc37cfa679d..4f53c1e78c75 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -2540,7 +2540,7 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Class with information if a node is a range. Use - * {@link RangeInfo#obtain(int, float, float, float) to get an instance. + * {@link RangeInfo#obtain(int, float, float, float)} to get an instance. */ public static final class RangeInfo { private static final int MAX_POOL_SIZE = 10; diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java new file mode 100644 index 000000000000..bbd3f2b0b15f --- /dev/null +++ b/core/java/android/webkit/CacheManager.java @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2006 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 android.webkit; + +import android.content.Context; +import android.net.http.Headers; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + + +/** + * Manages the HTTP cache used by an application's {@link WebView} instances. + * @deprecated Access to the HTTP cache will be removed in a future release. + * @hide Since {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} + */ +// The class CacheManager provides the persistent cache of content that is +// received over the network. The component handles parsing of HTTP headers and +// utilizes the relevant cache headers to determine if the content should be +// stored and if so, how long it is valid for. Network requests are provided to +// this component and if they can not be resolved by the cache, the HTTP headers +// are attached, as appropriate, to the request for revalidation of content. The +// class also manages the cache size. +// +// CacheManager may only be used if your activity contains a WebView. +@Deprecated +public final class CacheManager { + /** + * Represents a resource stored in the HTTP cache. Instances of this class + * can be obtained by calling + * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>))}. + * + * @deprecated Access to the HTTP cache will be removed in a future release. + */ + @Deprecated + public static class CacheResult { + // these fields are saved to the database + int httpStatusCode; + long contentLength; + long expires; + String expiresString; + String localPath; + String lastModified; + String etag; + String mimeType; + String location; + String encoding; + String contentdisposition; + String crossDomain; + + // these fields are NOT saved to the database + InputStream inStream; + OutputStream outStream; + File outFile; + + /** + * Gets the status code of this cache entry. + * + * @return the status code of this cache entry + */ + public int getHttpStatusCode() { + return httpStatusCode; + } + + /** + * Gets the content length of this cache entry. + * + * @return the content length of this cache entry + */ + public long getContentLength() { + return contentLength; + } + + /** + * Gets the path of the file used to store the content of this cache + * entry, relative to the base directory of the cache. See + * {@link CacheManager#getCacheFileBaseDir CacheManager.getCacheFileBaseDir()}. + * + * @return the path of the file used to store this cache entry + */ + public String getLocalPath() { + return localPath; + } + + /** + * Gets the expiry date of this cache entry, expressed in milliseconds + * since midnight, January 1, 1970 UTC. + * + * @return the expiry date of this cache entry + */ + public long getExpires() { + return expires; + } + + /** + * Gets the expiry date of this cache entry, expressed as a string. + * + * @return the expiry date of this cache entry + * + */ + public String getExpiresString() { + return expiresString; + } + + /** + * Gets the date at which this cache entry was last modified, expressed + * as a string. + * + * @return the date at which this cache entry was last modified + */ + public String getLastModified() { + return lastModified; + } + + /** + * Gets the entity tag of this cache entry. + * + * @return the entity tag of this cache entry + */ + public String getETag() { + return etag; + } + + /** + * Gets the MIME type of this cache entry. + * + * @return the MIME type of this cache entry + */ + public String getMimeType() { + return mimeType; + } + + /** + * Gets the value of the HTTP 'Location' header with which this cache + * entry was received. + * + * @return the HTTP 'Location' header for this cache entry + */ + public String getLocation() { + return location; + } + + /** + * Gets the encoding of this cache entry. + * + * @return the encoding of this cache entry + */ + public String getEncoding() { + return encoding; + } + + /** + * Gets the value of the HTTP 'Content-Disposition' header with which + * this cache entry was received. + * + * @return the HTTP 'Content-Disposition' header for this cache entry + * + */ + public String getContentDisposition() { + return contentdisposition; + } + + /** + * Gets the input stream to the content of this cache entry, to allow + * content to be read. See + * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>)}. + * + * @return an input stream to the content of this cache entry + */ + public InputStream getInputStream() { + return inStream; + } + + /** + * Gets an output stream to the content of this cache entry, to allow + * content to be written. See + * {@link CacheManager#saveCacheFile CacheManager.saveCacheFile(String, CacheResult)}. + * + * @return an output stream to the content of this cache entry + */ + // Note that this is always null for objects returned by getCacheFile()! + public OutputStream getOutputStream() { + return outStream; + } + + + /** + * Sets an input stream to the content of this cache entry. + * + * @param stream an input stream to the content of this cache entry + */ + public void setInputStream(InputStream stream) { + this.inStream = stream; + } + + /** + * Sets the encoding of this cache entry. + * + * @param encoding the encoding of this cache entry + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * @hide + */ + public void setContentLength(long contentLength) { + this.contentLength = contentLength; + } + } + + /** + * Gets the base directory in which the files used to store the contents of + * cache entries are placed. See + * {@link CacheManager.CacheResult#getLocalPath CacheManager.CacheResult.getLocalPath()}. + * + * @return the base directory of the cache + * @deprecated This method no longer has any effect and always returns null. + */ + @Deprecated + public static File getCacheFileBaseDir() { + return null; + } + + /** + * Gets whether the HTTP cache is disabled. + * + * @return true if the HTTP cache is disabled + * @deprecated This method no longer has any effect and always returns false. + */ + @Deprecated + public static boolean cacheDisabled() { + return false; + } + + /** + * Starts a cache transaction. Returns true if this is the only running + * transaction. Otherwise, this transaction is nested inside currently + * running transactions and false is returned. + * + * @return true if this is the only running transaction + * @deprecated This method no longer has any effect and always returns false. + */ + @Deprecated + public static boolean startCacheTransaction() { + return false; + } + + /** + * Ends the innermost cache transaction and returns whether this was the + * only running transaction. + * + * @return true if this was the only running transaction + * @deprecated This method no longer has any effect and always returns false. + */ + @Deprecated + public static boolean endCacheTransaction() { + return false; + } + + /** + * Gets the cache entry for the specified URL, or null if none is found. + * If a non-null value is provided for the HTTP headers map, and the cache + * entry needs validation, appropriate headers will be added to the map. + * The input stream of the CacheEntry object should be closed by the caller + * when access to the underlying file is no longer required. + * + * @param url the URL for which a cache entry is requested + * @param headers a map from HTTP header name to value, to be populated + * for the returned cache entry + * @return the cache entry for the specified URL + * @deprecated This method no longer has any effect and always returns null. + */ + @Deprecated + public static CacheResult getCacheFile(String url, + Map<String, String> headers) { + return null; + } + + /** + * Adds a cache entry to the HTTP cache for the specicifed URL. Also closes + * the cache entry's output stream. + * + * @param url the URL for which the cache entry should be added + * @param cacheResult the cache entry to add + * @deprecated Access to the HTTP cache will be removed in a future release. + */ + @Deprecated + public static void saveCacheFile(String url, CacheResult cacheResult) { + saveCacheFile(url, 0, cacheResult); + } + + static void saveCacheFile(String url, long postIdentifier, + CacheResult cacheRet) { + try { + cacheRet.outStream.close(); + } catch (IOException e) { + return; + } + + // This method is exposed in the public API but the API provides no + // way to obtain a new CacheResult object with a non-null output + // stream ... + // - CacheResult objects returned by getCacheFile() have a null + // output stream. + // - new CacheResult objects have a null output stream and no + // setter is provided. + // Since this method throws a null pointer exception in this case, + // it is effectively useless from the point of view of the public + // API. + // + // With the Chromium HTTP stack we continue to throw the same + // exception for 'backwards compatibility' with the Android HTTP + // stack. + // + // This method is not used from within this package, and for public API + // use, we should already have thrown an exception above. + assert false; + } +} diff --git a/core/java/android/webkit/PluginData.java b/core/java/android/webkit/PluginData.java new file mode 100644 index 000000000000..88fc9b70cc7a --- /dev/null +++ b/core/java/android/webkit/PluginData.java @@ -0,0 +1,141 @@ +/* + * 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 android.webkit; + +import java.io.InputStream; +import java.util.Map; + +/** + * This class encapsulates the content generated by a plugin. The + * data itself is meant to be loaded into webkit via the + * PluginContentLoader class, which needs to be able to construct an + * HTTP response. For this, it needs a stream with the response body, + * the length of the body, the response headers, and the response + * status code. The PluginData class is the container for all these + * parts. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ +@Deprecated +public final class PluginData { + /** + * The content stream. + */ + private InputStream mStream; + /** + * The content length. + */ + private long mContentLength; + /** + * The associated HTTP response headers stored as a map of + * lowercase header name to [ unmodified header name, header value]. + * TODO: This design was always a hack. Remove (involves updating + * the Gears C++ side). + */ + private Map<String, String[]> mHeaders; + + /** + * The associated HTTP response code. + */ + private int mStatusCode; + + /** + * Creates a PluginData instance. + * + * @param stream The stream that supplies content for the plugin. + * @param length The length of the plugin content. + * @param headers The response headers. Map of + * lowercase header name to [ unmodified header name, header value] + * @param length The HTTP response status code. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public PluginData( + InputStream stream, + long length, + Map<String, String[]> headers, + int code) { + mStream = stream; + mContentLength = length; + mHeaders = headers; + mStatusCode = code; + } + + /** + * Returns the input stream that contains the plugin content. + * + * @return An InputStream instance with the plugin content. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public InputStream getInputStream() { + return mStream; + } + + /** + * Returns the length of the plugin content. + * + * @return the length of the plugin content. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public long getContentLength() { + return mContentLength; + } + + /** + * Returns the HTTP response headers associated with the plugin + * content. + * + * @return A Map<String, String[]> containing all headers. The + * mapping is 'lowercase header name' to ['unmodified header + * name', header value]. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public Map<String, String[]> getHeaders() { + return mHeaders; + } + + /** + * Returns the HTTP status code for the response. + * + * @return The HTTP statue code, e.g 200. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public int getStatusCode() { + return mStatusCode; + } +} diff --git a/core/java/android/webkit/UrlInterceptHandler.java b/core/java/android/webkit/UrlInterceptHandler.java new file mode 100644 index 000000000000..59fc0cba1fd3 --- /dev/null +++ b/core/java/android/webkit/UrlInterceptHandler.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 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 android.webkit; + +import android.webkit.CacheManager.CacheResult; +import android.webkit.PluginData; +import java.util.Map; + +/** + * @hide + * @deprecated This interface was inteded to be used by Gears. Since Gears was + * deprecated, so is this class. + */ +@Deprecated +public interface UrlInterceptHandler { + + /** + * Given an URL, returns the CacheResult which contains the + * surrogate response for the request, or null if the handler is + * not interested. + * + * @param url URL string. + * @param headers The headers associated with the request. May be null. + * @return The CacheResult containing the surrogate response. + * + * @hide + * @deprecated Do not use, this interface is deprecated. + */ + @Deprecated + public CacheResult service(String url, Map<String, String> headers); + + /** + * Given an URL, returns the PluginData which contains the + * surrogate response for the request, or null if the handler is + * not interested. + * + * @param url URL string. + * @param headers The headers associated with the request. May be null. + * @return The PluginData containing the surrogate response. + * + * @hide + * @deprecated Do not use, this interface is deprecated. + */ + @Deprecated + public PluginData getPluginData(String url, Map<String, String> headers); +} diff --git a/core/java/android/webkit/UrlInterceptRegistry.java b/core/java/android/webkit/UrlInterceptRegistry.java new file mode 100644 index 000000000000..bdf6747aa5a4 --- /dev/null +++ b/core/java/android/webkit/UrlInterceptRegistry.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2008 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 android.webkit; + +import android.webkit.CacheManager.CacheResult; +import android.webkit.PluginData; +import android.webkit.UrlInterceptHandler; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; + +/** + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ +@Deprecated +public final class UrlInterceptRegistry { + + private final static String LOGTAG = "intercept"; + + private static boolean mDisabled = false; + + private static LinkedList mHandlerList; + + private static synchronized LinkedList getHandlers() { + if(mHandlerList == null) + mHandlerList = new LinkedList<UrlInterceptHandler>(); + return mHandlerList; + } + + /** + * set the flag to control whether url intercept is enabled or disabled + * + * @param disabled true to disable the cache + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public static synchronized void setUrlInterceptDisabled(boolean disabled) { + mDisabled = disabled; + } + + /** + * get the state of the url intercept, enabled or disabled + * + * @return return if it is disabled + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public static synchronized boolean urlInterceptDisabled() { + return mDisabled; + } + + /** + * Register a new UrlInterceptHandler. This handler will be called + * before any that were previously registered. + * + * @param handler The new UrlInterceptHandler object + * @return true if the handler was not previously registered. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public static synchronized boolean registerHandler( + UrlInterceptHandler handler) { + if (!getHandlers().contains(handler)) { + getHandlers().addFirst(handler); + return true; + } else { + return false; + } + } + + /** + * Unregister a previously registered UrlInterceptHandler. + * + * @param handler A previously registered UrlInterceptHandler. + * @return true if the handler was found and removed from the list. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public static synchronized boolean unregisterHandler( + UrlInterceptHandler handler) { + return getHandlers().remove(handler); + } + + /** + * Given an url, returns the CacheResult of the first + * UrlInterceptHandler interested, or null if none are. + * + * @return A CacheResult containing surrogate content. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public static synchronized CacheResult getSurrogate( + String url, Map<String, String> headers) { + if (urlInterceptDisabled()) { + return null; + } + Iterator iter = getHandlers().listIterator(); + while (iter.hasNext()) { + UrlInterceptHandler handler = (UrlInterceptHandler) iter.next(); + CacheResult result = handler.service(url, headers); + if (result != null) { + return result; + } + } + return null; + } + + /** + * Given an url, returns the PluginData of the first + * UrlInterceptHandler interested, or null if none are or if + * intercepts are disabled. + * + * @return A PluginData instance containing surrogate content. + * + * @hide + * @deprecated This class was intended to be used by Gears. Since Gears was + * deprecated, so is this class. + */ + @Deprecated + public static synchronized PluginData getPluginData( + String url, Map<String, String> headers) { + if (urlInterceptDisabled()) { + return null; + } + Iterator iter = getHandlers().listIterator(); + while (iter.hasNext()) { + UrlInterceptHandler handler = (UrlInterceptHandler) iter.next(); + PluginData data = handler.getPluginData(url, headers); + if (data != null) { + return data; + } + } + return null; + } +} diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java index e94cf18ca709..fdc06a64556a 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java @@ -16,6 +16,10 @@ package com.android.keyguard; +import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardSecurityModel.SecurityMode; +import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState; + import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; @@ -51,9 +55,6 @@ import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.RemoteViews.OnClickHandler; -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState; import java.io.File; import java.lang.ref.WeakReference; @@ -279,7 +280,7 @@ public class KeyguardHostView extends KeyguardViewBase { if (newState != mTransportState) { mTransportState = newState; if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed"); - KeyguardHostView.this.postShowAppropriateWidgetPage(); + KeyguardHostView.this.post(mSwitchPageRunnable); } } @Override @@ -291,7 +292,7 @@ public class KeyguardHostView extends KeyguardViewBase { if (newState != mTransportState) { mTransportState = newState; if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed"); - KeyguardHostView.this.postShowAppropriateWidgetPage(); + KeyguardHostView.this.post(mSwitchPageRunnable); } } } @@ -495,7 +496,6 @@ public class KeyguardHostView extends KeyguardViewBase { @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - removeCallbacks(mSwitchPageRunnable); mAppWidgetHost.stopListening(); KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks); } @@ -1438,7 +1438,7 @@ public class KeyguardHostView extends KeyguardViewBase { mAppWidgetToShow = ss.appWidgetToShow; setInsets(ss.insets); if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState); - postShowAppropriateWidgetPage(); + post(mSwitchPageRunnable); } @Override @@ -1471,22 +1471,13 @@ public class KeyguardHostView extends KeyguardViewBase { } } - void showAppropriateWidgetPage() { + private void showAppropriateWidgetPage() { int state = mTransportState; ensureTransportPresentOrRemoved(state); - if (mAppWidgetContainer.isLayoutRequested()) { - postShowAppropriateWidgetPage(); - return; - } int pageToShow = getAppropriateWidgetPage(state); mAppWidgetContainer.setCurrentPage(pageToShow); } - void postShowAppropriateWidgetPage() { - removeCallbacks(mSwitchPageRunnable); - post(mSwitchPageRunnable); - } - /** * Examines the current state and adds the transport to the widget pager when the state changes. * diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java index e07e0d077756..704af6e3aa39 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java @@ -40,6 +40,7 @@ import android.view.accessibility.AccessibilityManager; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.TextClock; + import com.android.internal.widget.LockPatternUtils; import java.util.ArrayList; diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java index ee5ff16f78cc..787b59ab400d 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java @@ -40,6 +40,7 @@ import android.os.Message; import android.os.RemoteException; import android.print.ILayoutResultCallback; import android.print.IPrintDocumentAdapter; +import android.print.IPrintDocumentAdapterObserver; import android.print.IWriteResultCallback; import android.print.PageRange; import android.print.PrintAttributes; @@ -201,6 +202,14 @@ public class PrintJobConfigActivity extends Activity { throw new IllegalArgumentException("PrintDocumentAdapter cannot be null"); } + try { + IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter) + .setObserver(new PrintDocumentAdapterObserver(this)); + } catch (RemoteException re) { + finish(); + return; + } + PrintAttributes attributes = printJob.getAttributes(); if (attributes != null) { mCurrPrintAttributes.copyFrom(attributes); @@ -249,27 +258,29 @@ public class PrintJobConfigActivity extends Activity { // We can safely do the work in here since at this point // the system is bound to our (spooler) process which // guarantees that this process will not be killed. - if (mController.hasStarted()) { + if (mController != null && mController.hasStarted()) { mController.finish(); } - if (mEditor.isPrintConfirmed() && mController.isFinished()) { - mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId, - PrintJobInfo.STATE_QUEUED, null); + if (mEditor != null && mEditor.isPrintConfirmed() + && mController != null && mController.isFinished()) { + mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId, + PrintJobInfo.STATE_QUEUED, null); } else { mSpoolerProvider.getSpooler().setPrintJobState(mPrintJobId, PrintJobInfo.STATE_CANCELED, null); } - mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0); if (mGeneratingPrintJobDialog != null) { mGeneratingPrintJobDialog.dismiss(); mGeneratingPrintJobDialog = null; } + mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0); mSpoolerProvider.destroy(); super.onDestroy(); } public boolean onTouchEvent(MotionEvent event) { - if (!mEditor.isPrintConfirmed() && mEditor.shouldCloseOnTouch(event)) { + if (mController != null && mEditor != null && + !mEditor.isPrintConfirmed() && mEditor.shouldCloseOnTouch(event)) { if (!mController.isWorking()) { PrintJobConfigActivity.this.finish(); } @@ -287,17 +298,19 @@ public class PrintJobConfigActivity extends Activity { } public boolean onKeyUp(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - if (mEditor.isShwoingGeneratingPrintJobUi()) { - return true; - } - if (event.isTracking() && !event.isCanceled()) { - if (!mController.isWorking()) { - PrintJobConfigActivity.this.finish(); + if (mController != null && mEditor != null) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (mEditor.isShwoingGeneratingPrintJobUi()) { + return true; + } + if (event.isTracking() && !event.isCanceled()) { + if (!mController.isWorking()) { + PrintJobConfigActivity.this.finish(); + } } + mEditor.cancel(); + return true; } - mEditor.cancel(); - return true; } return super.onKeyUp(keyCode, event); } @@ -2701,4 +2714,32 @@ public class PrintJobConfigActivity extends Activity { /* do noting - we are in the same process */ } } + + private static final class PrintDocumentAdapterObserver + extends IPrintDocumentAdapterObserver.Stub { + private final WeakReference<PrintJobConfigActivity> mWeakActvity; + + public PrintDocumentAdapterObserver(PrintJobConfigActivity activity) { + mWeakActvity = new WeakReference<PrintJobConfigActivity>(activity); + } + + @Override + public void onDestroy() { + final PrintJobConfigActivity activity = mWeakActvity.get(); + if (activity != null) { + activity.mController.mHandler.post(new Runnable() { + @Override + public void run() { + if (activity.mController != null) { + activity.mController.cancel(); + } + if (activity.mEditor != null) { + activity.mEditor.cancel(); + } + activity.finish(); + } + }); + } + } + } } |