Merge "First step towards cleaning up Global settings." into jb-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 5224491..91e5ddd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10665,7 +10665,7 @@
method public float getAccuracy();
method public double getAltitude();
method public float getBearing();
- method public long getElapsedRealtimeNano();
+ method public long getElapsedRealtimeNanos();
method public android.os.Bundle getExtras();
method public double getLatitude();
method public double getLongitude();
@@ -10685,7 +10685,7 @@
method public void setAccuracy(float);
method public void setAltitude(double);
method public void setBearing(float);
- method public void setElapsedRealtimeNano(long);
+ method public void setElapsedRealtimeNanos(long);
method public void setExtras(android.os.Bundle);
method public void setLatitude(double);
method public void setLongitude(double);
@@ -12745,14 +12745,12 @@
method public static javax.net.ssl.SSLSocketFactory getDefault(int, android.net.SSLSessionCache);
method public java.lang.String[] getDefaultCipherSuites();
method public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
- method public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, int, android.net.SSLSessionCache);
method public static javax.net.ssl.SSLSocketFactory getInsecure(int, android.net.SSLSessionCache);
method public byte[] getNpnSelectedProtocol(java.net.Socket);
method public java.lang.String[] getSupportedCipherSuites();
method public void setHostname(java.net.Socket, java.lang.String);
method public void setKeyManagers(javax.net.ssl.KeyManager[]);
method public void setNpnProtocols(byte[][]);
- method public void setSoWriteTimeout(java.net.Socket, int) throws java.net.SocketException;
method public void setTrustManagers(javax.net.ssl.TrustManager[]);
method public void setUseSessionTickets(java.net.Socket, boolean);
}
@@ -16576,7 +16574,7 @@
public final class SystemClock {
method public static long currentThreadTimeMillis();
method public static long elapsedRealtime();
- method public static long elapsedRealtimeNano();
+ method public static long elapsedRealtimeNanos();
method public static boolean setCurrentTimeMillis(long);
method public static void sleep(long);
method public static long uptimeMillis();
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 4257e0e..4999a2d 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -203,6 +203,12 @@
}
};
+ private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ onAccountsUpdated(null);
+ }
+ };
+
private final PowerManager mPowerManager;
// Use this as a random offset to seed all periodic syncs
@@ -456,8 +462,11 @@
});
if (!factoryTest) {
- AccountManager.get(mContext).addOnAccountsUpdatedListener(SyncManager.this,
- mSyncHandler, false /* updateImmediately */);
+ // Register for account list updates for all users
+ mContext.registerReceiverAsUser(mAccountsUpdatedReceiver,
+ UserHandle.ALL,
+ new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION),
+ null, null);
// do this synchronously to ensure we have the accounts before this call returns
onAccountsUpdated(null);
}
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 42fb5c3..846443d 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -90,7 +90,6 @@
private byte[] mNpnProtocols = null;
private final int mHandshakeTimeoutMillis;
- private final int mWriteTimeoutMillis;
private final SSLClientSessionCache mSessionCache;
private final boolean mSecure;
@@ -101,21 +100,12 @@
}
private SSLCertificateSocketFactory(
- int handshakeTimeoutMillis,
- int writeTimeoutMillis,
- SSLSessionCache cache,
- boolean secure) {
+ int handshakeTimeoutMillis, SSLSessionCache cache, boolean secure) {
mHandshakeTimeoutMillis = handshakeTimeoutMillis;
- mWriteTimeoutMillis = writeTimeoutMillis;
mSessionCache = cache == null ? null : cache.mSessionCache;
mSecure = secure;
}
- private SSLCertificateSocketFactory(
- int handshakeTimeoutMillis, SSLSessionCache cache, boolean secure) {
- this(handshakeTimeoutMillis, 0, cache, secure);
- }
-
/**
* Returns a new socket factory instance with an optional handshake timeout.
*
@@ -172,24 +162,6 @@
}
/**
- * Returns a socket factory (also named SSLSocketFactory, but in a different
- * namespace) for use with the Apache HTTP stack.
- *
- * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
- * for none. The socket timeout is reset to 0 after the handshake.
- * @param writeTimeoutMillis the desired write timeout in milliseconds or 0 for none.
- * @param cache The {@link SSLSessionCache} to use, or null for no cache.
- * @return a new SocketFactory with the specified parameters
- */
- public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(
- int handshakeTimeoutMillis,
- int writeTimeoutMillis,
- SSLSessionCache cache) {
- return new org.apache.http.conn.ssl.SSLSocketFactory(new SSLCertificateSocketFactory(
- handshakeTimeoutMillis, writeTimeoutMillis, cache, true));
- }
-
- /**
* Verify the hostname of the certificate used by the other end of a
* connected socket. You MUST call this if you did not supply a hostname
* to {@link #createSocket()}. It is harmless to call this method
@@ -376,8 +348,10 @@
* To take effect, this option must be set before the blocking method was called.
*
* @param socket a socket created by this factory.
- * @param writeTimeoutMilliseconds the desired write timeout in milliseconds.
+ * @param timeout the desired write timeout in milliseconds.
* @throws IllegalArgumentException if the socket was not created by this factory.
+ *
+ * @hide
*/
public void setSoWriteTimeout(Socket socket, int writeTimeoutMilliseconds)
throws SocketException {
@@ -404,7 +378,6 @@
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close);
s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
- s.setSoWriteTimeout(mWriteTimeoutMillis);
if (mSecure) {
verifyHostname(s, host);
}
@@ -424,7 +397,6 @@
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket();
s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
- s.setSoWriteTimeout(mWriteTimeoutMillis);
return s;
}
@@ -442,7 +414,6 @@
addr, port, localAddr, localPort);
s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
- s.setSoWriteTimeout(mWriteTimeoutMillis);
return s;
}
@@ -458,7 +429,6 @@
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port);
s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
- s.setSoWriteTimeout(mWriteTimeoutMillis);
return s;
}
@@ -475,7 +445,6 @@
host, port, localAddr, localPort);
s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
- s.setSoWriteTimeout(mWriteTimeoutMillis);
if (mSecure) {
verifyHostname(s, host);
}
@@ -493,7 +462,6 @@
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port);
s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
- s.setSoWriteTimeout(mWriteTimeoutMillis);
if (mSecure) {
verifyHostname(s, host);
}
diff --git a/core/java/android/net/http/AndroidHttpClient.java b/core/java/android/net/http/AndroidHttpClient.java
index 8169a94..c534e58 100644
--- a/core/java/android/net/http/AndroidHttpClient.java
+++ b/core/java/android/net/http/AndroidHttpClient.java
@@ -16,16 +16,7 @@
package android.net.http;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.SSLCertificateSocketFactory;
-import android.net.SSLSessionCache;
-import android.os.Looper;
-import android.util.Base64;
-import android.util.Log;
-
import com.android.internal.http.HttpDateTime;
-
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
@@ -34,18 +25,18 @@
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
+import org.apache.http.entity.AbstractHttpEntity;
+import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.protocol.ClientContext;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.HttpClientParams;
-import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.RequestWrapper;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
@@ -53,17 +44,25 @@
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.BasicHttpContext;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
-import java.net.URI;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
+import java.net.URI;
+
+import android.content.Context;
+import android.content.ContentResolver;
+import android.net.SSLCertificateSocketFactory;
+import android.net.SSLSessionCache;
+import android.os.Looper;
+import android.util.Base64;
+import android.util.Log;
/**
* Implementation of the Apache {@link DefaultHttpClient} that is configured with
@@ -135,7 +134,7 @@
PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https",
SSLCertificateSocketFactory.getHttpSocketFactory(
- SOCKET_OPERATION_TIMEOUT, SOCKET_OPERATION_TIMEOUT, sessionCache), 443));
+ SOCKET_OPERATION_TIMEOUT, sessionCache), 443));
ClientConnectionManager manager =
new ThreadSafeClientConnManager(params, schemeRegistry);
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 7aee644..eec19cb 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -34,6 +34,7 @@
void userActivity(long time, int event, int flags);
void wakeUp(long time);
void goToSleep(long time, int reason);
+ void nap(long time);
boolean isScreenOn();
void reboot(String reason);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index cc2c002..58372f4 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -426,7 +426,7 @@
* </p>
*
* @param when The time of the user activity, in the {@link SystemClock#uptimeMillis()}
- * time base. This timestamp is used to correctly order the user activity with
+ * time base. This timestamp is used to correctly order the user activity request with
* other power management functions. It should be set
* to the timestamp of the input event that caused the user activity.
* @param noChangeLights If true, does not cause the keyboard backlight to turn on
@@ -457,7 +457,7 @@
*
* @param time The time when the request to go to sleep was issued, in the
* {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
- * order the user activity with other power management functions. It should be set
+ * order the go to sleep request with other power management functions. It should be set
* to the timestamp of the input event that caused the request to go to sleep.
*
* @see #userActivity
@@ -481,7 +481,7 @@
*
* @param time The time when the request to wake up was issued, in the
* {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
- * order the user activity with other power management functions. It should be set
+ * order the wake up request with other power management functions. It should be set
* to the timestamp of the input event that caused the request to wake up.
*
* @see #userActivity
@@ -495,6 +495,34 @@
}
/**
+ * Forces the device to start napping.
+ * <p>
+ * If the device is currently awake, starts dreaming, otherwise does nothing.
+ * When the dream ends or if the dream cannot be started, the device will
+ * either wake up or go to sleep depending on whether there has been recent
+ * user activity.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to nap was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the nap request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to nap.
+ *
+ * @see #wakeUp
+ * @see #goToSleep
+ *
+ * @hide
+ */
+ public void nap(long time) {
+ try {
+ mService.nap(time);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* Sets the brightness of the backlights (screen, keyboard, button).
* <p>
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index a54c25b..c9adf45 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -50,7 +50,7 @@
* interval does not span device sleep. Most methods that accept a
* timestamp value currently expect the {@link #uptimeMillis} clock.
*
- * <li> <p> {@link #elapsedRealtime} and {@link #elapsedRealtimeNano}
+ * <li> <p> {@link #elapsedRealtime} and {@link #elapsedRealtimeNanos}
* return the time since the system was booted, and include deep sleep.
* This clock is guaranteed to be monotonic, and continues to tick even
* when the CPU is in power saving modes, so is the recommend basis
@@ -157,7 +157,7 @@
*
* @return elapsed nanoseconds since boot.
*/
- public static native long elapsedRealtimeNano();
+ public static native long elapsedRealtimeNanos();
/**
* Returns milliseconds running in the current thread.
diff --git a/core/java/android/service/dreams/Dream.java b/core/java/android/service/dreams/Dream.java
index 473414c..590acfa 100644
--- a/core/java/android/service/dreams/Dream.java
+++ b/core/java/android/service/dreams/Dream.java
@@ -72,6 +72,12 @@
private final String TAG = Dream.class.getSimpleName() + "[" + getClass().getSimpleName() + "]";
/**
+ * The name of the dream manager service.
+ * @hide
+ */
+ public static final String DREAM_SERVICE = "dreams";
+
+ /**
* Used with {@link Intent#ACTION_MAIN} to declare the necessary intent-filter for a dream.
*
* @see Dream
@@ -499,7 +505,7 @@
// end public api
private void loadSandman() {
- mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
+ mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
}
private final void attach(IBinder windowToken) {
@@ -584,7 +590,7 @@
mFinished = true;
if (mSandman != null) {
- mSandman.awakenSelf(mWindowToken);
+ mSandman.finishSelf(mWindowToken);
} else {
Slog.w(TAG, "No dream manager found");
}
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index bd1c524..1c1b390 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -30,5 +30,5 @@
ComponentName getDefaultDreamComponent();
void testDream(in ComponentName componentName);
boolean isDreaming();
- void awakenSelf(in IBinder token);
+ void finishSelf(in IBinder token);
}
\ No newline at end of file
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 123ce2a..b0a2711 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -314,7 +314,7 @@
}
}
- final boolean configChanged =
+ final boolean configChanged = action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_POINTER_UP ||
action == MotionEvent.ACTION_POINTER_DOWN;
final boolean pointerUp = action == MotionEvent.ACTION_POINTER_UP;
@@ -344,7 +344,7 @@
if (skipIndex == i) continue;
// Average touch major and touch minor and convert the resulting diameter into a radius.
- final float touchSize = getAdjustedTouchHistory(event.getPointerId(i));
+ final float touchSize = getAdjustedTouchHistory(event.getPointerId(i)) / 2;
devSumX += Math.abs(event.getX(i) - focusX) + touchSize;
devSumY += Math.abs(event.getY(i) - focusY) + touchSize;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 87396fb..7ca8322 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -789,6 +789,7 @@
if (resizeWidth) {
int newWidth = (int)(desiredAspect * (heightSize - ptop - pbottom)) +
pleft + pright;
+ widthSize = resolveAdjustedSize(newWidth, mMaxWidth, widthMeasureSpec);
if (newWidth <= widthSize) {
widthSize = newWidth;
done = true;
@@ -799,6 +800,7 @@
if (!done && resizeHeight) {
int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) +
ptop + pbottom;
+ heightSize = resolveAdjustedSize(newHeight, mMaxHeight, heightMeasureSpec);
if (newHeight <= heightSize) {
heightSize = newHeight;
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index bffbe11..4ad0819 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -436,9 +436,10 @@
if (mBaseResolveList != null) {
mCurrentResolveList = mBaseResolveList;
} else {
- mCurrentResolveList = mPm.queryIntentActivities(
+ mCurrentResolveList = mPm.queryIntentActivitiesAsUser(
mIntent, PackageManager.MATCH_DEFAULT_ONLY
- | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0));
+ | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0),
+ UserHandle.getUserId(mLaunchedFromUid));
// Filter out any activities that the launched uid does not
// have permission for. We don't do this when we have an explicit
// list of resolved activities, because that only happens when
diff --git a/core/jni/android_os_SystemClock.cpp b/core/jni/android_os_SystemClock.cpp
index 78f989a..5c135ee 100644
--- a/core/jni/android_os_SystemClock.cpp
+++ b/core/jni/android_os_SystemClock.cpp
@@ -137,7 +137,7 @@
(void*) android_os_SystemClock_currentThreadTimeMicro },
{ "currentTimeMicro", "()J",
(void*) android_os_SystemClock_currentTimeMicro },
- { "elapsedRealtimeNano", "()J",
+ { "elapsedRealtimeNanos", "()J",
(void*) android_os_SystemClock_elapsedRealtimeNano },
};
int register_android_os_SystemClock(JNIEnv* env)
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlend.java b/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
index 13c03af..65c69c0 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -36,17 +36,18 @@
* @return ScriptIntrinsicBlend
*/
public static ScriptIntrinsicBlend create(RenderScript rs, Element e) {
- int id = rs.nScriptIntrinsicCreate(6, e.getID(rs));
+ // 7 comes from RS_SCRIPT_INTRINSIC_ID_BLEND in rsDefines.h
+ int id = rs.nScriptIntrinsicCreate(7, e.getID(rs));
return new ScriptIntrinsicBlend(id, rs);
}
private void blend(int id, Allocation ain, Allocation aout) {
- if (ain.getElement() != Element.U8_4(mRS)) {
- throw new RSIllegalArgumentException("Input not of expected format.");
+ if (!ain.getElement().isCompatible(Element.U8_4(mRS))) {
+ throw new RSIllegalArgumentException("Input is not of expected format.");
}
- if (aout.getElement() != Element.U8_4(mRS)) {
- throw new RSIllegalArgumentException("Output not of expected format.");
+ if (!aout.getElement().isCompatible(Element.U8_4(mRS))) {
+ throw new RSIllegalArgumentException("Output is not of expected format.");
}
forEach(id, ain, aout, null);
}
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 5b1b57d..f0b5553 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -81,6 +81,7 @@
if (mInitialized) {
transform = addUniform("transform");
+ projection = addUniform("projection");
}
}
@@ -152,18 +153,20 @@
void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
const mat4& transformMatrix, bool offset) {
- mat4 t(projectionMatrix);
+ mat4 p(projectionMatrix);
if (offset) {
// offset screenspace xy by an amount that compensates for typical precision
// issues in GPU hardware that tends to paint hor/vert lines in pixels shifted
// up and to the left.
// This offset value is based on an assumption that some hardware may use as
// little as 12.4 precision, so we offset by slightly more than 1/16.
- t.translate(.375, .375, 0);
+ p.translate(.375, .375, 0);
}
- t.multiply(transformMatrix);
+
+ mat4 t(transformMatrix);
t.multiply(modelViewMatrix);
+ glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]);
glUniformMatrix4fv(transform, 1, GL_FALSE, &t.data[0]);
}
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index b1cb446..7e3aacf 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -374,6 +374,11 @@
*/
int transform;
+ /**
+ * Name of the projection uniform.
+ */
+ int projection;
+
protected:
/**
* Adds an attribute with the specified name.
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 7bc2b37..f536ade 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -48,6 +48,7 @@
const char* gVS_Header_Uniforms_TextureTransform =
"uniform mat4 mainTextureTransform;\n";
const char* gVS_Header_Uniforms =
+ "uniform mat4 projection;\n" \
"uniform mat4 transform;\n";
const char* gVS_Header_Uniforms_IsPoint =
"uniform mediump float pointSize;\n";
@@ -104,28 +105,28 @@
const char* gVS_Main_OutGradient[6] = {
// Linear
" linear = vec2((screenSpace * position).x, 0.5);\n"
- " ditherTexCoords = (gl_Position * ditherSize).xy;\n",
+ " ditherTexCoords = (transform * position).xy * ditherSize;\n",
" linear = (screenSpace * position).x;\n"
- " ditherTexCoords = (gl_Position * ditherSize).xy;\n",
+ " ditherTexCoords = (transform * position).xy * ditherSize;\n",
// Circular
" circular = (screenSpace * position).xy;\n"
- " ditherTexCoords = (gl_Position * ditherSize).xy;\n",
+ " ditherTexCoords = (transform * position).xy * ditherSize;\n",
" circular = (screenSpace * position).xy;\n"
- " ditherTexCoords = (gl_Position * ditherSize).xy;\n",
+ " ditherTexCoords = (transform * position).xy * ditherSize;\n",
// Sweep
" sweep = (screenSpace * position).xy;\n"
- " ditherTexCoords = (gl_Position * ditherSize).xy;\n",
+ " ditherTexCoords = (transform * position).xy * ditherSize;\n",
" sweep = (screenSpace * position).xy;\n"
- " ditherTexCoords = (gl_Position * ditherSize).xy;\n",
+ " ditherTexCoords = (transform * position).xy * ditherSize;\n",
};
const char* gVS_Main_OutBitmapTexCoords =
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_OutPointBitmapTexCoords =
" outPointBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_Position =
- " gl_Position = transform * position;\n";
+ " gl_Position = projection * transform * position;\n";
const char* gVS_Main_PointSize =
" gl_PointSize = pointSize;\n";
const char* gVS_Main_AALine =
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 672e378..f057ebc 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -71,7 +71,7 @@
private String mProvider;
private long mTime = 0;
- private long mElapsedRealtimeNano = 0;
+ private long mElapsedRealtimeNanos = 0;
private double mLatitude = 0.0;
private double mLongitude = 0.0;
private boolean mHasAltitude = false;
@@ -120,7 +120,7 @@
public void set(Location l) {
mProvider = l.mProvider;
mTime = l.mTime;
- mElapsedRealtimeNano = l.mElapsedRealtimeNano;
+ mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
mLatitude = l.mLatitude;
mLongitude = l.mLongitude;
mHasAltitude = l.mHasAltitude;
@@ -140,7 +140,7 @@
public void reset() {
mProvider = null;
mTime = 0;
- mElapsedRealtimeNano = 0;
+ mElapsedRealtimeNanos = 0;
mLatitude = 0;
mLongitude = 0;
mHasAltitude = false;
@@ -485,7 +485,7 @@
*
* <p>Note that the UTC time on a device is not monotonic: it
* can jump forwards or backwards unpredictably. So always use
- * {@link #getElapsedRealtimeNano} when calculating time deltas.
+ * {@link #getElapsedRealtimeNanos} when calculating time deltas.
*
* <p>On the other hand, {@link #getTime} is useful for presenting
* a human readable time to the user, or for carefully comparing
@@ -515,7 +515,7 @@
* Return the time of this fix, in elapsed real-time since system boot.
*
* <p>This value can be reliably compared to
- * {@link android.os.SystemClock#elapsedRealtimeNano},
+ * {@link android.os.SystemClock#elapsedRealtimeNanos},
* to calculate the age of a fix and to compare Location fixes. This
* is reliable because elapsed real-time is guaranteed monotonic for
* each system boot and continues to increment even when the system
@@ -526,8 +526,8 @@
*
* @return elapsed real-time of fix, in nanoseconds since system boot.
*/
- public long getElapsedRealtimeNano() {
- return mElapsedRealtimeNano;
+ public long getElapsedRealtimeNanos() {
+ return mElapsedRealtimeNanos;
}
/**
@@ -535,8 +535,8 @@
*
* @param time elapsed real-time of fix, in nanoseconds since system boot.
*/
- public void setElapsedRealtimeNano(long time) {
- mElapsedRealtimeNano = time;
+ public void setElapsedRealtimeNanos(long time) {
+ mElapsedRealtimeNanos = time;
}
/**
@@ -772,7 +772,7 @@
if (mProvider == null) return false;
if (!mHasAccuracy) return false;
if (mTime == 0) return false;
- if (mElapsedRealtimeNano == 0) return false;
+ if (mElapsedRealtimeNanos == 0) return false;
return true;
}
@@ -792,7 +792,7 @@
mAccuracy = 100.0f;
}
if (mTime == 0) mTime = System.currentTimeMillis();
- if (mElapsedRealtimeNano == 0) mElapsedRealtimeNano = SystemClock.elapsedRealtimeNano();
+ if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
}
/**
@@ -832,11 +832,11 @@
if (mTime == 0) {
s.append(" t=?!?");
}
- if (mElapsedRealtimeNano == 0) {
+ if (mElapsedRealtimeNanos == 0) {
s.append(" et=?!?");
} else {
s.append(" et=");
- TimeUtils.formatDuration(mElapsedRealtimeNano / 1000000L, s);
+ TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
}
if (mHasAltitude) s.append(" alt=").append(mAltitude);
if (mHasSpeed) s.append(" vel=").append(mSpeed);
@@ -860,7 +860,7 @@
String provider = in.readString();
Location l = new Location(provider);
l.mTime = in.readLong();
- l.mElapsedRealtimeNano = in.readLong();
+ l.mElapsedRealtimeNanos = in.readLong();
l.mLatitude = in.readDouble();
l.mLongitude = in.readDouble();
l.mHasAltitude = in.readInt() != 0;
@@ -890,7 +890,7 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mProvider);
parcel.writeLong(mTime);
- parcel.writeLong(mElapsedRealtimeNano);
+ parcel.writeLong(mElapsedRealtimeNanos);
parcel.writeDouble(mLatitude);
parcel.writeDouble(mLongitude);
parcel.writeInt(mHasAltitude ? 1 : 0);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 5b3c9e2..4ad8fd0 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1186,7 +1186,7 @@
* Get the last known location.
*
* <p>This location could be very old so use
- * {@link Location#getElapsedRealtimeNano} to calculate its age. It can
+ * {@link Location#getElapsedRealtimeNanos} to calculate its age. It can
* also return null if no previous location is available.
*
* <p>Always returns immediately.
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
index b83521ae..2cf795d 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
@@ -215,7 +215,7 @@
}
private static double weighAge(Location loc) {
- long ageSeconds = SystemClock.elapsedRealtimeNano() - loc.getElapsedRealtimeNano();
+ long ageSeconds = SystemClock.elapsedRealtimeNanos() - loc.getElapsedRealtimeNanos();
ageSeconds /= 1000000000L;
if (ageSeconds < 0) ageSeconds = 0;
return Math.exp(-ageSeconds * AGE_DECAY_CONSTANT_S);
@@ -266,7 +266,7 @@
// fused time - now
fused.setTime(System.currentTimeMillis());
- fused.setElapsedRealtimeNano(SystemClock.elapsedRealtimeNano());
+ fused.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
// fuse altitude
if (mGpsLocation.hasAltitude() && !mNetworkLocation.hasAltitude() &&
diff --git a/packages/SystemUI/src/com/android/systemui/Somnambulator.java b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
index 89d4ef7..bd87238 100644
--- a/packages/SystemUI/src/com/android/systemui/Somnambulator.java
+++ b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
@@ -20,6 +20,7 @@
import android.content.Intent;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.service.dreams.Dream;
import android.service.dreams.IDreamManager;
import android.util.Slog;
@@ -45,7 +46,7 @@
setResult(RESULT_OK, resultIntent);
} else {
IDreamManager somnambulist = IDreamManager.Stub.asInterface(
- ServiceManager.checkService("dreams"));
+ ServiceManager.checkService(Dream.DREAM_SERVICE));
if (somnambulist != null) {
try {
Slog.v("Somnambulator", "Dreaming by user request.");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e6aa632..d72632f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -45,6 +45,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.dreams.Dream;
import android.service.dreams.IDreamManager;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -262,7 +263,7 @@
.getDefaultDisplay();
mDreamManager = IDreamManager.Stub.asInterface(
- ServiceManager.checkService("dreams"));
+ ServiceManager.checkService(Dream.DREAM_SERVICE));
super.start(); // calls createAndAddWindows()
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 8ad5a91..4a8bf72 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -16,9 +16,6 @@
package com.android.server;
-import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK;
-import static android.provider.Settings.Secure.SCREENSAVER_ENABLED;
-
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -27,16 +24,12 @@
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Handler;
-import android.os.Looper;
import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UEventObserver;
import android.os.UserHandle;
import android.provider.Settings;
-import android.service.dreams.IDreamManager;
import android.util.Log;
import android.util.Slog;
@@ -48,14 +41,10 @@
*/
final class DockObserver extends UEventObserver {
private static final String TAG = DockObserver.class.getSimpleName();
- private static final boolean LOG = false;
private static final String DOCK_UEVENT_MATCH = "DEVPATH=/devices/virtual/switch/dock";
private static final String DOCK_STATE_PATH = "/sys/class/switch/dock/state";
- private static final int DEFAULT_SCREENSAVER_ENABLED = 1;
- private static final int DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK = 1;
-
private static final int MSG_DOCK_STATE_CHANGED = 0;
private final Object mLock = new Object();
@@ -66,11 +55,16 @@
private boolean mSystemReady;
private final Context mContext;
+ private final PowerManager mPowerManager;
+ private final PowerManager.WakeLock mWakeLock;
public DockObserver(Context context) {
mContext = context;
- init(); // set initial status
+ mPowerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+
+ init(); // set initial status
startObserving(DOCK_UEVENT_MATCH);
}
@@ -87,17 +81,9 @@
mPreviousDockState = mDockState;
mDockState = newState;
if (mSystemReady) {
- // Don't force screen on when undocking from the desk dock.
- // The change in power state will do this anyway.
- // FIXME - we should be configurable.
- if ((mPreviousDockState != Intent.EXTRA_DOCK_STATE_DESK
- && mPreviousDockState != Intent.EXTRA_DOCK_STATE_LE_DESK
- && mPreviousDockState != Intent.EXTRA_DOCK_STATE_HE_DESK) ||
- mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
- PowerManager pm =
- (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- pm.wakeUp(SystemClock.uptimeMillis());
- }
+ // Wake up immediately when docked or undocked.
+ mPowerManager.wakeUp(SystemClock.uptimeMillis());
+
updateLocked();
}
}
@@ -138,6 +124,7 @@
}
private void updateLocked() {
+ mWakeLock.acquire();
mHandler.sendEmptyMessage(MSG_DOCK_STATE_CHANGED);
}
@@ -145,8 +132,8 @@
synchronized (mLock) {
Slog.i(TAG, "Dock state changed: " + mDockState);
+ // Skip the dock intent if not yet provisioned.
final ContentResolver cr = mContext.getContentResolver();
-
if (Settings.Global.getInt(cr,
Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
Slog.i(TAG, "Device not provisioned, skipping dock broadcast");
@@ -158,16 +145,8 @@
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
- // Check if this is Bluetooth Dock
- // TODO(BT): Get Dock address.
- // String address = null;
- // if (address != null) {
- // intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
- // BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
- // }
-
- // User feedback to confirm dock connection. Particularly
- // useful for flaky contact pins...
+ // Play a sound to provide feedback to confirm dock connection.
+ // Particularly useful for flaky contact pins...
if (Settings.Global.getInt(cr,
Settings.Global.DOCK_SOUNDS_ENABLED, 1) == 1) {
String whichSound = null;
@@ -204,44 +183,16 @@
}
}
- IDreamManager mgr = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
- if (mgr != null) {
- // dreams feature enabled
- boolean undocked = mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED;
- if (undocked) {
- try {
- if (mgr.isDreaming()) {
- mgr.awaken();
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to awaken!", e);
- }
- } else {
- if (isScreenSaverEnabled(mContext) && isScreenSaverActivatedOnDock(mContext)) {
- try {
- mgr.dream();
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to dream!", e);
- }
- }
- }
- } else {
- // dreams feature not enabled, send legacy intent
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
+ // Send the dock event intent.
+ // There are many components in the system watching for this so as to
+ // adjust audio routing, screen orientation, etc.
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+
+ // Release the wake lock that was acquired when the message was posted.
+ mWakeLock.release();
}
}
- private static boolean isScreenSaverEnabled(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED) != 0;
- }
-
- private static boolean isScreenSaverActivatedOnDock(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK) != 0;
- }
-
private final Handler mHandler = new Handler(true /*async*/) {
@Override
public void handleMessage(Message msg) {
diff --git a/services/java/com/android/server/DreamController.java b/services/java/com/android/server/DreamController.java
deleted file mode 100644
index 498e581..0000000
--- a/services/java/com/android/server/DreamController.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.IBinder.DeathRecipient;
-import android.service.dreams.IDreamService;
-import android.util.Slog;
-import android.view.IWindowManager;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-
-import com.android.internal.util.DumpUtils;
-
-import java.io.PrintWriter;
-import java.util.NoSuchElementException;
-
-/**
- * Internal controller for starting and stopping the current dream and managing related state.
- *
- * Assumes all operations (except {@link #dump}) are called from a single thread.
- */
-final class DreamController {
- private static final boolean DEBUG = true;
- private static final String TAG = DreamController.class.getSimpleName();
-
- public interface Listener {
- void onDreamStopped(boolean wasTest);
- }
-
- private final Context mContext;
- private final IWindowManager mIWindowManager;
- private final DeathRecipient mDeathRecipient;
- private final ServiceConnection mServiceConnection;
- private final Listener mListener;
-
- private Handler mHandler;
-
- private ComponentName mCurrentDreamComponent;
- private IDreamService mCurrentDream;
- private Binder mCurrentDreamToken;
- private boolean mCurrentDreamIsTest;
-
- public DreamController(Context context, DeathRecipient deathRecipient,
- ServiceConnection serviceConnection, Listener listener) {
- mContext = context;
- mDeathRecipient = deathRecipient;
- mServiceConnection = serviceConnection;
- mListener = listener;
- mIWindowManager = WindowManagerGlobal.getWindowManagerService();
- }
-
- public void setHandler(Handler handler) {
- mHandler = handler;
- }
-
- public void dump(PrintWriter pw) {
- if (mHandler== null || pw == null) {
- return;
- }
- DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
- @Override
- public void dump(PrintWriter pw) {
- pw.print(" component="); pw.println(mCurrentDreamComponent);
- pw.print(" token="); pw.println(mCurrentDreamToken);
- pw.print(" dream="); pw.println(mCurrentDream);
- }
- }, pw, 200);
- }
-
- public void start(ComponentName dream, boolean isTest) {
- if (DEBUG) Slog.v(TAG, String.format("start(%s,%s)", dream, isTest));
-
- if (mCurrentDreamComponent != null ) {
- if (dream.equals(mCurrentDreamComponent) && isTest == mCurrentDreamIsTest) {
- if (DEBUG) Slog.v(TAG, "Dream is already started: " + dream);
- return;
- }
- // stop the current dream before starting a new one
- stop();
- }
-
- mCurrentDreamComponent = dream;
- mCurrentDreamIsTest = isTest;
- mCurrentDreamToken = new Binder();
-
- try {
- if (DEBUG) Slog.v(TAG, "Adding window token: " + mCurrentDreamToken
- + " for window type: " + WindowManager.LayoutParams.TYPE_DREAM);
- mIWindowManager.addWindowToken(mCurrentDreamToken,
- WindowManager.LayoutParams.TYPE_DREAM);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to add window token.");
- stop();
- return;
- }
-
- Intent intent = new Intent(Intent.ACTION_MAIN)
- .setComponent(mCurrentDreamComponent)
- .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- .putExtra("android.dreams.TEST", mCurrentDreamIsTest);
-
- if (!mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE)) {
- Slog.w(TAG, "Unable to bind service");
- stop();
- return;
- }
- if (DEBUG) Slog.v(TAG, "Bound service");
- }
-
- public void attach(ComponentName name, IBinder dream) {
- if (DEBUG) Slog.v(TAG, String.format("attach(%s,%s)", name, dream));
- mCurrentDream = IDreamService.Stub.asInterface(dream);
-
- boolean linked = linkDeathRecipient(dream);
- if (!linked) {
- stop();
- return;
- }
-
- try {
- if (DEBUG) Slog.v(TAG, "Attaching with token:" + mCurrentDreamToken);
- mCurrentDream.attach(mCurrentDreamToken);
- } catch (Throwable ex) {
- Slog.w(TAG, "Unable to send window token to dream:" + ex);
- stop();
- }
- }
-
- public void stop() {
- if (DEBUG) Slog.v(TAG, "stop()");
-
- if (mCurrentDream != null) {
- unlinkDeathRecipient(mCurrentDream.asBinder());
-
- if (DEBUG) Slog.v(TAG, "Unbinding: " + mCurrentDreamComponent + " service: " + mCurrentDream);
- mContext.unbindService(mServiceConnection);
- }
- if (mCurrentDreamToken != null) {
- removeWindowToken(mCurrentDreamToken);
- }
-
- final boolean wasTest = mCurrentDreamIsTest;
- mCurrentDream = null;
- mCurrentDreamToken = null;
- mCurrentDreamComponent = null;
- mCurrentDreamIsTest = false;
-
- if (mListener != null && mHandler != null) {
- mHandler.post(new Runnable(){
- @Override
- public void run() {
- mListener.onDreamStopped(wasTest);
- }});
- }
- }
-
- public void stopSelf(IBinder token) {
- if (DEBUG) Slog.v(TAG, String.format("stopSelf(%s)", token));
- if (token == null || token != mCurrentDreamToken) {
- Slog.w(TAG, "Stop requested for non-current dream token: " + token);
- } else {
- stop();
- }
- }
-
- private void removeWindowToken(IBinder token) {
- if (DEBUG) Slog.v(TAG, "Removing window token: " + token);
- try {
- mIWindowManager.removeWindowToken(token);
- } catch (Throwable e) {
- Slog.w(TAG, "Error removing window token", e);
- }
- }
-
- private boolean linkDeathRecipient(IBinder dream) {
- if (DEBUG) Slog.v(TAG, "Linking death recipient");
- try {
- dream.linkToDeath(mDeathRecipient, 0);
- return true;
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to link death recipient", e);
- return false;
- }
- }
-
- private void unlinkDeathRecipient(IBinder dream) {
- if (DEBUG) Slog.v(TAG, "Unlinking death recipient");
- try {
- dream.unlinkToDeath(mDeathRecipient, 0);
- } catch (NoSuchElementException e) {
- // we tried
- }
- }
-
-}
\ No newline at end of file
diff --git a/services/java/com/android/server/DreamManagerService.java b/services/java/com/android/server/DreamManagerService.java
deleted file mode 100644
index b02ea7f..0000000
--- a/services/java/com/android/server/DreamManagerService.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.provider.Settings.Secure.SCREENSAVER_COMPONENTS;
-import static android.provider.Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT;
-
-import android.app.ActivityManagerNative;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.service.dreams.Dream;
-import android.service.dreams.IDreamManager;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Service api for managing dreams.
- *
- * @hide
- */
-public final class DreamManagerService
- extends IDreamManager.Stub
- implements ServiceConnection {
- private static final boolean DEBUG = true;
- private static final String TAG = DreamManagerService.class.getSimpleName();
-
- private static final Intent mDreamingStartedIntent = new Intent(Dream.ACTION_DREAMING_STARTED)
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- private static final Intent mDreamingStoppedIntent = new Intent(Dream.ACTION_DREAMING_STOPPED)
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-
- private final Object mLock = new Object();
- private final DreamController mController;
- private final DreamControllerHandler mHandler;
- private final Context mContext;
-
- private final CurrentUserManager mCurrentUserManager = new CurrentUserManager();
-
- private final DeathRecipient mAwakenOnBinderDeath = new DeathRecipient() {
- @Override
- public void binderDied() {
- if (DEBUG) Slog.v(TAG, "binderDied()");
- awaken();
- }
- };
-
- private final DreamController.Listener mControllerListener = new DreamController.Listener() {
- @Override
- public void onDreamStopped(boolean wasTest) {
- synchronized(mLock) {
- setDreamingLocked(false, wasTest);
- }
- }};
-
- private boolean mIsDreaming;
-
- public DreamManagerService(Context context) {
- if (DEBUG) Slog.v(TAG, "DreamManagerService startup");
- mContext = context;
- mController = new DreamController(context, mAwakenOnBinderDeath, this, mControllerListener);
- mHandler = new DreamControllerHandler(mController);
- mController.setHandler(mHandler);
- }
-
- public void systemReady() {
- mCurrentUserManager.init(mContext);
-
- if (DEBUG) Slog.v(TAG, "Ready to dream!");
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
- pw.println("Dreamland:");
- mController.dump(pw);
- mCurrentUserManager.dump(pw);
- }
-
- // begin IDreamManager api
- @Override
- public ComponentName[] getDreamComponents() {
- checkPermission(android.Manifest.permission.READ_DREAM_STATE);
- int userId = UserHandle.getCallingUserId();
-
- final long ident = Binder.clearCallingIdentity();
- try {
- return getDreamComponentsForUser(userId);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void setDreamComponents(ComponentName[] componentNames) {
- checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
- int userId = UserHandle.getCallingUserId();
-
- final long ident = Binder.clearCallingIdentity();
- try {
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- SCREENSAVER_COMPONENTS,
- componentsToString(componentNames),
- userId);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public ComponentName getDefaultDreamComponent() {
- checkPermission(android.Manifest.permission.READ_DREAM_STATE);
- int userId = UserHandle.getCallingUserId();
-
- final long ident = Binder.clearCallingIdentity();
- try {
- String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
- SCREENSAVER_DEFAULT_COMPONENT,
- userId);
- return name == null ? null : ComponentName.unflattenFromString(name);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
-
- }
-
- @Override
- public boolean isDreaming() {
- checkPermission(android.Manifest.permission.READ_DREAM_STATE);
-
- return mIsDreaming;
- }
-
- @Override
- public void dream() {
- checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
-
- final long ident = Binder.clearCallingIdentity();
- try {
- if (DEBUG) Slog.v(TAG, "Dream now");
- ComponentName[] dreams = getDreamComponentsForUser(mCurrentUserManager.getCurrentUserId());
- ComponentName firstDream = dreams != null && dreams.length > 0 ? dreams[0] : null;
- if (firstDream != null) {
- mHandler.requestStart(firstDream, false /*isTest*/);
- synchronized (mLock) {
- setDreamingLocked(true, false /*isTest*/);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void testDream(ComponentName dream) {
- checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
-
- final long ident = Binder.clearCallingIdentity();
- try {
- if (DEBUG) Slog.v(TAG, "Test dream name=" + dream);
- if (dream != null) {
- mHandler.requestStart(dream, true /*isTest*/);
- synchronized (mLock) {
- setDreamingLocked(true, true /*isTest*/);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
-
- }
-
- @Override
- public void awaken() {
- checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
-
- final long ident = Binder.clearCallingIdentity();
- try {
- if (DEBUG) Slog.v(TAG, "Wake up");
- mHandler.requestStop();
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void awakenSelf(IBinder token) {
- // requires no permission, called by Dream from an arbitrary process
-
- final long ident = Binder.clearCallingIdentity();
- try {
- if (DEBUG) Slog.v(TAG, "Wake up from dream: " + token);
- if (token != null) {
- mHandler.requestStopSelf(token);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- // end IDreamManager api
-
- // begin ServiceConnection
- @Override
- public void onServiceConnected(ComponentName name, IBinder dream) {
- if (DEBUG) Slog.v(TAG, "Service connected: " + name + " binder=" +
- dream + " thread=" + Thread.currentThread().getId());
- mHandler.requestAttach(name, dream);
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- if (DEBUG) Slog.v(TAG, "Service disconnected: " + name);
- // Only happens in exceptional circumstances, awaken just to be safe
- awaken();
- }
- // end ServiceConnection
-
- private void checkPermission(String permission) {
- if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(permission)) {
- throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
- + ", must have permission " + permission);
- }
- }
-
- private void setDreamingLocked(boolean isDreaming, boolean isTest) {
- boolean wasDreaming = mIsDreaming;
- if (!isTest) {
- if (!wasDreaming && isDreaming) {
- if (DEBUG) Slog.v(TAG, "Firing ACTION_DREAMING_STARTED");
- mContext.sendBroadcast(mDreamingStartedIntent);
- } else if (wasDreaming && !isDreaming) {
- if (DEBUG) Slog.v(TAG, "Firing ACTION_DREAMING_STOPPED");
- mContext.sendBroadcast(mDreamingStoppedIntent);
- }
- }
- mIsDreaming = isDreaming;
- }
-
- private ComponentName[] getDreamComponentsForUser(int userId) {
- String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
- SCREENSAVER_COMPONENTS,
- userId);
- return names == null ? null : componentsFromString(names);
- }
-
- private static String componentsToString(ComponentName[] componentNames) {
- StringBuilder names = new StringBuilder();
- if (componentNames != null) {
- for (ComponentName componentName : componentNames) {
- if (names.length() > 0) {
- names.append(',');
- }
- names.append(componentName.flattenToString());
- }
- }
- return names.toString();
- }
-
- private static ComponentName[] componentsFromString(String names) {
- String[] namesArray = names.split(",");
- ComponentName[] componentNames = new ComponentName[namesArray.length];
- for (int i = 0; i < namesArray.length; i++) {
- componentNames[i] = ComponentName.unflattenFromString(namesArray[i]);
- }
- return componentNames;
- }
-
- /**
- * Keeps track of the current user, since dream() uses the current user's configuration.
- */
- private static class CurrentUserManager {
- private final Object mLock = new Object();
- private int mCurrentUserId;
-
- public void init(Context context) {
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_USER_SWITCHED);
- context.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- synchronized(mLock) {
- mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
- if (DEBUG) Slog.v(TAG, "userId " + mCurrentUserId + " is in the house");
- }
- }
- }}, filter);
- try {
- synchronized (mLock) {
- mCurrentUserId = ActivityManagerNative.getDefault().getCurrentUser().id;
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "Couldn't get current user ID; guessing it's 0", e);
- }
- }
-
- public void dump(PrintWriter pw) {
- pw.print(" user="); pw.println(getCurrentUserId());
- }
-
- public int getCurrentUserId() {
- synchronized(mLock) {
- return mCurrentUserId;
- }
- }
- }
-
- /**
- * Handler for asynchronous operations performed by the dream manager.
- *
- * Ensures operations to {@link DreamController} are single-threaded.
- */
- private static final class DreamControllerHandler extends Handler {
- private final DreamController mController;
- private final Runnable mStopRunnable = new Runnable() {
- @Override
- public void run() {
- mController.stop();
- }};
-
- public DreamControllerHandler(DreamController controller) {
- super(true /*async*/);
- mController = controller;
- }
-
- public void requestStart(final ComponentName name, final boolean isTest) {
- post(new Runnable(){
- @Override
- public void run() {
- mController.start(name, isTest);
- }});
- }
-
- public void requestAttach(final ComponentName name, final IBinder dream) {
- post(new Runnable(){
- @Override
- public void run() {
- mController.attach(name, dream);
- }});
- }
-
- public void requestStopSelf(final IBinder token) {
- post(new Runnable(){
- @Override
- public void run() {
- mController.stopSelf(token);
- }});
- }
-
- public void requestStop() {
- post(mStopRunnable);
- }
-
- }
-
-}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 578e602..a0c1552 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -17,17 +17,14 @@
package com.android.server;
import android.app.PendingIntent;
-import android.content.ContentQueryMap;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.ContentObserver;
-import android.database.Cursor;
import android.location.Address;
import android.location.Criteria;
import android.location.GeocoderParams;
@@ -41,7 +38,6 @@
import android.location.LocationManager;
import android.location.LocationProvider;
import android.location.LocationRequest;
-import android.net.ConnectivityManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -55,7 +51,6 @@
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
-import android.provider.Settings.NameValueTable;
import android.util.Log;
import android.util.Slog;
@@ -80,8 +75,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Observable;
-import java.util.Observer;
import java.util.Set;
/**
@@ -1343,7 +1336,7 @@
// Check whether sufficient time has passed
long minTime = record.mRequest.getFastestInterval();
- long delta = (loc.getElapsedRealtimeNano() - lastLoc.getElapsedRealtimeNano()) / 1000000L;
+ long delta = (loc.getElapsedRealtimeNanos() - lastLoc.getElapsedRealtimeNanos()) / 1000000L;
if (delta < minTime - MAX_PROVIDER_SCHEDULING_JITTER_MS) {
return false;
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index eeab757..738e19b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -38,6 +38,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.server.search.SearchManagerService;
+import android.service.dreams.Dream;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -51,6 +52,7 @@
import com.android.server.am.ActivityManagerService;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.DisplayManagerService;
+import com.android.server.dreams.DreamManagerService;
import com.android.server.input.InputManagerService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
@@ -738,8 +740,8 @@
try {
Slog.i(TAG, "Dreams Service");
// Dreams (interactive idle-time views, a/k/a screen savers)
- dreamy = new DreamManagerService(context);
- ServiceManager.addService("dreams", dreamy);
+ dreamy = new DreamManagerService(context, wmHandler);
+ ServiceManager.addService(Dream.DREAM_SERVICE, dreamy);
} catch (Throwable e) {
reportWtf("starting DreamManagerService", e);
}
@@ -810,7 +812,7 @@
context.getResources().updateConfiguration(config, metrics);
try {
- power.systemReady(twilight);
+ power.systemReady(twilight, dreamy);
} catch (Throwable e) {
reportWtf("making Power Manager Service ready", e);
}
diff --git a/services/java/com/android/server/TwilightService.java b/services/java/com/android/server/TwilightService.java
index a7bce54..154de1c 100644
--- a/services/java/com/android/server/TwilightService.java
+++ b/services/java/com/android/server/TwilightService.java
@@ -147,7 +147,7 @@
}
// if new location is older than the current one, the device hasn't moved.
- if (to.getElapsedRealtimeNano() < from.getElapsedRealtimeNano()) {
+ if (to.getElapsedRealtimeNanos() < from.getElapsedRealtimeNanos()) {
return false;
}
@@ -428,8 +428,8 @@
mLocationManager.getLastKnownLocation(providers.next());
// pick the most recent location
if (location == null || (lastKnownLocation != null &&
- location.getElapsedRealtimeNano() <
- lastKnownLocation.getElapsedRealtimeNano())) {
+ location.getElapsedRealtimeNanos() <
+ lastKnownLocation.getElapsedRealtimeNanos())) {
location = lastKnownLocation;
}
}
@@ -447,7 +447,7 @@
location.setLatitude(0);
location.setAccuracy(417000.0f);
location.setTime(System.currentTimeMillis());
- location.setElapsedRealtimeNano(SystemClock.elapsedRealtimeNano());
+ location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
if (DEBUG) {
Slog.d(TAG, "Estimated location from timezone: " + location);
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 85a6e41..07e8f18 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -17,6 +17,7 @@
package com.android.server;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IUiModeManager;
import android.app.Notification;
@@ -39,6 +40,8 @@
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.dreams.Dream;
+import android.service.dreams.IDreamManager;
import android.util.Slog;
import java.io.FileDescriptor;
@@ -56,6 +59,9 @@
private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
+ private static final int DEFAULT_SCREENSAVER_ENABLED = 1;
+ private static final int DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK = 1;
+
private final Context mContext;
private final TwilightService mTwilightService;
private final Handler mHandler = new Handler();
@@ -110,72 +116,10 @@
return;
}
- final int enableFlags = intent.getIntExtra("enableFlags", 0);
- final int disableFlags = intent.getIntExtra("disableFlags", 0);
-
+ final int enableFlags = intent.getIntExtra("enableFlags", 0);
+ final int disableFlags = intent.getIntExtra("disableFlags", 0);
synchronized (mLock) {
- // Launch a dock activity
- String category = null;
- if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
- // Only launch car home when car mode is enabled and the caller
- // has asked us to switch to it.
- if (ENABLE_LAUNCH_CAR_DOCK_APP
- && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
- category = Intent.CATEGORY_CAR_DOCK;
- }
- } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) {
- // Only launch car home when desk mode is enabled and the caller
- // has asked us to switch to it. Currently re-using the car
- // mode flag since we don't have a formal API for "desk mode".
- if (ENABLE_LAUNCH_DESK_DOCK_APP
- && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
- category = Intent.CATEGORY_DESK_DOCK;
- }
- } else {
- // Launch the standard home app if requested.
- if ((disableFlags&UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
- category = Intent.CATEGORY_HOME;
- }
- }
-
- if (LOG) {
- Slog.v(TAG, String.format(
- "Handling broadcast result for action %s: enable=0x%08x disable=0x%08x category=%s",
- intent.getAction(), enableFlags, disableFlags, category));
- }
-
- if (category != null) {
- // This is the new activity that will serve as home while
- // we are in care mode.
- Intent homeIntent = buildHomeIntent(category);
-
- // Now we are going to be careful about switching the
- // configuration and starting the activity -- we need to
- // do this in a specific order under control of the
- // activity manager, to do it cleanly. So compute the
- // new config, but don't set it yet, and let the
- // activity manager take care of both the start and config
- // change.
- Configuration newConfig = null;
- if (mHoldingConfiguration) {
- mHoldingConfiguration = false;
- updateConfigurationLocked(false);
- newConfig = mConfiguration;
- }
- try {
- ActivityManagerNative.getDefault().startActivityWithConfig(
- null, homeIntent, null, null, null, 0, 0,
- newConfig, null, UserHandle.USER_CURRENT);
- mHoldingConfiguration = false;
- } catch (RemoteException e) {
- Slog.w(TAG, e.getCause());
- }
- }
-
- if (mHoldingConfiguration) {
- mHoldingConfiguration = false;
- updateConfigurationLocked(true);
- }
+ updateAfterBroadcastLocked(intent.getAction(), enableFlags, disableFlags);
}
}
};
@@ -335,9 +279,8 @@
}
}
- final void updateConfigurationLocked(boolean sendIt) {
- int uiMode = mTelevision ? Configuration.UI_MODE_TYPE_TELEVISION
- : mDefaultUiModeType;
+ final void updateConfigurationLocked() {
+ int uiMode = mTelevision ? Configuration.UI_MODE_TYPE_TELEVISION : mDefaultUiModeType;
if (mCarModeEnabled) {
uiMode = Configuration.UI_MODE_TYPE_CAR;
} else if (isDeskDockState(mDockState)) {
@@ -365,17 +308,19 @@
}
mCurUiMode = uiMode;
-
- if (!mHoldingConfiguration && uiMode != mSetUiMode) {
- mSetUiMode = uiMode;
+ if (!mHoldingConfiguration) {
mConfiguration.uiMode = uiMode;
+ }
+ }
- if (sendIt) {
- try {
- ActivityManagerNative.getDefault().updateConfiguration(mConfiguration);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failure communicating with activity manager", e);
- }
+ final void sendConfigurationLocked() {
+ if (mSetUiMode != mConfiguration.uiMode) {
+ mSetUiMode = mConfiguration.uiMode;
+
+ try {
+ ActivityManagerNative.getDefault().updateConfiguration(mConfiguration);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failure communicating with activity manager", e);
}
}
}
@@ -434,43 +379,38 @@
intent.putExtra("disableFlags", disableFlags);
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
mResultReceiver, null, Activity.RESULT_OK, null, null);
+
// Attempting to make this transition a little more clean, we are going
// to hold off on doing a configuration change until we have finished
// the broadcast and started the home activity.
mHoldingConfiguration = true;
+ updateConfigurationLocked();
} else {
- Intent homeIntent = null;
+ String category = null;
if (mCarModeEnabled) {
if (ENABLE_LAUNCH_CAR_DOCK_APP
- && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
- homeIntent = buildHomeIntent(Intent.CATEGORY_CAR_DOCK);
+ && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+ category = Intent.CATEGORY_CAR_DOCK;
}
} else if (isDeskDockState(mDockState)) {
if (ENABLE_LAUNCH_DESK_DOCK_APP
- && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
- homeIntent = buildHomeIntent(Intent.CATEGORY_DESK_DOCK);
+ && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+ category = Intent.CATEGORY_DESK_DOCK;
}
} else {
- if ((disableFlags&UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
- homeIntent = buildHomeIntent(Intent.CATEGORY_HOME);
+ if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
+ category = Intent.CATEGORY_HOME;
}
}
if (LOG) {
Slog.v(TAG, "updateLocked: null action, mDockState="
- + mDockState +", firing homeIntent: " + homeIntent);
+ + mDockState +", category=" + category);
}
- if (homeIntent != null) {
- try {
- mContext.startActivityAsUser(homeIntent, UserHandle.CURRENT);
- } catch (ActivityNotFoundException e) {
- }
- }
+ sendConfigurationAndStartDreamOrDockAppLocked(category);
}
- updateConfigurationLocked(true);
-
// keep screen on when charging and in car mode
boolean keepScreenOn = mCharging &&
((mCarModeEnabled && mCarModeKeepsScreenOn) ||
@@ -487,6 +427,100 @@
}
}
+ private void updateAfterBroadcastLocked(String action, int enableFlags, int disableFlags) {
+ // Launch a dock activity
+ String category = null;
+ if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(action)) {
+ // Only launch car home when car mode is enabled and the caller
+ // has asked us to switch to it.
+ if (ENABLE_LAUNCH_CAR_DOCK_APP
+ && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+ category = Intent.CATEGORY_CAR_DOCK;
+ }
+ } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(action)) {
+ // Only launch car home when desk mode is enabled and the caller
+ // has asked us to switch to it. Currently re-using the car
+ // mode flag since we don't have a formal API for "desk mode".
+ if (ENABLE_LAUNCH_DESK_DOCK_APP
+ && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+ category = Intent.CATEGORY_DESK_DOCK;
+ }
+ } else {
+ // Launch the standard home app if requested.
+ if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
+ category = Intent.CATEGORY_HOME;
+ }
+ }
+
+ if (LOG) {
+ Slog.v(TAG, String.format(
+ "Handling broadcast result for action %s: enable=0x%08x, disable=0x%08x, "
+ + "category=%s",
+ action, enableFlags, disableFlags, category));
+ }
+
+ sendConfigurationAndStartDreamOrDockAppLocked(category);
+ }
+
+ private void sendConfigurationAndStartDreamOrDockAppLocked(String category) {
+ // Update the configuration but don't send it yet.
+ mHoldingConfiguration = false;
+ updateConfigurationLocked();
+
+ // Start the dock app, if there is one.
+ boolean dockAppStarted = false;
+ if (category != null) {
+ // Now we are going to be careful about switching the
+ // configuration and starting the activity -- we need to
+ // do this in a specific order under control of the
+ // activity manager, to do it cleanly. So compute the
+ // new config, but don't set it yet, and let the
+ // activity manager take care of both the start and config
+ // change.
+ Intent homeIntent = buildHomeIntent(category);
+ try {
+ int result = ActivityManagerNative.getDefault().startActivityWithConfig(
+ null, homeIntent, null, null, null, 0, 0,
+ mConfiguration, null, UserHandle.USER_CURRENT);
+ if (result >= ActivityManager.START_SUCCESS) {
+ dockAppStarted = true;
+ } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) {
+ Slog.e(TAG, "Could not start dock app: " + homeIntent
+ + ", startActivityWithConfig result " + result);
+ }
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "Could not start dock app: " + homeIntent, ex);
+ }
+ }
+
+ // Send the new configuration.
+ sendConfigurationLocked();
+
+ // If we did not start a dock app, then start dreaming if supported.
+ if (!dockAppStarted && isScreenSaverEnabled() && isScreenSaverActivatedOnDock()) {
+ Slog.i(TAG, "Activating dream while docked.");
+ try {
+ IDreamManager dreamManagerService = IDreamManager.Stub.asInterface(
+ ServiceManager.getService(Dream.DREAM_SERVICE));
+ dreamManagerService.dream();
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "Could not start dream when docked.", ex);
+ }
+ }
+ }
+
+ private boolean isScreenSaverEnabled() {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED,
+ UserHandle.USER_CURRENT) != 0;
+ }
+
+ private boolean isScreenSaverActivatedOnDock() {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
+ DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK, UserHandle.USER_CURRENT) != 0;
+ }
+
private void adjustStatusBarCarModeLocked() {
if (mStatusBarManager == null) {
mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
diff --git a/services/java/com/android/server/dreams/DreamController.java b/services/java/com/android/server/dreams/DreamController.java
new file mode 100644
index 0000000..81c80187
--- /dev/null
+++ b/services/java/com/android/server/dreams/DreamController.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.dreams;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.IBinder.DeathRecipient;
+import android.service.dreams.Dream;
+import android.service.dreams.IDreamService;
+import android.util.Slog;
+import android.view.IWindowManager;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import java.io.PrintWriter;
+import java.util.NoSuchElementException;
+
+/**
+ * Internal controller for starting and stopping the current dream and managing related state.
+ *
+ * Assumes all operations are called from the dream handler thread.
+ */
+final class DreamController {
+ private static final String TAG = "DreamController";
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final Listener mListener;
+ private final IWindowManager mIWindowManager;
+
+ private final Intent mDreamingStartedIntent = new Intent(Dream.ACTION_DREAMING_STARTED)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ private final Intent mDreamingStoppedIntent = new Intent(Dream.ACTION_DREAMING_STOPPED)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+
+ private DreamRecord mCurrentDream;
+
+ public DreamController(Context context, Handler handler, Listener listener) {
+ mContext = context;
+ mHandler = handler;
+ mListener = listener;
+ mIWindowManager = WindowManagerGlobal.getWindowManagerService();
+ }
+
+ public void dump(PrintWriter pw) {
+ pw.println("Dreamland:");
+ if (mCurrentDream != null) {
+ pw.println(" mCurrentDream:");
+ pw.println(" mToken=" + mCurrentDream.mToken);
+ pw.println(" mName=" + mCurrentDream.mName);
+ pw.println(" mIsTest=" + mCurrentDream.mIsTest);
+ pw.println(" mUserId=" + mCurrentDream.mUserId);
+ pw.println(" mBound=" + mCurrentDream.mBound);
+ pw.println(" mService=" + mCurrentDream.mService);
+ pw.println(" mSentStartBroadcast=" + mCurrentDream.mSentStartBroadcast);
+ } else {
+ pw.println(" mCurrentDream: null");
+ }
+ }
+
+ public void startDream(Binder token, ComponentName name, boolean isTest, int userId) {
+ stopDream();
+
+ Slog.i(TAG, "Starting dream: name=" + name + ", isTest=" + isTest + ", userId=" + userId);
+
+ mCurrentDream = new DreamRecord(token, name, isTest, userId);
+
+ try {
+ mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "Unable to add window token for dream.", ex);
+ stopDream();
+ return;
+ }
+
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Dream.CATEGORY_DREAM);
+ intent.setComponent(name);
+ intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ try {
+ if (!mContext.bindService(intent, mCurrentDream,
+ Context.BIND_AUTO_CREATE, userId)) {
+ Slog.e(TAG, "Unable to bind dream service: " + intent);
+ stopDream();
+ return;
+ }
+ } catch (SecurityException ex) {
+ Slog.e(TAG, "Unable to bind dream service: " + intent, ex);
+ stopDream();
+ return;
+ }
+
+ mCurrentDream.mBound = true;
+ }
+
+ public void stopDream() {
+ if (mCurrentDream == null) {
+ return;
+ }
+
+ final DreamRecord oldDream = mCurrentDream;
+ mCurrentDream = null;
+ Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
+ + ", isTest=" + oldDream.mIsTest + ", userId=" + oldDream.mUserId);
+
+ if (oldDream.mSentStartBroadcast) {
+ mContext.sendBroadcast(mDreamingStoppedIntent);
+ }
+
+ if (oldDream.mService != null) {
+ // TODO: It would be nice to tell the dream that it's being stopped so that
+ // it can shut down nicely before we yank its window token out from under it.
+ try {
+ oldDream.mService.asBinder().unlinkToDeath(oldDream, 0);
+ } catch (NoSuchElementException ex) {
+ // don't care
+ }
+ oldDream.mService = null;
+ }
+
+ if (oldDream.mBound) {
+ mContext.unbindService(oldDream);
+ }
+
+ try {
+ mIWindowManager.removeWindowToken(oldDream.mToken);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Error removing window token for dream.", ex);
+ }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onDreamStopped(oldDream.mToken);
+ }
+ });
+ }
+
+ private void attach(IDreamService service) {
+ try {
+ service.asBinder().linkToDeath(mCurrentDream, 0);
+ service.attach(mCurrentDream.mToken);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "The dream service died unexpectedly.", ex);
+ stopDream();
+ return;
+ }
+
+ mCurrentDream.mService = service;
+
+ if (!mCurrentDream.mIsTest) {
+ mContext.sendBroadcast(mDreamingStartedIntent);
+ mCurrentDream.mSentStartBroadcast = true;
+ }
+ }
+
+ /**
+ * Callback interface to be implemented by the {@link DreamManagerService}.
+ */
+ public interface Listener {
+ void onDreamStopped(Binder token);
+ }
+
+ private final class DreamRecord implements DeathRecipient, ServiceConnection {
+ public final Binder mToken;
+ public final ComponentName mName;
+ public final boolean mIsTest;
+ public final int mUserId;
+
+ public boolean mBound;
+ public IDreamService mService;
+ public boolean mSentStartBroadcast;
+
+ public DreamRecord(Binder token, ComponentName name,
+ boolean isTest, int userId) {
+ mToken = token;
+ mName = name;
+ mIsTest = isTest;
+ mUserId = userId;
+ }
+
+ // May be called on any thread.
+ @Override
+ public void binderDied() {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mService = null;
+ if (mCurrentDream == DreamRecord.this) {
+ stopDream();
+ }
+ }
+ });
+ }
+
+ // May be called on any thread.
+ @Override
+ public void onServiceConnected(ComponentName name, final IBinder service) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCurrentDream == DreamRecord.this && mService == null) {
+ attach(IDreamService.Stub.asInterface(service));
+ }
+ }
+ });
+ }
+
+ // May be called on any thread.
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mService = null;
+ if (mCurrentDream == DreamRecord.this) {
+ stopDream();
+ }
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/dreams/DreamManagerService.java b/services/java/com/android/server/dreams/DreamManagerService.java
new file mode 100644
index 0000000..1f40176
--- /dev/null
+++ b/services/java/com/android/server/dreams/DreamManagerService.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.dreams;
+
+import com.android.internal.util.DumpUtils;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.dreams.IDreamManager;
+import android.util.Slog;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import libcore.util.Objects;
+
+/**
+ * Service api for managing dreams.
+ *
+ * @hide
+ */
+public final class DreamManagerService extends IDreamManager.Stub {
+ private static final boolean DEBUG = true;
+ private static final String TAG = "DreamManagerService";
+
+ private final Object mLock = new Object();
+
+ private final Context mContext;
+ private final DreamHandler mHandler;
+ private final DreamController mController;
+ private final PowerManager mPowerManager;
+
+ private Binder mCurrentDreamToken;
+ private ComponentName mCurrentDreamName;
+ private int mCurrentDreamUserId;
+ private boolean mCurrentDreamIsTest;
+
+ public DreamManagerService(Context context, Handler mainHandler) {
+ mContext = context;
+ mHandler = new DreamHandler(mainHandler.getLooper());
+ mController = new DreamController(context, mHandler, mControllerListener);
+
+ mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ }
+
+ public void systemReady() {
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ synchronized (mLock) {
+ stopDreamLocked();
+ }
+ }
+ }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
+ pw.println("DREAM MANAGER (dumpsys dreams)");
+ pw.println();
+
+ pw.println("mCurrentDreamToken=" + mCurrentDreamToken);
+ pw.println("mCurrentDreamName=" + mCurrentDreamName);
+ pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId);
+ pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
+ pw.println();
+
+ DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
+ @Override
+ public void dump(PrintWriter pw) {
+ mController.dump(pw);
+ }
+ }, pw, 200);
+ }
+
+ @Override // Binder call
+ public ComponentName[] getDreamComponents() {
+ checkPermission(android.Manifest.permission.READ_DREAM_STATE);
+
+ final int userId = UserHandle.getCallingUserId();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ return getDreamComponentsForUser(userId);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ public void setDreamComponents(ComponentName[] componentNames) {
+ checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+ final int userId = UserHandle.getCallingUserId();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_COMPONENTS,
+ componentsToString(componentNames),
+ userId);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ public ComponentName getDefaultDreamComponent() {
+ checkPermission(android.Manifest.permission.READ_DREAM_STATE);
+
+ final int userId = UserHandle.getCallingUserId();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
+ userId);
+ return name == null ? null : ComponentName.unflattenFromString(name);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ public boolean isDreaming() {
+ checkPermission(android.Manifest.permission.READ_DREAM_STATE);
+
+ synchronized (mLock) {
+ return mCurrentDreamToken != null && !mCurrentDreamIsTest;
+ }
+ }
+
+ @Override // Binder call
+ public void dream() {
+ checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ // Ask the power manager to nap. It will eventually call back into
+ // startDream() if/when it is appropriate to start dreaming.
+ // Because napping could cause the screen to turn off immediately if the dream
+ // cannot be started, we keep one eye open and gently poke user activity.
+ long time = SystemClock.uptimeMillis();
+ mPowerManager.userActivity(time, true /*noChangeLights*/);
+ mPowerManager.nap(time);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ public void testDream(ComponentName dream) {
+ checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+ if (dream == null) {
+ throw new IllegalArgumentException("dream must not be null");
+ }
+
+ final int callingUserId = UserHandle.getCallingUserId();
+ final int currentUserId = ActivityManager.getCurrentUser();
+ if (callingUserId != currentUserId) {
+ // This check is inherently prone to races but at least it's something.
+ Slog.w(TAG, "Aborted attempt to start a test dream while a different "
+ + " user is active: callingUserId=" + callingUserId
+ + ", currentUserId=" + currentUserId);
+ return;
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ startDreamLocked(dream, true /*isTest*/, callingUserId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ public void awaken() {
+ checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ // Treat an explicit request to awaken as user activity so that the
+ // device doesn't immediately go to sleep if the timeout expired,
+ // for example when being undocked.
+ long time = SystemClock.uptimeMillis();
+ mPowerManager.userActivity(time, false /*noChangeLights*/);
+ stopDream();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
+ public void finishSelf(IBinder token) {
+ // Requires no permission, called by Dream from an arbitrary process.
+ if (token == null) {
+ throw new IllegalArgumentException("token must not be null");
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (DEBUG) {
+ Slog.d(TAG, "Dream finished: " + token);
+ }
+
+ // Note that a dream finishing and self-terminating is not
+ // itself considered user activity. If the dream is ending because
+ // the user interacted with the device then user activity will already
+ // have been poked so the device will stay awake a bit longer.
+ // If the dream is ending on its own for other reasons and no wake
+ // locks are held and the user activity timeout has expired then the
+ // device may simply go to sleep.
+ synchronized (mLock) {
+ if (mCurrentDreamToken == token) {
+ stopDreamLocked();
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ /**
+ * Called by the power manager to start a dream.
+ */
+ public void startDream() {
+ int userId = ActivityManager.getCurrentUser();
+ ComponentName dream = chooseDreamForUser(userId);
+ if (dream != null) {
+ synchronized (mLock) {
+ startDreamLocked(dream, false /*isTest*/, userId);
+ }
+ }
+ }
+
+ /**
+ * Called by the power manager to stop a dream.
+ */
+ public void stopDream() {
+ synchronized (mLock) {
+ stopDreamLocked();
+ }
+ }
+
+ private ComponentName chooseDreamForUser(int userId) {
+ ComponentName[] dreams = getDreamComponentsForUser(userId);
+ return dreams != null && dreams.length != 0 ? dreams[0] : null;
+ }
+
+ private ComponentName[] getDreamComponentsForUser(int userId) {
+ String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+ Settings.Secure.SCREENSAVER_COMPONENTS,
+ userId);
+ return names == null ? null : componentsFromString(names);
+ }
+
+ private void startDreamLocked(final ComponentName name,
+ final boolean isTest, final int userId) {
+ if (Objects.equal(mCurrentDreamName, name)
+ && mCurrentDreamIsTest == isTest
+ && mCurrentDreamUserId == userId) {
+ return;
+ }
+
+ stopDreamLocked();
+
+ Slog.i(TAG, "Entering dreamland.");
+
+ final Binder newToken = new Binder();
+ mCurrentDreamToken = newToken;
+ mCurrentDreamName = name;
+ mCurrentDreamIsTest = isTest;
+ mCurrentDreamUserId = userId;
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mController.startDream(newToken, name, isTest, userId);
+ }
+ });
+ }
+
+ private void stopDreamLocked() {
+ if (mCurrentDreamToken != null) {
+ Slog.i(TAG, "Leaving dreamland.");
+
+ cleanupDreamLocked();
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mController.stopDream();
+ }
+ });
+ }
+ }
+
+ private void cleanupDreamLocked() {
+ mCurrentDreamToken = null;
+ mCurrentDreamName = null;
+ mCurrentDreamIsTest = false;
+ mCurrentDreamUserId = 0;
+ }
+
+ private void checkPermission(String permission) {
+ if (mContext.checkCallingOrSelfPermission(permission)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
+ + ", must have permission " + permission);
+ }
+ }
+
+ private static String componentsToString(ComponentName[] componentNames) {
+ StringBuilder names = new StringBuilder();
+ if (componentNames != null) {
+ for (ComponentName componentName : componentNames) {
+ if (names.length() > 0) {
+ names.append(',');
+ }
+ names.append(componentName.flattenToString());
+ }
+ }
+ return names.toString();
+ }
+
+ private static ComponentName[] componentsFromString(String names) {
+ String[] namesArray = names.split(",");
+ ComponentName[] componentNames = new ComponentName[namesArray.length];
+ for (int i = 0; i < namesArray.length; i++) {
+ componentNames[i] = ComponentName.unflattenFromString(namesArray[i]);
+ }
+ return componentNames;
+ }
+
+ private final DreamController.Listener mControllerListener = new DreamController.Listener() {
+ @Override
+ public void onDreamStopped(Binder token) {
+ synchronized (mLock) {
+ if (mCurrentDreamToken == token) {
+ cleanupDreamLocked();
+ }
+ }
+ }
+ };
+
+ /**
+ * Handler for asynchronous operations performed by the dream manager.
+ * Ensures operations to {@link DreamController} are single-threaded.
+ */
+ private final class DreamHandler extends Handler {
+ public DreamHandler(Looper looper) {
+ super(looper, null, true /*async*/);
+ }
+ }
+}
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 28870a2..84adb83 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -1029,7 +1029,7 @@
mLocation.setTime(timestamp);
// It would be nice to push the elapsed real-time timestamp
// further down the stack, but this is still useful
- mLocation.setElapsedRealtimeNano(SystemClock.elapsedRealtimeNano());
+ mLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}
if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
mLocation.setAltitude(altitude);
diff --git a/services/java/com/android/server/location/LocationBasedCountryDetector.java b/services/java/com/android/server/location/LocationBasedCountryDetector.java
index 38871d78..03db621 100755
--- a/services/java/com/android/server/location/LocationBasedCountryDetector.java
+++ b/services/java/com/android/server/location/LocationBasedCountryDetector.java
@@ -115,8 +115,8 @@
Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
if (lastKnownLocation != null) {
if (bestLocation == null ||
- bestLocation.getElapsedRealtimeNano() <
- lastKnownLocation.getElapsedRealtimeNano()) {
+ bestLocation.getElapsedRealtimeNanos() <
+ lastKnownLocation.getElapsedRealtimeNanos()) {
bestLocation = lastKnownLocation;
}
}
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 030eb5e..ad138e8 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -24,6 +24,7 @@
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService;
import com.android.server.display.DisplayManagerService;
+import com.android.server.dreams.DreamManagerService;
import android.Manifest;
import android.content.BroadcastReceiver;
@@ -46,13 +47,11 @@
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
import android.service.dreams.Dream;
-import android.service.dreams.IDreamManager;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -100,14 +99,12 @@
private static final int DIRTY_STAY_ON = 1 << 7;
// Dirty bit: battery state changed
private static final int DIRTY_BATTERY_STATE = 1 << 8;
- // Dirty bit: dream ended
- private static final int DIRTY_DREAM_ENDED = 1 << 9;
// Wakefulness: The device is asleep and can only be awoken by a call to wakeUp().
// The screen should be off or in the process of being turned off by the display controller.
private static final int WAKEFULNESS_ASLEEP = 0;
// Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
- // When the user activity timeout expires, the device may start napping.
+ // When the user activity timeout expires, the device may start napping or go to sleep.
private static final int WAKEFULNESS_AWAKE = 1;
// Wakefulness: The device is napping. It is deciding whether to dream or go to sleep
// but hasn't gotten around to it yet. It can be awoken by a call to wakeUp(), which
@@ -149,7 +146,7 @@
private Notifier mNotifier;
private DisplayPowerController mDisplayPowerController;
private SettingsObserver mSettingsObserver;
- private IDreamManager mDreamManager;
+ private DreamManagerService mDreamManager;
private LightsService.Light mAttentionLight;
private final Object mLock = new Object();
@@ -335,9 +332,10 @@
}
}
- public void systemReady(TwilightService twilight) {
+ public void systemReady(TwilightService twilight, DreamManagerService dreamManager) {
synchronized (mLock) {
mSystemReady = true;
+ mDreamManager = dreamManager;
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
@@ -365,10 +363,7 @@
mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
filter = new IntentFilter();
- filter.addAction(Intent.ACTION_DOCK_EVENT);
- mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
-
- filter = new IntentFilter();
+ filter.addAction(Dream.ACTION_DREAMING_STARTED);
filter.addAction(Dream.ACTION_DREAMING_STOPPED);
mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
@@ -887,6 +882,47 @@
return true;
}
+ @Override // Binder call
+ public void nap(long eventTime) {
+ if (eventTime > SystemClock.uptimeMillis()) {
+ throw new IllegalArgumentException("event time must not be in the future");
+ }
+
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ napInternal(eventTime);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void napInternal(long eventTime) {
+ synchronized (mLock) {
+ if (napNoUpdateLocked(eventTime)) {
+ updatePowerStateLocked();
+ }
+ }
+ }
+
+ private boolean napNoUpdateLocked(long eventTime) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime);
+ }
+
+ if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
+ || !mBootCompleted || !mSystemReady) {
+ return false;
+ }
+
+ Slog.i(TAG, "Nap time...");
+
+ mDirty |= DIRTY_WAKEFULNESS;
+ mWakefulness = WAKEFULNESS_NAPPING;
+ return true;
+ }
+
/**
* Updates the global power state based on dirty bits recorded in mDirty.
*
@@ -1143,11 +1179,15 @@
| DIRTY_WAKEFULNESS | DIRTY_STAY_ON)) != 0) {
if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakefulnessLocked: Nap time...");
+ Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
}
- mWakefulness = WAKEFULNESS_NAPPING;
- mDirty |= DIRTY_WAKEFULNESS;
- changed = true;
+ final long time = SystemClock.uptimeMillis();
+ if (mDreamsActivateOnSleepSetting) {
+ changed = napNoUpdateLocked(time);
+ } else {
+ changed = goToSleepNoUpdateLocked(time,
+ PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+ }
}
}
return changed;
@@ -1172,8 +1212,7 @@
| DIRTY_SETTINGS
| DIRTY_IS_POWERED
| DIRTY_STAY_ON
- | DIRTY_BATTERY_STATE
- | DIRTY_DREAM_ENDED)) != 0) {
+ | DIRTY_BATTERY_STATE)) != 0) {
scheduleSandmanLocked();
}
}
@@ -1210,32 +1249,15 @@
}
}
- // Get the dream manager, if needed.
- if (startDreaming && mDreamManager == null) {
- mDreamManager = IDreamManager.Stub.asInterface(
- ServiceManager.checkService("dreams"));
- if (mDreamManager == null) {
- Slog.w(TAG, "Unable to find IDreamManager.");
- }
- }
-
// Start dreaming if needed.
// We only control the dream on the handler thread, so we don't need to worry about
// concurrent attempts to start or stop the dream.
boolean isDreaming = false;
if (mDreamManager != null) {
- try {
- isDreaming = mDreamManager.isDreaming();
- if (startDreaming && !isDreaming) {
- Slog.i(TAG, "Entering dreamland.");
- mDreamManager.dream();
- isDreaming = mDreamManager.isDreaming();
- if (!isDreaming) {
- Slog.i(TAG, "Could not enter dreamland. Sleep will be dreamless.");
- }
- }
- } catch (RemoteException ex) {
+ if (startDreaming) {
+ mDreamManager.startDream();
}
+ isDreaming = mDreamManager.isDreaming();
}
// Update dream state.
@@ -1255,18 +1277,6 @@
if (!continueDreaming) {
handleDreamFinishedLocked();
}
-
- // In addition to listening for the intent, poll the sandman periodically to detect
- // when the dream has ended (as a watchdog only, ensuring our state is always correct).
- if (mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_NAPPING) {
- if (!mSandmanScheduled) {
- mSandmanScheduled = true;
- Message msg = mHandler.obtainMessage(MSG_SANDMAN);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, 5000);
- }
- }
}
// Stop dreaming if needed.
@@ -1274,26 +1284,22 @@
// If so, then the power manager will have posted another message to the handler
// to take care of it later.
if (mDreamManager != null) {
- try {
- if (!continueDreaming && isDreaming) {
- Slog.i(TAG, "Leaving dreamland.");
- mDreamManager.awaken();
- }
- } catch (RemoteException ex) {
+ if (!continueDreaming) {
+ mDreamManager.stopDream();
}
}
}
/**
* Returns true if the device is allowed to dream in its current state,
- * assuming there has been no recent user activity and no wake locks are held.
+ * assuming that there was either an explicit request to nap or the user activity
+ * timeout expired and no wake locks are held.
*/
private boolean canDreamLocked() {
return mIsPowered
&& mDreamsSupportedConfig
&& mDreamsEnabledSetting
- && mDreamsActivateOnSleepSetting
- && !mBatteryService.isBatteryLow();
+ && mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
}
/**
@@ -1313,7 +1319,6 @@
}
}
-
/**
* Updates the display power state asynchronously.
* When the update is finished, mDisplayReady will be set to true. The display
@@ -1494,15 +1499,6 @@
updatePowerStateLocked();
}
- private void handleDockStateChangedLocked(int dockState) {
- // TODO
- }
-
- private void handleDreamEndedLocked() {
- mDirty |= DIRTY_DREAM_ENDED;
- updatePowerStateLocked();
- }
-
/**
* Reboot the device immediately, passing 'reason' (may be null)
* to the underlying __reboot system call. Should not return.
@@ -1957,22 +1953,11 @@
}
}
- private final class DockReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- synchronized (mLock) {
- int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
- Intent.EXTRA_DOCK_STATE_UNDOCKED);
- handleDockStateChangedLocked(dockState);
- }
- }
- }
-
private final class DreamReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
- handleDreamEndedLocked();
+ scheduleSandmanLocked();
}
}
}
diff --git a/tests/RenderScriptTests/ImageProcessing/res/layout/main.xml b/tests/RenderScriptTests/ImageProcessing/res/layout/main.xml
index 4715d6e..f0a2b92 100644
--- a/tests/RenderScriptTests/ImageProcessing/res/layout/main.xml
+++ b/tests/RenderScriptTests/ImageProcessing/res/layout/main.xml
@@ -54,6 +54,10 @@
android:id="@+id/filterselection"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
+ <Spinner
+ android:id="@+id/spinner1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
<TextView
android:id="@+id/slider1Text"
android:layout_width="match_parent"
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blend.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blend.java
new file mode 100644
index 0000000..2920824
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blend.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.image;
+
+import java.lang.Math;
+import java.lang.Short;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScript;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
+import android.renderscript.ScriptGroup;
+import android.renderscript.ScriptIntrinsicBlend;
+import android.renderscript.Type;
+import android.util.Log;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.view.View;
+import android.widget.Spinner;
+
+public class Blend extends TestBase {
+ private ScriptIntrinsicBlend mBlend;
+ private ScriptC_blend mBlendHelper;
+ private short image1Alpha = 128;
+ private short image2Alpha = 128;
+
+ String mIntrinsicNames[];
+
+ private Allocation image1;
+ private Allocation image2;
+ private int currentIntrinsic = 0;
+
+ private AdapterView.OnItemSelectedListener mIntrinsicSpinnerListener =
+ new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+ currentIntrinsic = pos;
+ runTest();
+ act.updateDisplay();
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+
+ }
+ };
+
+ public void createTest(android.content.res.Resources res) {
+ mBlend = ScriptIntrinsicBlend.create(mRS, Element.U8_4(mRS));
+ mBlendHelper = new ScriptC_blend(mRS);
+ mBlendHelper.set_alpha((short)128);
+
+ image1 = Allocation.createTyped(mRS, mInPixelsAllocation.getType());
+ image2 = Allocation.createTyped(mRS, mInPixelsAllocation2.getType());
+
+ mIntrinsicNames = new String[14];
+ mIntrinsicNames[0] = "Source";
+ mIntrinsicNames[1] = "Destination";
+ mIntrinsicNames[2] = "Source Over";
+ mIntrinsicNames[3] = "Destination Over";
+ mIntrinsicNames[4] = "Source In";
+ mIntrinsicNames[5] = "Destination In";
+ mIntrinsicNames[6] = "Source Out";
+ mIntrinsicNames[7] = "Destination Out";
+ mIntrinsicNames[8] = "Source Atop";
+ mIntrinsicNames[9] = "Destination Atop";
+ mIntrinsicNames[10] = "XOR";
+ mIntrinsicNames[11] = "Add";
+ mIntrinsicNames[12] = "Subtract";
+ mIntrinsicNames[13] = "Multiply";
+ }
+
+ public boolean onSpinner1Setup(Spinner s) {
+ s.setAdapter(new ArrayAdapter<String>(
+ act, R.layout.spinner_layout, mIntrinsicNames));
+ s.setOnItemSelectedListener(mIntrinsicSpinnerListener);
+ return true;
+ }
+
+ public boolean onBar1Setup(SeekBar b, TextView t) {
+ t.setText("Image 1 Alpha");
+ b.setMax(255);
+ b.setProgress(image1Alpha);
+ return true;
+ }
+
+ public void onBar1Changed(int progress) {
+ image1Alpha = (short)progress;
+ }
+
+ public boolean onBar2Setup(SeekBar b, TextView t) {
+ t.setText("Image 2 Alpha");
+ b.setMax(255);
+ b.setProgress(image2Alpha);
+ return true;
+ }
+
+ public void onBar2Changed(int progress) {
+ image2Alpha = (short)progress;
+ }
+
+ public void runTest() {
+ image1.copy2DRangeFrom(0, 0, mInPixelsAllocation.getType().getX(), mInPixelsAllocation.getType().getY(), mInPixelsAllocation, 0, 0);
+ image2.copy2DRangeFrom(0, 0, mInPixelsAllocation2.getType().getX(), mInPixelsAllocation2.getType().getY(), mInPixelsAllocation2, 0, 0);
+
+ mBlendHelper.set_alpha(image1Alpha);
+ mBlendHelper.forEach_setImageAlpha(image1);
+
+ mBlendHelper.set_alpha(image2Alpha);
+ mBlendHelper.forEach_setImageAlpha(image2);
+
+ switch (currentIntrinsic) {
+ case 0:
+ mBlend.forEachSrc(image1, image2);
+ break;
+ case 1:
+ mBlend.forEachDst(image1, image2);
+ break;
+ case 2:
+ mBlend.forEachSrcOver(image1, image2);
+ break;
+ case 3:
+ mBlend.forEachDstOver(image1, image2);
+ break;
+ case 4:
+ mBlend.forEachSrcIn(image1, image2);
+ break;
+ case 5:
+ mBlend.forEachDstIn(image1, image2);
+ break;
+ case 6:
+ mBlend.forEachSrcOut(image1, image2);
+ break;
+ case 7:
+ mBlend.forEachDstOut(image1, image2);
+ break;
+ case 8:
+ mBlend.forEachSrcAtop(image1, image2);
+ break;
+ case 9:
+ mBlend.forEachDstAtop(image1, image2);
+ break;
+ case 10:
+ mBlend.forEachXor(image1, image2);
+ break;
+ case 11:
+ mBlend.forEachAdd(image1, image2);
+ break;
+ case 12:
+ mBlend.forEachSubtract(image1, image2);
+ break;
+ case 13:
+ mBlend.forEachMultiply(image1, image2);
+ break;
+ }
+
+ mOutPixelsAllocation.copy2DRangeFrom(0, 0, image2.getType().getX(), image2.getType().getY(), image2, 0, 0);
+ }
+
+}
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index a8462e6..db0ef78 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -55,9 +55,11 @@
private final String RESULT_FILE = "image_processing_result.csv";
Bitmap mBitmapIn;
+ Bitmap mBitmapIn2;
Bitmap mBitmapOut;
String mTestNames[];
+ private Spinner mSpinner;
private SeekBar mBar1;
private SeekBar mBar2;
private SeekBar mBar3;
@@ -81,6 +83,10 @@
private TestBase mTest;
+ public void updateDisplay() {
+ mTest.updateBitmap(mBitmapOut);
+ mDisplayView.invalidate();
+ }
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
@@ -98,8 +104,7 @@
}
mTest.runTest();
- mTest.updateBitmap(mBitmapOut);
- mDisplayView.invalidate();
+ updateDisplay();
}
}
@@ -110,6 +115,9 @@
}
void setupBars() {
+ mSpinner.setVisibility(View.VISIBLE);
+ mTest.onSpinner1Setup(mSpinner);
+
mBar1.setVisibility(View.VISIBLE);
mText1.setVisibility(View.VISIBLE);
mTest.onBar1Setup(mBar1, mText1);
@@ -221,19 +229,21 @@
case 27:
mTest = new Mandelbrot();
break;
+ case 28:
+ mTest = new Blend();
+ break;
}
- mTest.createBaseTest(this, mBitmapIn);
+ mTest.createBaseTest(this, mBitmapIn, mBitmapIn2);
setupBars();
mTest.runTest();
- mTest.updateBitmap(mBitmapOut);
- mDisplayView.invalidate();
+ updateDisplay();
mBenchmarkResult.setText("Result: not run");
}
void setupTests() {
- mTestNames = new String[28];
+ mTestNames = new String[29];
mTestNames[0] = "Levels Vec3 Relaxed";
mTestNames[1] = "Levels Vec4 Relaxed";
mTestNames[2] = "Levels Vec3 Full";
@@ -262,6 +272,7 @@
mTestNames[25] = "Convolve 5x5";
mTestNames[26] = "Intrinsics Convolve 5x5";
mTestNames[27] = "Mandelbrot";
+ mTestNames[28] = "Intrinsics Blend";
mTestSpinner.setAdapter(new ArrayAdapter<String>(
this, R.layout.spinner_layout, mTestNames));
@@ -284,6 +295,7 @@
setContentView(R.layout.main);
mBitmapIn = loadBitmap(R.drawable.img1600x1067);
+ mBitmapIn2 = loadBitmap(R.drawable.img1600x1067b);
mBitmapOut = loadBitmap(R.drawable.img1600x1067);
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
@@ -291,6 +303,8 @@
mDisplayView = (ImageView) findViewById(R.id.display);
mDisplayView.setImageBitmap(mBitmapOut);
+ mSpinner = (Spinner) findViewById(R.id.spinner1);
+
mBar1 = (SeekBar) findViewById(R.id.slider1);
mBar2 = (SeekBar) findViewById(R.id.slider2);
mBar3 = (SeekBar) findViewById(R.id.slider3);
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java
index 6885181..8009daa 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java
@@ -36,14 +36,18 @@
import android.view.View;
import android.util.Log;
import java.lang.Math;
+import android.widget.Spinner;
public class TestBase {
protected final String TAG = "Img";
protected RenderScript mRS;
protected Allocation mInPixelsAllocation;
+ protected Allocation mInPixelsAllocation2;
protected Allocation mOutPixelsAllocation;
+ protected ImageProcessingActivity act;
+
// Override to use UI elements
public void onBar1Changed(int progress) {
}
@@ -84,11 +88,20 @@
return false;
}
- public final void createBaseTest(ImageProcessingActivity act, Bitmap b) {
+ public boolean onSpinner1Setup(Spinner s) {
+ s.setVisibility(View.INVISIBLE);
+ return false;
+ }
+
+ public final void createBaseTest(ImageProcessingActivity ipact, Bitmap b, Bitmap b2) {
+ act = ipact;
mRS = RenderScript.create(act);
mInPixelsAllocation = Allocation.createFromBitmap(mRS, b,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
+ mInPixelsAllocation2 = Allocation.createFromBitmap(mRS, b2,
+ Allocation.MipmapControl.MIPMAP_NONE,
+ Allocation.USAGE_SCRIPT);
mOutPixelsAllocation = Allocation.createFromBitmap(mRS, b,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/blend.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/blend.rs
new file mode 100644
index 0000000..87b56f77
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/blend.rs
@@ -0,0 +1,24 @@
+// Copyright (C) 2011 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.
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.rs.image)
+
+uchar alpha = 0x0;
+
+void setImageAlpha(uchar4 *v_out, uint32_t x, uint32_t y) {
+ v_out->rgba = convert_uchar4((convert_uint4(v_out->rgba) * alpha) >> (uint4)8);
+ v_out->a = alpha;
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index 83fadcb..7662007 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -72,6 +72,7 @@
unitTests.add(new UT_array_alloc(this, mRes, mCtx));
unitTests.add(new UT_kernel(this, mRes, mCtx));
unitTests.add(new UT_kernel_struct(this, mRes, mCtx));
+ unitTests.add(new UT_bug_char(this, mRes, mCtx));
unitTests.add(new UT_clamp(this, mRes, mCtx));
unitTests.add(new UT_clamp_relaxed(this, mRes, mCtx));
unitTests.add(new UT_convert(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_bug_char.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_bug_char.java
new file mode 100644
index 0000000..faf3a31
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_bug_char.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+import java.util.Arrays;
+
+public class UT_bug_char extends UnitTest {
+ private Resources mRes;
+
+ protected UT_bug_char(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Bug Char", ctx);
+ mRes = res;
+ }
+
+ // packing functions
+ private Byte2 pack_b2(byte[] val) {
+ assert val.length == 2;
+ Log.i("bug_char", "pack_b2 " + val[0] + " " + val[1]);
+ return new Byte2(val[0], val[1]);
+ }
+
+ private byte min(byte v1, byte v2) {
+ return v1 < v2 ? v1 : v2;
+ }
+ private byte[] min(byte[] v1, byte[] v2) {
+ assert v1.length == v2.length;
+ byte[] rv = new byte[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2[i]);
+ return rv;
+ }
+
+ private void initializeValues(ScriptC_bug_char s) {
+ byte rand_sc1_0 = (byte)7;
+ byte[] rand_sc2_0 = new byte[2];
+ rand_sc2_0[0] = 11;
+ rand_sc2_0[1] = 21;
+ Log.i("bug_char", "Generated sc2_0 to " + Arrays.toString(rand_sc2_0));
+ byte rand_sc1_1 = (byte)10;
+ byte[] rand_sc2_1 = new byte[2];
+ rand_sc2_1[0] = 13;
+ rand_sc2_1[1] = 15;
+ Log.i("bug_char", "Generated sc2_1 to " + Arrays.toString(rand_sc2_1));
+
+ s.set_rand_sc1_0(rand_sc1_0);
+ s.set_rand_sc2_0(pack_b2(rand_sc2_0));
+ s.set_rand_sc1_1(rand_sc1_1);
+ s.set_rand_sc2_1(pack_b2(rand_sc2_1));
+ // Set results for min
+ s.set_min_rand_sc1_sc1(min(rand_sc1_0, rand_sc1_1));
+ byte[] min_rand_sc2_raw = min(rand_sc2_0, rand_sc2_1);
+ Log.i("bug_char", "Generating min_rand_sc2_sc2 to " +
+ Arrays.toString(min_rand_sc2_raw));
+ Byte2 min_rand_sc2 = pack_b2(min_rand_sc2_raw);
+ Log.i("bug_char", "Setting min_rand_sc2_sc2 to [" + min_rand_sc2.x +
+ ", " + min_rand_sc2.y + "]");
+ s.set_min_rand_sc2_sc2(min_rand_sc2);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_bug_char s = new ScriptC_bug_char(pRS, mRes,
+ R.raw.bug_char);
+ pRS.setMessageHandler(mRsMessage);
+ initializeValues(s);
+ s.invoke_bug_char_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java
index 40f7213..220509c 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java
@@ -347,8 +347,6 @@
long[] rand_sl2_1 = randvec_long(2);
long[] rand_sl3_1 = randvec_long(3);
long[] rand_sl4_1 = randvec_long(4);
- // FIXME: generate signed char vectors once bug 6865598 is fixed
- /*
byte rand_sc1_0 = (byte)rand.nextInt(0x1 << 8);
byte[] rand_sc2_0 = randvec_char(2);
byte[] rand_sc3_0 = randvec_char(3);
@@ -357,7 +355,6 @@
byte[] rand_sc2_1 = randvec_char(2);
byte[] rand_sc3_1 = randvec_char(3);
byte[] rand_sc4_1 = randvec_char(4);
- */
// TODO: generate unsigned long vectors
// Set random vectors in renderscript code
@@ -417,8 +414,6 @@
s.set_rand_uc2_0(pack_s2(rand_uc2_0));
s.set_rand_uc3_0(pack_s3(rand_uc3_0));
s.set_rand_uc4_0(pack_s4(rand_uc4_0));
- // FIXME: set char input vectors once bug 6865598 is fixed
- /*
s.set_rand_sc1_0(rand_sc1_0);
s.set_rand_sc2_0(pack_b2(rand_sc2_0));
s.set_rand_sc3_0(pack_b3(rand_sc3_0));
@@ -427,7 +422,6 @@
s.set_rand_sc2_1(pack_b2(rand_sc2_1));
s.set_rand_sc3_1(pack_b3(rand_sc3_1));
s.set_rand_sc4_1(pack_b4(rand_sc4_1));
- */
// TODO: set unsigned long vectors
// Set results for min
@@ -459,13 +453,10 @@
s.set_min_rand_sl2_sl2(pack_l2(min(rand_sl2_0, rand_sl2_1)));
s.set_min_rand_sl3_sl3(pack_l3(min(rand_sl3_0, rand_sl3_1)));
s.set_min_rand_sl4_sl4(pack_l4(min(rand_sl4_0, rand_sl4_1)));
- // FIXME: set char min reference vectors once bug 6865598 is fixed
- /*
s.set_min_rand_sc1_sc1(min(rand_sc1_0, rand_sc1_1));
s.set_min_rand_sc2_sc2(pack_b2(min(rand_sc2_0, rand_sc2_1)));
s.set_min_rand_sc3_sc3(pack_b3(min(rand_sc3_0, rand_sc3_1)));
s.set_min_rand_sc4_sc4(pack_b4(min(rand_sc4_0, rand_sc4_1)));
- */
// TODO: set results for unsigned long min
// Set results for max
@@ -497,13 +488,10 @@
s.set_max_rand_sl2_sl2(pack_l2(max(rand_sl2_0, rand_sl2_1)));
s.set_max_rand_sl3_sl3(pack_l3(max(rand_sl3_0, rand_sl3_1)));
s.set_max_rand_sl4_sl4(pack_l4(max(rand_sl4_0, rand_sl4_1)));
- // FIXME: set signed char max reference vectors once bug 6865598 is fixed
- /*
s.set_max_rand_sc1_sc1(max(rand_sc1_0, rand_sc1_1));
s.set_max_rand_sc2_sc2(pack_b2(max(rand_sc2_0, rand_sc2_1)));
s.set_max_rand_sc3_sc3(pack_b3(max(rand_sc3_0, rand_sc3_1)));
s.set_max_rand_sc4_sc4(pack_b4(max(rand_sc4_0, rand_sc4_1)));
- */
// TODO: set results for unsigned long max
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/bug_char.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/bug_char.rs
new file mode 100644
index 0000000..dcd7b72
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/bug_char.rs
@@ -0,0 +1,47 @@
+#include "shared.rsh"
+
+char rand_sc1_0, rand_sc1_1;
+char2 rand_sc2_0, rand_sc2_1;
+
+char min_rand_sc1_sc1;
+char2 min_rand_sc2_sc2;
+
+static bool test_bug_char() {
+ bool failed = false;
+
+ rsDebug("rand_sc2_0.x: ", rand_sc2_0.x);
+ rsDebug("rand_sc2_0.y: ", rand_sc2_0.y);
+ rsDebug("rand_sc2_1.x: ", rand_sc2_1.x);
+ rsDebug("rand_sc2_1.y: ", rand_sc2_1.y);
+ char temp_sc1;
+ char2 temp_sc2;
+
+ temp_sc1 = min( rand_sc1_0, rand_sc1_1 );
+ if (temp_sc1 != min_rand_sc1_sc1) {
+ rsDebug("temp_sc1", temp_sc1);
+ failed = true;
+ }
+ rsDebug("broken", 'y');
+
+ temp_sc2 = min( rand_sc2_0, rand_sc2_1 );
+ if (temp_sc2.x != min_rand_sc2_sc2.x
+ || temp_sc2.y != min_rand_sc2_sc2.y) {
+ failed = true;
+ }
+
+
+ return failed;
+}
+
+void bug_char_test() {
+ bool failed = false;
+ failed |= test_bug_char();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs
index 1adb036..5bfbb2b 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs
@@ -338,16 +338,13 @@
#define TEST_VEC_VEC_ALL(func) \
TEST_FN_FN_ALL(func) \
+TEST_SC_SC_ALL(func) \
TEST_UC_UC_ALL(func) \
TEST_SS_SS_ALL(func) \
TEST_US_US_ALL(func) \
TEST_SI_SI_ALL(func) \
TEST_UI_UI_ALL(func)
-// FIXME: Add char tests back in once bug 6865598 is fixed
-#if 0
-TEST_SC_SC_ALL(func)
-#endif
// TODO: add long types to ALL macro
#if 0
TEST_SL_SL_ALL(func) \
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 0c85204..0cf0f21 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -60,6 +60,11 @@
}
@Override
+ public void nap(long arg0) throws RemoteException {
+ // pass for now.
+ }
+
+ @Override
public void preventScreenOn(boolean arg0) throws RemoteException {
// pass for now.
}