summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml120
-rw-r--r--core/java/android/content/Intent.java9
-rw-r--r--core/java/android/content/SyncStorageEngine.java2
-rw-r--r--core/java/android/os/StrictMode.java5
-rw-r--r--core/java/android/os/storage/IMountService.java20
-rw-r--r--core/java/android/os/storage/IObbActionListener.java19
-rw-r--r--core/java/android/os/storage/OnObbStateChangeListener.java58
-rw-r--r--core/java/android/os/storage/StorageManager.java129
-rw-r--r--core/java/android/provider/Telephony.java5
-rw-r--r--core/java/android/view/MenuItem.java6
-rw-r--r--core/java/android/view/ViewConfiguration.java6
-rw-r--r--core/java/android/view/ViewGroup.java3
-rw-r--r--core/java/android/view/WindowManager.java13
-rw-r--r--core/java/android/webkit/DebugFlags.java2
-rw-r--r--core/java/android/webkit/WebSettings.java37
-rw-r--r--core/java/android/webkit/WebTextView.java4
-rw-r--r--core/java/android/webkit/WebView.java232
-rw-r--r--core/java/android/widget/AbsListView.java31
-rw-r--r--core/java/android/widget/TextView.java35
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl1
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl3
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuItemView.java8
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java24
-rw-r--r--core/jni/android/graphics/Canvas.cpp38
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--core/res/res/values/arrays.xml3
-rwxr-xr-xcore/res/res/values/attrs.xml20
-rw-r--r--core/res/res/values/config.xml8
-rw-r--r--core/tests/coretests/src/com/android/server/MountServiceTests.java145
-rw-r--r--docs/html/guide/guide_toc.cs8
-rw-r--r--docs/html/guide/practices/design/responsiveness.jd4
-rw-r--r--graphics/java/android/graphics/utils/BoundaryPatch.java173
-rw-r--r--graphics/java/android/renderscript/RenderScript.java19
-rw-r--r--graphics/java/android/renderscript/RenderScriptGL.java17
-rw-r--r--graphics/jni/android_renderscript_RenderScript.cpp26
-rw-r--r--include/storage/IMountService.h4
-rw-r--r--include/storage/IObbActionListener.h2
-rw-r--r--include/surfaceflinger/ISurfaceComposer.h5
-rw-r--r--libs/hwui/FontRenderer.cpp6
-rw-r--r--libs/hwui/OpenGLRenderer.cpp7
-rw-r--r--libs/hwui/OpenGLRenderer.h3
-rw-r--r--libs/hwui/ProgramCache.cpp2
-rw-r--r--libs/hwui/ProgramCache.h2
-rw-r--r--libs/hwui/Rect.h8
-rw-r--r--libs/rs/RenderScript.h17
-rw-r--r--libs/rs/rsContext.cpp236
-rw-r--r--libs/rs/rsContext.h8
-rw-r--r--libs/rs/rsProgramStore.cpp19
-rw-r--r--libs/storage/IMountService.cpp8
-rw-r--r--libs/storage/IObbActionListener.cpp7
-rw-r--r--libs/surfaceflinger_client/ISurfaceComposer.cpp15
-rw-r--r--libs/ui/InputDispatcher.cpp16
-rw-r--r--native/android/storage_manager.cpp93
-rw-r--r--native/include/android/storage_manager.h69
-rw-r--r--packages/SystemUI/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java30
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java6
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java67
-rw-r--r--preloaded-classes1
-rw-r--r--services/java/com/android/server/MountService.java508
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java4
-rw-r--r--services/java/com/android/server/PackageManagerService.java2
-rw-r--r--services/java/com/android/server/PowerManagerService.java380
-rw-r--r--services/java/com/android/server/StatusBarManagerService.java33
-rw-r--r--services/jni/Android.mk3
-rw-r--r--services/jni/com_android_server_InputManager.cpp108
-rw-r--r--services/jni/com_android_server_PowerManagerService.cpp13
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp18
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp234
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h4
-rw-r--r--telephony/java/com/android/internal/telephony/CallManager.java8
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfo.java8
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java26
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SIMRecords.java6
-rw-r--r--telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java4
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhone.java19
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java13
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java16
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java18
-rw-r--r--voip/java/com/android/server/sip/SipService.java1
87 files changed, 1968 insertions, 1396 deletions
diff --git a/api/current.xml b/api/current.xml
index fde5d21..1d84c39 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -143602,9 +143602,97 @@
>
<parameter name="path" type="java.lang.String">
</parameter>
-<parameter name="state" type="java.lang.String">
+<parameter name="state" type="int">
</parameter>
</method>
+<field name="ERROR_ALREADY_MOUNTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="24"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_COULD_NOT_MOUNT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="21"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_COULD_NOT_UNMOUNT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="22"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_INTERNAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="20"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_NOT_MOUNTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="23"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_PERMISSION_DENIED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="25"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MOUNTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="UNMOUNTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="StorageEventListener"
extends="java.lang.Object"
@@ -143708,8 +143796,6 @@
>
<parameter name="filename" type="java.lang.String">
</parameter>
-<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
-</exception>
</method>
<method name="isUsbMassStorageConnected"
return="boolean"
@@ -198458,6 +198544,17 @@
visibility="public"
>
</field>
+<field name="SHOW_AS_ACTION_WITH_TEXT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</interface>
<interface name="MenuItem.OnMenuItemClickListener"
abstract="true"
@@ -225433,6 +225530,23 @@
</parameter>
<parameter name="offset" type="int">
</parameter>
+<parameter name="duration" type="int">
+</parameter>
+</method>
+<method name="smoothScrollToPositionFromTop"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="position" type="int">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
</method>
<method name="verifyDrawable"
return="boolean"
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 4d0b8b0..a486ccc 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5282,7 +5282,14 @@ public class Intent implements Parcelable, Cloneable {
b.append(' ');
}
first = false;
- b.append("dat=").append(mData);
+ b.append("dat=");
+ if (mData.getScheme().equalsIgnoreCase("tel")) {
+ b.append("tel:xxx-xxx-xxxx");
+ } else if (mData.getScheme().equalsIgnoreCase("smsto")) {
+ b.append("smsto:xxx-xxx-xxxx");
+ } else {
+ b.append(mData);
+ }
}
if (mType != null) {
if (!first) {
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 0639573..bae6ad3 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -411,7 +411,7 @@ public class SyncStorageEngine extends Handler {
}
public void setSyncAutomatically(Account account, String providerName, boolean sync) {
- Log.d(TAG, "setSyncAutomatically: " + account + ", provider " + providerName
+ Log.d(TAG, "setSyncAutomatically: " + /*account +*/ ", provider " + providerName
+ " -> " + sync);
synchronized (mAuthorities) {
AuthorityInfo authority = getOrCreateAuthorityLocked(account, providerName, -1, false);
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index c185007..de5b7b9 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -38,7 +38,10 @@ import java.util.HashMap;
* network access on the application's main thread, where UI
* operations are received and animations take place. Keeping disk
* and network operations off the main thread makes for much smoother,
- * more responsive applications.
+ * more responsive applications. By keeping your application's main thread
+ * responsive, you also prevent
+ * <a href="{@docRoot}guide/practices/design/responsiveness.html">ANR dialogs</a>
+ * from being shown to users.
*
* <p class="note">Note that even though an Android device's disk is
* often on flash memory, many devices run a filesystem on top of that
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 57e208a..3a2add4 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -484,7 +484,7 @@ public interface IMountService extends IInterface {
* IObbActionListener to inform it of the terminal state of the
* call.
*/
- public void mountObb(String filename, String key, IObbActionListener token)
+ public void mountObb(String filename, String key, IObbActionListener token, int nonce)
throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -493,6 +493,7 @@ public interface IMountService extends IInterface {
_data.writeString(filename);
_data.writeString(key);
_data.writeStrongBinder((token != null ? token.asBinder() : null));
+ _data.writeInt(nonce);
mRemote.transact(Stub.TRANSACTION_mountObb, _data, _reply, 0);
_reply.readException();
} finally {
@@ -508,8 +509,8 @@ public interface IMountService extends IInterface {
* IObbActionListener to inform it of the terminal state of the
* call.
*/
- public void unmountObb(String filename, boolean force, IObbActionListener token)
- throws RemoteException {
+ public void unmountObb(String filename, boolean force, IObbActionListener token,
+ int nonce) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
@@ -517,6 +518,7 @@ public interface IMountService extends IInterface {
_data.writeString(filename);
_data.writeInt((force ? 1 : 0));
_data.writeStrongBinder((token != null ? token.asBinder() : null));
+ _data.writeInt(nonce);
mRemote.transact(Stub.TRANSACTION_unmountObb, _data, _reply, 0);
_reply.readException();
} finally {
@@ -876,7 +878,9 @@ public interface IMountService extends IInterface {
key = data.readString();
IObbActionListener observer;
observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
- mountObb(filename, key, observer);
+ int nonce;
+ nonce = data.readInt();
+ mountObb(filename, key, observer, nonce);
reply.writeNoException();
return true;
}
@@ -888,7 +892,9 @@ public interface IMountService extends IInterface {
force = 0 != data.readInt();
IObbActionListener observer;
observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
- unmountObb(filename, force, observer);
+ int nonce;
+ nonce = data.readInt();
+ unmountObb(filename, force, observer, nonce);
reply.writeNoException();
return true;
}
@@ -1007,7 +1013,7 @@ public interface IMountService extends IInterface {
* MountService will call back to the supplied IObbActionListener to inform
* it of the terminal state of the call.
*/
- public void mountObb(String filename, String key, IObbActionListener token)
+ public void mountObb(String filename, String key, IObbActionListener token, int nonce)
throws RemoteException;
/*
@@ -1051,7 +1057,7 @@ public interface IMountService extends IInterface {
* MountService will call back to the supplied IObbActionListener to inform
* it of the terminal state of the call.
*/
- public void unmountObb(String filename, boolean force, IObbActionListener token)
+ public void unmountObb(String filename, boolean force, IObbActionListener token, int nonce)
throws RemoteException;
/*
diff --git a/core/java/android/os/storage/IObbActionListener.java b/core/java/android/os/storage/IObbActionListener.java
index 2c098ac..d6fa58a 100644
--- a/core/java/android/os/storage/IObbActionListener.java
+++ b/core/java/android/os/storage/IObbActionListener.java
@@ -69,9 +69,11 @@ public interface IObbActionListener extends IInterface {
data.enforceInterface(DESCRIPTOR);
String filename;
filename = data.readString();
- String status;
- status = data.readString();
- this.onObbResult(filename, status);
+ int nonce;
+ nonce = data.readInt();
+ int status;
+ status = data.readInt();
+ this.onObbResult(filename, nonce, status);
reply.writeNoException();
return true;
}
@@ -101,13 +103,15 @@ public interface IObbActionListener extends IInterface {
* on
* @param returnCode status of the operation
*/
- public void onObbResult(String filename, String status) throws RemoteException {
+ public void onObbResult(String filename, int nonce, int status)
+ throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(filename);
- _data.writeString(status);
+ _data.writeInt(nonce);
+ _data.writeInt(status);
mRemote.transact(Stub.TRANSACTION_onObbResult, _data, _reply, 0);
_reply.readException();
} finally {
@@ -124,7 +128,8 @@ public interface IObbActionListener extends IInterface {
* Return from an OBB action result.
*
* @param filename the path to the OBB the operation was performed on
- * @param returnCode status of the operation
+ * @param nonce identifier that is meaningful to the receiver
+ * @param status status code as defined in {@link OnObbStateChangeListener}
*/
- public void onObbResult(String filename, String status) throws RemoteException;
+ public void onObbResult(String filename, int nonce, int status) throws RemoteException;
}
diff --git a/core/java/android/os/storage/OnObbStateChangeListener.java b/core/java/android/os/storage/OnObbStateChangeListener.java
index a2d0a56..950195b 100644
--- a/core/java/android/os/storage/OnObbStateChangeListener.java
+++ b/core/java/android/os/storage/OnObbStateChangeListener.java
@@ -17,15 +17,69 @@
package android.os.storage;
/**
- * Used for receiving notifications from {@link StorageManager}.
+ * Used for receiving notifications from {@link StorageManager} about OBB file
+ * states.
*/
public abstract class OnObbStateChangeListener {
+
+ /**
+ * The OBB container is now mounted and ready for use. Returned in status
+ * messages from calls made via {@link StorageManager}
+ */
+ public static final int MOUNTED = 1;
+
+ /**
+ * The OBB container is now unmounted and not usable. Returned in status
+ * messages from calls made via {@link StorageManager}
+ */
+ public static final int UNMOUNTED = 2;
+
+ /**
+ * There was an internal system error encountered while trying to mount the
+ * OBB. Returned in status messages from calls made via
+ * {@link StorageManager}
+ */
+ public static final int ERROR_INTERNAL = 20;
+
+ /**
+ * The OBB could not be mounted by the system. Returned in status messages
+ * from calls made via {@link StorageManager}
+ */
+ public static final int ERROR_COULD_NOT_MOUNT = 21;
+
+ /**
+ * The OBB could not be unmounted. This most likely indicates that a file is
+ * in use on the OBB. Returned in status messages from calls made via
+ * {@link StorageManager}
+ */
+ public static final int ERROR_COULD_NOT_UNMOUNT = 22;
+
+ /**
+ * A call was made to unmount the OBB when it was not mounted. Returned in
+ * status messages from calls made via {@link StorageManager}
+ */
+ public static final int ERROR_NOT_MOUNTED = 23;
+
+ /**
+ * The OBB has already been mounted. Returned in status messages from calls
+ * made via {@link StorageManager}
+ */
+ public static final int ERROR_ALREADY_MOUNTED = 24;
+
+ /**
+ * The current application does not have permission to use this OBB because
+ * the OBB indicates it's owned by a different package or the key used to
+ * open it is incorrect. Returned in status messages from calls made via
+ * {@link StorageManager}
+ */
+ public static final int ERROR_PERMISSION_DENIED = 25;
+
/**
* Called when an OBB has changed states.
*
* @param path path to the OBB file the state change has happened on
* @param state the current state of the OBB
*/
- public void onObbStateChange(String path, String state) {
+ public void onObbStateChange(String path, int state) {
}
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 8554ece..fb76937 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -22,12 +22,13 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* StorageManager is the interface to the systems storage service. The storage
@@ -69,7 +70,12 @@ public class StorageManager
/*
* List of our listeners
*/
- private ArrayList<ListenerDelegate> mListeners = new ArrayList<ListenerDelegate>();
+ private List<ListenerDelegate> mListeners = new ArrayList<ListenerDelegate>();
+
+ /*
+ * Next available nonce
+ */
+ final private AtomicInteger mNextNonce = new AtomicInteger(0);
private class MountServiceBinderListener extends IMountServiceListener.Stub {
public void onUsbMassStorageConnectionChanged(boolean available) {
@@ -93,57 +99,38 @@ public class StorageManager
private final ObbActionListener mObbActionListener = new ObbActionListener();
private class ObbActionListener extends IObbActionListener.Stub {
- private List<WeakReference<ObbListenerDelegate>> mListeners = new LinkedList<WeakReference<ObbListenerDelegate>>();
+ private SparseArray<ObbListenerDelegate> mListeners = new SparseArray<ObbListenerDelegate>();
@Override
- public void onObbResult(String filename, String status) throws RemoteException {
+ public void onObbResult(String filename, int nonce, int status) throws RemoteException {
+ final ObbListenerDelegate delegate;
synchronized (mListeners) {
- final Iterator<WeakReference<ObbListenerDelegate>> iter = mListeners.iterator();
- while (iter.hasNext()) {
- final WeakReference<ObbListenerDelegate> ref = iter.next();
-
- final ObbListenerDelegate delegate = (ref == null) ? null : ref.get();
- if (delegate == null) {
- iter.remove();
- continue;
- }
-
- delegate.sendObbStateChanged(filename, status);
+ delegate = mListeners.get(nonce);
+ if (delegate != null) {
+ mListeners.remove(nonce);
}
}
- }
- public void addListener(OnObbStateChangeListener listener) {
- if (listener == null) {
- return;
+ if (delegate != null) {
+ delegate.sendObbStateChanged(filename, status);
}
+ }
- synchronized (mListeners) {
- final Iterator<WeakReference<ObbListenerDelegate>> iter = mListeners.iterator();
- while (iter.hasNext()) {
- final WeakReference<ObbListenerDelegate> ref = iter.next();
-
- final ObbListenerDelegate delegate = (ref == null) ? null : ref.get();
- if (delegate == null) {
- iter.remove();
- continue;
- }
-
- /*
- * If we're already in the listeners, we don't need to be in
- * there again.
- */
- if (listener.equals(delegate.getListener())) {
- return;
- }
- }
+ public int addListener(OnObbStateChangeListener listener) {
+ final ObbListenerDelegate delegate = new ObbListenerDelegate(listener);
- final ObbListenerDelegate delegate = new ObbListenerDelegate(listener);
- mListeners.add(new WeakReference<ObbListenerDelegate>(delegate));
+ synchronized (mListeners) {
+ mListeners.put(delegate.nonce, delegate);
}
+
+ return delegate.nonce;
}
}
+ private int getNextNonce() {
+ return mNextNonce.getAndIncrement();
+ }
+
/**
* Private class containing sender and receiver code for StorageEvents.
*/
@@ -151,7 +138,10 @@ public class StorageManager
private final WeakReference<OnObbStateChangeListener> mObbEventListenerRef;
private final Handler mHandler;
+ private final int nonce;
+
ObbListenerDelegate(OnObbStateChangeListener listener) {
+ nonce = getNextNonce();
mObbEventListenerRef = new WeakReference<OnObbStateChangeListener>(listener);
mHandler = new Handler(mTgtLooper) {
@Override
@@ -180,7 +170,7 @@ public class StorageManager
return mObbEventListenerRef.get();
}
- void sendObbStateChanged(String path, String state) {
+ void sendObbStateChanged(String path, int state) {
ObbStateChangedStorageEvent e = new ObbStateChangedStorageEvent(path, state);
mHandler.sendMessage(e.getMessage());
}
@@ -191,9 +181,10 @@ public class StorageManager
*/
private class ObbStateChangedStorageEvent extends StorageEvent {
public final String path;
- public final String state;
- public ObbStateChangedStorageEvent(String path, String state) {
+ public final int state;
+
+ public ObbStateChangedStorageEvent(String path, int state) {
super(EVENT_OBB_STATE_CHANGED);
this.path = path;
this.state = state;
@@ -410,10 +401,8 @@ public class StorageManager
* <p>
* The OBB will remain mounted for as long as the StorageManager reference
* is held by the application. As soon as this reference is lost, the OBBs
- * in use will be unmounted. The {@link OnObbStateChangeListener} registered with
- * this call will receive all further OBB-related events until it goes out
- * of scope. If the caller is not interested in whether the call succeeds,
- * the <code>listener</code> may be specified as <code>null</code>.
+ * in use will be unmounted. The {@link OnObbStateChangeListener} registered
+ * with this call will receive the success or failure of this operation.
* <p>
* <em>Note:</em> you can only mount OBB files for which the OBB tag on the
* file matches a package ID that is owned by the calling program's UID.
@@ -423,12 +412,21 @@ public class StorageManager
* @param filename the path to the OBB file
* @param key secret used to encrypt the OBB; may be <code>null</code> if no
* encryption was used on the OBB.
+ * @param listener will receive the success or failure of the operation
* @return whether the mount call was successfully queued or not
*/
public boolean mountObb(String filename, String key, OnObbStateChangeListener listener) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename cannot be null");
+ }
+
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+
try {
- mObbActionListener.addListener(listener);
- mMountService.mountObb(filename, key, mObbActionListener);
+ final int nonce = mObbActionListener.addListener(listener);
+ mMountService.mountObb(filename, key, mObbActionListener, nonce);
return true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to mount OBB", e);
@@ -442,10 +440,8 @@ public class StorageManager
* <code>force</code> flag is true, it will kill any application needed to
* unmount the given OBB (even the calling application).
* <p>
- * The {@link OnObbStateChangeListener} registered with this call will receive all
- * further OBB-related events until it goes out of scope. If the caller is
- * not interested in whether the call succeeded, the listener may be
- * specified as <code>null</code>.
+ * The {@link OnObbStateChangeListener} registered with this call will
+ * receive the success or failure of this operation.
* <p>
* <em>Note:</em> you can only mount OBB files for which the OBB tag on the
* file matches a package ID that is owned by the calling program's UID.
@@ -456,12 +452,21 @@ public class StorageManager
* @param filename path to the OBB file
* @param force whether to kill any programs using this in order to unmount
* it
+ * @param listener will receive the success or failure of the operation
* @return whether the unmount call was successfully queued or not
*/
public boolean unmountObb(String filename, boolean force, OnObbStateChangeListener listener) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename cannot be null");
+ }
+
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+
try {
- mObbActionListener.addListener(listener);
- mMountService.unmountObb(filename, force, mObbActionListener);
+ final int nonce = mObbActionListener.addListener(listener);
+ mMountService.unmountObb(filename, force, mObbActionListener, nonce);
return true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to mount OBB", e);
@@ -476,7 +481,11 @@ public class StorageManager
* @param filename path to OBB image
* @return true if OBB is mounted; false if not mounted or on error
*/
- public boolean isObbMounted(String filename) throws IllegalArgumentException {
+ public boolean isObbMounted(String filename) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename cannot be null");
+ }
+
try {
return mMountService.isObbMounted(filename);
} catch (RemoteException e) {
@@ -496,12 +505,14 @@ public class StorageManager
* not mounted or exception encountered trying to read status
*/
public String getMountedObbPath(String filename) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename cannot be null");
+ }
+
try {
return mMountService.getMountedObbPath(filename);
} catch (RemoteException e) {
Log.e(TAG, "Failed to find mounted path for OBB", e);
- } catch (IllegalArgumentException e) {
- Log.d(TAG, "Couldn't read OBB file", e);
}
return null;
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index fa5cd8b..803446f 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1215,9 +1215,8 @@ public final class Telephony {
}
Uri uri = uriBuilder.build();
- if (DEBUG) {
- Log.v(TAG, "getOrCreateThreadId uri: " + uri);
- }
+ //if (DEBUG) Log.v(TAG, "getOrCreateThreadId uri: " + uri);
+
Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
uri, ID_PROJECTION, null, null, null);
if (DEBUG) {
diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java
index 8b9d659..99da43b 100644
--- a/core/java/android/view/MenuItem.java
+++ b/core/java/android/view/MenuItem.java
@@ -45,6 +45,12 @@ public interface MenuItem {
* A good rule of thumb is to have no more than 2 items set to always show at a time.
*/
public static final int SHOW_AS_ACTION_ALWAYS = 2;
+
+ /**
+ * When this item is in the action bar, always show it with a text label even if
+ * it also has an icon specified.
+ */
+ public static final int SHOW_AS_ACTION_WITH_TEXT = 4;
/**
* Interface definition for a callback to be invoked when a menu item is
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index f413475..85981d2 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -37,7 +37,11 @@ public class ViewConfiguration {
* @hide
*/
public static final float ALPHA_THRESHOLD = 0.5f / PANEL_BIT_DEPTH;
-
+ /**
+ * @hide
+ */
+ public static final float ALPHA_THRESHOLD_INT = 0x7f / PANEL_BIT_DEPTH;
+
/**
* Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
* pixels
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b1db5ca..4eea2d2 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2188,7 +2188,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
float alpha = child.getAlpha();
// Bail out early if the view does not need to be drawn
- if (alpha <= ViewConfiguration.ALPHA_THRESHOLD && (child.mPrivateFlags & ALPHA_SET) == 0) {
+ if (alpha <= ViewConfiguration.ALPHA_THRESHOLD && (child.mPrivateFlags & ALPHA_SET) == 0 &&
+ !(child instanceof SurfaceView)) {
return more;
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index eddd04e..7cb4671 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -611,6 +611,19 @@ public interface WindowManager extends ViewManager {
* {@hide} */
public static final int FLAG_SPLIT_TOUCH = 0x00800000;
+ /**
+ * Flag for a window belonging to an activity that responds to {@link KeyEvent#KEYCODE_MENU}
+ * and therefore needs a Menu key. For devices where Menu is a physical button this flag is
+ * ignored, but on devices where the Menu key is drawn in software it may be hidden unless
+ * this flag is set.
+ *
+ * (Note that Action Bars, when available, are the preferred way to offer additional
+ * functions otherwise accessed via an options menu.)
+ *
+ * {@hide}
+ */
+ public static final int FLAG_NEEDS_MENU_KEY = 0x01000000;
+
/** Window flag: *sigh* The lock screen wants to continue running its
* animation while it is fading. A kind-of hack to allow this. Maybe
* in the future we just make this the default behavior.
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index dca52f6..8e25395 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -32,8 +32,6 @@ class DebugFlags {
public static final boolean CALLBACK_PROXY = false;
public static final boolean COOKIE_MANAGER = false;
public static final boolean COOKIE_SYNC_MANAGER = false;
- public static final boolean DRAG_TRACKER = false;
- public static final String DRAG_TRACKER_LOGTAG = "skia";
public static final boolean FRAME_LOADER = false;
public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
public static final boolean LOAD_LISTENER = false;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index c42c601..4689740 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -226,20 +226,41 @@ public class WebSettings {
public static class AutoFillProfile {
private String mFullName;
private String mEmailAddress;
-
- public AutoFillProfile() {
- }
-
- public AutoFillProfile(String fullName, String email) {
+ private String mCompanyName;
+ private String mAddressLine1;
+ private String mAddressLine2;
+ private String mCity;
+ private String mState;
+ private String mZipCode;
+ private String mCountry;
+ private String mPhoneNumber;
+
+ public AutoFillProfile(String fullName, String email,
+ String companyName, String addressLine1, String addressLine2,
+ String city, String state, String zipCode, String country,
+ String phoneNumber) {
mFullName = fullName;
mEmailAddress = email;
+ mCompanyName = companyName;
+ mAddressLine1 = addressLine1;
+ mAddressLine2 = addressLine2;
+ mCity = city;
+ mState = state;
+ mZipCode = zipCode;
+ mCountry = country;
+ mPhoneNumber = phoneNumber;
}
- public void setFullName(String fullName) { mFullName = fullName; }
- public void setEmailAddress(String emailAddress) { mEmailAddress = emailAddress; }
-
public String getFullName() { return mFullName; }
public String getEmailAddress() { return mEmailAddress; }
+ public String getCompanyName() { return mCompanyName; }
+ public String getAddressLine1() { return mAddressLine1; }
+ public String getAddressLine2() { return mAddressLine2; }
+ public String getCity() { return mCity; }
+ public String getState() { return mState; }
+ public String getZipCode() { return mZipCode; }
+ public String getCountry() { return mCountry; }
+ public String getPhoneNumber() { return mPhoneNumber; }
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 1aff170..812e126 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -583,6 +583,7 @@ import java.util.ArrayList;
return false;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
+ super.onTouchEvent(event);
if (mHasPerformedLongClick) {
mGotTouchDown = false;
return false;
@@ -780,9 +781,6 @@ import java.util.ArrayList;
// webkit's drawing.
setWillNotDraw(!inPassword);
setBackgroundDrawable(inPassword ? mBackground : null);
- // For non-password fields, avoid the invals from TextView's blinking
- // cursor
- setCursorVisible(inPassword);
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index ea29d5e..a7e51a4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -33,7 +33,6 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.DrawFilter;
-import android.graphics.Interpolator;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Picture;
@@ -48,7 +47,6 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.os.SystemClock;
import android.provider.Settings;
import android.speech.tts.TextToSpeech;
import android.text.Selection;
@@ -93,8 +91,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
@@ -309,8 +305,6 @@ public class WebView extends AbsoluteLayout
implements ViewTreeObserver.OnGlobalFocusChangeListener,
ViewGroup.OnHierarchyChangeListener {
- // enable debug output for drag trackers
- private static final boolean DEBUG_DRAG_TRACKER = false;
// if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
// the screen all-the-time. Good for profiling our drawing code
static private final boolean AUTO_REDRAW_HACK = false;
@@ -3464,17 +3458,7 @@ public class WebView extends AbsoluteLayout
if (mTitleBar != null) {
canvas.translate(0, (int) mTitleBar.getHeight());
}
- if (mDragTrackerHandler == null) {
- drawContent(canvas);
- } else {
- if (!mDragTrackerHandler.draw(canvas)) {
- // sometimes the tracker doesn't draw, even though its active
- drawContent(canvas);
- }
- if (mDragTrackerHandler.isFinished()) {
- mDragTrackerHandler = null;
- }
- }
+ drawContent(canvas);
canvas.restoreToCount(saveCount);
// Now draw the shadow.
@@ -4724,207 +4708,6 @@ public class WebView extends AbsoluteLayout
private static final float MAX_SLOPE_FOR_DIAG = 1.5f;
private static final int MIN_BREAK_SNAP_CROSS_DISTANCE = 80;
- private static int sign(float x) {
- return x > 0 ? 1 : (x < 0 ? -1 : 0);
- }
-
- // if the page can scroll <= this value, we won't allow the drag tracker
- // to have any effect.
- private static final int MIN_SCROLL_AMOUNT_TO_DISABLE_DRAG_TRACKER = 4;
-
- private class DragTrackerHandler {
- private final DragTracker mProxy;
- private final float mStartY, mStartX;
- private final float mMinDY, mMinDX;
- private final float mMaxDY, mMaxDX;
- private float mCurrStretchY, mCurrStretchX;
- private int mSX, mSY;
- private Interpolator mInterp;
- private float[] mXY = new float[2];
-
- // inner (non-state) classes can't have enums :(
- private static final int DRAGGING_STATE = 0;
- private static final int ANIMATING_STATE = 1;
- private static final int FINISHED_STATE = 2;
- private int mState;
-
- public DragTrackerHandler(float x, float y, DragTracker proxy) {
- mProxy = proxy;
-
- int docBottom = computeVerticalScrollRange() + getTitleHeight();
- int viewTop = getScrollY();
- int viewBottom = viewTop + getHeight();
-
- mStartY = y;
- mMinDY = -viewTop;
- mMaxDY = docBottom - viewBottom;
-
- if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
- Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, " dragtracker y= " + y +
- " up/down= " + mMinDY + " " + mMaxDY);
- }
-
- int docRight = computeHorizontalScrollRange();
- int viewLeft = getScrollX();
- int viewRight = viewLeft + getWidth();
- mStartX = x;
- mMinDX = -viewLeft;
- mMaxDX = docRight - viewRight;
-
- mState = DRAGGING_STATE;
- mProxy.onStartDrag(x, y);
-
- // ensure we buildBitmap at least once
- mSX = -99999;
- }
-
- private float computeStretch(float delta, float min, float max) {
- float stretch = 0;
- if (max - min > MIN_SCROLL_AMOUNT_TO_DISABLE_DRAG_TRACKER) {
- if (delta < min) {
- stretch = delta - min;
- } else if (delta > max) {
- stretch = delta - max;
- }
- }
- return stretch;
- }
-
- public void dragTo(float x, float y) {
- float sy = computeStretch(mStartY - y, mMinDY, mMaxDY);
- float sx = computeStretch(mStartX - x, mMinDX, mMaxDX);
-
- if ((mSnapScrollMode & SNAP_X) != 0) {
- sy = 0;
- } else if ((mSnapScrollMode & SNAP_Y) != 0) {
- sx = 0;
- }
-
- if (mCurrStretchX != sx || mCurrStretchY != sy) {
- mCurrStretchX = sx;
- mCurrStretchY = sy;
- if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
- Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, "---- stretch " + sx +
- " " + sy);
- }
- if (mProxy.onStretchChange(sx, sy)) {
- invalidate();
- }
- }
- }
-
- public void stopDrag() {
- final int DURATION = 200;
- int now = (int)SystemClock.uptimeMillis();
- mInterp = new Interpolator(2);
- mXY[0] = mCurrStretchX;
- mXY[1] = mCurrStretchY;
- // float[] blend = new float[] { 0.5f, 0, 0.75f, 1 };
- float[] blend = new float[] { 0, 0.5f, 0.75f, 1 };
- mInterp.setKeyFrame(0, now, mXY, blend);
- float[] zerozero = new float[] { 0, 0 };
- mInterp.setKeyFrame(1, now + DURATION, zerozero, null);
- mState = ANIMATING_STATE;
-
- if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
- Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, "----- stopDrag, starting animation");
- }
- }
-
- // Call this after each draw. If it ruturns null, the tracker is done
- public boolean isFinished() {
- return mState == FINISHED_STATE;
- }
-
- private int hiddenHeightOfTitleBar() {
- return getTitleHeight() - getVisibleTitleHeight();
- }
-
- // need a way to know if 565 or 8888 is the right config for
- // capturing the display and giving it to the drag proxy
- private Bitmap.Config offscreenBitmapConfig() {
- // hard code 565 for now
- return Bitmap.Config.RGB_565;
- }
-
- /* If the tracker draws, then this returns true, otherwise it will
- return false, and draw nothing.
- */
- public boolean draw(Canvas canvas) {
- if (mCurrStretchX != 0 || mCurrStretchY != 0) {
- int sx = getScrollX();
- int sy = getScrollY() - hiddenHeightOfTitleBar();
- if (mSX != sx || mSY != sy) {
- buildBitmap(sx, sy);
- mSX = sx;
- mSY = sy;
- }
-
- if (mState == ANIMATING_STATE) {
- Interpolator.Result result = mInterp.timeToValues(mXY);
- if (result == Interpolator.Result.FREEZE_END) {
- mState = FINISHED_STATE;
- return false;
- } else {
- mProxy.onStretchChange(mXY[0], mXY[1]);
- invalidate();
- // fall through to the draw
- }
- }
- int count = canvas.save(Canvas.MATRIX_SAVE_FLAG);
- canvas.translate(sx, sy);
- mProxy.onDraw(canvas);
- canvas.restoreToCount(count);
- return true;
- }
- if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
- Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, " -- draw false " +
- mCurrStretchX + " " + mCurrStretchY);
- }
- return false;
- }
-
- private void buildBitmap(int sx, int sy) {
- int w = getWidth();
- int h = getViewHeight();
- Bitmap bm = Bitmap.createBitmap(w, h, offscreenBitmapConfig());
- Canvas canvas = new Canvas(bm);
- canvas.translate(-sx, -sy);
- drawContent(canvas);
-
- if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
- Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, "--- buildBitmap " + sx +
- " " + sy + " " + w + " " + h);
- }
- mProxy.onBitmapChange(bm);
- }
- }
-
- /** @hide */
- public static class DragTracker {
- public void onStartDrag(float x, float y) {}
- public boolean onStretchChange(float sx, float sy) {
- // return true to have us inval the view
- return false;
- }
- public void onStopDrag() {}
- public void onBitmapChange(Bitmap bm) {}
- public void onDraw(Canvas canvas) {}
- }
-
- /** @hide */
- public DragTracker getDragTracker() {
- return mDragTracker;
- }
-
- /** @hide */
- public void setDragTracker(DragTracker tracker) {
- mDragTracker = tracker;
- }
-
- private DragTracker mDragTracker;
- private DragTrackerHandler mDragTrackerHandler;
-
private boolean hitFocusedPlugin(int contentX, int contentY) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "nativeFocusIsPlugin()=" + nativeFocusIsPlugin());
@@ -5330,10 +5113,6 @@ public class WebView extends AbsoluteLayout
startDrag();
}
- if (mDragTrackerHandler != null) {
- mDragTrackerHandler.dragTo(x, y);
- }
-
// do pan
if (mTouchMode != TOUCH_DRAG_LAYER_MODE) {
int newScrollX = pinLocX(mScrollX + deltaX);
@@ -5607,9 +5386,6 @@ public class WebView extends AbsoluteLayout
mLastTouchTime = eventTime;
mVelocityTracker = VelocityTracker.obtain();
mSnapScrollMode = SNAP_NONE;
- if (mDragTracker != null) {
- mDragTrackerHandler = new DragTrackerHandler(x, y, mDragTracker);
- }
}
private void startDrag() {
@@ -5642,9 +5418,6 @@ public class WebView extends AbsoluteLayout
}
private void stopTouch() {
- if (mDragTrackerHandler != null) {
- mDragTrackerHandler.stopDrag();
- }
// we also use mVelocityTracker == null to tell us that we are
// not "moving around", so we can take the slower/prettier
// mode in the drawing code
@@ -5655,9 +5428,6 @@ public class WebView extends AbsoluteLayout
}
private void cancelTouch() {
- if (mDragTrackerHandler != null) {
- mDragTrackerHandler.stopDrag();
- }
// we also use mVelocityTracker == null to tell us that we are
// not "moving around", so we can take the slower/prettier
// mode in the drawing code
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4d77a7a..f295c41 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3050,6 +3050,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
void startWithOffset(int position, int offset) {
+ startWithOffset(position, offset, SCROLL_DURATION);
+ }
+
+ void startWithOffset(int position, int offset, int duration) {
mTargetPos = position;
mOffsetFromTop = offset;
mBoundPos = INVALID_POSITION;
@@ -3068,14 +3072,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
} else {
// On-screen, just scroll.
final int targetTop = getChildAt(position - firstPos).getTop();
- smoothScrollBy(targetTop - offset, SCROLL_DURATION);
+ smoothScrollBy(targetTop - offset, duration);
return;
}
// Estimate how many screens we should travel
final float screenTravelCount = (float) viewTravelCount / childCount;
- mScrollDuration = screenTravelCount < 1 ? (int) (screenTravelCount * SCROLL_DURATION) :
- (int) (SCROLL_DURATION / screenTravelCount);
+ mScrollDuration = screenTravelCount < 1 ? (int) (screenTravelCount * duration) :
+ (int) (duration / screenTravelCount);
mLastSeenPos = INVALID_POSITION;
post(this);
@@ -3284,7 +3288,26 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
mPositionScroller.start(position);
}
-
+
+ /**
+ * Smoothly scroll to the specified adapter position. The view will scroll
+ * such that the indicated position is displayed <code>offset</code> pixels from
+ * the top edge of the view. If this is impossible, (e.g. the offset would scroll
+ * the first or last item beyond the boundaries of the list) it will get as close
+ * as possible. The scroll will take <code>duration</code> milliseconds to complete.
+ *
+ * @param position Position to scroll to
+ * @param offset Desired distance in pixels of <code>position</code> from the top
+ * of the view when scrolling is finished
+ * @param duration Number of milliseconds to use for the scroll
+ */
+ public void smoothScrollToPositionFromTop(int position, int offset, int duration) {
+ if (mPositionScroller == null) {
+ mPositionScroller = new PositionScroller();
+ }
+ mPositionScroller.startWithOffset(position, offset, duration);
+ }
+
/**
* Smoothly scroll to the specified adapter position. The view will scroll
* such that the indicated position is displayed <code>offset</code> pixels from
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 57fd251..09a19cd 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.view.ViewConfiguration;
import com.android.internal.util.FastMath;
import com.android.internal.widget.EditableInputConnection;
@@ -97,6 +98,7 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
+import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.view.ViewRoot;
@@ -3954,6 +3956,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected void onDraw(Canvas canvas) {
+ if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return;
+
restartMarqueeIfNeeded();
// Draw the background for this view
@@ -6943,8 +6947,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void prepareCursorControllers() {
+ boolean windowSupportsHandles = false;
+
+ ViewGroup.LayoutParams params = getRootView().getLayoutParams();
+ if (params instanceof WindowManager.LayoutParams) {
+ WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
+ windowSupportsHandles = windowParams.type < WindowManager.LayoutParams.FIRST_SUB_WINDOW
+ || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
+ }
+
// TODO Add an extra android:cursorController flag to disable the controller?
- if (mCursorVisible && mLayout != null) {
+ if (windowSupportsHandles && mCursorVisible && mLayout != null) {
if (mInsertionPointCursorController == null) {
mInsertionPointCursorController = new InsertionPointCursorController();
}
@@ -6952,7 +6965,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mInsertionPointCursorController = null;
}
- if (textCanBeSelected() && mLayout != null) {
+ if (windowSupportsHandles && textCanBeSelected() && mLayout != null) {
if (mSelectionModifierCursorController == null) {
mSelectionModifierCursorController = new SelectionModifierCursorController();
}
@@ -7047,6 +7060,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected float getLeftFadingEdgeStrength() {
+ if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return 0.0f;
if (mEllipsize == TextUtils.TruncateAt.MARQUEE) {
if (mMarquee != null && !mMarquee.isStopped()) {
final Marquee marquee = mMarquee;
@@ -7073,6 +7087,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected float getRightFadingEdgeStrength() {
+ if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return 0.0f;
if (mEllipsize == TextUtils.TruncateAt.MARQUEE) {
if (mMarquee != null && !mMarquee.isStopped()) {
final Marquee marquee = mMarquee;
@@ -7708,28 +7723,36 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (canSelectText()) {
menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
setIcon(com.android.internal.R.drawable.ic_menu_select_all).
- setAlphabeticShortcut('a');
+ setAlphabeticShortcut('a').
+ setShowAsAction(
+ MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
atLeastOne = true;
}
if (canCut()) {
menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
setIcon(styledAttributes.getResourceId(R.styleable.Theme_actionModeCutDrawable, 0)).
- setAlphabeticShortcut('x');
+ setAlphabeticShortcut('x').
+ setShowAsAction(
+ MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
atLeastOne = true;
}
if (canCopy()) {
menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
setIcon(styledAttributes.getResourceId(R.styleable.Theme_actionModeCopyDrawable, 0)).
- setAlphabeticShortcut('c');
+ setAlphabeticShortcut('c').
+ setShowAsAction(
+ MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
atLeastOne = true;
}
if (canPaste()) {
menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
setIcon(styledAttributes.getResourceId(R.styleable.Theme_actionModePasteDrawable, 0)).
- setAlphabeticShortcut('v');
+ setAlphabeticShortcut('v').
+ setShowAsAction(
+ MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
atLeastOne = true;
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index e884af8..34a5b11 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -31,5 +31,6 @@ oneway interface IStatusBar
void animateExpand();
void animateCollapse();
void setLightsOn(boolean on);
+ void setMenuKeyVisible(boolean visible);
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 0763f5e..90f4d48 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -31,12 +31,13 @@ interface IStatusBarService
void setIconVisibility(String slot, boolean visible);
void removeIcon(String slot);
void setActiveWindowIsFullscreen(boolean fullscreen);
+ void setMenuKeyVisible(boolean visible);
// ---- Methods below are for use by the status bar policy services ----
// You need the STATUS_BAR_SERVICE permission
void registerStatusBar(IStatusBar callbacks, out StatusBarIconList iconList,
out List<IBinder> notificationKeys, out List<StatusBarNotification> notifications,
- out boolean[] lightsOn);
+ out boolean[] switches);
void onPanelRevealed();
void onNotificationClick(String pkg, String tag, int id);
void onNotificationError(String pkg, String tag, int id,
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index f97bfb4..d5f69ba 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -21,13 +21,13 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
-import android.widget.FrameLayout;
import android.widget.ImageButton;
+import android.widget.LinearLayout;
/**
* @hide
*/
-public class ActionMenuItemView extends FrameLayout
+public class ActionMenuItemView extends LinearLayout
implements MenuView.ItemView, View.OnClickListener {
private static final String TAG = "ActionMenuItemView";
@@ -65,8 +65,6 @@ public class ActionMenuItemView extends FrameLayout
public void initialize(MenuItemImpl itemData, int menuType) {
mItemData = itemData;
- setClickable(true);
- setFocusable(true);
setIcon(itemData.getIcon());
setTitle(itemData.getTitle()); // Title only takes effect if there is no icon
setId(itemData.getItemId());
@@ -128,7 +126,7 @@ public class ActionMenuItemView extends FrameLayout
// populate accessibility description with title
setContentDescription(title);
- if (mImageButton.getDrawable() == null) {
+ if (mImageButton.getDrawable() == null || mItemData.showsTextAsAction()) {
mTextButton.setText(mTitle);
mTextButton.setVisibility(VISIBLE);
}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 42f9771..8eee360 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -38,6 +38,10 @@ import com.android.internal.view.menu.MenuView.ItemView;
public final class MenuItemImpl implements MenuItem {
private static final String TAG = "MenuItemImpl";
+ private static final int SHOW_AS_ACTION_MASK = SHOW_AS_ACTION_NEVER |
+ SHOW_AS_ACTION_IF_ROOM |
+ SHOW_AS_ACTION_ALWAYS;
+
private final int mId;
private final int mGroup;
private final int mCategoryOrder;
@@ -649,11 +653,11 @@ public final class MenuItemImpl implements MenuItem {
}
public boolean requestsActionButton() {
- return mShowAsAction == SHOW_AS_ACTION_IF_ROOM;
+ return (mShowAsAction & SHOW_AS_ACTION_IF_ROOM) == SHOW_AS_ACTION_IF_ROOM;
}
public boolean requiresActionButton() {
- return mShowAsAction == SHOW_AS_ACTION_ALWAYS;
+ return (mShowAsAction & SHOW_AS_ACTION_ALWAYS) == SHOW_AS_ACTION_ALWAYS;
}
public void setIsActionButton(boolean isActionButton) {
@@ -664,7 +668,23 @@ public final class MenuItemImpl implements MenuItem {
}
}
+ public boolean showsTextAsAction() {
+ return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT;
+ }
+
public void setShowAsAction(int actionEnum) {
+ switch (actionEnum & SHOW_AS_ACTION_MASK) {
+ case SHOW_AS_ACTION_ALWAYS:
+ case SHOW_AS_ACTION_IF_ROOM:
+ case SHOW_AS_ACTION_NEVER:
+ // Looks good!
+ break;
+
+ default:
+ // Mutually exclusive options selected!
+ throw new IllegalArgumentException("SHOW_AS_ACTION_ALWAYS, SHOW_AS_ACTION_IF_ROOM,"
+ + " and SHOW_AS_ACTION_NEVER are mutually exclusive.");
+ }
mShowAsAction = actionEnum;
mMenu.onItemActionRequestChanged(this);
}
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index bf150a9..8944d47 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -26,9 +26,6 @@
#include "SkShader.h"
#include "SkTemplates.h"
-#include "SkBoundaryPatch.h"
-#include "SkMeshUtils.h"
-
#include "TextLayout.h"
#include "unicode/ubidi.h"
@@ -968,40 +965,6 @@ static JNINativeMethod gCanvasMethods[] = {
///////////////////////////////////////////////////////////////////////////////
-static void BoundaryPatch_computeCubic(JNIEnv* env, jobject, jfloatArray jpts,
- int texW, int texH, int rows, int cols,
- jfloatArray jverts, jshortArray jidx) {
- AutoJavaFloatArray ptsArray(env, jpts, 24, kRO_JNIAccess);
-
- int vertCount = rows * cols;
- AutoJavaFloatArray vertsArray(env, jverts, vertCount * 4, kRW_JNIAccess);
- SkPoint* verts = (SkPoint*)vertsArray.ptr();
- SkPoint* texs = verts + vertCount;
-
- int idxCount = (rows - 1) * (cols - 1) * 6;
- AutoJavaShortArray idxArray(env, jidx, idxCount, kRW_JNIAccess);
- uint16_t* idx = (uint16_t*)idxArray.ptr(); // cast from int16_t*
-
- SkCubicBoundary cubic;
- memcpy(cubic.fPts, ptsArray.ptr(), 12 * sizeof(SkPoint));
-
- SkBoundaryPatch patch;
- patch.setBoundary(&cubic);
- // generate our verts
- patch.evalPatch(verts, rows, cols);
-
- SkMeshIndices mesh;
- // generate our texs and idx
- mesh.init(texs, idx, texW, texH, rows, cols);
-}
-
-static JNINativeMethod gBoundaryPatchMethods[] = {
- {"nativeComputeCubicPatch", "([FIIII[F[S)V",
- (void*)BoundaryPatch_computeCubic },
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
#include <android_runtime/AndroidRuntime.h>
#define REG(env, name, array) \
@@ -1013,7 +976,6 @@ int register_android_graphics_Canvas(JNIEnv* env) {
int result;
REG(env, "android/graphics/Canvas", gCanvasMethods);
- REG(env, "android/graphics/utils/BoundaryPatch", gBoundaryPatchMethods);
return result;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 85e8a60..73341fe 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1341,10 +1341,6 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
- <activity android:name="com.android.internal.app.ExternalMediaFormatActivity"
- android:theme="@style/Theme.Dialog.Alert"
- android:excludeFromRecents="true">
- </activity>
<activity android:name="android.accounts.ChooseAccountActivity"
android:excludeFromRecents="true"
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 830fb01..3e546a1 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -63,6 +63,9 @@
<item>@drawable/scrollbar_handle_horizontal</item>
<item>@drawable/scrollbar_handle_vertical</item>
<item>@drawable/spinner_dropdown_background</item>
+ <item>@drawable/text_select_handle_left</item>
+ <item>@drawable/text_select_handle_middle</item>
+ <item>@drawable/text_select_handle_right</item>
<item>@drawable/title_bar</item>
<item>@drawable/title_bar_shadow</item>
<!-- Visual lock screen -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 1ea6fc4..ef6d6cb 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3590,10 +3590,22 @@
<attr name="onClick" />
<!-- How this item should display in the Action Bar, if present. -->
- <attr name="showAsAction" format="enum">
- <enum name="never" value="0" />
- <enum name="ifRoom" value="1" />
- <enum name="always" value="2" />
+ <attr name="showAsAction">
+ <!-- Never show this item in an action bar, show it in the overflow menu instead.
+ Mutually exclusive with "ifRoom" and "always". -->
+ <flag name="never" value="0" />
+ <!-- Show this item in an action bar if there is room for it as determined
+ by the system. Favor this option over "always" where possible.
+ Mutually exclusive with "never" and "always". -->
+ <flag name="ifRoom" value="1" />
+ <!-- Always show this item in an actionbar, even if it would override
+ the system's limits of how much stuff to put there. This may make
+ your action bar look bad on some screens. In most cases you should
+ use "ifRoom" instead. Mutually exclusive with "ifRoom" and "never". -->
+ <flag name="always" value="2" />
+ <!-- When this item is shown as an action in the action bar, show a text
+ label with it even if it has an icon representation. -->
+ <flag name="withText" value="4" />
</attr>
<!-- An optional layout to be used as an action view.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index eed7e73..de2b930 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -174,9 +174,15 @@
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">false</bool>
+ <!-- Don't name config resources like this. It should look like config_annoyDianne -->
+ <bool name="config_annoy_dianne">true</bool>
+
<!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
<bool name="config_unplugTurnsOnScreen">false</bool>
+ <!-- If this is true, the screen will fade off. -->
+ <bool name="config_animateScreenLights">true</bool>
+
<!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
<!-- The number of degrees to rotate the display when the keyboard is open. -->
@@ -433,7 +439,7 @@
<string name="gsm_alphabet_default_charset"></string>
<!-- Enables SIP on WIFI only -->
- <bool name="config_sip_wifi_only">false</bool>
+ <bool name="config_sip_wifi_only">true</bool>
<!-- Boolean indicating if restoring network selection should be skipped -->
<!-- The restoring is handled by modem if it is true-->
diff --git a/core/tests/coretests/src/com/android/server/MountServiceTests.java b/core/tests/coretests/src/com/android/server/MountServiceTests.java
index 83e9d18..1f8c92e 100644
--- a/core/tests/coretests/src/com/android/server/MountServiceTests.java
+++ b/core/tests/coretests/src/com/android/server/MountServiceTests.java
@@ -21,7 +21,6 @@ import com.android.frameworks.coretests.R;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
-import android.os.Environment;
import android.os.FileUtils;
import android.os.storage.OnObbStateChangeListener;
import android.os.storage.StorageManager;
@@ -57,17 +56,15 @@ public class MountServiceTests extends AndroidTestCase {
}
}
- private interface CompletableTask {
- public boolean isDone();
- }
+ private static class ObbObserver extends OnObbStateChangeListener {
+ private String path;
- private static class ObbObserver extends OnObbStateChangeListener implements CompletableTask {
- public String path;
- public String state;
+ public int state = -1;
boolean done = false;
@Override
- public void onObbStateChange(String path, String state) {
+ public void onObbStateChange(String path, int state) {
+ Log.d(TAG, "Received message. path=" + path + ", state=" + state);
synchronized (this) {
this.path = path;
this.state = state;
@@ -76,32 +73,43 @@ public class MountServiceTests extends AndroidTestCase {
}
}
+ public String getPath() {
+ assertTrue("Expected ObbObserver to have received a state change.", done);
+ return path;
+ }
+
+ public int getState() {
+ assertTrue("Expected ObbObserver to have received a state change.", done);
+ return state;
+ }
+
public void reset() {
this.path = null;
- this.state = null;
+ this.state = -1;
done = false;
}
public boolean isDone() {
return done;
}
- }
- private boolean waitForCompletion(CompletableTask task) {
- long waitTime = 0;
- synchronized (task) {
- while (!task.isDone() && waitTime < MAX_WAIT_TIME) {
- try {
- task.wait(WAIT_TIME_INCR);
- waitTime += WAIT_TIME_INCR;
- } catch (InterruptedException e) {
- Log.i(TAG, "Interrupted during sleep", e);
+ public boolean waitForCompletion() {
+ long waitTime = 0;
+ synchronized (this) {
+ while (!isDone() && waitTime < MAX_WAIT_TIME) {
+ try {
+ wait(WAIT_TIME_INCR);
+ waitTime += WAIT_TIME_INCR;
+ } catch (InterruptedException e) {
+ Log.i(TAG, "Interrupted during sleep", e);
+ }
}
}
- }
- return task.isDone();
+ return isDone();
+ }
}
+
private File getFilePath(String name) {
final File filesDir = mContext.getFilesDir();
final File outFile = new File(filesDir, name);
@@ -128,23 +136,52 @@ public class MountServiceTests extends AndroidTestCase {
}
private void mountObb(StorageManager sm, final int resource, final File file,
- String expectedState) {
+ int expectedState) {
copyRawToFile(resource, file);
- ObbObserver observer = new ObbObserver();
+ final ObbObserver observer = new ObbObserver();
assertTrue("mountObb call on " + file.getPath() + " should succeed",
sm.mountObb(file.getPath(), null, observer));
assertTrue("Mount should have completed",
- waitForCompletion(observer));
+ observer.waitForCompletion());
+
+ if (expectedState == OnObbStateChangeListener.MOUNTED) {
+ assertTrue("OBB should be mounted", sm.isObbMounted(file.getPath()));
+ }
assertEquals("Actual file and resolved file should be the same",
- file.getPath(), observer.path);
+ file.getPath(), observer.getPath());
+
+ assertEquals(expectedState, observer.getState());
+ }
+
+ private ObbObserver mountObbWithoutWait(final StorageManager sm, final int resource,
+ final File file) {
+ copyRawToFile(resource, file);
+
+ final ObbObserver observer = new ObbObserver();
+ assertTrue("mountObb call on " + file.getPath() + " should succeed", sm.mountObb(file
+ .getPath(), null, observer));
+
+ return observer;
+ }
- assertEquals(expectedState, observer.state);
+ private void waitForObbActionCompletion(final StorageManager sm, final File file,
+ final ObbObserver observer, int expectedState, boolean checkPath) {
+ assertTrue("Mount should have completed", observer.waitForCompletion());
+
+ assertTrue("OBB should be mounted", sm.isObbMounted(file.getPath()));
+
+ if (checkPath) {
+ assertEquals("Actual file and resolved file should be the same", file.getPath(),
+ observer.getPath());
+ }
+
+ assertEquals(expectedState, observer.getState());
}
- private String checkMountedPath(StorageManager sm, File file) {
+ private String checkMountedPath(final StorageManager sm, final File file) {
final String mountPath = sm.getMountedObbPath(file.getPath());
assertStartsWith("Path should be in " + OBB_MOUNT_PREFIX,
OBB_MOUNT_PREFIX,
@@ -152,13 +189,21 @@ public class MountServiceTests extends AndroidTestCase {
return mountPath;
}
- private void unmountObb(StorageManager sm, final File outFile) {
- ObbObserver observer = new ObbObserver();
+ private void unmountObb(final StorageManager sm, final File file, int expectedState) {
+ final ObbObserver observer = new ObbObserver();
+
assertTrue("unmountObb call on test1.obb should succeed",
- sm.unmountObb(outFile.getPath(), false, observer));
+ sm.unmountObb(file.getPath(),
+ false, observer));
assertTrue("Unmount should have completed",
- waitForCompletion(observer));
+ observer.waitForCompletion());
+
+ assertEquals(expectedState, observer.getState());
+
+ if (expectedState == OnObbStateChangeListener.UNMOUNTED) {
+ assertFalse("OBB should not be mounted", sm.isObbMounted(file.getPath()));
+ }
}
@LargeTest
@@ -167,7 +212,9 @@ public class MountServiceTests extends AndroidTestCase {
final File outFile = getFilePath("test1.obb");
- mountObb(sm, R.raw.test1, outFile, Environment.MEDIA_MOUNTED);
+ mountObb(sm, R.raw.test1, outFile, OnObbStateChangeListener.MOUNTED);
+
+ mountObb(sm, R.raw.test1, outFile, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
final String mountPath = checkMountedPath(sm, outFile);
final File mountDir = new File(mountPath);
@@ -175,7 +222,7 @@ public class MountServiceTests extends AndroidTestCase {
assertTrue("OBB mounted path should be a directory",
mountDir.isDirectory());
- unmountObb(sm, outFile);
+ unmountObb(sm, outFile, OnObbStateChangeListener.UNMOUNTED);
}
@LargeTest
@@ -184,7 +231,7 @@ public class MountServiceTests extends AndroidTestCase {
final File outFile = getFilePath("test1_nosig.obb");
- mountObb(sm, R.raw.test1_nosig, outFile, Environment.MEDIA_BAD_REMOVAL);
+ mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
assertFalse("OBB should not be mounted",
sm.isObbMounted(outFile.getPath()));
@@ -199,7 +246,8 @@ public class MountServiceTests extends AndroidTestCase {
final File outFile = getFilePath("test1_wrongpackage.obb");
- mountObb(sm, R.raw.test1_wrongpackage, outFile, Environment.MEDIA_BAD_REMOVAL);
+ mountObb(sm, R.raw.test1_wrongpackage, outFile,
+ OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
assertFalse("OBB should not be mounted",
sm.isObbMounted(outFile.getPath()));
@@ -207,4 +255,31 @@ public class MountServiceTests extends AndroidTestCase {
assertNull("OBB's mounted path should be null",
sm.getMountedObbPath(outFile.getPath()));
}
+
+ @LargeTest
+ public void testMountAndUnmountTwoObbs() {
+ StorageManager sm = getStorageManager();
+
+ final File file1 = getFilePath("test1.obb");
+ final File file2 = getFilePath("test2.obb");
+
+ ObbObserver oo1 = mountObbWithoutWait(sm, R.raw.test1, file1);
+ ObbObserver oo2 = mountObbWithoutWait(sm, R.raw.test1, file2);
+
+ Log.d(TAG, "Waiting for OBB #1 to complete mount");
+ waitForObbActionCompletion(sm, file1, oo1, OnObbStateChangeListener.MOUNTED, false);
+ Log.d(TAG, "Waiting for OBB #2 to complete mount");
+ waitForObbActionCompletion(sm, file2, oo2, OnObbStateChangeListener.MOUNTED, false);
+
+ final String mountPath1 = checkMountedPath(sm, file1);
+ final File mountDir1 = new File(mountPath1);
+ assertTrue("OBB mounted path should be a directory", mountDir1.isDirectory());
+
+ final String mountPath2 = checkMountedPath(sm, file2);
+ final File mountDir2 = new File(mountPath2);
+ assertTrue("OBB mounted path should be a directory", mountDir2.isDirectory());
+
+ unmountObb(sm, file1, OnObbStateChangeListener.UNMOUNTED);
+ unmountObb(sm, file2, OnObbStateChangeListener.UNMOUNTED);
+ }
}
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 76d5f4f..2b80342 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -279,12 +279,8 @@
</ul>
</li>
<li><a href="<?cs var:toroot?>guide/topics/admin/device-admin.html">
- <span class="en">Device Administration</span></a>
- <span class="new">new!</span>
- </li>
- <li><a href="<?cs var:toroot?>guide/topics/admin/device-admin.html">
- <span class="en">Device Administration</span>
- </a> <span class="new">new!</span><!-- 10/8/10 -->
+ <span class="en">Device Administration</span>
+ </a> <span class="new">new!</span>
</li>
</ul>
</li>
diff --git a/docs/html/guide/practices/design/responsiveness.jd b/docs/html/guide/practices/design/responsiveness.jd
index b811d1b..a00e3aa 100644
--- a/docs/html/guide/practices/design/responsiveness.jd
+++ b/docs/html/guide/practices/design/responsiveness.jd
@@ -99,6 +99,10 @@ responsive to input and thus avoid ANR dialogs caused by the 5 second input
event timeout. These same practices should be followed for any other threads
that display UI, as they are also subject to the same timeouts.</p>
+<p>You can use {@link android.os.StrictMode} to help find potentially
+long running operations such as network or database operations that
+you might accidentally be doing your main thread.</p>
+
<p>The specific constraint on IntentReceiver execution time emphasizes what
they were meant to do: small, discrete amounts of work in the background such
as saving a setting or registering a Notification. So as with other methods
diff --git a/graphics/java/android/graphics/utils/BoundaryPatch.java b/graphics/java/android/graphics/utils/BoundaryPatch.java
deleted file mode 100644
index 1cd5e13..0000000
--- a/graphics/java/android/graphics/utils/BoundaryPatch.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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.graphics.utils;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Shader;
-import android.graphics.Xfermode;
-
-/**
- * @hide
- */
-public class BoundaryPatch {
- private Paint mPaint;
- private Bitmap mTexture;
- private int mRows;
- private int mCols;
- private float[] mCubicPoints;
- private boolean mDirty;
- // these are the computed output of the native code
- private float[] mVerts;
- private short[] mIndices;
-
- public BoundaryPatch() {
- mRows = mCols = 2; // default minimum
- mCubicPoints = new float[24];
- mPaint = new Paint();
- mPaint.setDither(true);
- mPaint.setFilterBitmap(true);
- mDirty = true;
- }
-
- /**
- * Set the boundary to be 4 cubics. This takes a single array of floats,
- * and picks up the 12 pairs starting at offset, and treats them as
- * the x,y coordinates of the cubic control points. The points wrap around
- * a patch, as follows. For documentation purposes, pts[i] will mean the
- * x,y pair of floats, as if pts[] were an array of "points".
- *
- * Top: pts[0..3]
- * Right: pts[3..6]
- * Bottom: pts[6..9]
- * Right: pts[9..11], pts[0]
- *
- * The coordinates are copied from the input array, so subsequent changes
- * to pts[] will not be reflected in the boundary.
- *
- * @param pts The src array of x,y pairs for the boundary cubics
- * @param offset The index into pts of the first pair
- * @param rows The number of points across to approximate the boundary.
- * Must be >= 2, though very large values may slow down drawing
- * @param cols The number of points down to approximate the boundary.
- * Must be >= 2, though very large values may slow down drawing
- */
- public void setCubicBoundary(float[] pts, int offset, int rows, int cols) {
- if (rows < 2 || cols < 2) {
- throw new RuntimeException("rows and cols must be >= 2");
- }
- System.arraycopy(pts, offset, mCubicPoints, 0, 24);
- if (mRows != rows || mCols != cols) {
- mRows = rows;
- mCols = cols;
- }
- mDirty = true;
- }
-
- /**
- * Reference a bitmap texture to be mapped onto the patch.
- */
- public void setTexture(Bitmap texture) {
- if (mTexture != texture) {
- if (mTexture == null ||
- mTexture.getWidth() != texture.getWidth() ||
- mTexture.getHeight() != texture.getHeight()) {
- // need to recompute texture coordinates
- mDirty = true;
- }
- mTexture = texture;
- mPaint.setShader(new BitmapShader(texture,
- Shader.TileMode.CLAMP,
- Shader.TileMode.CLAMP));
- }
- }
-
- /**
- * Return the paint flags for the patch
- */
- public int getPaintFlags() {
- return mPaint.getFlags();
- }
-
- /**
- * Set the paint flags for the patch
- */
- public void setPaintFlags(int flags) {
- mPaint.setFlags(flags);
- }
-
- /**
- * Set the xfermode for the patch
- */
- public void setXfermode(Xfermode mode) {
- mPaint.setXfermode(mode);
- }
-
- /**
- * Set the alpha for the patch
- */
- public void setAlpha(int alpha) {
- mPaint.setAlpha(alpha);
- }
-
- /**
- * Draw the patch onto the canvas.
- *
- * setCubicBoundary() and setTexture() must be called before drawing.
- */
- public void draw(Canvas canvas) {
- if (mDirty) {
- buildCache();
- mDirty = false;
- }
-
- // cut the count in half, since mVerts.length is really the length of
- // the verts[] and tex[] arrays combined
- // (tex[] are stored after verts[])
- int vertCount = mVerts.length >> 1;
- canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertCount,
- mVerts, 0, mVerts, vertCount, null, 0,
- mIndices, 0, mIndices.length,
- mPaint);
- }
-
- private void buildCache() {
- // we need mRows * mCols points, for verts and another set for textures
- // so *2 for going from points -> floats, and *2 for verts and textures
- int vertCount = mRows * mCols * 4;
- if (mVerts == null || mVerts.length != vertCount) {
- mVerts = new float[vertCount];
- }
-
- int indexCount = (mRows - 1) * (mCols - 1) * 6;
- if (mIndices == null || mIndices.length != indexCount) {
- mIndices = new short[indexCount];
- }
-
- nativeComputeCubicPatch(mCubicPoints,
- mTexture.getWidth(), mTexture.getHeight(),
- mRows, mCols, mVerts, mIndices);
- }
-
- private static native
- void nativeComputeCubicPatch(float[] cubicPoints,
- int texW, int texH, int rows, int cols,
- float[] verts, short[] indices);
-}
-
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 0f9ed87..97ce7dc 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -69,9 +69,22 @@ public class RenderScript {
// Methods below are wrapped to protect the non-threadsafe
// lockless fifo.
- native int rsnContextCreateGL(int dev, int ver, boolean useDepth);
- synchronized int nContextCreateGL(int dev, int ver, boolean useDepth) {
- return rsnContextCreateGL(dev, ver, useDepth);
+ native int rsnContextCreateGL(int dev, int ver,
+ int colorMin, int colorPref,
+ int alphaMin, int alphaPref,
+ int depthMin, int depthPref,
+ int stencilMin, int stencilPref,
+ int samplesMin, int samplesPref, float samplesQ);
+ synchronized int nContextCreateGL(int dev, int ver,
+ int colorMin, int colorPref,
+ int alphaMin, int alphaPref,
+ int depthMin, int depthPref,
+ int stencilMin, int stencilPref,
+ int samplesMin, int samplesPref, float samplesQ) {
+ return rsnContextCreateGL(dev, ver, colorMin, colorPref,
+ alphaMin, alphaPref, depthMin, depthPref,
+ stencilMin, stencilPref,
+ samplesMin, samplesPref, samplesQ);
}
native int rsnContextCreate(int dev, int ver);
synchronized int nContextCreate(int dev, int ver) {
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index b60c689..0477d75 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -18,6 +18,7 @@ package android.renderscript;
import java.lang.reflect.Field;
+import android.graphics.PixelFormat;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Config;
@@ -103,7 +104,11 @@ public class RenderScriptGL extends RenderScript {
SurfaceConfig mSurfaceConfig;
public void configureSurface(SurfaceHolder sh) {
- //getHolder().setFormat(PixelFormat.TRANSLUCENT);
+ if (mSurfaceConfig.mAlphaMin > 1) {
+ sh.setFormat(PixelFormat.RGBA_8888);
+ } else {
+ sh.setFormat(PixelFormat.RGBX_8888);
+ }
}
public void checkSurface(SurfaceHolder sh) {
@@ -112,13 +117,17 @@ public class RenderScriptGL extends RenderScript {
public RenderScriptGL(SurfaceConfig sc) {
mSurfaceConfig = new SurfaceConfig(sc);
-
-
mSurface = null;
mWidth = 0;
mHeight = 0;
mDev = nDeviceCreate();
- mContext = nContextCreateGL(mDev, 0, mSurfaceConfig.mDepthMin > 0);
+ mContext = nContextCreateGL(mDev, 0,
+ mSurfaceConfig.mColorMin, mSurfaceConfig.mColorPref,
+ mSurfaceConfig.mAlphaMin, mSurfaceConfig.mAlphaPref,
+ mSurfaceConfig.mDepthMin, mSurfaceConfig.mDepthPref,
+ mSurfaceConfig.mStencilMin, mSurfaceConfig.mStencilPref,
+ mSurfaceConfig.mSamplesMin, mSurfaceConfig.mSamplesPref,
+ mSurfaceConfig.mSamplesQ);
mMessageThread = new MessageThread(this);
mMessageThread.start();
Element.initPredefined(this);
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 014f03b..ce2a40c 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -158,10 +158,26 @@ nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver)
}
static jint
-nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver, jboolean useDepth)
-{
+nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver,
+ int colorMin, int colorPref,
+ int alphaMin, int alphaPref,
+ int depthMin, int depthPref,
+ int stencilMin, int stencilPref,
+ int samplesMin, int samplesPref, float samplesQ)
+{
+ RsSurfaceConfig sc;
+ sc.alphaMin = alphaMin;
+ sc.alphaPref = alphaPref;
+ sc.colorMin = colorMin;
+ sc.colorPref = colorPref;
+ sc.depthMin = depthMin;
+ sc.depthPref = depthPref;
+ sc.samplesMin = samplesMin;
+ sc.samplesPref = samplesPref;
+ sc.samplesQ = samplesQ;
+
LOG_API("nContextCreateGL");
- return (jint)rsContextCreateGL((RsDevice)dev, ver, useDepth);
+ return (jint)rsContextCreateGL((RsDevice)dev, ver, sc);
}
static void
@@ -309,7 +325,7 @@ nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id, jint
rsElementGetSubElements(con, (RsElement)id, ids, names, (uint32_t)dataSize);
- for(jint i = 0; i < dataSize; i ++) {
+ for(jint i = 0; i < dataSize; i++) {
_env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
_env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
}
@@ -1220,7 +1236,7 @@ static JNINativeMethod methods[] = {
// All methods below are thread protected in java.
{"rsnContextCreate", "(II)I", (void*)nContextCreate },
-{"rsnContextCreateGL", "(IIZ)I", (void*)nContextCreateGL },
+{"rsnContextCreateGL", "(IIIIIIIIIIIIF)I", (void*)nContextCreateGL },
{"rsnContextFinish", "(I)V", (void*)nContextFinish },
{"rsnContextSetPriority", "(II)V", (void*)nContextSetPriority },
{"rsnContextSetSurface", "(IIILandroid/view/Surface;)V", (void*)nContextSetSurface },
diff --git a/include/storage/IMountService.h b/include/storage/IMountService.h
index 436fc38..51f9aeb 100644
--- a/include/storage/IMountService.h
+++ b/include/storage/IMountService.h
@@ -61,9 +61,9 @@ public:
virtual void shutdown(const sp<IMountShutdownObserver>& observer) = 0;
virtual void finishMediaUpdate() = 0;
virtual void mountObb(const String16& filename, const String16& key,
- const sp<IObbActionListener>& token) = 0;
+ const sp<IObbActionListener>& token, const int32_t nonce) = 0;
virtual void unmountObb(const String16& filename, const bool force,
- const sp<IObbActionListener>& token) = 0;
+ const sp<IObbActionListener>& token, const int32_t nonce) = 0;
virtual bool isObbMounted(const String16& filename) = 0;
virtual bool getMountedObbPath(const String16& filename, String16& path) = 0;
};
diff --git a/include/storage/IObbActionListener.h b/include/storage/IObbActionListener.h
index 1bedcc6..d78273c 100644
--- a/include/storage/IObbActionListener.h
+++ b/include/storage/IObbActionListener.h
@@ -29,7 +29,7 @@ class IObbActionListener: public IInterface
public:
DECLARE_META_INTERFACE(ObbActionListener);
- virtual void onObbResult(const String16& filename, const String16& status) = 0;
+ virtual void onObbResult(const String16& filename, const int32_t nonce, const int32_t state) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index b181781..ac69a06 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -119,6 +119,8 @@ public:
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth, uint32_t reqHeight) = 0;
+ virtual status_t turnElectronBeamOff(int32_t mode) = 0;
+
/* Signal surfaceflinger that there might be some work to do
* This is an ASYNCHRONOUS call.
*/
@@ -143,7 +145,8 @@ public:
FREEZE_DISPLAY,
UNFREEZE_DISPLAY,
SIGNAL,
- CAPTURE_SCREEN
+ CAPTURE_SCREEN,
+ TURN_ELECTRON_BEAM_OFF
};
virtual status_t onTransact( uint32_t code,
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 8389e56..1b21aee 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -482,9 +482,9 @@ void FontRenderer::initVertexArrayBuffers() {
}
glGenBuffers(1, &mIndexBufferID);
- glBindBuffer(GL_ARRAY_BUFFER, mIndexBufferID);
- glBufferData(GL_ARRAY_BUFFER, indexBufferSizeBytes, indexBufferData, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBufferID);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeBytes, indexBufferData, GL_STATIC_DRAW);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
free(indexBufferData);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 92875b1..2876010 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -455,7 +455,7 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
#endif
// Clear the FBO
- glScissor(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
+ glScissor(0.0f, 0.0f, bounds.getWidth() + 1.0f, bounds.getHeight() + 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
@@ -585,7 +585,10 @@ void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
}
const float* OpenGLRenderer::getMatrix() const {
- return &mSnapshot->transform->data[0];
+ if (mSnapshot->fbo != 0) {
+ return &mSnapshot->transform->data[0];
+ }
+ return &mIdentity.data[0];
}
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index f8828e2..423614b 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -432,6 +432,9 @@ private:
// Misc
GLint mMaxTextureSize;
+ // Indentity matrix
+ const mat4 mIdentity;
+
friend class DisplayListRenderer;
}; // class OpenGLRenderer
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 1eac239..3cd85c8 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -417,7 +417,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
}
// Optimization for common cases
- if (!blendFramebuffer) {
+ if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone) {
bool fast = false;
const bool noShader = !description.hasGradient && !description.hasBitmap;
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index ec9851e..9cb13b3 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -135,7 +135,7 @@ struct ProgramDescription {
GLenum bitmapWrapT;
// Color operations
- int colorOp;
+ ColorModifier colorOp;
SkXfermode::Mode colorMode;
// Framebuffer blending (requires Extensions.hasFramebufferFetch())
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index f03a602..c571ea1 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -149,10 +149,10 @@ struct Rect {
}
void snapToPixelBoundaries() {
- left = floor(left);
- top = floor(top);
- right = ceil(right);
- bottom = ceil(bottom);
+ left = floorf(left);
+ top = floorf(top);
+ right = ceilf(right);
+ bottom = ceilf(bottom);
}
void dump() const {
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 66e27f3..da8edbe 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -55,12 +55,26 @@ enum RsDeviceParam {
RS_DEVICE_PARAM_COUNT
};
+typedef struct {
+ uint32_t colorMin;
+ uint32_t colorPref;
+ uint32_t alphaMin;
+ uint32_t alphaPref;
+ uint32_t depthMin;
+ uint32_t depthPref;
+ uint32_t stencilMin;
+ uint32_t stencilPref;
+ uint32_t samplesMin;
+ uint32_t samplesPref;
+ float samplesQ;
+} RsSurfaceConfig;
+
RsDevice rsDeviceCreate();
void rsDeviceDestroy(RsDevice);
void rsDeviceSetConfig(RsDevice, RsDeviceParam, int32_t value);
RsContext rsContextCreate(RsDevice, uint32_t version);
-RsContext rsContextCreateGL(RsDevice, uint32_t version, bool useDepth);
+RsContext rsContextCreateGL(RsDevice, uint32_t version, RsSurfaceConfig sc);
void rsContextDestroy(RsContext);
uint32_t rsContextGetMessage(RsContext, void *data, size_t *receiveLen, size_t bufferLen, bool wait);
@@ -270,6 +284,7 @@ typedef struct {
} RsScriptCall;
+
#ifndef NO_RS_FUNCS
#include "rsgApiFuncDecl.h"
#endif
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 30add62..be8fb0e 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -18,6 +18,7 @@
#include "rsContext.h"
#include "rsThreadIO.h"
#include <ui/FramebufferNativeWindow.h>
+#include <ui/PixelFormat.h>
#include <ui/EGLUtils.h>
#include <ui/egl/android_natives.h>
@@ -56,8 +57,61 @@ static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
}
}
-void Context::initEGL(bool useGL2)
+void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+
+#define X(VAL) {VAL, #VAL}
+ struct {EGLint attribute; const char* name;} names[] = {
+ X(EGL_BUFFER_SIZE),
+ X(EGL_ALPHA_SIZE),
+ X(EGL_BLUE_SIZE),
+ X(EGL_GREEN_SIZE),
+ X(EGL_RED_SIZE),
+ X(EGL_DEPTH_SIZE),
+ X(EGL_STENCIL_SIZE),
+ X(EGL_CONFIG_CAVEAT),
+ X(EGL_CONFIG_ID),
+ X(EGL_LEVEL),
+ X(EGL_MAX_PBUFFER_HEIGHT),
+ X(EGL_MAX_PBUFFER_PIXELS),
+ X(EGL_MAX_PBUFFER_WIDTH),
+ X(EGL_NATIVE_RENDERABLE),
+ X(EGL_NATIVE_VISUAL_ID),
+ X(EGL_NATIVE_VISUAL_TYPE),
+ X(EGL_SAMPLES),
+ X(EGL_SAMPLE_BUFFERS),
+ X(EGL_SURFACE_TYPE),
+ X(EGL_TRANSPARENT_TYPE),
+ X(EGL_TRANSPARENT_RED_VALUE),
+ X(EGL_TRANSPARENT_GREEN_VALUE),
+ X(EGL_TRANSPARENT_BLUE_VALUE),
+ X(EGL_BIND_TO_TEXTURE_RGB),
+ X(EGL_BIND_TO_TEXTURE_RGBA),
+ X(EGL_MIN_SWAP_INTERVAL),
+ X(EGL_MAX_SWAP_INTERVAL),
+ X(EGL_LUMINANCE_SIZE),
+ X(EGL_ALPHA_MASK_SIZE),
+ X(EGL_COLOR_BUFFER_TYPE),
+ X(EGL_RENDERABLE_TYPE),
+ X(EGL_CONFORMANT),
+ };
+#undef X
+
+ for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+ EGLint value = -1;
+ EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+ EGLint error = eglGetError();
+ if (returnVal && error == EGL_SUCCESS) {
+ LOGV(" %s: %d (0x%x)", names[j].name, value, value);
+ }
+ }
+}
+
+
+void Context::initGLThread()
{
+ pthread_mutex_lock(&gInitMutex);
+ LOGV("initGLThread start %p", this);
+
mEGL.mNumConfigs = -1;
EGLint configAttribs[128];
EGLint *configAttribsPtr = configAttribs;
@@ -69,15 +123,13 @@ void Context::initEGL(bool useGL2)
configAttribsPtr[1] = EGL_WINDOW_BIT;
configAttribsPtr += 2;
- if (useGL2) {
- configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
- configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
- configAttribsPtr += 2;
- }
+ configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
+ configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
+ configAttribsPtr += 2;
- if (mUseDepth) {
+ if (mUserSurfaceConfig.depthMin > 0) {
configAttribsPtr[0] = EGL_DEPTH_SIZE;
- configAttribsPtr[1] = 16;
+ configAttribsPtr[1] = mUserSurfaceConfig.depthMin;
configAttribsPtr += 2;
}
@@ -97,29 +149,94 @@ void Context::initEGL(bool useGL2)
eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion);
checkEglError("eglInitialize");
- status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig);
+#if 1
+ PixelFormat pf = PIXEL_FORMAT_RGBA_8888;
+ if (mUserSurfaceConfig.alphaMin == 0) {
+ pf = PIXEL_FORMAT_RGBX_8888;
+ }
+
+ status_t err = EGLUtils::selectConfigForPixelFormat(mEGL.mDisplay, configAttribs, pf, &mEGL.mConfig);
if (err) {
LOGE("%p, couldn't find an EGLConfig matching the screen format\n", this);
}
- //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
-
-
- if (useGL2) {
- mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2);
- } else {
- mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL);
+ if (props.mLogVisual) {
+ printEGLConfiguration(mEGL.mDisplay, mEGL.mConfig);
}
+#else
+ eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
+#endif
+
+ mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2);
checkEglError("eglCreateContext");
if (mEGL.mContext == EGL_NO_CONTEXT) {
LOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", this);
}
gGLContextCount++;
+
+
+ EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
+ mEGL.mSurfaceDefault = eglCreatePbufferSurface(mEGL.mDisplay, mEGL.mConfig, pbuffer_attribs);
+ checkEglError("eglCreatePbufferSurface");
+ if (mEGL.mSurfaceDefault == EGL_NO_SURFACE) {
+ LOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
+ }
+
+ EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurfaceDefault, mEGL.mSurfaceDefault, mEGL.mContext);
+ checkEglError("eglMakeCurrent", ret);
+
+ mGL.mVersion = glGetString(GL_VERSION);
+ mGL.mVendor = glGetString(GL_VENDOR);
+ mGL.mRenderer = glGetString(GL_RENDERER);
+ mGL.mExtensions = glGetString(GL_EXTENSIONS);
+
+ //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
+ LOGV("GL Version %s", mGL.mVersion);
+ //LOGV("GL Vendor %s", mGL.mVendor);
+ LOGV("GL Renderer %s", mGL.mRenderer);
+ //LOGV("GL Extensions %s", mGL.mExtensions);
+
+ const char *verptr = NULL;
+ if (strlen((const char *)mGL.mVersion) > 9) {
+ if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) {
+ verptr = (const char *)mGL.mVersion + 12;
+ }
+ if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) {
+ verptr = (const char *)mGL.mVersion + 9;
+ }
+ }
+
+ if (!verptr) {
+ LOGE("Error, OpenGL ES Lite not supported");
+ } else {
+ sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
+ }
+
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mGL.mMaxVertexAttribs);
+ glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &mGL.mMaxVertexUniformVectors);
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGL.mMaxVertexTextureUnits);
+
+ glGetIntegerv(GL_MAX_VARYING_VECTORS, &mGL.mMaxVaryingVectors);
+ glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGL.mMaxTextureImageUnits);
+
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mGL.mMaxFragmentTextureImageUnits);
+ glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors);
+
+ mGL.OES_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_OES_texture_npot");
+ mGL.EXT_texture_max_aniso = 1.0f;
+ bool hasAniso = NULL != strstr((const char *)mGL.mExtensions, "GL_EXT_texture_filter_anisotropic");
+ if(hasAniso) {
+ glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mGL.EXT_texture_max_aniso);
+ }
+
+ LOGV("initGLThread end %p", this);
+ pthread_mutex_unlock(&gInitMutex);
}
void Context::deinitEGL()
{
LOGV("%p, deinitEGL", this);
- setSurface(0, 0, NULL);
+
+ eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEGL.mContext);
eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
checkEglError("eglDestroyContext");
@@ -312,6 +429,8 @@ void * Context::threadProc(void *vrsc)
LOGE("pthread_setspecific %i", status);
}
+ rsc->initGLThread();
+
rsc->mScriptC.init(rsc);
if (rsc->mIsGraphicsContext) {
rsc->mStateRaster.init(rsc);
@@ -460,7 +579,7 @@ void Context::setPriority(int32_t p)
#endif
}
-Context::Context(Device *dev, bool isGraphics, bool useDepth)
+Context::Context(Device *dev, const RsSurfaceConfig *sc)
{
pthread_mutex_lock(&gInitMutex);
@@ -468,15 +587,19 @@ Context::Context(Device *dev, bool isGraphics, bool useDepth)
mDev = dev;
mRunning = false;
mExit = false;
- mUseDepth = useDepth;
mPaused = false;
mObjHead = NULL;
mError = RS_ERROR_NONE;
mErrorMsg = NULL;
+ if (sc) {
+ mUserSurfaceConfig = *sc;
+ } else {
+ memset(&mUserSurfaceConfig, 0, sizeof(mUserSurfaceConfig));
+ }
memset(&mEGL, 0, sizeof(mEGL));
memset(&mGL, 0, sizeof(mGL));
- mIsGraphicsContext = isGraphics;
+ mIsGraphicsContext = sc != NULL;
int status;
pthread_attr_t threadAttr;
@@ -490,6 +613,7 @@ Context::Context(Device *dev, bool isGraphics, bool useDepth)
}
}
gThreadTLSKeyCount++;
+
pthread_mutex_unlock(&gInitMutex);
// Global init done at this point.
@@ -534,8 +658,6 @@ Context::Context(Device *dev, bool isGraphics, bool useDepth)
break;
}
}
-
-
pthread_attr_destroy(&threadAttr);
}
@@ -568,28 +690,21 @@ void Context::setSurface(uint32_t w, uint32_t h, ANativeWindow *sur)
EGLBoolean ret;
if (mEGL.mSurface != NULL) {
- ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurfaceDefault, mEGL.mSurfaceDefault, mEGL.mContext);
checkEglError("eglMakeCurrent", ret);
ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
checkEglError("eglDestroySurface", ret);
mEGL.mSurface = NULL;
- mWidth = 0;
- mHeight = 0;
+ mWidth = 1;
+ mHeight = 1;
}
mWndSurface = sur;
if (mWndSurface != NULL) {
mWidth = w;
mHeight = h;
- bool first = false;
- if (!mEGL.mContext) {
- first = true;
- pthread_mutex_lock(&gInitMutex);
- initEGL(true);
- pthread_mutex_unlock(&gInitMutex);
- }
mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
checkEglError("eglCreateWindowSurface");
@@ -601,53 +716,6 @@ void Context::setSurface(uint32_t w, uint32_t h, ANativeWindow *sur)
checkEglError("eglMakeCurrent", ret);
mStateVertex.updateSize(this);
-
- if (first) {
- mGL.mVersion = glGetString(GL_VERSION);
- mGL.mVendor = glGetString(GL_VENDOR);
- mGL.mRenderer = glGetString(GL_RENDERER);
- mGL.mExtensions = glGetString(GL_EXTENSIONS);
-
- //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
- LOGV("GL Version %s", mGL.mVersion);
- //LOGV("GL Vendor %s", mGL.mVendor);
- LOGV("GL Renderer %s", mGL.mRenderer);
- //LOGV("GL Extensions %s", mGL.mExtensions);
-
- const char *verptr = NULL;
- if (strlen((const char *)mGL.mVersion) > 9) {
- if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) {
- verptr = (const char *)mGL.mVersion + 12;
- }
- if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) {
- verptr = (const char *)mGL.mVersion + 9;
- }
- }
-
- if (!verptr) {
- LOGE("Error, OpenGL ES Lite not supported");
- } else {
- sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion);
- }
-
- glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mGL.mMaxVertexAttribs);
- glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &mGL.mMaxVertexUniformVectors);
- glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGL.mMaxVertexTextureUnits);
-
- glGetIntegerv(GL_MAX_VARYING_VECTORS, &mGL.mMaxVaryingVectors);
- glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGL.mMaxTextureImageUnits);
-
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mGL.mMaxFragmentTextureImageUnits);
- glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors);
-
- mGL.OES_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_OES_texture_npot");
- mGL.EXT_texture_max_aniso = 1.0f;
- bool hasAniso = NULL != strstr((const char *)mGL.mExtensions, "GL_EXT_texture_filter_anisotropic");
- if(hasAniso) {
- glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mGL.EXT_texture_max_aniso);
- }
- }
-
}
}
@@ -829,7 +897,7 @@ void Context::dumpDebug() const
LOGE(" GL Extensions: %s", mGL.mExtensions);
LOGE(" GL int Versions %i %i", mGL.mMajorVersion, mGL.mMinorVersion);
LOGE(" RS width %i, height %i", mWidth, mHeight);
- LOGE(" RS running %i, exit %i, useDepth %i, paused %i", mRunning, mExit, mUseDepth, mPaused);
+ LOGE(" RS running %i, exit %i, paused %i", mRunning, mExit, mPaused);
LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId);
LOGV("MAX Textures %i, %i %i", mGL.mMaxVertexTextureUnits, mGL.mMaxFragmentTextureImageUnits, mGL.mMaxTextureImageUnits);
@@ -957,15 +1025,15 @@ RsContext rsContextCreate(RsDevice vdev, uint32_t version)
{
LOGV("rsContextCreate %p", vdev);
Device * dev = static_cast<Device *>(vdev);
- Context *rsc = new Context(dev, false, false);
+ Context *rsc = new Context(dev, NULL);
return rsc;
}
-RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, bool useDepth)
+RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, RsSurfaceConfig sc)
{
- LOGV("rsContextCreateGL %p, %i", vdev, useDepth);
+ LOGV("rsContextCreateGL %p", vdev);
Device * dev = static_cast<Device *>(vdev);
- Context *rsc = new Context(dev, true, useDepth);
+ Context *rsc = new Context(dev, &sc);
LOGV("rsContextCreateGL ret %p ", rsc);
return rsc;
}
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 8a8b8a8..dbe2c79 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -69,7 +69,7 @@ namespace renderscript {
class Context
{
public:
- Context(Device *, bool isGraphics, bool useDepth);
+ Context(Device *, const RsSurfaceConfig *sc);
~Context();
static pthread_key_t gThreadTLSKey;
@@ -82,6 +82,7 @@ public:
Script * mScript;
};
ScriptTLSStruct *mTlsStruct;
+ RsSurfaceConfig mUserSurfaceConfig;
typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
@@ -207,6 +208,7 @@ protected:
EGLConfig mConfig;
EGLContext mContext;
EGLSurface mSurface;
+ EGLSurface mSurfaceDefault;
EGLDisplay mDisplay;
} mEGL;
@@ -240,7 +242,6 @@ protected:
bool mRunning;
bool mExit;
- bool mUseDepth;
bool mPaused;
RsError mError;
const char *mErrorMsg;
@@ -274,7 +275,8 @@ protected:
private:
Context();
- void initEGL(bool useGL2);
+ void initEGL();
+ void initGLThread();
void deinitEGL();
uint32_t runRootScript();
diff --git a/libs/rs/rsProgramStore.cpp b/libs/rs/rsProgramStore.cpp
index 3f90d7a..586a89f 100644
--- a/libs/rs/rsProgramStore.cpp
+++ b/libs/rs/rsProgramStore.cpp
@@ -76,14 +76,25 @@ void ProgramStore::setupGL2(const Context *rsc, ProgramStoreState *state)
//LOGE("pfs %i, %i, %x", mDepthWriteEnable, mDepthTestEnable, mDepthFunc);
- glDepthMask(mDepthWriteEnable);
- if(mDepthTestEnable || mDepthWriteEnable) {
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(mDepthFunc);
+ if (rsc->mUserSurfaceConfig.depthMin > 0) {
+ glDepthMask(mDepthWriteEnable);
+ if(mDepthTestEnable || mDepthWriteEnable) {
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(mDepthFunc);
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ }
} else {
+ glDepthMask(false);
glDisable(GL_DEPTH_TEST);
}
+ if (rsc->mUserSurfaceConfig.stencilMin > 0) {
+ } else {
+ glStencilMask(0);
+ glDisable(GL_STENCIL_TEST);
+ }
+
if (mDitherEnable) {
glEnable(GL_DITHER);
} else {
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index 17a961b..b5f9c47 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -431,13 +431,14 @@ public:
}
void mountObb(const String16& filename, const String16& key,
- const sp<IObbActionListener>& token)
+ const sp<IObbActionListener>& token, int32_t nonce)
{
Parcel data, reply;
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
data.writeString16(filename);
data.writeString16(key);
data.writeStrongBinder(token->asBinder());
+ data.writeInt32(nonce);
if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
LOGD("mountObb could not contact remote\n");
return;
@@ -449,12 +450,15 @@ public:
}
}
- void unmountObb(const String16& filename, const bool force, const sp<IObbActionListener>& token)
+ void unmountObb(const String16& filename, const bool force,
+ const sp<IObbActionListener>& token, const int32_t nonce)
{
Parcel data, reply;
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
data.writeString16(filename);
data.writeInt32(force ? 1 : 0);
+ data.writeStrongBinder(token->asBinder());
+ data.writeInt32(nonce);
if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
LOGD("unmountObb could not contact remote\n");
return;
diff --git a/libs/storage/IObbActionListener.cpp b/libs/storage/IObbActionListener.cpp
index 5bfece7..eaa211e 100644
--- a/libs/storage/IObbActionListener.cpp
+++ b/libs/storage/IObbActionListener.cpp
@@ -30,7 +30,7 @@ public:
: BpInterface<IObbActionListener>(impl)
{ }
- virtual void onObbResult(const String16& filename, const String16& status) { }
+ virtual void onObbResult(const String16& filename, const int32_t nonce, const int32_t state) { }
};
IMPLEMENT_META_INTERFACE(ObbActionListener, "IObbActionListener");
@@ -44,8 +44,9 @@ status_t BnObbActionListener::onTransact(
case TRANSACTION_onObbResult: {
CHECK_INTERFACE(IObbActionListener, data, reply);
String16 filename = data.readString16();
- String16 state = data.readString16();
- onObbResult(filename, state);
+ int32_t nonce = data.readInt32();
+ int32_t state = data.readInt32();
+ onObbResult(filename, nonce, state);
reply->writeNoException();
return NO_ERROR;
} break;
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index d676f5e..d72561f 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -142,6 +142,15 @@ public:
return reply.readInt32();
}
+ virtual status_t turnElectronBeamOff(int32_t mode)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ data.writeInt32(mode);
+ remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_OFF, data, &reply);
+ return reply.readInt32();
+ }
+
virtual void signal() const
{
Parcel data, reply;
@@ -224,6 +233,12 @@ status_t BnSurfaceComposer::onTransact(
reply->writeInt32(f);
reply->writeInt32(res);
} break;
+ case TURN_ELECTRON_BEAM_OFF: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ int32_t mode = data.readInt32();
+ status_t res = turnElectronBeamOff(mode);
+ reply->writeInt32(res);
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 52e488a..84c3db8 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -432,10 +432,9 @@ void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropR
switch (dropReason) {
case DROP_REASON_POLICY:
#if DEBUG_INBOUND_EVENT_DETAILS
- LOGD("Dropped event because policy requested that it not be delivered to the application.");
+ LOGD("Dropped event because policy consumed it.");
#endif
- reason = "inbound event was dropped because the policy requested that it not be "
- "delivered to the application";
+ reason = "inbound event was dropped because the policy consumed it";
break;
case DROP_REASON_DISABLED:
LOGI("Dropped event because input dispatch is disabled.");
@@ -625,15 +624,13 @@ bool InputDispatcher::dispatchKeyLocked(
if (*dropReason == DROP_REASON_NOT_DROPPED) {
*dropReason = DROP_REASON_POLICY;
}
- resetTargetsLocked();
- setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
- return true;
}
// Clean up if dropping the event.
if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
- setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+ setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
+ ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true;
}
@@ -713,7 +710,8 @@ bool InputDispatcher::dispatchMotionLocked(
// Clean up if dropping the event.
if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
- setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+ setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
+ ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true;
}
@@ -3396,7 +3394,7 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim
}
}
- for (size_t i = 0; i < mMotionMementos.size(); i++) {
+ for (size_t i = 0; i < mMotionMementos.size(); ) {
const MotionMemento& memento = mMotionMementos.itemAt(i);
if (shouldCancelEvent(memento.source, options)) {
outEvents.push(allocator->obtainMotionEntry(currentTime,
diff --git a/native/android/storage_manager.cpp b/native/android/storage_manager.cpp
index 2f20641..a4233e7 100644
--- a/native/android/storage_manager.cpp
+++ b/native/android/storage_manager.cpp
@@ -21,10 +21,13 @@
#include <binder/Binder.h>
#include <binder/IServiceManager.h>
+#include <utils/Atomic.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/String16.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
using namespace android;
@@ -38,20 +41,46 @@ public:
mStorageManager(mgr)
{}
- virtual void onObbResult(const android::String16& filename, const android::String16& state);
+ virtual void onObbResult(const android::String16& filename, const int32_t nonce,
+ const int32_t state);
+};
+
+class ObbCallback {
+public:
+ ObbCallback(int32_t _nonce, AStorageManager_obbCallbackFunc _cb, void* _data)
+ : nonce(_nonce)
+ , cb(_cb)
+ , data(_data)
+ {}
+
+ int32_t nonce;
+ AStorageManager_obbCallbackFunc cb;
+ void* data;
};
struct AStorageManager : public RefBase {
protected:
- AStorageManager_obbCallbackFunc mObbCallback;
- void* mObbCallbackData;
+ Mutex mCallbackLock;
+ Vector<ObbCallback*> mCallbacks;
+ volatile int32_t mNextNonce;
sp<ObbActionListener> mObbActionListener;
sp<IMountService> mMountService;
+ int32_t getNextNonce() {
+ return android_atomic_inc(&mNextNonce);
+ }
+
+ ObbCallback* registerObbCallback(AStorageManager_obbCallbackFunc func, void* data) {
+ ObbCallback* cb = new ObbCallback(getNextNonce(), func, data);
+ {
+ AutoMutex _l(mCallbackLock);
+ mCallbacks.push(cb);
+ }
+ return cb;
+ }
+
public:
AStorageManager()
- : mObbCallback(NULL)
- , mObbCallbackData(NULL)
{
}
@@ -73,26 +102,40 @@ public:
return true;
}
- void setObbCallback(AStorageManager_obbCallbackFunc cb, void* data) {
- mObbCallback = cb;
- mObbCallbackData = data;
- }
+ void fireCallback(const char* filename, const int32_t nonce, const int32_t state) {
+ ObbCallback* target = NULL;
+ {
+ AutoMutex _l(mCallbackLock);
+ int N = mCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ ObbCallback* cb = mCallbacks.editItemAt(i);
+ if (cb->nonce == nonce) {
+ target = cb;
+ mCallbacks.removeAt(i);
+ break;
+ }
+ }
+ }
- void fireCallback(const char* filename, const char* state) {
- if (mObbCallback != NULL) {
- mObbCallback(filename, state, mObbCallbackData);
+ if (target != NULL) {
+ target->cb(filename, state, target->data);
+ delete target;
+ } else {
+ LOGI("Didn't find the callback handler for: %s\n", filename);
}
}
- void mountObb(const char* filename, const char* key) {
+ void mountObb(const char* filename, const char* key, AStorageManager_obbCallbackFunc func, void* data) {
+ ObbCallback* cb = registerObbCallback(func, data);
String16 filename16(filename);
String16 key16(key);
- mMountService->mountObb(filename16, key16, mObbActionListener);
+ mMountService->mountObb(filename16, key16, mObbActionListener, cb->nonce);
}
- void unmountObb(const char* filename, const bool force) {
+ void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
+ ObbCallback* cb = registerObbCallback(func, data);
String16 filename16(filename);
- mMountService->unmountObb(filename16, force, mObbActionListener);
+ mMountService->unmountObb(filename16, force, mObbActionListener, cb->nonce);
}
int isObbMounted(const char* filename) {
@@ -111,8 +154,8 @@ public:
}
};
-void ObbActionListener::onObbResult(const android::String16& filename, const android::String16& state) {
- mStorageManager->fireCallback(String8(filename).string(), String8(state).string());
+void ObbActionListener::onObbResult(const android::String16& filename, const int32_t nonce, const int32_t state) {
+ mStorageManager->fireCallback(String8(filename).string(), nonce, state);
}
@@ -131,16 +174,14 @@ void AStorageManager_delete(AStorageManager* mgr) {
}
}
-void AStorageManager_setObbCallback(AStorageManager* mgr, AStorageManager_obbCallbackFunc cb, void* data) {
- mgr->setObbCallback(cb, data);
-}
-
-void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key) {
- mgr->mountObb(filename, key);
+void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
+ AStorageManager_obbCallbackFunc cb, void* data) {
+ mgr->mountObb(filename, key, cb, data);
}
-void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force) {
- mgr->unmountObb(filename, force != 0);
+void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
+ AStorageManager_obbCallbackFunc cb, void* data) {
+ mgr->unmountObb(filename, force != 0, cb, data);
}
int AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename) {
diff --git a/native/include/android/storage_manager.h b/native/include/android/storage_manager.h
index 6f925c1..c202693 100644
--- a/native/include/android/storage_manager.h
+++ b/native/include/android/storage_manager.h
@@ -18,6 +18,8 @@
#ifndef ANDROID_STORAGE_MANAGER_H
#define ANDROID_STORAGE_MANAGER_H
+#include <stdint.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -25,6 +27,60 @@ extern "C" {
struct AStorageManager;
typedef struct AStorageManager AStorageManager;
+enum {
+ /*
+ * The OBB container is now mounted and ready for use. Can be returned
+ * as the status for callbacks made during asynchronous OBB actions.
+ */
+ AOBB_STATE_MOUNTED = 1,
+
+ /*
+ * The OBB container is now unmounted and not usable. Can be returned
+ * as the status for callbacks made during asynchronous OBB actions.
+ */
+ AOBB_STATE_UNMOUNTED = 2,
+
+ /*
+ * There was an internal system error encountered while trying to
+ * mount the OBB. Can be returned as the status for callbacks made
+ * during asynchronous OBB actions.
+ */
+ AOBB_STATE_ERROR_INTERNAL = 20,
+
+ /*
+ * The OBB could not be mounted by the system. Can be returned as the
+ * status for callbacks made during asynchronous OBB actions.
+ */
+ AOBB_STATE_ERROR_COULD_NOT_MOUNT = 21,
+
+ /*
+ * The OBB could not be unmounted. This most likely indicates that a
+ * file is in use on the OBB. Can be returned as the status for
+ * callbacks made during asynchronous OBB actions.
+ */
+ AOBB_STATE_ERROR_COULD_NOT_UNMOUNT = 22,
+
+ /*
+ * A call was made to unmount the OBB when it was not mounted. Can be
+ * returned as the status for callbacks made during asynchronous OBB
+ * actions.
+ */
+ AOBB_STATE_ERROR_NOT_MOUNTED = 23,
+
+ /*
+ * The OBB has already been mounted. Can be returned as the status for
+ * callbacks made during asynchronous OBB actions.
+ */
+ AOBB_STATE_ERROR_ALREADY_MOUNTED = 24,
+
+ /*
+ * The current application does not have permission to use this OBB
+ * because the OBB indicates it's owned by a different package or the
+ * key used to open it is incorrect. Can be returned as the status for
+ * callbacks made during asynchronous OBB actions.
+ */
+ AOBB_STATE_ERROR_PERMISSION_DENIED = 25,
+};
/**
* Obtains a new instance of AStorageManager.
@@ -39,22 +95,19 @@ void AStorageManager_delete(AStorageManager* mgr);
/**
* Callback function for asynchronous calls made on OBB files.
*/
-typedef void (*AStorageManager_obbCallbackFunc)(const char* filename, const char* state, void* data);
-
-/**
- * Callback to call when requested asynchronous OBB operation is complete.
- */
-void AStorageManager_setObbCallback(AStorageManager* mgr, AStorageManager_obbCallbackFunc cb, void* data);
+typedef void (*AStorageManager_obbCallbackFunc)(const char* filename, const int32_t state, void* data);
/**
* Attempts to mount an OBB file. This is an asynchronous operation.
*/
-void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key);
+void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
+ AStorageManager_obbCallbackFunc cb, void* data);
/**
* Attempts to unmount an OBB file. This is an asynchronous operation.
*/
-void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force);
+void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
+ AStorageManager_obbCallbackFunc cb, void* data);
/**
* Check whether an OBB is mounted.
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6057023..5fde3c3 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -28,6 +28,10 @@
<activity android:name=".usb.UsbStorageActivity"
android:excludeFromRecents="true">
</activity>
+ <activity android:name="com.android.internal.app.ExternalMediaFormatActivity"
+ android:theme="@*android:style/Theme.Dialog.Alert"
+ android:excludeFromRecents="true">
+ </activity>
<activity android:name=".recent.RecentApplicationsActivity"
android:theme="@android:style/Theme.NoTitleBar"
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 494dfa8..295c79b 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -144,6 +144,7 @@
android:paddingLeft="4dip"
android:paddingRight="4dip"
systemui:keyCode="82"
+ android:visibility="invisible"
/>
<ImageButton android:id="@+id/recent"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 81091e3..c164eb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -54,6 +54,8 @@ public class CommandQueue extends IStatusBar.Stub {
private static final int MSG_SET_LIGHTS_ON = 0x00070000;
+ private static final int MSG_SHOW_MENU = 0x00080000;
+
private StatusBarIconList mList;
private Callbacks mCallbacks;
private Handler mHandler = new H();
@@ -78,6 +80,7 @@ public class CommandQueue extends IStatusBar.Stub {
public void animateExpand();
public void animateCollapse();
public void setLightsOn(boolean on);
+ public void setMenuKeyVisible(boolean visible);
}
public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -153,6 +156,13 @@ public class CommandQueue extends IStatusBar.Stub {
}
}
+ public void setMenuKeyVisible(boolean visible) {
+ synchronized (mList) {
+ mHandler.removeMessages(MSG_SHOW_MENU);
+ mHandler.obtainMessage(MSG_SHOW_MENU, visible ? 1 : 0, 0, null).sendToTarget();
+ }
+ }
+
private final class H extends Handler {
public void handleMessage(Message msg) {
final int what = msg.what & MSG_MASK;
@@ -210,6 +220,9 @@ public class CommandQueue extends IStatusBar.Stub {
case MSG_SET_LIGHTS_ON:
mCallbacks.setLightsOn(msg.arg1 != 0);
break;
+ case MSG_SHOW_MENU:
+ mCallbacks.setMenuKeyVisible(msg.arg1 != 0);
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
index 1e89624..2f94af6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
@@ -23,12 +23,22 @@ import android.view.MotionEvent;
import android.widget.FrameLayout;
public class LatestItemView extends FrameLayout {
+ private boolean mDispatchTorches;
public LatestItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean dispatchTouchEvent(MotionEvent ev) {
- return onTouchEvent(ev);
+ if (mDispatchTorches) {
+ return super.dispatchTouchEvent(ev);
+ } else {
+ return onTouchEvent(ev);
+ }
+ }
+
+ public void setOnClickListener(OnClickListener l) {
+ mDispatchTorches = l == null;
+ super.setOnClickListener(l);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index 57ebd27..fc7b534 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -440,6 +440,8 @@ public class PhoneStatusBarService extends StatusBarService {
if (contentIntent != null) {
oldEntry.content.setOnClickListener(new Launcher(contentIntent,
notification.pkg, notification.tag, notification.id));
+ } else {
+ oldEntry.content.setOnClickListener(null);
}
// Update the icon.
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
@@ -516,6 +518,8 @@ public class PhoneStatusBarService extends StatusBarService {
if (contentIntent != null) {
content.setOnClickListener(new Launcher(contentIntent, notification.pkg,
notification.tag, notification.id));
+ } else {
+ content.setOnClickListener(null);
}
View expanded = null;
@@ -1013,6 +1017,9 @@ public class PhoneStatusBarService extends StatusBarService {
}
}
+ // Not supported
+ public void setMenuKeyVisible(boolean visible) { }
+
private class Launcher implements View.OnClickListener {
private PendingIntent mIntent;
private String mPkg;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
index 695fdba..5594a47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -72,15 +72,16 @@ public abstract class StatusBarService extends Service implements CommandQueue.C
mCommandQueue = new CommandQueue(this, iconList);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
- boolean[] lightsOn = new boolean[1];
+ boolean[] switches = new boolean[2];
try {
mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications,
- lightsOn);
+ switches);
} catch (RemoteException ex) {
// If the system process isn't there we're doomed anyway.
}
- setLightsOn(lightsOn[0]);
+ setLightsOn(switches[0]);
+ setMenuKeyVisible(switches[1]);
// Set up the initial icon state
int N = iconList.size();
@@ -120,7 +121,11 @@ public abstract class StatusBarService extends Service implements CommandQueue.C
// TODO lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(sb, lp);
- Slog.d(TAG, "Added status bar view w/ gravity 0x" + Integer.toHexString(lp.gravity));
+ Slog.d(TAG, "Added status bar view: gravity=0x" + Integer.toHexString(lp.gravity)
+ + " icons=" + iconList.size()
+ + " lights=" + (switches[0]?"on":"off")
+ + " menu=" + (switches[1]?"visible":"invisible")
+ );
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 0e26f52..340e269 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -79,6 +79,7 @@ public class TabletStatusBarService extends StatusBarService {
View mNotificationButtons;
View mSystemInfo;
View mNavigationArea;
+ View mMenuButton;
NotificationPanel mNotificationPanel;
SystemPanel mSystemPanel;
@@ -205,6 +206,7 @@ public class TabletStatusBarService extends StatusBarService {
// The navigation buttons
mNavigationArea = sb.findViewById(R.id.navigationArea);
+ mMenuButton = mNavigationArea.findViewById(R.id.menu);
// set the initial view visibility
setAreThereNotifications();
@@ -370,6 +372,8 @@ public class TabletStatusBarService extends StatusBarService {
if (contentIntent != null) {
oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
notification.pkg, notification.tag, notification.id));
+ } else {
+ oldEntry.content.setOnClickListener(null);
}
// Update the icon.
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
@@ -503,6 +507,15 @@ public class TabletStatusBarService extends StatusBarService {
}
}
+ public void setMenuKeyVisible(boolean visible) {
+ if (DEBUG) {
+ Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
+ }
+ setViewVisibility(mMenuButton,
+ visible ? View.VISIBLE : View.INVISIBLE,
+ visible ? R.anim.navigation_in : R.anim.navigation_out);
+ }
+
private void setAreThereNotifications() {
final boolean hasClearable = mNotns.hasClearableItems();
@@ -760,6 +773,8 @@ public class TabletStatusBarService extends StatusBarService {
if (contentIntent != null) {
content.setOnClickListener(new NotificationClicker(contentIntent,
sbn.pkg, sbn.tag, sbn.id));
+ } else {
+ content.setOnClickListener(null);
}
View expanded = null;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index b9e915a4..47ed7da 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -16,33 +16,17 @@
package com.android.systemui.usb;
-import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.os.Bundle;
import android.os.Environment;
-import android.os.Handler;
-import android.os.storage.IMountService;
-import android.os.Message;
-import android.os.ServiceManager;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
-import android.os.storage.StorageResultCode;
import android.provider.Settings;
import android.util.Slog;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
public class StorageNotification extends StorageEventListener {
private static final String TAG = "StorageNotification";
@@ -165,10 +149,16 @@ public class StorageNotification extends StorageEventListener {
* Show safe to unmount media notification, and enable UMS
* notification if connected.
*/
- setMediaStorageNotification(
- com.android.internal.R.string.ext_media_safe_unmount_notification_title,
- com.android.internal.R.string.ext_media_safe_unmount_notification_message,
- com.android.internal.R.drawable.stat_notify_sdcard, true, true, null);
+ if (Environment.isExternalStorageRemovable()) {
+ setMediaStorageNotification(
+ com.android.internal.R.string.ext_media_safe_unmount_notification_title,
+ com.android.internal.R.string.ext_media_safe_unmount_notification_message,
+ com.android.internal.R.drawable.stat_notify_sdcard, true, true, null);
+ } else {
+ // This device does not have removable storage, so
+ // don't tell the user they can remove it.
+ setMediaStorageNotification(0, 0, 0, false, false, null);
+ }
updateUsbMassStorageNotification(mUmsAvailable);
}
} else {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 24c9443..db5f6c1 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.RootViewSurfaceTaker;
@@ -2324,6 +2325,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));
}
+ if (getContext().getApplicationInfo().targetSdkVersion
+ < android.os.Build.VERSION_CODES.HONEYCOMB) {
+ addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
+ }
+
WindowManager.LayoutParams params = getAttributes();
if (!hasSoftInputMode()) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 449bd4c..c6898d4 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -287,6 +287,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Intent mDeskDockIntent;
boolean mSearchKeyPressed;
boolean mConsumeSearchKeyUp;
+ boolean mShowMenuKey = false; // track FLAG_NEEDS_MENU_KEY on frontmost window
// support for activating the lock screen while the screen is on
boolean mAllowLockscreenWhenOn;
@@ -1123,10 +1124,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
int keyCode, int metaState, int repeatCount, int policyFlags) {
- if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
- return false;
- }
-
final boolean keyguardOn = keyguardOn();
final boolean down = (action == KeyEvent.ACTION_DOWN);
final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
@@ -1603,8 +1600,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
public int finishAnimationLw() {
int changes = 0;
-
boolean topIsFullscreen = false;
+
+ final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null)
+ ? mTopFullscreenOpaqueWindowState.getAttrs()
+ : null;
+
if (mStatusBar != null) {
if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar
+ " top=" + mTopFullscreenOpaqueWindowState);
@@ -1612,7 +1613,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar");
if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
} else if (mTopFullscreenOpaqueWindowState != null) {
- final WindowManager.LayoutParams lp = mTopFullscreenOpaqueWindowState.getAttrs();
if (localLOGV) {
Log.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
+ " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw());
@@ -1637,10 +1637,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
}
-
- if (topIsFullscreen != mTopIsFullscreen) {
+
+ boolean topNeedsMenu = mShowMenuKey;
+ if (lp != null) {
+ topNeedsMenu = (lp.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
+ }
+
+ if (DEBUG_LAYOUT) Log.v(TAG, "Top window "
+ + (topNeedsMenu ? "needs" : "does not need")
+ + " the MENU key");
+
+ final boolean changedFullscreen = (mTopIsFullscreen != topIsFullscreen);
+ final boolean changedMenu = (topNeedsMenu != mShowMenuKey);
+
+ if (changedFullscreen || changedMenu) {
final boolean topIsFullscreenF = topIsFullscreen;
+ final boolean topNeedsMenuF = topNeedsMenu;
+
mTopIsFullscreen = topIsFullscreen;
+ mShowMenuKey = topNeedsMenu;
+
mHandler.post(new Runnable() {
public void run() {
if (mStatusBarService == null) {
@@ -1654,7 +1670,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final IStatusBarService sbs = mStatusBarService;
if (mStatusBarService != null) {
try {
- sbs.setActiveWindowIsFullscreen(topIsFullscreenF);
+ if (changedFullscreen) {
+ sbs.setActiveWindowIsFullscreen(topIsFullscreenF);
+ }
+ if (changedMenu) {
+ sbs.setMenuKeyVisible(topNeedsMenuF);
+ }
} catch (RemoteException e) {
// This should be impossible because we're in the same process.
mStatusBarService = null;
@@ -1835,9 +1856,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
int policyFlags, boolean isScreenOn) {
int result = ACTION_PASS_TO_USER;
- if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
- return result;
- }
if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
@@ -1845,7 +1863,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final boolean isWakeKey = (policyFlags
& (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
-
+
+ // If the key is injected, pretend that the screen is on and don't let the
+ // device go to sleep. This feature is mainly used for testing purposes.
+ final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
+ if (isInjected) {
+ isScreenOn = true;
+ }
+
// If screen is off then we treat the case where the keyguard is open but hidden
// the same as if it were open and in front.
// This will prevent any keys other than the power button from waking the screen
@@ -1944,7 +1969,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|| (handled && hungUp && keyCode == KeyEvent.KEYCODE_POWER)) {
mShouldTurnOffOnKeyUp = false;
} else {
- // only try to turn off the screen if we didn't already hang up
+ // Only try to turn off the screen if we didn't already hang up.
mShouldTurnOffOnKeyUp = true;
mHandler.postDelayed(mPowerLongPress,
ViewConfiguration.getGlobalActionKeyTimeout());
@@ -1967,12 +1992,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (keyguardActive
|| (sleeps && !gohome)
|| (gohome && !goHome() && sleeps)) {
- // they must already be on the keyguad or home screen,
- // go to sleep instead
- Log.d(TAG, "I'm tired mEndcallBehavior=0x"
- + Integer.toHexString(mEndcallBehavior));
- result &= ~ACTION_POKE_USER_ACTIVITY;
- result |= ACTION_GO_TO_SLEEP;
+ // They must already be on the keyguard or home screen,
+ // go to sleep instead unless the event was injected.
+ if (!isInjected) {
+ Log.d(TAG, "I'm tired mEndcallBehavior=0x"
+ + Integer.toHexString(mEndcallBehavior));
+ result &= ~ACTION_POKE_USER_ACTIVITY;
+ result |= ACTION_GO_TO_SLEEP;
+ }
}
result &= ~ACTION_PASS_TO_USER;
}
diff --git a/preloaded-classes b/preloaded-classes
index ee82a2c..21c5df8 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -254,7 +254,6 @@ android.graphics.drawable.StateListDrawable
android.graphics.drawable.StateListDrawable$StateListState
android.graphics.drawable.TransitionDrawable
android.graphics.drawable.TransitionDrawable$TransitionState
-android.graphics.utils.BoundaryPatch
android.hardware.Camera
android.hardware.Camera$Parameters
android.hardware.GeomagneticField
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index baa5016..f8611e4 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -44,6 +44,7 @@ import android.os.storage.IMountService;
import android.os.storage.IMountServiceListener;
import android.os.storage.IMountShutdownObserver;
import android.os.storage.IObbActionListener;
+import android.os.storage.OnObbStateChangeListener;
import android.os.storage.StorageResultCode;
import android.security.MessageDigest;
import android.util.Slog;
@@ -53,7 +54,6 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -163,25 +163,25 @@ class MountService extends IMountService.Stub
final private Map<String, ObbState> mObbPathToStateMap = new HashMap<String, ObbState>();
class ObbState implements IBinder.DeathRecipient {
- public ObbState(String filename, IObbActionListener token, int callerUid)
+ public ObbState(String filename, int callerUid, IObbActionListener token, int nonce)
throws RemoteException {
this.filename = filename;
- this.token = token;
this.callerUid = callerUid;
- mounted = false;
+ this.token = token;
+ this.nonce = nonce;
}
// OBB source filename
- final String filename;
-
- // Token of remote Binder caller
- final IObbActionListener token;
+ String filename;
// Binder.callingUid()
final public int callerUid;
- // Whether this is mounted currently.
- boolean mounted;
+ // Token of remote Binder caller
+ final IObbActionListener token;
+
+ // Identifier to pass back to the token
+ final int nonce;
public IBinder getBinder() {
return token.asBinder();
@@ -210,8 +210,6 @@ class MountService extends IMountService.Stub
sb.append(token.toString());
sb.append(",callerUid=");
sb.append(callerUid);
- sb.append(",mounted=");
- sb.append(mounted);
sb.append('}');
return sb.toString();
}
@@ -225,6 +223,7 @@ class MountService extends IMountService.Stub
private static final int OBB_MCS_BOUND = 2;
private static final int OBB_MCS_UNBIND = 3;
private static final int OBB_MCS_RECONNECT = 4;
+ private static final int OBB_FLUSH_MOUNT_STATE = 5;
/*
* Default Container Service information
@@ -508,38 +507,19 @@ class MountService extends IMountService.Stub
if (!mEmulateExternalStorage) {
if (Environment.MEDIA_UNMOUNTED.equals(state)) {
mPms.updateExternalMediaStatus(false, false);
+
+ /*
+ * Some OBBs might have been unmounted when this volume was
+ * unmounted, so send a message to the handler to let it know to
+ * remove those from the list of mounted OBBS.
+ */
+ mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_FLUSH_MOUNT_STATE,
+ path));
} else if (Environment.MEDIA_MOUNTED.equals(state)) {
mPms.updateExternalMediaStatus(true, false);
}
}
- // Remove all OBB mappings and listeners from this path
- synchronized (mObbMounts) {
- final List<ObbState> obbStatesToRemove = new LinkedList<ObbState>();
-
- final Iterator<Entry<String, ObbState>> i = mObbPathToStateMap.entrySet().iterator();
- while (i.hasNext()) {
- final Entry<String, ObbState> obbEntry = i.next();
-
- // If this entry's source file is in the volume path that got
- // unmounted, remove it because it's no longer valid.
- if (obbEntry.getKey().startsWith(path)) {
- obbStatesToRemove.add(obbEntry.getValue());
- }
- }
-
- for (final ObbState obbState : obbStatesToRemove) {
- removeObbState(obbState);
-
- try {
- obbState.token.onObbResult(obbState.filename, Environment.MEDIA_UNMOUNTED);
- } catch (RemoteException e) {
- Slog.i(TAG, "Couldn't send unmount notification for OBB: "
- + obbState.filename);
- }
- }
- }
-
String oldState = mLegacyState;
mLegacyState = state;
@@ -1547,6 +1527,10 @@ class MountService extends IMountService.Stub
}
public String getMountedObbPath(String filename) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename cannot be null");
+ }
+
waitForReady();
warnOnNotMounted();
@@ -1569,164 +1553,98 @@ class MountService extends IMountService.Stub
}
public boolean isObbMounted(String filename) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename cannot be null");
+ }
+
synchronized (mObbMounts) {
- final ObbState obbState = mObbPathToStateMap.get(filename);
- if (obbState != null) {
- synchronized (obbState) {
- return obbState.mounted;
- }
- }
+ return mObbPathToStateMap.containsKey(filename);
}
- return false;
}
- public void mountObb(String filename, String key, IObbActionListener token)
+ public void mountObb(String filename, String key, IObbActionListener token, int nonce)
throws RemoteException {
- waitForReady();
- warnOnNotMounted();
-
if (filename == null) {
throw new IllegalArgumentException("filename cannot be null");
- } else if (token == null) {
- throw new IllegalArgumentException("token cannot be null");
}
- final ObbState obbState;
-
- synchronized (mObbMounts) {
- if (isObbMounted(filename)) {
- try {
- token.onObbResult(filename, Environment.MEDIA_MOUNTED);
- } catch (RemoteException e) {
- Slog.d(TAG, "Could not send unmount notification for: " + filename);
- }
- return;
- }
-
- final int callerUid = Binder.getCallingUid();
- obbState = new ObbState(filename, token, callerUid);
- addObbState(obbState);
- }
-
- String hashedKey = null;
- if (key != null) {
- final MessageDigest md;
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- Slog.e(TAG, "Could not load MD5 algorithm", e);
- try {
- token.onObbResult(filename, Environment.MEDIA_UNMOUNTED);
- } catch (RemoteException e1) {
- Slog.d(TAG, "Could not send unmount notification for: " + filename);
- }
- return;
- }
-
- hashedKey = HexDump.toHexString(md.digest(key.getBytes()));
+ if (token == null) {
+ throw new IllegalArgumentException("token cannot be null");
}
- ObbAction action = new MountObbAction(obbState, hashedKey);
+ final int callerUid = Binder.getCallingUid();
+ final ObbState obbState = new ObbState(filename, callerUid, token, nonce);
+ final ObbAction action = new MountObbAction(obbState, key);
mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
if (DEBUG_OBB)
Slog.i(TAG, "Send to OBB handler: " + action.toString());
}
- public void unmountObb(String filename, boolean force, IObbActionListener token) {
+ public void unmountObb(String filename, boolean force, IObbActionListener token, int nonce)
+ throws RemoteException {
if (filename == null) {
throw new IllegalArgumentException("filename cannot be null");
- } else if (token == null) {
- throw new IllegalArgumentException("token cannot be null");
}
- final ObbState obbState;
-
- synchronized (mObbMounts) {
- if (!isObbMounted(filename)) {
- try {
- token.onObbResult(filename, Environment.MEDIA_UNMOUNTED);
- } catch (RemoteException e) {
- Slog.d(TAG, "Could not send unmount notification for: " + filename);
- }
- return;
- }
-
- obbState = mObbPathToStateMap.get(filename);
-
- if (Binder.getCallingUid() != obbState.callerUid) {
- throw new SecurityException("caller UID does not match original mount caller UID");
- } else if (!token.asBinder().equals(obbState.getBinder())) {
- throw new SecurityException("caller does not match original mount caller");
- }
- }
-
- ObbAction action = new UnmountObbAction(obbState, force);
+ final int callerUid = Binder.getCallingUid();
+ final ObbState obbState = new ObbState(filename, callerUid, token, nonce);
+ final ObbAction action = new UnmountObbAction(obbState, force);
mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
if (DEBUG_OBB)
Slog.i(TAG, "Send to OBB handler: " + action.toString());
}
- private void addObbState(ObbState obbState) throws RemoteException {
- synchronized (mObbMounts) {
- final IBinder binder = obbState.getBinder();
- List<ObbState> obbStates = mObbMounts.get(binder);
- final boolean unique;
-
- if (obbStates == null) {
- obbStates = new ArrayList<ObbState>();
- mObbMounts.put(binder, obbStates);
- unique = true;
- } else {
- unique = obbStates.contains(obbState);
- }
-
- if (unique) {
- obbStates.add(obbState);
- try {
- obbState.link();
- } catch (RemoteException e) {
- /*
- * The binder died before we could link it, so clean up our
- * state and return failure.
- */
- obbStates.remove(obbState);
- if (obbStates.isEmpty()) {
- mObbMounts.remove(binder);
- }
+ private void addObbStateLocked(ObbState obbState) throws RemoteException {
+ final IBinder binder = obbState.getBinder();
+ List<ObbState> obbStates = mObbMounts.get(binder);
- // Rethrow the error so mountObb can get it
- throw e;
+ if (obbStates == null) {
+ obbStates = new ArrayList<ObbState>();
+ mObbMounts.put(binder, obbStates);
+ } else {
+ for (final ObbState o : obbStates) {
+ if (o.filename.equals(obbState.filename)) {
+ throw new IllegalStateException("Attempt to add ObbState twice. "
+ + "This indicates an error in the MountService logic.");
}
}
-
- mObbPathToStateMap.put(obbState.filename, obbState);
}
- }
- private void removeObbState(ObbState obbState) {
- synchronized (mObbMounts) {
- final IBinder binder = obbState.getBinder();
- final List<ObbState> obbStates = mObbMounts.get(binder);
- if (obbStates != null) {
- if (obbStates.remove(obbState)) {
- obbState.unlink();
- }
- if (obbStates.isEmpty()) {
- mObbMounts.remove(binder);
- }
+ obbStates.add(obbState);
+ try {
+ obbState.link();
+ } catch (RemoteException e) {
+ /*
+ * The binder died before we could link it, so clean up our state
+ * and return failure.
+ */
+ obbStates.remove(obbState);
+ if (obbStates.isEmpty()) {
+ mObbMounts.remove(binder);
}
- mObbPathToStateMap.remove(obbState.filename);
+ // Rethrow the error so mountObb can get it
+ throw e;
}
+
+ mObbPathToStateMap.put(obbState.filename, obbState);
}
- private void replaceObbState(ObbState oldObbState, ObbState newObbState) throws RemoteException {
- synchronized (mObbMounts) {
- removeObbState(oldObbState);
- addObbState(newObbState);
+ private void removeObbStateLocked(ObbState obbState) {
+ final IBinder binder = obbState.getBinder();
+ final List<ObbState> obbStates = mObbMounts.get(binder);
+ if (obbStates != null) {
+ if (obbStates.remove(obbState)) {
+ obbState.unlink();
+ }
+ if (obbStates.isEmpty()) {
+ mObbMounts.remove(binder);
+ }
}
+
+ mObbPathToStateMap.remove(obbState.filename);
}
private class ObbActionHandler extends Handler {
@@ -1825,6 +1743,47 @@ class MountService extends IMountService.Stub
}
break;
}
+ case OBB_FLUSH_MOUNT_STATE: {
+ final String path = (String) msg.obj;
+
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Flushing all OBB state for path " + path);
+
+ synchronized (mObbMounts) {
+ final List<ObbState> obbStatesToRemove = new LinkedList<ObbState>();
+
+ final Iterator<Entry<String, ObbState>> i =
+ mObbPathToStateMap.entrySet().iterator();
+ while (i.hasNext()) {
+ final Entry<String, ObbState> obbEntry = i.next();
+
+ /*
+ * If this entry's source file is in the volume path
+ * that got unmounted, remove it because it's no
+ * longer valid.
+ */
+ if (obbEntry.getKey().startsWith(path)) {
+ obbStatesToRemove.add(obbEntry.getValue());
+ }
+ }
+
+ for (final ObbState obbState : obbStatesToRemove) {
+ if (DEBUG_OBB)
+ Slog.i(TAG, "Removing state for " + obbState.filename);
+
+ removeObbStateLocked(obbState);
+
+ try {
+ obbState.token.onObbResult(obbState.filename, obbState.nonce,
+ OnObbStateChangeListener.UNMOUNTED);
+ } catch (RemoteException e) {
+ Slog.i(TAG, "Couldn't send unmount notification for OBB: "
+ + obbState.filename);
+ }
+ }
+ }
+ break;
+ }
}
}
@@ -1903,9 +1862,13 @@ class MountService extends IMountService.Stub
return obbInfo;
}
- protected void sendNewStatusOrIgnore(String filename, String status) {
+ protected void sendNewStatusOrIgnore(int status) {
+ if (mObbState == null || mObbState.token == null) {
+ return;
+ }
+
try {
- mObbState.token.onObbResult(filename, status);
+ mObbState.token.onObbResult(mObbState.filename, mObbState.nonce, status);
} catch (RemoteException e) {
Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged");
}
@@ -1921,89 +1884,80 @@ class MountService extends IMountService.Stub
}
public void handleExecute() throws IOException, RemoteException {
+ waitForReady();
+ warnOnNotMounted();
+
final ObbInfo obbInfo = getObbInfo();
+ if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mObbState.callerUid)) {
+ Slog.w(TAG, "Denied attempt to mount OBB " + obbInfo.filename
+ + " which is owned by " + obbInfo.packageName);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
+ return;
+ }
+
+ final boolean isMounted;
+ synchronized (mObbMounts) {
+ isMounted = mObbPathToStateMap.containsKey(obbInfo.filename);
+ }
+ if (isMounted) {
+ Slog.w(TAG, "Attempt to mount OBB which is already mounted: " + obbInfo.filename);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
+ return;
+ }
+
/*
- * If someone tried to trick us with some weird characters, rectify
- * it here.
+ * The filename passed in might not be the canonical name, so just
+ * set the filename to the canonicalized version.
*/
- if (!mObbState.filename.equals(obbInfo.filename)) {
- if (DEBUG_OBB)
- Slog.i(TAG, "OBB filename " + mObbState.filename + " is actually "
- + obbInfo.filename);
-
- synchronized (mObbMounts) {
- /*
- * If the real filename is already mounted, discard this
- * state and notify the caller that the OBB is already
- * mounted.
- */
- if (isObbMounted(obbInfo.filename)) {
- if (DEBUG_OBB)
- Slog.i(TAG, "OBB already mounted as " + obbInfo.filename);
-
- removeObbState(mObbState);
- sendNewStatusOrIgnore(obbInfo.filename, Environment.MEDIA_MOUNTED);
- return;
- }
+ mObbState.filename = obbInfo.filename;
- /*
- * It's not already mounted, so we have to replace the state
- * with the state containing the actual filename.
- */
- ObbState newObbState = new ObbState(obbInfo.filename, mObbState.token,
- mObbState.callerUid);
- replaceObbState(mObbState, newObbState);
- mObbState = newObbState;
+ final String hashedKey;
+ if (mKey == null) {
+ hashedKey = "none";
+ } else {
+ final MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ Slog.e(TAG, "Could not load MD5 algorithm", e);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
+ return;
}
- }
- if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mObbState.callerUid)) {
- throw new IllegalArgumentException("Caller package does not match OBB file");
+ hashedKey = HexDump.toHexString(md.digest(mKey.getBytes()));
}
- boolean mounted = false;
- int rc;
- synchronized (mObbState) {
- if (mObbState.mounted) {
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED);
- return;
+ int rc = StorageResultCode.OperationSucceeded;
+ String cmd = String.format("obb mount %s %s %d", mObbState.filename, hashedKey,
+ mObbState.callerUid);
+ try {
+ mConnector.doCommand(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ int code = e.getCode();
+ if (code != VoldResponseCode.OpFailedStorageBusy) {
+ rc = StorageResultCode.OperationFailedInternalError;
}
+ }
- rc = StorageResultCode.OperationSucceeded;
- String cmd = String.format("obb mount %s %s %d", mObbState.filename,
- mKey != null ? mKey : "none",
- mObbState.callerUid);
- try {
- mConnector.doCommand(cmd);
- } catch (NativeDaemonConnectorException e) {
- int code = e.getCode();
- if (code != VoldResponseCode.OpFailedStorageBusy) {
- rc = StorageResultCode.OperationFailedInternalError;
- }
- }
+ if (rc == StorageResultCode.OperationSucceeded) {
+ if (DEBUG_OBB)
+ Slog.d(TAG, "Successfully mounted OBB " + mObbState.filename);
- if (rc == StorageResultCode.OperationSucceeded) {
- mObbState.mounted = mounted = true;
+ synchronized (mObbMounts) {
+ addObbStateLocked(mObbState);
}
- }
- if (mounted) {
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.MOUNTED);
} else {
Slog.e(TAG, "Couldn't mount OBB file: " + rc);
- // We didn't succeed, so remove this from the mount-set.
- removeObbState(mObbState);
-
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT);
}
}
public void handleError() {
- removeObbState(mObbState);
-
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_BAD_REMOVAL);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
}
@Override
@@ -2016,6 +1970,8 @@ class MountService extends IMountService.Stub
sb.append(mObbState.callerUid);
sb.append(",token=");
sb.append(mObbState.token != null ? mObbState.token.toString() : "NULL");
+ sb.append(",binder=");
+ sb.append(mObbState.token != null ? mObbState.getBinder().toString() : "null");
sb.append('}');
return sb.toString();
}
@@ -2030,68 +1986,61 @@ class MountService extends IMountService.Stub
}
public void handleExecute() throws IOException {
+ waitForReady();
+ warnOnNotMounted();
+
final ObbInfo obbInfo = getObbInfo();
- /*
- * If someone tried to trick us with some weird characters, rectify
- * it here.
- */
+ final ObbState obbState;
synchronized (mObbMounts) {
- if (!isObbMounted(obbInfo.filename)) {
- removeObbState(mObbState);
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED);
- return;
- }
+ obbState = mObbPathToStateMap.get(obbInfo.filename);
+ }
- if (!mObbState.filename.equals(obbInfo.filename)) {
- removeObbState(mObbState);
- mObbState = mObbPathToStateMap.get(obbInfo.filename);
- }
+ if (obbState == null) {
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_NOT_MOUNTED);
+ return;
}
- boolean unmounted = false;
- synchronized (mObbState) {
- if (!mObbState.mounted) {
- sendNewStatusOrIgnore(obbInfo.filename, Environment.MEDIA_UNMOUNTED);
- return;
- }
+ if (obbState.callerUid != mObbState.callerUid) {
+ Slog.w(TAG, "Permission denied attempting to unmount OBB " + obbInfo.filename
+ + " (owned by " + obbInfo.packageName + ")");
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
+ return;
+ }
- int rc = StorageResultCode.OperationSucceeded;
- String cmd = String.format("obb unmount %s%s", mObbState.filename,
- (mForceUnmount ? " force" : ""));
- try {
- mConnector.doCommand(cmd);
- } catch (NativeDaemonConnectorException e) {
- int code = e.getCode();
- if (code == VoldResponseCode.OpFailedStorageBusy) {
- rc = StorageResultCode.OperationFailedStorageBusy;
- } else if (code == VoldResponseCode.OpFailedStorageNotFound) {
- // If it's not mounted then we've already won.
- rc = StorageResultCode.OperationSucceeded;
- } else {
- rc = StorageResultCode.OperationFailedInternalError;
- }
- }
+ mObbState.filename = obbInfo.filename;
- if (rc == StorageResultCode.OperationSucceeded) {
- mObbState.mounted = false;
- unmounted = true;
+ int rc = StorageResultCode.OperationSucceeded;
+ String cmd = String.format("obb unmount %s%s", mObbState.filename,
+ (mForceUnmount ? " force" : ""));
+ try {
+ mConnector.doCommand(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ int code = e.getCode();
+ if (code == VoldResponseCode.OpFailedStorageBusy) {
+ rc = StorageResultCode.OperationFailedStorageBusy;
+ } else if (code == VoldResponseCode.OpFailedStorageNotFound) {
+ // If it's not mounted then we've already won.
+ rc = StorageResultCode.OperationSucceeded;
+ } else {
+ rc = StorageResultCode.OperationFailedInternalError;
}
}
- if (unmounted) {
- removeObbState(mObbState);
+ if (rc == StorageResultCode.OperationSucceeded) {
+ synchronized (mObbMounts) {
+ removeObbStateLocked(obbState);
+ }
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_UNMOUNTED);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.UNMOUNTED);
} else {
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_MOUNTED);
+ Slog.w(TAG, "Could not mount OBB: " + mObbState.filename);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_COULD_NOT_UNMOUNT);
}
}
public void handleError() {
- removeObbState(mObbState);
-
- sendNewStatusOrIgnore(mObbState.filename, Environment.MEDIA_BAD_REMOVAL);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
}
@Override
@@ -2107,7 +2056,7 @@ class MountService extends IMountService.Stub
sb.append(",token=");
sb.append(mObbState.token != null ? mObbState.token.toString() : "null");
sb.append(",binder=");
- sb.append(mObbState.getBinder().toString());
+ sb.append(mObbState.token != null ? mObbState.getBinder().toString() : "null");
sb.append('}');
return sb.toString();
}
@@ -2122,16 +2071,27 @@ class MountService extends IMountService.Stub
return;
}
- pw.println(" mObbMounts:");
-
synchronized (mObbMounts) {
- final Collection<List<ObbState>> obbStateLists = mObbMounts.values();
+ pw.println(" mObbMounts:");
- for (final List<ObbState> obbStates : obbStateLists) {
+ final Iterator<Entry<IBinder, List<ObbState>>> binders = mObbMounts.entrySet().iterator();
+ while (binders.hasNext()) {
+ Entry<IBinder, List<ObbState>> e = binders.next();
+ pw.print(" Key="); pw.println(e.getKey().toString());
+ final List<ObbState> obbStates = e.getValue();
for (final ObbState obbState : obbStates) {
- pw.print(" "); pw.println(obbState.toString());
+ pw.print(" "); pw.println(obbState.toString());
}
}
+
+ pw.println("");
+ pw.println(" mObbPathToStateMap:");
+ final Iterator<Entry<String, ObbState>> maps = mObbPathToStateMap.entrySet().iterator();
+ while (maps.hasNext()) {
+ final Entry<String, ObbState> e = maps.next();
+ pw.print(" "); pw.print(e.getKey());
+ pw.print(" -> "); pw.println(e.getValue().toString());
+ }
}
}
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 5afabbd..15eaa9e 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -741,10 +741,6 @@ public class NotificationManagerService extends INotificationManager.Stub
throw new IllegalArgumentException("contentView required: pkg=" + pkg
+ " id=" + id + " notification=" + notification);
}
- if (notification.contentIntent == null) {
- throw new IllegalArgumentException("contentIntent required: pkg=" + pkg
- + " id=" + id + " notification=" + notification);
- }
}
synchronized (mNotificationList) {
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index a3d5961..608ffe1 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -7208,6 +7208,8 @@ class PackageManagerService extends IPackageManager.Stub {
pw.print(" pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
pw.print(" installStatus="); pw.print(ps.installStatus);
pw.print(" enabled="); pw.println(ps.enabled);
+ pw.print(" versionCode="); pw.print(ps.versionCode);
+ pw.print(" versionName="); pw.println(ps.pkg.mVersionName);
if (ps.disabledComponents.size() > 0) {
pw.println(" disabledComponents:");
for (String s : ps.disabledComponents) {
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 9d9ad26..36298d1 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -141,9 +141,7 @@ class PowerManagerService extends IPowerManager.Stub
// used for noChangeLights in setPowerState()
private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;
- static final boolean ANIMATE_SCREEN_LIGHTS = true;
- static final boolean ANIMATE_BUTTON_LIGHTS = false;
- static final boolean ANIMATE_KEYBOARD_LIGHTS = false;
+ boolean mAnimateScreenLights = true;
static final int ANIM_STEPS = 60/4;
// Slower animation for autobrightness changes
@@ -201,15 +199,12 @@ class PowerManagerService extends IPowerManager.Stub
private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
private UnsynchronizedWakeLock mProximityPartialLock;
private HandlerThread mHandlerThread;
+ private HandlerThread mScreenOffThread;
+ private Handler mScreenOffHandler;
private Handler mHandler;
private final TimeoutTask mTimeoutTask = new TimeoutTask();
- private final LightAnimator mLightAnimator = new LightAnimator();
private final BrightnessState mScreenBrightness
= new BrightnessState(SCREEN_BRIGHT_BIT);
- private final BrightnessState mKeyboardBrightness
- = new BrightnessState(KEYBOARD_BRIGHT_BIT);
- private final BrightnessState mButtonBrightness
- = new BrightnessState(BUTTON_BRIGHT_BIT);
private boolean mStillNeedSleepNotification;
private boolean mIsPowered = false;
private IActivityManager mActivityService;
@@ -261,6 +256,7 @@ class PowerManagerService extends IPowerManager.Stub
private native void nativeInit();
private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
+ private native void nativeStartSurfaceFlingerAnimation();
/*
static PrintStream mLog;
@@ -485,6 +481,35 @@ class PowerManagerService extends IPowerManager.Stub
mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
+ nativeInit();
+ synchronized (mLocks) {
+ updateNativePowerStateLocked();
+ }
+
+ mInitComplete = false;
+ mScreenOffThread = new HandlerThread("PowerManagerService.mScreenOffThread") {
+ @Override
+ protected void onLooperPrepared() {
+ mScreenOffHandler = new Handler();
+ synchronized (mScreenOffThread) {
+ mInitComplete = true;
+ mScreenOffThread.notifyAll();
+ }
+ }
+ };
+ mScreenOffThread.start();
+
+ synchronized (mScreenOffThread) {
+ while (!mInitComplete) {
+ try {
+ mScreenOffThread.wait();
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+
+ mInitComplete = false;
mHandlerThread = new HandlerThread("PowerManagerService") {
@Override
protected void onLooperPrepared() {
@@ -531,6 +556,9 @@ class PowerManagerService extends IPowerManager.Stub
Resources resources = mContext.getResources();
+ mAnimateScreenLights = resources.getBoolean(
+ com.android.internal.R.bool.config_animateScreenLights);
+
mUnplugTurnsOnScreen = resources.getBoolean(
com.android.internal.R.bool.config_unplugTurnsOnScreen);
@@ -1093,8 +1121,6 @@ class PowerManagerService extends IPowerManager.Stub
pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
mScreenBrightness.dump(pw, " mScreenBrightness: ");
- mKeyboardBrightness.dump(pw, " mKeyboardBrightness: ");
- mButtonBrightness.dump(pw, " mButtonBrightness: ");
int N = mLocks.size();
pw.println();
@@ -1724,7 +1750,8 @@ class PowerManagerService extends IPowerManager.Stub
// I don't think we need to check the current state here because all of these
// Power.setScreenState and sendNotificationLocked can both handle being
// called multiple times in the same state. -joeo
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime, mTouchCycles);
+ EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
+ mTouchCycles);
mLastTouchDown = 0;
int err = setScreenStateLocked(false);
if (err == 0) {
@@ -1754,145 +1781,95 @@ class PowerManagerService extends IPowerManager.Stub
int onMask = 0;
int preferredBrightness = getPreferredBrightness();
- boolean startAnimation = false;
if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
- if (ANIMATE_KEYBOARD_LIGHTS) {
- if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
- mKeyboardBrightness.setTargetLocked(Power.BRIGHTNESS_OFF,
- ANIM_STEPS, INITIAL_KEYBOARD_BRIGHTNESS,
- Power.BRIGHTNESS_ON);
- } else {
- mKeyboardBrightness.setTargetLocked(Power.BRIGHTNESS_ON,
- ANIM_STEPS, INITIAL_KEYBOARD_BRIGHTNESS,
- Power.BRIGHTNESS_OFF);
- }
- startAnimation = true;
+ if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
+ offMask |= KEYBOARD_BRIGHT_BIT;
} else {
- if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
- offMask |= KEYBOARD_BRIGHT_BIT;
- } else {
- onMask |= KEYBOARD_BRIGHT_BIT;
- }
+ onMask |= KEYBOARD_BRIGHT_BIT;
}
}
if ((difference & BUTTON_BRIGHT_BIT) != 0) {
- if (ANIMATE_BUTTON_LIGHTS) {
- if ((newState & BUTTON_BRIGHT_BIT) == 0) {
- mButtonBrightness.setTargetLocked(Power.BRIGHTNESS_OFF,
- ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- Power.BRIGHTNESS_ON);
- } else {
- mButtonBrightness.setTargetLocked(Power.BRIGHTNESS_ON,
- ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- Power.BRIGHTNESS_OFF);
- }
- startAnimation = true;
+ if ((newState & BUTTON_BRIGHT_BIT) == 0) {
+ offMask |= BUTTON_BRIGHT_BIT;
} else {
- if ((newState & BUTTON_BRIGHT_BIT) == 0) {
- offMask |= BUTTON_BRIGHT_BIT;
- } else {
- onMask |= BUTTON_BRIGHT_BIT;
- }
+ onMask |= BUTTON_BRIGHT_BIT;
}
}
if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
- if (ANIMATE_SCREEN_LIGHTS) {
- int nominalCurrentValue = -1;
- // If there was an actual difference in the light state, then
- // figure out the "ideal" current value based on the previous
- // state. Otherwise, this is a change due to the brightness
- // override, so we want to animate from whatever the current
- // value is.
- if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
- switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
- case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
- nominalCurrentValue = preferredBrightness;
- break;
- case SCREEN_ON_BIT:
- nominalCurrentValue = Power.BRIGHTNESS_DIM;
- break;
- case 0:
- nominalCurrentValue = Power.BRIGHTNESS_OFF;
- break;
- case SCREEN_BRIGHT_BIT:
- default:
- // not possible
- nominalCurrentValue = (int)mScreenBrightness.curValue;
- break;
- }
+ int nominalCurrentValue = -1;
+ // If there was an actual difference in the light state, then
+ // figure out the "ideal" current value based on the previous
+ // state. Otherwise, this is a change due to the brightness
+ // override, so we want to animate from whatever the current
+ // value is.
+ if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
+ switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
+ case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
+ nominalCurrentValue = preferredBrightness;
+ break;
+ case SCREEN_ON_BIT:
+ nominalCurrentValue = Power.BRIGHTNESS_DIM;
+ break;
+ case 0:
+ nominalCurrentValue = Power.BRIGHTNESS_OFF;
+ break;
+ case SCREEN_BRIGHT_BIT:
+ default:
+ // not possible
+ nominalCurrentValue = (int)mScreenBrightness.curValue;
+ break;
}
- int brightness = preferredBrightness;
- int steps = ANIM_STEPS;
- if ((newState & SCREEN_BRIGHT_BIT) == 0) {
- // dim or turn off backlight, depending on if the screen is on
- // the scale is because the brightness ramp isn't linear and this biases
- // it so the later parts take longer.
- final float scale = 1.5f;
- float ratio = (((float)Power.BRIGHTNESS_DIM)/preferredBrightness);
- if (ratio > 1.0f) ratio = 1.0f;
- if ((newState & SCREEN_ON_BIT) == 0) {
- if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
- // was bright
- steps = ANIM_STEPS;
- } else {
- // was dim
- steps = (int)(ANIM_STEPS*ratio*scale);
- }
- brightness = Power.BRIGHTNESS_OFF;
+ }
+ int brightness = preferredBrightness;
+ int steps = ANIM_STEPS;
+ if ((newState & SCREEN_BRIGHT_BIT) == 0) {
+ // dim or turn off backlight, depending on if the screen is on
+ // the scale is because the brightness ramp isn't linear and this biases
+ // it so the later parts take longer.
+ final float scale = 1.5f;
+ float ratio = (((float)Power.BRIGHTNESS_DIM)/preferredBrightness);
+ if (ratio > 1.0f) ratio = 1.0f;
+ if ((newState & SCREEN_ON_BIT) == 0) {
+ if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
+ // was bright
+ steps = ANIM_STEPS;
} else {
- if ((oldState & SCREEN_ON_BIT) != 0) {
- // was bright
- steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
- } else {
- // was dim
- steps = (int)(ANIM_STEPS*ratio);
- }
- if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
- // If the "stay on while plugged in" option is
- // turned on, then the screen will often not
- // automatically turn off while plugged in. To
- // still have a sense of when it is inactive, we
- // will then count going dim as turning off.
- mScreenOffTime = SystemClock.elapsedRealtime();
- }
- brightness = Power.BRIGHTNESS_DIM;
+ // was dim
+ steps = (int)(ANIM_STEPS*ratio*scale);
}
- }
- long identity = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteScreenBrightness(brightness);
- } catch (RemoteException e) {
- // Nothing interesting to do.
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- if (mScreenBrightness.setTargetLocked(brightness,
- steps, INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue)) {
- startAnimation = true;
- }
- } else {
- if ((newState & SCREEN_BRIGHT_BIT) == 0) {
- // dim or turn off backlight, depending on if the screen is on
- if ((newState & SCREEN_ON_BIT) == 0) {
- offMask |= SCREEN_BRIGHT_BIT;
+ brightness = Power.BRIGHTNESS_OFF;
+ } else {
+ if ((oldState & SCREEN_ON_BIT) != 0) {
+ // was bright
+ steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
} else {
- dimMask |= SCREEN_BRIGHT_BIT;
+ // was dim
+ steps = (int)(ANIM_STEPS*ratio);
}
- } else {
- onMask |= SCREEN_BRIGHT_BIT;
+ if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
+ // If the "stay on while plugged in" option is
+ // turned on, then the screen will often not
+ // automatically turn off while plugged in. To
+ // still have a sense of when it is inactive, we
+ // will then count going dim as turning off.
+ mScreenOffTime = SystemClock.elapsedRealtime();
+ }
+ brightness = Power.BRIGHTNESS_DIM;
}
}
- }
-
- if (startAnimation) {
- if (mSpew) {
- Slog.i(TAG, "Scheduling light animator!");
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteScreenBrightness(brightness);
+ } catch (RemoteException e) {
+ // Nothing interesting to do.
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- mHandler.removeCallbacks(mLightAnimator);
- mHandler.post(mLightAnimator);
+ mScreenBrightness.setTargetLocked(brightness, steps,
+ INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
}
if (offMask != 0) {
@@ -1934,7 +1911,7 @@ class PowerManagerService extends IPowerManager.Stub
}
}
- class BrightnessState {
+ class BrightnessState implements Runnable {
final int mask;
boolean initialized;
@@ -1954,13 +1931,13 @@ class PowerManagerService extends IPowerManager.Stub
+ " delta=" + delta);
}
- boolean setTargetLocked(int target, int stepsToTarget, int initialValue,
+ void setTargetLocked(int target, int stepsToTarget, int initialValue,
int nominalCurrentValue) {
if (!initialized) {
initialized = true;
curValue = (float)initialValue;
} else if (targetValue == target) {
- return false;
+ return;
}
targetValue = target;
delta = (targetValue -
@@ -1974,7 +1951,12 @@ class PowerManagerService extends IPowerManager.Stub
+ noticeMe);
}
animating = true;
- return true;
+
+ if (mSpew) {
+ Slog.i(TAG, "scheduling light animator");
+ }
+ mScreenOffHandler.removeCallbacks(this);
+ mScreenOffHandler.post(this);
}
boolean stepLocked() {
@@ -2000,32 +1982,50 @@ class PowerManagerService extends IPowerManager.Stub
more = false;
}
}
- //Slog.i(TAG, "Animating brightess " + curIntValue + ": " + mask);
+ if (mSpew) Slog.d(TAG, "Animating curIntValue=" + curIntValue + ": " + mask);
setLightBrightness(mask, curIntValue);
+ finishAnimation(more, curIntValue);
+ return more;
+ }
+
+ void jumpToTarget() {
+ if (mSpew) Slog.d(TAG, "jumpToTarget targetValue=" + targetValue + ": " + mask);
+ setLightBrightness(mask, targetValue);
+ final int tv = targetValue;
+ curValue = tv;
+ targetValue = -1;
+ finishAnimation(false, tv);
+ }
+
+ private void finishAnimation(boolean more, int curIntValue) {
animating = more;
if (!more) {
if (mask == SCREEN_BRIGHT_BIT && curIntValue == Power.BRIGHTNESS_OFF) {
screenOffFinishedAnimatingLocked(mScreenOffReason);
}
}
- return more;
}
- }
- private class LightAnimator implements Runnable {
public void run() {
- synchronized (mLocks) {
- long now = SystemClock.uptimeMillis();
- boolean more = mScreenBrightness.stepLocked();
- if (mKeyboardBrightness.stepLocked()) {
- more = true;
+ if (mAnimateScreenLights) {
+ synchronized (mLocks) {
+ long now = SystemClock.uptimeMillis();
+ boolean more = mScreenBrightness.stepLocked();
+ if (more) {
+ mScreenOffHandler.postAtTime(this, now+(1000/60));
+ }
}
- if (mButtonBrightness.stepLocked()) {
- more = true;
+ } else {
+ boolean animate;
+ boolean jump;
+ synchronized (mLocks) {
+ jump = animating; // we haven't already run this animation
+ animate = jump && targetValue == Power.BRIGHTNESS_OFF; // we're turning off
}
- if (more) {
- mHandler.postAtTime(mLightAnimator, now+(1000/60));
+ if (animate) {
+ nativeStartSurfaceFlingerAnimation();
}
+ mScreenBrightness.jumpToTarget();
}
}
}
@@ -2343,49 +2343,15 @@ class PowerManagerService extends IPowerManager.Stub
Slog.d(TAG, "keyboardValue " + keyboardValue);
}
- boolean startAnimation = false;
if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
- if (ANIMATE_SCREEN_LIGHTS) {
- if (mScreenBrightness.setTargetLocked(lcdValue,
- AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_SCREEN_BRIGHTNESS,
- (int)mScreenBrightness.curValue)) {
- startAnimation = true;
- }
- } else {
- int brightnessMode = (mAutoBrightessEnabled
- ? LightsService.BRIGHTNESS_MODE_SENSOR
- : LightsService.BRIGHTNESS_MODE_USER);
- mLcdLight.setBrightness(lcdValue, brightnessMode);
- }
+ mScreenBrightness.setTargetLocked(lcdValue, AUTOBRIGHTNESS_ANIM_STEPS,
+ INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue);
}
if (mButtonBrightnessOverride < 0) {
- if (ANIMATE_BUTTON_LIGHTS) {
- if (mButtonBrightness.setTargetLocked(buttonValue,
- AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- (int)mButtonBrightness.curValue)) {
- startAnimation = true;
- }
- } else {
- mButtonLight.setBrightness(buttonValue);
- }
+ mButtonLight.setBrightness(buttonValue);
}
if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
- if (ANIMATE_KEYBOARD_LIGHTS) {
- if (mKeyboardBrightness.setTargetLocked(keyboardValue,
- AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- (int)mKeyboardBrightness.curValue)) {
- startAnimation = true;
- }
- } else {
- mKeyboardLight.setBrightness(keyboardValue);
- }
- }
- if (startAnimation) {
- if (mDebugLightSensor) {
- Slog.i(TAG, "lightSensorChangedLocked scheduling light animator");
- }
- mHandler.removeCallbacks(mLightAnimator);
- mHandler.post(mLightAnimator);
+ mKeyboardLight.setBrightness(keyboardValue);
}
}
}
@@ -2754,6 +2720,7 @@ class PowerManagerService extends IPowerManager.Stub
}
}
+ // for watchdog
public void monitor() {
synchronized (mLocks) { }
}
@@ -2773,34 +2740,23 @@ class PowerManagerService extends IPowerManager.Stub
public void setBacklightBrightness(int brightness) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
// Don't let applications turn the screen all the way off
- brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
- mLcdLight.setBrightness(brightness);
- mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
- mButtonLight.setBrightness(brightness);
- long identity = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteScreenBrightness(brightness);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ synchronized (mLocks) {
+ brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
+ mLcdLight.setBrightness(brightness);
+ mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
+ mButtonLight.setBrightness(brightness);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteScreenBrightness(brightness);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
- // update our animation state
- if (ANIMATE_SCREEN_LIGHTS) {
- mScreenBrightness.curValue = brightness;
- mScreenBrightness.animating = false;
- mScreenBrightness.targetValue = -1;
- }
- if (ANIMATE_KEYBOARD_LIGHTS) {
- mKeyboardBrightness.curValue = brightness;
- mKeyboardBrightness.animating = false;
- mKeyboardBrightness.targetValue = -1;
- }
- if (ANIMATE_BUTTON_LIGHTS) {
- mButtonBrightness.curValue = brightness;
- mButtonBrightness.animating = false;
- mButtonBrightness.targetValue = -1;
+ // update our animation state
+ mScreenBrightness.targetValue = brightness;
+ mScreenBrightness.jumpToTarget();
}
}
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index b1baec5..66e0214 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -72,6 +72,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub
// We usually call it lights out mode, but double negatives are annoying
boolean mLightsOn = true;
+ boolean mMenuVisible = false;
+
private class DisableRecord implements IBinder.DeathRecipient {
String pkg;
int what;
@@ -246,6 +248,32 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}
}
+ /**
+ * Hide or show the on-screen Menu key. Only call this from the window manager, typically in
+ * response to a window with FLAG_NEEDS_MENU_KEY set.
+ */
+ public void setMenuKeyVisible(final boolean visible) {
+ enforceStatusBar();
+
+ if (SPEW) Slog.d(TAG, (visible?"showing":"hiding") + " MENU key");
+
+ synchronized(mLock) {
+ if (mMenuVisible != visible) {
+ mMenuVisible = visible;
+ mHandler.post(new Runnable() {
+ public void run() {
+ if (mBar != null) {
+ try {
+ mBar.setMenuKeyVisible(visible);
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
/**
* This is used for the automatic version of lights-out mode. Only call this from
* the window manager.
@@ -317,7 +345,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub
// ================================================================================
public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
List<IBinder> notificationKeys, List<StatusBarNotification> notifications,
- boolean lightsOn[]) {
+ boolean switches[]) {
enforceStatusBarService();
Slog.i(TAG, "registerStatusBar bar=" + bar);
@@ -332,7 +360,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}
}
synchronized (mLock) {
- lightsOn[0] = mLightsOn;
+ switches[0] = mLightsOn;
+ switches[1] = mMenuVisible;
}
}
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index 459551d..d10f54f 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -24,7 +24,8 @@ LOCAL_SHARED_LIBRARIES := \
libnativehelper \
libsystem_server \
libutils \
- libui
+ libui \
+ libsurfaceflinger_client
LOCAL_STATIC_LIBRARIES := libusbhost
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index e15e8d8..599163b 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -842,31 +842,35 @@ void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
}
- const int32_t WM_ACTION_PASS_TO_USER = 1;
- const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
- const int32_t WM_ACTION_GO_TO_SLEEP = 4;
+ // Policy:
+ // - Ignore untrusted events and pass them along.
+ // - Ask the window manager what to do with normal events and trusted injected events.
+ // - For normal events wake and brighten the screen if currently off or dim.
+ if ((policyFlags & POLICY_FLAG_TRUSTED)) {
+ const int32_t WM_ACTION_PASS_TO_USER = 1;
+ const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
+ const int32_t WM_ACTION_GO_TO_SLEEP = 4;
+
+ bool isScreenOn = this->isScreenOn();
+ bool isScreenBright = this->isScreenBright();
- bool isScreenOn = this->isScreenOn();
- bool isScreenBright = this->isScreenBright();
-
- JNIEnv* env = jniEnv();
- jint wmActions = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.interceptKeyBeforeQueueing,
- when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
- if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
- wmActions = 0;
- }
-
- if (policyFlags & POLICY_FLAG_TRUSTED) {
- if (! isScreenOn) {
- // Key presses and releases wake the device.
- policyFlags |= POLICY_FLAG_WOKE_HERE;
- flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+ JNIEnv* env = jniEnv();
+ jint wmActions = env->CallIntMethod(mCallbacksObj,
+ gCallbacksClassInfo.interceptKeyBeforeQueueing,
+ when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
+ if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
+ wmActions = 0;
}
- if (! isScreenBright) {
- // Key presses and releases brighten the screen if dimmed.
- policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+ if (!(flags & POLICY_FLAG_INJECTED)) {
+ if (!isScreenOn) {
+ policyFlags |= POLICY_FLAG_WOKE_HERE;
+ flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+ }
+
+ if (!isScreenBright) {
+ policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+ }
}
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
@@ -876,9 +880,11 @@ void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
}
- }
- if (wmActions & WM_ACTION_PASS_TO_USER) {
+ if (wmActions & WM_ACTION_PASS_TO_USER) {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
+ }
+ } else {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
}
@@ -888,33 +894,47 @@ void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t&
LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
#endif
- if (isScreenOn()) {
- // Only dispatch events when the device is awake.
- // Do not wake the device.
- policyFlags |= POLICY_FLAG_PASS_TO_USER;
-
- if ((policyFlags & POLICY_FLAG_TRUSTED) && !isScreenBright()) {
- // Brighten the screen if dimmed.
- policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+ // Policy:
+ // - Ignore untrusted events and pass them along.
+ // - No special filtering for injected events required at this time.
+ // - Filter normal events based on screen state.
+ // - For normal events brighten (but do not wake) the screen if currently dim.
+ if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
+ if (isScreenOn()) {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
+
+ if (!isScreenBright()) {
+ policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+ }
}
+ } else {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
}
bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags) {
- JNIEnv* env = jniEnv();
+ // Policy:
+ // - Ignore untrusted events and pass them along.
+ // - Filter normal events and trusted injected events through the window manager policy to
+ // handle the HOME key and the like.
+ if (policyFlags & POLICY_FLAG_TRUSTED) {
+ JNIEnv* env = jniEnv();
+
+ // Note: inputChannel may be null.
+ jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
+ jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
+ gCallbacksClassInfo.interceptKeyBeforeDispatching,
+ inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
+ keyEvent->getKeyCode(), keyEvent->getMetaState(),
+ keyEvent->getRepeatCount(), policyFlags);
+ bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
- // Note: inputChannel may be null.
- jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
- jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
- gCallbacksClassInfo.interceptKeyBeforeDispatching,
- inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
- keyEvent->getKeyCode(), keyEvent->getMetaState(),
- keyEvent->getRepeatCount(), policyFlags);
- bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
-
- env->DeleteLocalRef(inputChannelObj);
- return consumed && ! error;
+ env->DeleteLocalRef(inputChannelObj);
+ return consumed && ! error;
+ } else {
+ return false;
+ }
}
void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp
index 146c177..2ec20bd 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_PowerManagerService.cpp
@@ -20,9 +20,14 @@
#include "JNIHelp.h"
#include "jni.h"
+
#include <limits.h>
+
#include <android_runtime/AndroidRuntime.h>
#include <utils/Timers.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
#include "com_android_server_PowerManagerService.h"
namespace android {
@@ -119,6 +124,12 @@ static void android_server_PowerManagerService_nativeSetPowerState(JNIEnv* env,
gScreenBright = screenBright;
}
+static void android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation(JNIEnv* env,
+ jobject obj) {
+ sp<ISurfaceComposer> s(ComposerService::getComposerService());
+ s->turnElectronBeamOff(0);
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gPowerManagerServiceMethods[] = {
@@ -127,6 +138,8 @@ static JNINativeMethod gPowerManagerServiceMethods[] = {
(void*) android_server_PowerManagerService_nativeInit },
{ "nativeSetPowerState", "(ZZ)V",
(void*) android_server_PowerManagerService_nativeSetPowerState },
+ { "nativeStartSurfaceFlingerAnimation", "()V",
+ (void*) android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation },
};
#define FIND_CLASS(var, className) \
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
index 1d09f84..fe9a5ab 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -359,7 +359,7 @@ status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
uint32_t displayIndex)
- : mCanDraw(true)
+ : mCanDraw(true), mScreenAcquired(true)
{
mDisplayEventThread = new DisplayEventThread(flinger);
if (mDisplayEventThread->initCheck() != NO_ERROR) {
@@ -374,18 +374,21 @@ DisplayHardwareBase::~DisplayHardwareBase()
mDisplayEventThread->requestExitAndWait();
}
+void DisplayHardwareBase::setCanDraw(bool canDraw)
+{
+ mCanDraw = canDraw;
+}
bool DisplayHardwareBase::canDraw() const
{
- return mCanDraw;
+ return mCanDraw && mScreenAcquired;
}
void DisplayHardwareBase::releaseScreen() const
{
status_t err = mDisplayEventThread->releaseScreen();
if (err >= 0) {
- //LOGD("screen given-up");
- mCanDraw = false;
+ mScreenAcquired = false;
}
}
@@ -393,9 +396,14 @@ void DisplayHardwareBase::acquireScreen() const
{
status_t err = mDisplayEventThread->acquireScreen();
if (err >= 0) {
- //LOGD("screen returned");
mCanDraw = true;
+ mScreenAcquired = true;
}
}
+bool DisplayHardwareBase::isScreenAcquired() const
+{
+ return mScreenAcquired;
+}
+
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
index 8369bb8..fa6a0c4 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
@@ -40,7 +40,11 @@ public:
// console managment
void releaseScreen() const;
void acquireScreen() const;
+ bool isScreenAcquired() const;
+
bool canDraw() const;
+ void setCanDraw(bool canDraw);
+
private:
class DisplayEventThreadBase : public Thread {
@@ -89,6 +93,7 @@ private:
sp<DisplayEventThreadBase> mDisplayEventThread;
mutable int mCanDraw;
+ mutable int mScreenAcquired;
};
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e6bdfd1..97365aa 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -430,14 +430,14 @@ void SurfaceFlinger::handleConsoleEvents()
hw.acquireScreen();
}
- if (mDeferReleaseConsole && hw.canDraw()) {
+ if (mDeferReleaseConsole && hw.isScreenAcquired()) {
// We got the release signal before the acquire signal
mDeferReleaseConsole = false;
hw.releaseScreen();
}
if (what & eConsoleReleased) {
- if (hw.canDraw()) {
+ if (hw.isScreenAcquired()) {
hw.releaseScreen();
} else {
mDeferReleaseConsole = true;
@@ -1558,6 +1558,7 @@ status_t SurfaceFlinger::onTransact(
case FREEZE_DISPLAY:
case UNFREEZE_DISPLAY:
case BOOT_FINISHED:
+ case TURN_ELECTRON_BEAM_OFF:
{
// codes that require permission check
IPCThreadState* ipc = IPCThreadState::self();
@@ -1651,6 +1652,231 @@ status_t SurfaceFlinger::onTransact(
return err;
}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::turnElectronBeamOffImplLocked()
+{
+ status_t result = PERMISSION_DENIED;
+
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
+ // get screen geometry
+ const int dpy = 0;
+ const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
+ if (!hw.canDraw()) {
+ // we're already off
+ return NO_ERROR;
+ }
+
+ const uint32_t hw_w = hw.getWidth();
+ const uint32_t hw_h = hw.getHeight();
+ const Region screenBounds(hw.bounds());
+ GLfloat u = 1;
+ GLfloat v = 1;
+
+ // make sure to clear all GL error flags
+ while ( glGetError() != GL_NO_ERROR ) ;
+
+ // create a FBO
+ GLuint name, tname;
+ glGenTextures(1, &tname);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
+ if (glGetError() != GL_NO_ERROR) {
+ GLint tw = (2 << (31 - clz(hw_w)));
+ GLint th = (2 << (31 - clz(hw_h)));
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
+ u = GLfloat(hw_w) / tw;
+ v = GLfloat(hw_h) / th;
+ }
+ glGenFramebuffersOES(1, &name);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+ glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
+
+ GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+ if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
+ // redraw the screen entirely...
+ glClearColor(0,0,0,1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const size_t count = layers.size();
+ for (size_t i=0 ; i<count ; ++i) {
+ const sp<LayerBase>& layer(layers[i]);
+ layer->drawForSreenShot();
+ }
+ // back to main framebuffer
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+ glDisable(GL_SCISSOR_TEST);
+
+ GLfloat vtx[8];
+ const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, vtx);
+
+ class s_curve_interpolator {
+ const float nbFrames, s, v;
+ public:
+ s_curve_interpolator(int nbFrames, float s)
+ : nbFrames(1.0f / (nbFrames-1)), s(s),
+ v(1.0f + expf(-s + 0.5f*s)) {
+ }
+ float operator()(int f) {
+ const float x = f * nbFrames;
+ return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
+ }
+ };
+
+ class v_stretch {
+ const GLfloat hw_w, hw_h;
+ public:
+ v_stretch(uint32_t hw_w, uint32_t hw_h)
+ : hw_w(hw_w), hw_h(hw_h) {
+ }
+ void operator()(GLfloat* vtx, float v) {
+ const GLfloat w = hw_w + (hw_w * v);
+ const GLfloat h = hw_h - (hw_h * v);
+ const GLfloat x = (hw_w - w) * 0.5f;
+ const GLfloat y = (hw_h - h) * 0.5f;
+ vtx[0] = x; vtx[1] = y;
+ vtx[2] = x; vtx[3] = y + h;
+ vtx[4] = x + w; vtx[5] = y + h;
+ vtx[6] = x + w; vtx[7] = y;
+ }
+ };
+
+ class h_stretch {
+ const GLfloat hw_w, hw_h;
+ public:
+ h_stretch(uint32_t hw_w, uint32_t hw_h)
+ : hw_w(hw_w), hw_h(hw_h) {
+ }
+ void operator()(GLfloat* vtx, float v) {
+ const GLfloat w = hw_w - (hw_w * v);
+ const GLfloat h = 1.0f;
+ const GLfloat x = (hw_w - w) * 0.5f;
+ const GLfloat y = (hw_h - h) * 0.5f;
+ vtx[0] = x; vtx[1] = y;
+ vtx[2] = x; vtx[3] = y + h;
+ vtx[4] = x + w; vtx[5] = y + h;
+ vtx[6] = x + w; vtx[7] = y;
+ }
+ };
+
+ // the full animation is 24 frames
+ const int nbFrames = 12;
+
+ v_stretch vverts(hw_w, hw_h);
+ s_curve_interpolator itr(nbFrames, 7.5f);
+ s_curve_interpolator itg(nbFrames, 8.0f);
+ s_curve_interpolator itb(nbFrames, 8.5f);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ for (int i=0 ; i<nbFrames ; i++) {
+ float x, y, w, h;
+ const float vr = itr(i);
+ const float vg = itg(i);
+ const float vb = itb(i);
+
+ // clear screen
+ glColorMask(1,1,1,1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glEnable(GL_TEXTURE_2D);
+
+ // draw the red plane
+ vverts(vtx, vr);
+ glColorMask(1,0,0,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the green plane
+ vverts(vtx, vg);
+ glColorMask(0,1,0,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the blue plane
+ vverts(vtx, vb);
+ glColorMask(0,0,1,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the white highlight (we use the last vertices)
+ glDisable(GL_TEXTURE_2D);
+ glColorMask(1,1,1,1);
+ glColor4f(vg, vg, vg, 1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ hw.flip(screenBounds);
+ }
+
+ h_stretch hverts(hw_w, hw_h);
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glColorMask(1,1,1,1);
+ for (int i=0 ; i<nbFrames ; i++) {
+ const float v = itg(i);
+ hverts(vtx, v);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor4f(1-v, 1-v, 1-v, 1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ hw.flip(screenBounds);
+ }
+
+ glColorMask(1,1,1,1);
+ glEnable(GL_SCISSOR_TEST);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ result = NO_ERROR;
+ } else {
+ // release FBO resources
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+ result = BAD_VALUE;
+ }
+
+ glDeleteFramebuffersOES(1, &name);
+ glDeleteTextures(1, &tname);
+
+ if (result == NO_ERROR) {
+ DisplayHardware& hw(graphicPlane(dpy).editDisplayHardware());
+ hw.setCanDraw(false);
+ }
+
+ return result;
+}
+
+status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
+{
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
+ class MessageTurnElectronBeamOff : public MessageBase {
+ SurfaceFlinger* flinger;
+ status_t result;
+ public:
+ MessageTurnElectronBeamOff(SurfaceFlinger* flinger)
+ : flinger(flinger), result(PERMISSION_DENIED) {
+ }
+ status_t getResult() const {
+ return result;
+ }
+ virtual bool handler() {
+ Mutex::Autolock _l(flinger->mStateLock);
+ result = flinger->turnElectronBeamOffImplLocked();
+ return true;
+ }
+ };
+
+ sp<MessageBase> msg = new MessageTurnElectronBeamOff(this);
+ status_t res = postMessageSync(msg);
+ if (res == NO_ERROR) {
+ res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
+ }
+ return res;
+}
+
// ---------------------------------------------------------------------------
status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
@@ -2115,6 +2341,10 @@ const DisplayHardware& GraphicPlane::displayHardware() const {
return *mHw;
}
+DisplayHardware& GraphicPlane::editDisplayHardware() {
+ return *mHw;
+}
+
const Transform& GraphicPlane::transform() const {
return mGlobalTransform;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 732e57e..3470d87 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -141,6 +141,7 @@ public:
int getHeight() const;
const DisplayHardware& displayHardware() const;
+ DisplayHardware& editDisplayHardware();
const Transform& transform() const;
EGLDisplay getEGLDisplay() const;
@@ -200,6 +201,7 @@ public:
PixelFormat* format,
uint32_t reqWidth,
uint32_t reqHeight);
+ virtual status_t turnElectronBeamOff(int32_t mode);
void screenReleased(DisplayID dpy);
void screenAcquired(DisplayID dpy);
@@ -326,6 +328,8 @@ private:
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth = 0, uint32_t reqHeight = 0);
+ status_t turnElectronBeamOffImplLocked();
+
friend class FreezeLock;
sp<FreezeLock> getFreezeLock() const;
inline void incFreezeCount() {
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index b09df82..3f0ec0a 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -56,7 +56,7 @@ public final class CallManager {
private static final String LOG_TAG ="CallManager";
private static final boolean DBG = true;
- private static final boolean VDBG = true;
+ private static final boolean VDBG = false;
private static final int EVENT_DISCONNECT = 100;
private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
@@ -292,7 +292,7 @@ public final class CallManager {
if (basePhone != null && !mPhones.contains(basePhone)) {
- if (VDBG) {
+ if (DBG) {
Log.d(LOG_TAG, "registerPhone(" +
phone.getPhoneName() + " " + phone + ")");
}
@@ -319,7 +319,7 @@ public final class CallManager {
if (basePhone != null && mPhones.contains(basePhone)) {
- if (VDBG) {
+ if (DBG) {
Log.d(LOG_TAG, "unregisterPhone(" +
phone.getPhoneName() + " " + phone + ")");
}
@@ -487,7 +487,7 @@ public final class CallManager {
boolean hasBgCall = ! (activePhone.getBackgroundCall().isIdle());
boolean sameChannel = (activePhone == ringingPhone);
- if (DBG) {
+ if (VDBG) {
Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
}
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index c67b995..db16dec 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -390,8 +390,8 @@ public class CallerInfo {
*/
public String toString() {
return new StringBuilder(384)
- .append("\nname: " + name)
- .append("\nphoneNumber: " + phoneNumber)
+ .append("\nname: " + /*name*/ "nnnnnn")
+ .append("\nphoneNumber: " + /*phoneNumber*/ "xxxxxxx")
.append("\ncnapName: " + cnapName)
.append("\nnumberPresentation: " + numberPresentation)
.append("\nnamePresentation: " + namePresentation)
@@ -402,8 +402,8 @@ public class CallerInfo {
.append("\nphotoResource: " + photoResource)
.append("\nperson_id: " + person_id)
.append("\nneedUpdate: " + needUpdate)
- .append("\ncontactRefUri: " + contactRefUri)
- .append("\ncontactRingtoneUri: " + contactRefUri)
+ .append("\ncontactRefUri: " + /*contactRefUri*/ "xxxxxxx")
+ .append("\ncontactRingtoneUri: " + /*contactRefUri*/ "xxxxxxx")
.append("\nshouldSendToVoicemail: " + shouldSendToVoicemail)
.append("\ncachedPhoto: " + cachedPhoto)
.append("\nisCachedPhotoCurrent: " + isCachedPhotoCurrent)
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index a967850..de5bb943 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -136,7 +136,7 @@ public class CallerInfoAsyncQuery {
} else {
if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
- " command: " + msg.what + " query URI: " + args.uri);
+ " command: " + msg.what + " query URI: " + sanitizeUriToString(args.uri));
switch (cw.event) {
case EVENT_NEW_QUERY:
@@ -302,7 +302,7 @@ public class CallerInfoAsyncQuery {
OnQueryCompleteListener listener, Object cookie) {
if (DBG) {
log("##### CallerInfoAsyncQuery startQuery()... #####");
- log("- number: " + number);
+ log("- number: " + /*number*/ "xxxxxxx");
log("- cookie: " + cookie);
}
@@ -314,7 +314,7 @@ public class CallerInfoAsyncQuery {
if (PhoneNumberUtils.isUriNumber(number)) {
// "number" is really a SIP address.
- if (DBG) log(" - Treating number as a SIP address: " + number);
+ if (DBG) log(" - Treating number as a SIP address: " + /*number*/ "xxxxxxx");
// We look up SIP addresses directly in the Data table:
contactRef = Data.CONTENT_URI;
@@ -346,7 +346,7 @@ public class CallerInfoAsyncQuery {
}
if (DBG) {
- log("==> contactRef: " + contactRef);
+ log("==> contactRef: " + sanitizeUriToString(contactRef));
log("==> selection: " + selection);
if (selectionArgs != null) {
for (int i = 0; i < selectionArgs.length; i++) {
@@ -388,8 +388,8 @@ public class CallerInfoAsyncQuery {
*/
public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {
- if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " +
- mHandler.toString());
+ if (DBG) log("adding listener to query: " + sanitizeUriToString(mHandler.mQueryUri) +
+ " handler: " + mHandler.toString());
//create cookieWrapper, add query request to end of queue.
CookieWrapper cw = new CookieWrapper();
@@ -423,6 +423,20 @@ public class CallerInfoAsyncQuery {
mHandler = null;
}
+ private static String sanitizeUriToString(Uri uri) {
+ if (uri != null) {
+ String uriString = uri.toString();
+ int indexOfLastSlash = uriString.lastIndexOf('/');
+ if (indexOfLastSlash > 0) {
+ return uriString.substring(0, indexOfLastSlash) + "/xxxxxxx";
+ } else {
+ return uriString;
+ }
+ } else {
+ return "";
+ }
+ }
+
/**
* static logging method
*/
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index c80c608..438996f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -241,7 +241,7 @@ public final class SIMRecords extends IccRecords {
msisdn = number;
msisdnTag = alphaTag;
- if(DBG) log("Set MSISDN: " + msisdnTag +" " + msisdn);
+ if(DBG) log("Set MSISDN: " + msisdnTag + " " + /*msisdn*/ "xxxxxxx");
AdnRecord adn = new AdnRecord(msisdnTag, msisdn);
@@ -499,7 +499,7 @@ public final class SIMRecords extends IccRecords {
imsi = null;
}
- Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxxxx");
+ Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxx");
if (mncLength == UNKNOWN) {
// the SIM has told us all it knows, but it didn't know the mnc length.
@@ -629,7 +629,7 @@ public final class SIMRecords extends IccRecords {
msisdn = adn.getNumber();
msisdnTag = adn.getAlphaTag();
- Log.d(LOG_TAG, "MSISDN: " + msisdn);
+ Log.d(LOG_TAG, "MSISDN: " + /*msisdn*/ "xxxxxxx");
break;
case EVENT_SET_MSISDN_DONE:
diff --git a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
index c139a64..209fe06 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
@@ -57,8 +57,8 @@ abstract class SipConnectionBase extends Connection {
private DisconnectCause mCause = DisconnectCause.NOT_DISCONNECTED;
private PostDialState postDialState = PostDialState.NOT_STARTED;
- SipConnectionBase(String calleeSipUri) {
- dialString = calleeSipUri;
+ SipConnectionBase(String dialString) {
+ this.dialString = dialString;
postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index a951040..09d3c8e 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -390,7 +390,8 @@ public class SipPhone extends SipPhoneBase {
try {
SipProfile callee =
new SipProfile.Builder(calleeSipUri).build();
- SipConnection c = new SipConnection(this, callee);
+ SipConnection c = new SipConnection(this, callee,
+ originalNumber);
connections.add(c);
c.dial();
setState(Call.State.DIALING);
@@ -581,6 +582,7 @@ public class SipPhone extends SipPhoneBase {
private SipAudioCall mSipAudioCall;
private Call.State mState = Call.State.IDLE;
private SipProfile mPeer;
+ private String mOriginalNumber; // may be a PSTN number
private boolean mIncoming = false;
private SipAudioCallAdapter mAdapter = new SipAudioCallAdapter() {
@@ -662,10 +664,16 @@ public class SipPhone extends SipPhoneBase {
}
};
- public SipConnection(SipCall owner, SipProfile callee) {
- super(getUriString(callee));
+ public SipConnection(SipCall owner, SipProfile callee,
+ String originalNumber) {
+ super(originalNumber);
mOwner = owner;
mPeer = callee;
+ mOriginalNumber = originalNumber;
+ }
+
+ public SipConnection(SipCall owner, SipProfile callee) {
+ this(owner, callee, getUriString(callee));
}
void initIncomingCall(SipAudioCall sipAudioCall, Call.State newState) {
@@ -738,7 +746,10 @@ public class SipPhone extends SipPhoneBase {
@Override
public String getAddress() {
- return getUriString(mPeer);
+ // Phone app uses this to query caller ID. Return the original dial
+ // number (which may be a PSTN number) instead of the peer's SIP
+ // URI.
+ return mOriginalNumber;
}
@Override
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 19815fd..643dbf5 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -66,7 +66,9 @@ public class TestShellActivity extends Activity implements LayoutTestController
static enum DumpDataType {DUMP_AS_TEXT, EXT_REPR, NO_OP}
// String constants for use with layoutTestController.overridePreferences
- private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED = "WebKitOfflineWebApplicationCacheEnabled";
+ private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED =
+ "WebKitOfflineWebApplicationCacheEnabled";
+ private final String WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY = "WebKitUsesPageCachePreferenceKey";
public class AsyncHandler extends Handler {
@Override
@@ -524,8 +526,14 @@ public class TestShellActivity extends Activity implements LayoutTestController
// called the layoutTestController method. Currently, we just use the
// WebView for the main frame. EventSender suffers from the same
// problem.
- if (key.equals(WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED)) {
+ if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) {
mWebView.getSettings().setAppCacheEnabled(value);
+ } else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) {
+ // Cache the maximum possible number of pages.
+ mWebView.getSettings().setPageCacheCapacity(Integer.MAX_VALUE);
+ } else {
+ Log.w(LOGTAG, "LayoutTestController.overridePreference(): " +
+ "Unsupported preference '" + key + "'");
}
}
@@ -879,6 +887,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
settings.setDomStorageEnabled(true);
settings.setWorkersEnabled(false);
settings.setXSSAuditorEnabled(false);
+ settings.setPageCacheCapacity(0);
}
private WebView mWebView;
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
index 97d7cca..af8f6ea 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
@@ -394,6 +394,7 @@ public class LayoutTestsExecutor extends Activity {
webViewSettings.setDomStorageEnabled(true);
webViewSettings.setWorkersEnabled(false);
webViewSettings.setXSSAuditorEnabled(false);
+ webViewSettings.setPageCacheCapacity(0);
// This is asynchronous, but it gets processed by WebCore before it starts loading pages.
mCurrentWebView.useMockDeviceOrientation();
@@ -565,6 +566,7 @@ public class LayoutTestsExecutor extends Activity {
/** String constants for use with layoutTestController.overridePreference() */
private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED =
"WebKitOfflineWebApplicationCacheEnabled";
+ private final String WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY = "WebKitUsesPageCachePreferenceKey";
Handler mLayoutTestControllerHandler = new Handler() {
@Override
@@ -609,12 +611,16 @@ public class LayoutTestsExecutor extends Activity {
* WebView for the main frame. EventSender suffers from the same
* problem.
*/
- if (msg.getData().getString("key").equals(
- WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED)) {
- mCurrentWebView.getSettings().setAppCacheEnabled(msg.getData().getBoolean(
- "value"));
+ String key = msg.getData().getString("key");
+ boolean value = msg.getData().getBoolean("value");
+ if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) {
+ mCurrentWebView.getSettings().setAppCacheEnabled(value);
+ } else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) {
+ // Cache the maximum possible number of pages.
+ mCurrentWebView.getSettings().setPageCacheCapacity(Integer.MAX_VALUE);
} else {
- Log.w(LOG_TAG, "MSG_OVERRIDE_PREFERENCE: unsupported preference!");
+ Log.w(LOG_TAG, "LayoutTestController.overridePreference(): " +
+ "Unsupported preference '" + key + "'");
}
break;
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index e30cf4a..9c267d6 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -86,6 +86,18 @@ public class NotificationTestList extends TestActivity
}
},
+ new Test("custom intent on text view") {
+ public void run() {
+ Notification n = new Notification(R.drawable.icon1, null,
+ mActivityCreateTime);
+ n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
+ "This is a notification!!!", null);
+ n.contentView.setOnClickPendingIntent(com.android.internal.R.id.text,
+ makeIntent2());
+ mNM.notify(1, n);
+ }
+ },
+
new Test("Ticker 1 line") {
public void run() {
Notification n = new Notification(R.drawable.icon1, "tick tick tick",
@@ -776,6 +788,12 @@ public class NotificationTestList extends TestActivity
return PendingIntent.getActivity(this, 0, intent, 0);
}
+ private PendingIntent makeIntent2() {
+ Intent intent = new Intent(this, StatusBarTest.class);
+ return PendingIntent.getActivity(this, 0, intent, 0);
+ }
+
+
class StateStress extends Test {
StateStress(String name, int pause, int iterations, Runnable[] tasks) {
super(name);
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
index ee554b5..6f426c9 100644
--- a/voip/java/com/android/server/sip/SipService.java
+++ b/voip/java/com/android/server/sip/SipService.java
@@ -868,6 +868,7 @@ public final class SipService extends ISipService.Stub {
case SipErrorCode.SERVER_UNREACHABLE:
if (DEBUG) Log.d(TAG, " pause auto-registration");
stop();
+ break;
default:
restartLater();
}