summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt67
-rw-r--r--core/java/android/app/ActivityThread.java42
-rw-r--r--core/java/android/app/ContextImpl.java199
-rw-r--r--core/java/android/app/LoadedApk.java51
-rw-r--r--core/java/android/content/Intent.java6
-rw-r--r--core/java/android/os/BatteryStats.java70
-rw-r--r--core/java/android/os/Vibrator.java4
-rw-r--r--core/java/android/view/ContextThemeWrapper.java9
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl3
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java82
-rw-r--r--core/java/com/android/internal/widget/SwipeDismissLayout.java28
-rw-r--r--core/jni/android_view_DisplayList.cpp106
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp4
-rw-r--r--core/jni/android_view_GLRenderer.cpp2
-rw-r--r--core/jni/android_view_HardwareLayer.cpp2
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp4
-rw-r--r--docs/html/google/auth/api-client.jd4
-rw-r--r--docs/html/guide/topics/ui/controls/button.jd2
-rw-r--r--docs/html/guide/topics/ui/controls/togglebutton.jd2
-rw-r--r--libs/hwui/AmbientShadow.cpp54
-rw-r--r--libs/hwui/Caches.cpp28
-rw-r--r--libs/hwui/Caches.h9
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp2
-rw-r--r--libs/hwui/DeferredLayerUpdater.h4
-rw-r--r--libs/hwui/DisplayList.cpp221
-rw-r--r--libs/hwui/DisplayList.h21
-rw-r--r--libs/hwui/DisplayListOp.h32
-rw-r--r--libs/hwui/DisplayListRenderer.cpp2
-rw-r--r--libs/hwui/DisplayListRenderer.h4
-rw-r--r--libs/hwui/Layer.cpp4
-rw-r--r--libs/hwui/Layer.h6
-rw-r--r--libs/hwui/Matrix.cpp85
-rw-r--r--libs/hwui/Matrix.h5
-rw-r--r--libs/hwui/OpenGLRenderer.cpp53
-rw-r--r--libs/hwui/OpenGLRenderer.h8
-rw-r--r--libs/hwui/Renderer.h4
-rw-r--r--libs/hwui/ShadowTessellator.cpp29
-rw-r--r--libs/hwui/ShadowTessellator.h12
-rw-r--r--libs/hwui/SpotShadow.cpp254
-rw-r--r--libs/hwui/SpotShadow.h6
-rw-r--r--libs/hwui/Vector.h4
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp4
-rw-r--r--libs/hwui/renderthread/CanvasContext.h6
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp8
-rw-r--r--libs/hwui/renderthread/RenderProxy.h6
-rwxr-xr-xmedia/java/android/mtp/MtpDatabase.java43
-rw-r--r--media/java/android/mtp/MtpServer.java6
-rw-r--r--media/jni/android_mtp_MtpDatabase.cpp142
-rw-r--r--media/jni/android_mtp_MtpServer.cpp14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java3
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java30
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java16
-rw-r--r--services/core/java/com/android/server/power/DisplayPowerController.java110
-rw-r--r--services/core/java/com/android/server/power/DisplayPowerState.java9
-rw-r--r--services/core/java/com/android/server/power/Notifier.java33
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java21
56 files changed, 1085 insertions, 900 deletions
diff --git a/api/current.txt b/api/current.txt
index 6519008..eb6de96 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6772,6 +6772,7 @@ package android.content {
field public static final java.lang.String CATEGORY_HOME = "android.intent.category.HOME";
field public static final java.lang.String CATEGORY_INFO = "android.intent.category.INFO";
field public static final java.lang.String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
+ field public static final java.lang.String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
field public static final java.lang.String CATEGORY_LE_DESK_DOCK = "android.intent.category.LE_DESK_DOCK";
field public static final java.lang.String CATEGORY_MONKEY = "android.intent.category.MONKEY";
field public static final java.lang.String CATEGORY_OPENABLE = "android.intent.category.OPENABLE";
@@ -38593,6 +38594,11 @@ package java.net {
method public abstract java.net.SocketImpl createSocketImpl();
}
+ public abstract interface SocketOption {
+ method public abstract java.lang.String name();
+ method public abstract java.lang.Class<T> type();
+ }
+
public abstract interface SocketOptions {
method public abstract java.lang.Object getOption(int) throws java.net.SocketException;
method public abstract void setOption(int, java.lang.Object) throws java.net.SocketException;
@@ -38623,6 +38629,21 @@ package java.net {
ctor public SocketTimeoutException(java.lang.String);
}
+ public final class StandardSocketOptions {
+ ctor public StandardSocketOptions();
+ field public static final java.net.SocketOption IP_MULTICAST_IF;
+ field public static final java.net.SocketOption IP_MULTICAST_LOOP;
+ field public static final java.net.SocketOption IP_MULTICAST_TTL;
+ field public static final java.net.SocketOption IP_TOS;
+ field public static final java.net.SocketOption SO_BROADCAST;
+ field public static final java.net.SocketOption SO_KEEPALIVE;
+ field public static final java.net.SocketOption SO_LINGER;
+ field public static final java.net.SocketOption SO_RCVBUF;
+ field public static final java.net.SocketOption SO_REUSEADDR;
+ field public static final java.net.SocketOption SO_SNDBUF;
+ field public static final java.net.SocketOption TCP_NODELAY;
+ }
+
public final class URI implements java.lang.Comparable java.io.Serializable {
ctor public URI(java.lang.String) throws java.net.URISyntaxException;
ctor public URI(java.lang.String, java.lang.String, java.lang.String) throws java.net.URISyntaxException;
@@ -38718,6 +38739,7 @@ package java.net {
method public java.lang.Object getContent(java.lang.Class[]) throws java.io.IOException;
method public java.lang.String getContentEncoding();
method public int getContentLength();
+ method public long getContentLengthLong();
method public java.lang.String getContentType();
method public long getDate();
method public static boolean getDefaultAllowUserInteraction();
@@ -38732,6 +38754,7 @@ package java.net {
method public long getHeaderFieldDate(java.lang.String, long);
method public int getHeaderFieldInt(java.lang.String, int);
method public java.lang.String getHeaderFieldKey(int);
+ method public long getHeaderFieldLong(java.lang.String, long);
method public java.util.Map<java.lang.String, java.util.List<java.lang.String>> getHeaderFields();
method public long getIfModifiedSince();
method public java.io.InputStream getInputStream() throws java.io.IOException;
@@ -39082,6 +39105,10 @@ package java.nio {
package java.nio.channels {
+ public class AlreadyBoundException extends java.lang.IllegalStateException {
+ ctor public AlreadyBoundException();
+ }
+
public class AlreadyConnectedException extends java.lang.IllegalStateException {
ctor public AlreadyConnectedException();
}
@@ -39131,8 +39158,11 @@ package java.nio.channels {
public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
+ method public java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
method public abstract java.nio.channels.DatagramChannel disconnect() throws java.io.IOException;
+ method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+ method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
method public abstract boolean isConnected();
method public static java.nio.channels.DatagramChannel open() throws java.io.IOException;
method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
@@ -39140,14 +39170,16 @@ package java.nio.channels {
method public final synchronized long read(java.nio.ByteBuffer[]) throws java.io.IOException;
method public abstract java.net.SocketAddress receive(java.nio.ByteBuffer) throws java.io.IOException;
method public abstract int send(java.nio.ByteBuffer, java.net.SocketAddress) throws java.io.IOException;
+ method public java.nio.channels.DatagramChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
method public abstract java.net.DatagramSocket socket();
+ method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
method public final int validOps();
method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
method public abstract long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
method public final synchronized long write(java.nio.ByteBuffer[]) throws java.io.IOException;
}
- public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+ public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel java.nio.channels.SeekableByteChannel {
ctor protected FileChannel();
method public abstract void force(boolean) throws java.io.IOException;
method public final java.nio.channels.FileLock lock() throws java.io.IOException;
@@ -39211,6 +39243,14 @@ package java.nio.channels {
method public abstract void close() throws java.io.IOException;
}
+ public abstract interface NetworkChannel implements java.lang.AutoCloseable java.nio.channels.Channel java.io.Closeable {
+ method public abstract java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
+ method public abstract java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+ method public abstract T getOption(java.net.SocketOption<T>) throws java.io.IOException;
+ method public abstract java.nio.channels.NetworkChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+ method public abstract java.util.Set<java.net.SocketOption<?>> supportedOptions();
+ }
+
public class NoConnectionPendingException extends java.lang.IllegalStateException {
ctor public NoConnectionPendingException();
}
@@ -39261,6 +39301,15 @@ package java.nio.channels {
method public abstract long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
}
+ public abstract interface SeekableByteChannel implements java.nio.channels.ByteChannel {
+ method public abstract long position() throws java.io.IOException;
+ method public abstract java.nio.channels.SeekableByteChannel position(long) throws java.io.IOException;
+ method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
+ method public abstract long size() throws java.io.IOException;
+ method public abstract java.nio.channels.SeekableByteChannel truncate(long) throws java.io.IOException;
+ method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
+ }
+
public abstract class SelectableChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.Channel {
ctor protected SelectableChannel();
method public abstract java.lang.Object blockingLock();
@@ -39309,18 +39358,27 @@ package java.nio.channels {
method public abstract java.nio.channels.Selector wakeup();
}
- public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel {
+ public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.NetworkChannel {
ctor protected ServerSocketChannel(java.nio.channels.spi.SelectorProvider);
method public abstract java.nio.channels.SocketChannel accept() throws java.io.IOException;
+ method public final java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
+ method public java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
+ method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+ method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
method public static java.nio.channels.ServerSocketChannel open() throws java.io.IOException;
+ method public java.nio.channels.ServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
method public abstract java.net.ServerSocket socket();
+ method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
method public final int validOps();
}
- public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+ public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
+ method public java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
method public abstract boolean connect(java.net.SocketAddress) throws java.io.IOException;
method public abstract boolean finishConnect() throws java.io.IOException;
+ method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+ method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
method public abstract boolean isConnected();
method public abstract boolean isConnectionPending();
method public static java.nio.channels.SocketChannel open() throws java.io.IOException;
@@ -39328,7 +39386,9 @@ package java.nio.channels {
method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
method public abstract long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
method public final synchronized long read(java.nio.ByteBuffer[]) throws java.io.IOException;
+ method public java.nio.channels.SocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
method public abstract java.net.Socket socket();
+ method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
method public final int validOps();
method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
method public abstract long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
@@ -45378,6 +45438,7 @@ package java.util.concurrent.locks {
method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
method public final boolean hasContended();
+ method public final boolean hasQueuedPredecessors();
method public final boolean hasQueuedThreads();
method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
method protected boolean isHeldExclusively();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9cfd85a..69ada6a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -161,7 +161,7 @@ public final class ActivityThread {
private static final int LOG_ON_PAUSE_CALLED = 30021;
private static final int LOG_ON_RESUME_CALLED = 30022;
- static ContextImpl mSystemContext = null;
+ private ContextImpl mSystemContext;
static IPackageManager sPackageManager;
@@ -1709,7 +1709,7 @@ public final class ActivityThread {
? mBoundApplication.processName : null)
+ ")");
packageInfo =
- new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
+ new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
if (includeCode) {
@@ -1762,26 +1762,15 @@ public final class ActivityThread {
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
- ContextImpl context =
- ContextImpl.createSystemContext(this);
- LoadedApk info = new LoadedApk(this, "android", context, null,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
- context.init(info, null, this);
- context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),
- mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
- mSystemContext = context;
- //Slog.i(TAG, "Created system resources " + context.getResources()
- // + ": " + context.getResources().getConfiguration());
+ mSystemContext = ContextImpl.createSystemContext(this);
}
+ return mSystemContext;
}
- return mSystemContext;
}
public void installSystemApplicationInfo(ApplicationInfo info) {
synchronized (this) {
- ContextImpl context = getSystemContext();
- context.init(new LoadedApk(this, "android", context, info,
- CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
+ getSystemContext().installSystemApplicationInfo(info);
// give ourselves a default profiler
mProfiler = new Profiler();
@@ -2268,8 +2257,7 @@ public final class ActivityThread {
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
- ContextImpl appContext = new ContextImpl();
- appContext.init(r.packageInfo, r.token, this);
+ ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
appContext.setOuterContext(activity);
Context baseContext = appContext;
@@ -2567,8 +2555,7 @@ public final class ActivityThread {
agent = (BackupAgent) cl.loadClass(classname).newInstance();
// set up the agent's context
- ContextImpl context = new ContextImpl();
- context.init(packageInfo, null, this);
+ ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(agent);
agent.attach(context);
@@ -2640,11 +2627,10 @@ public final class ActivityThread {
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
- ContextImpl context = new ContextImpl();
- context.init(packageInfo, null, this);
+ ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
+ context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
- context.setOuterContext(service);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
@@ -4249,8 +4235,7 @@ public final class ActivityThread {
}
updateDefaultDensity();
- final ContextImpl appContext = new ContextImpl();
- appContext.init(data.info, null, this);
+ final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
if (!Process.isIsolated()) {
final File cacheDir = appContext.getCacheDir();
@@ -4366,8 +4351,7 @@ public final class ActivityThread {
instrApp.nativeLibraryDir = ii.nativeLibraryDir;
LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true);
- ContextImpl instrContext = new ContextImpl();
- instrContext.init(pi, null, this);
+ ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
java.lang.ClassLoader cl = instrContext.getClassLoader();
@@ -4982,8 +4966,8 @@ public final class ActivityThread {
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
- ContextImpl context = new ContextImpl();
- context.init(getSystemContext().mPackageInfo, null, this);
+ ContextImpl context = ContextImpl.createAppContext(
+ this, getSystemContext().mPackageInfo);
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 9b3643c..0351292 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -185,22 +185,31 @@ class ContextImpl extends Context {
*/
private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;
- /*package*/ LoadedApk mPackageInfo;
- private String mBasePackageName;
- private String mOpPackageName;
- private Resources mResources;
- /*package*/ ActivityThread mMainThread;
+ final ActivityThread mMainThread;
+ final LoadedApk mPackageInfo;
+
+ private final IBinder mActivityToken;
+
+ private final UserHandle mUser;
+
+ private final ApplicationContentResolver mContentResolver;
+
+ private final String mBasePackageName;
+ private final String mOpPackageName;
+
+ private final ResourcesManager mResourcesManager;
+ private final Resources mResources;
+ private final Display mDisplay; // may be null if default display
+ private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
+ private final Configuration mOverrideConfiguration;
+
+ private final boolean mRestricted;
+
private Context mOuterContext;
- private IBinder mActivityToken = null;
- private ApplicationContentResolver mContentResolver;
private int mThemeResource = 0;
private Resources.Theme mTheme = null;
private PackageManager mPackageManager;
- private Display mDisplay; // may be null if default display
private Context mReceiverRestrictedContext = null;
- private boolean mRestricted;
- private UserHandle mUser;
- private ResourcesManager mResourcesManager;
private final Object mSync = new Object();
@@ -222,8 +231,6 @@ class ContextImpl extends Context {
private static final String[] EMPTY_FILE_LIST = {};
- final private DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
-
/**
* Override this class when the system service constructor needs a
* ContextImpl. Else, use StaticServiceFetcher below.
@@ -1887,20 +1894,17 @@ class ContextImpl extends Context {
@Override
public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
throws NameNotFoundException {
+ final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
if (packageName.equals("system") || packageName.equals("android")) {
- final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
- context.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
- context.init(mPackageInfo, null, mMainThread, mResources, mBasePackageName, user);
- return context;
+ return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+ user, restricted, mDisplay, mOverrideConfiguration);
}
- LoadedApk pi =
- mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags,
- user.getIdentifier());
+ LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
+ flags, user.getIdentifier());
if (pi != null) {
- ContextImpl c = new ContextImpl();
- c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
- c.init(pi, null, mMainThread, mResources, mBasePackageName, user);
+ ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
+ user, restricted, mDisplay, mOverrideConfiguration);
if (c.mResources != null) {
return c;
}
@@ -1908,7 +1912,7 @@ class ContextImpl extends Context {
// Should be a better exception.
throw new PackageManager.NameNotFoundException(
- "Application package " + packageName + " not found");
+ "Application package " + packageName + " not found");
}
@Override
@@ -1917,12 +1921,8 @@ class ContextImpl extends Context {
throw new IllegalArgumentException("overrideConfiguration must not be null");
}
- ContextImpl c = new ContextImpl();
- c.init(mPackageInfo, null, mMainThread);
- c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- mPackageInfo.getOverlayDirs(), getDisplayId(), overrideConfiguration,
- mResources.getCompatibilityInfo(), mActivityToken);
- return c;
+ return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+ mUser, mRestricted, mDisplay, overrideConfiguration);
}
@Override
@@ -1931,15 +1931,8 @@ class ContextImpl extends Context {
throw new IllegalArgumentException("display must not be null");
}
- int displayId = display.getDisplayId();
-
- ContextImpl context = new ContextImpl();
- context.init(mPackageInfo, null, mMainThread);
- context.mDisplay = display;
- DisplayAdjustments daj = getDisplayAdjustments(displayId);
- context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- mPackageInfo.getOverlayDirs(), displayId, null, daj.getCompatibilityInfo(), null);
- return context;
+ return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+ mUser, mRestricted, display, mOverrideConfiguration);
}
private int getDisplayId() {
@@ -1981,43 +1974,76 @@ class ContextImpl extends Context {
}
static ContextImpl createSystemContext(ActivityThread mainThread) {
- final ContextImpl context = new ContextImpl();
- context.init(Resources.getSystem(), mainThread, Process.myUserHandle());
+ LoadedApk packageInfo = new LoadedApk(mainThread);
+ ContextImpl context = new ContextImpl(null, mainThread,
+ packageInfo, null, null, false, null, null);
+ context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
+ context.mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
return context;
}
- ContextImpl() {
- mOuterContext = this;
+ static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
+ if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
+ return new ContextImpl(null, mainThread,
+ packageInfo, null, null, false, null, null);
}
- /**
- * Create a new ApplicationContext from an existing one. The new one
- * works and operates the same as the one it is copying.
- *
- * @param context Existing application context.
- */
- public ContextImpl(ContextImpl context) {
- mPackageInfo = context.mPackageInfo;
- mBasePackageName = context.mBasePackageName;
- mOpPackageName = context.mOpPackageName;
- mResources = context.mResources;
- mMainThread = context.mMainThread;
- mContentResolver = context.mContentResolver;
- mUser = context.mUser;
- mDisplay = context.mDisplay;
- mOuterContext = this;
- mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
+ static ContextImpl createActivityContext(ActivityThread mainThread,
+ LoadedApk packageInfo, IBinder activityToken) {
+ if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
+ if (activityToken == null) throw new IllegalArgumentException("activityInfo");
+ return new ContextImpl(null, mainThread,
+ packageInfo, activityToken, null, false, null, null);
}
- final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
- init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
- }
+ private ContextImpl(ContextImpl container, ActivityThread mainThread,
+ LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
+ Display display, Configuration overrideConfiguration) {
+ mOuterContext = this;
+
+ mMainThread = mainThread;
+ mActivityToken = activityToken;
+ mRestricted = restricted;
+
+ if (user == null) {
+ user = Process.myUserHandle();
+ }
+ mUser = user;
- final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
- Resources container, String basePackageName, UserHandle user) {
mPackageInfo = packageInfo;
- if (basePackageName != null) {
- mBasePackageName = mOpPackageName = basePackageName;
+ mContentResolver = new ApplicationContentResolver(this, mainThread, user);
+ mResourcesManager = ResourcesManager.getInstance();
+ mDisplay = display;
+ mOverrideConfiguration = overrideConfiguration;
+
+ final int displayId = getDisplayId();
+ CompatibilityInfo compatInfo = null;
+ if (container != null) {
+ compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
+ }
+ if (compatInfo == null && displayId == Display.DEFAULT_DISPLAY) {
+ compatInfo = packageInfo.getCompatibilityInfo();
+ }
+ mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+ mDisplayAdjustments.setActivityToken(activityToken);
+
+ Resources resources = packageInfo.getResources(mainThread);
+ if (resources != null) {
+ if (activityToken != null
+ || displayId != Display.DEFAULT_DISPLAY
+ || overrideConfiguration != null
+ || (compatInfo != null && compatInfo.applicationScale
+ != resources.getCompatibilityInfo().applicationScale)) {
+ resources = mResourcesManager.getTopLevelResources(
+ packageInfo.getResDir(), packageInfo.getOverlayDirs(), displayId,
+ overrideConfiguration, compatInfo, activityToken);
+ }
+ }
+ mResources = resources;
+
+ if (container != null) {
+ mBasePackageName = container.mBasePackageName;
+ mOpPackageName = container.mOpPackageName;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
@@ -2031,45 +2057,10 @@ class ContextImpl extends Context {
mOpPackageName = mBasePackageName;
}
}
- mResources = mPackageInfo.getResources(mainThread);
- mResourcesManager = ResourcesManager.getInstance();
-
- CompatibilityInfo compatInfo =
- container == null ? null : container.getCompatibilityInfo();
- if (mResources != null &&
- ((compatInfo != null && compatInfo.applicationScale !=
- mResources.getCompatibilityInfo().applicationScale)
- || activityToken != null)) {
- if (DEBUG) {
- Log.d(TAG, "loaded context has different scaling. Using container's" +
- " compatiblity info:" + container.getDisplayMetrics());
- }
- if (compatInfo == null) {
- compatInfo = packageInfo.getCompatibilityInfo();
- }
- mDisplayAdjustments.setCompatibilityInfo(compatInfo);
- mDisplayAdjustments.setActivityToken(activityToken);
- mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- mPackageInfo.getOverlayDirs(), Display.DEFAULT_DISPLAY, null, compatInfo,
- activityToken);
- } else {
- mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
- mDisplayAdjustments.setActivityToken(activityToken);
- }
- mMainThread = mainThread;
- mActivityToken = activityToken;
- mContentResolver = new ApplicationContentResolver(this, mainThread, user);
- mUser = user;
}
- final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
- mPackageInfo = null;
- mBasePackageName = null;
- mOpPackageName = null;
- mResources = resources;
- mMainThread = mainThread;
- mContentResolver = new ApplicationContentResolver(this, mainThread, user);
- mUser = user;
+ void installSystemApplicationInfo(ApplicationInfo info) {
+ mPackageInfo.installSystemApplicationInfo(info);
}
final void scheduleFinalCleanup(String who, String what) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 0115d1b..d409352 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -72,7 +72,7 @@ public final class LoadedApk {
private static final String TAG = "LoadedApk";
private final ActivityThread mActivityThread;
- private final ApplicationInfo mApplicationInfo;
+ private ApplicationInfo mApplicationInfo;
final String mPackageName;
private final String mAppDir;
private final String mResDir;
@@ -111,8 +111,7 @@ public final class LoadedApk {
* so MUST NOT call back out to the activity manager.
*/
public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
- CompatibilityInfo compatInfo,
- ActivityThread mainThread, ClassLoader baseLoader,
+ CompatibilityInfo compatInfo, ClassLoader baseLoader,
boolean securityViolation, boolean includeCode) {
mActivityThread = activityThread;
mApplicationInfo = aInfo;
@@ -134,31 +133,17 @@ public final class LoadedApk {
mSecurityViolation = securityViolation;
mIncludeCode = includeCode;
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
-
- if (mAppDir == null) {
- if (ActivityThread.mSystemContext == null) {
- ActivityThread.mSystemContext =
- ContextImpl.createSystemContext(mainThread);
- ResourcesManager resourcesManager = ResourcesManager.getInstance();
- ActivityThread.mSystemContext.getResources().updateConfiguration(
- resourcesManager.getConfiguration(),
- resourcesManager.getDisplayMetricsLocked(
- Display.DEFAULT_DISPLAY, mDisplayAdjustments), compatInfo);
- //Slog.i(TAG, "Created system resources "
- // + mSystemContext.getResources() + ": "
- // + mSystemContext.getResources().getConfiguration());
- }
- mClassLoader = ActivityThread.mSystemContext.getClassLoader();
- mResources = ActivityThread.mSystemContext.getResources();
- }
}
- public LoadedApk(ActivityThread activityThread, String name,
- Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {
+ /**
+ * Create information about the system package.
+ * Must call {@link #installSystemApplicationInfo} later.
+ */
+ LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
- mApplicationInfo = info != null ? info : new ApplicationInfo();
- mApplicationInfo.packageName = name;
- mPackageName = name;
+ mApplicationInfo = new ApplicationInfo();
+ mApplicationInfo.packageName = "android";
+ mPackageName = "android";
mAppDir = null;
mResDir = null;
mOverlayDirs = null;
@@ -169,9 +154,16 @@ public final class LoadedApk {
mBaseClassLoader = null;
mSecurityViolation = false;
mIncludeCode = true;
- mClassLoader = systemContext.getClassLoader();
- mResources = systemContext.getResources();
- mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+ mClassLoader = ClassLoader.getSystemClassLoader();
+ mResources = Resources.getSystem();
+ }
+
+ /**
+ * Sets application info about the system package.
+ */
+ void installSystemApplicationInfo(ApplicationInfo info) {
+ assert info.packageName.equals("android");
+ mApplicationInfo = info;
}
public String getPackageName() {
@@ -513,8 +505,7 @@ public final class LoadedApk {
try {
java.lang.ClassLoader cl = getClassLoader();
- ContextImpl appContext = new ContextImpl();
- appContext.init(this, null, mActivityThread);
+ ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f0b7ca8..96479e2 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2768,6 +2768,12 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
/**
+ * Indicates an activity optimized for Leanback mode, and that should
+ * be displayed in the Leanback launcher.
+ */
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+ /**
* Provides information about the package it is in; typically used if
* a package does not contain a {@link #CATEGORY_LAUNCHER} to provide
* a front-door to the user without having to be shown in the all apps list.
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 0da77ea..7db4ac2 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -343,8 +343,9 @@ public abstract class BatteryStats implements Parcelable {
}
public class Pid {
- public long mWakeSum;
- public long mWakeStart;
+ public int mWakeNesting;
+ public long mWakeSumMs;
+ public long mWakeStartMs;
}
/**
@@ -515,7 +516,8 @@ public abstract class BatteryStats implements Parcelable {
public static final byte CMD_UPDATE = 0; // These can be written as deltas
public static final byte CMD_NULL = -1;
public static final byte CMD_START = 4;
- public static final byte CMD_OVERFLOW = 5;
+ public static final byte CMD_CURRENT_TIME = 5;
+ public static final byte CMD_OVERFLOW = 6;
public byte cmd = CMD_NULL;
@@ -610,6 +612,9 @@ public abstract class BatteryStats implements Parcelable {
public int eventCode;
public HistoryTag eventTag;
+ // Only set for CMD_CURRENT_TIME.
+ public long currentTime;
+
// Meta-data when reading.
public int numReadInts;
@@ -637,29 +642,28 @@ public abstract class BatteryStats implements Parcelable {
| ((((int)batteryLevel)<<8)&0xff00)
| ((((int)batteryStatus)<<16)&0xf0000)
| ((((int)batteryHealth)<<20)&0xf00000)
- | ((((int)batteryPlugType)<<24)&0xf000000);
+ | ((((int)batteryPlugType)<<24)&0xf000000)
+ | (wakelockTag != null ? 0x10000000 : 0)
+ | (wakeReasonTag != null ? 0x20000000 : 0)
+ | (eventCode != EVENT_NONE ? 0x40000000 : 0);
dest.writeInt(bat);
bat = (((int)batteryTemperature)&0xffff)
| ((((int)batteryVoltage)<<16)&0xffff0000);
dest.writeInt(bat);
dest.writeInt(states);
if (wakelockTag != null) {
- dest.writeInt(1);
wakelockTag.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
}
if (wakeReasonTag != null) {
- dest.writeInt(1);
wakeReasonTag.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
}
- dest.writeInt(eventCode);
if (eventCode != EVENT_NONE) {
dest.writeInt(eventCode);
eventTag.writeToParcel(dest, flags);
}
+ if (cmd == CMD_CURRENT_TIME) {
+ dest.writeLong(currentTime);
+ }
}
public void readFromParcel(Parcel src) {
@@ -670,26 +674,34 @@ public abstract class BatteryStats implements Parcelable {
batteryStatus = (byte)((bat>>16)&0xf);
batteryHealth = (byte)((bat>>20)&0xf);
batteryPlugType = (byte)((bat>>24)&0xf);
- bat = src.readInt();
- batteryTemperature = (short)(bat&0xffff);
- batteryVoltage = (char)((bat>>16)&0xffff);
+ int bat2 = src.readInt();
+ batteryTemperature = (short)(bat2&0xffff);
+ batteryVoltage = (char)((bat2>>16)&0xffff);
states = src.readInt();
- if (src.readInt() != 0) {
+ if ((bat&0x10000000) != 0) {
wakelockTag = localWakelockTag;
wakelockTag.readFromParcel(src);
} else {
wakelockTag = null;
}
- if (src.readInt() != 0) {
+ if ((bat&0x20000000) != 0) {
wakeReasonTag = localWakeReasonTag;
wakeReasonTag.readFromParcel(src);
} else {
wakeReasonTag = null;
}
- eventCode = src.readInt();
- if (eventCode != EVENT_NONE) {
+ if ((bat&0x40000000) != 0) {
+ eventCode = src.readInt();
eventTag = localEventTag;
eventTag.readFromParcel(src);
+ } else {
+ eventCode = EVENT_NONE;
+ eventTag = null;
+ }
+ if (cmd == CMD_CURRENT_TIME) {
+ currentTime = src.readLong();
+ } else {
+ currentTime = 0;
}
numReadInts += (src.dataPosition()-start)/4;
}
@@ -749,6 +761,7 @@ public abstract class BatteryStats implements Parcelable {
} else {
eventTag = null;
}
+ currentTime = o.currentTime;
}
public boolean sameNonEvent(HistoryItem o) {
@@ -758,7 +771,8 @@ public abstract class BatteryStats implements Parcelable {
&& batteryPlugType == o.batteryPlugType
&& batteryTemperature == o.batteryTemperature
&& batteryVoltage == o.batteryVoltage
- && states == o.states;
+ && states == o.states
+ && currentTime == o.currentTime;
}
public boolean same(HistoryItem o) {
@@ -2788,6 +2802,18 @@ public abstract class BatteryStats implements Parcelable {
pw.print(":");
}
pw.println("START");
+ } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
+ if (checkin) {
+ pw.print(":");
+ }
+ pw.print("TIME:");
+ if (checkin) {
+ pw.println(rec.currentTime);
+ } else {
+ pw.print(" ");
+ pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
+ rec.currentTime).toString());
+ }
} else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
if (checkin) {
pw.print(":");
@@ -2941,8 +2967,8 @@ public abstract class BatteryStats implements Parcelable {
}
}
pw.println();
+ oldState = rec.states;
}
- oldState = rec.states;
}
}
@@ -3059,8 +3085,8 @@ public abstract class BatteryStats implements Parcelable {
pw.println("Per-PID Stats:");
didPid = true;
}
- long time = pid.mWakeSum + (pid.mWakeStart != 0
- ? (nowRealtime - pid.mWakeStart) : 0);
+ long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
+ ? (nowRealtime - pid.mWakeStartMs) : 0);
pw.print(" PID "); pw.print(pids.keyAt(j));
pw.print(" wake time: ");
TimeUtils.formatDuration(time, pw);
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 6650fca..5d55143 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -21,11 +21,11 @@ import android.content.Context;
/**
* Class that operates the vibrator on the device.
* <p>
- * If your process exits, any vibration you started with will stop.
+ * If your process exits, any vibration you started will stop.
* </p>
*
* To obtain an instance of the system vibrator, call
- * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
+ * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as the argument.
*/
public abstract class Vibrator {
/**
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index 1de9c35..0afbde9 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -26,7 +26,6 @@ import android.content.res.Resources;
* wrapped context.
*/
public class ContextThemeWrapper extends ContextWrapper {
- private Context mBase;
private int mThemeResource;
private Resources.Theme mTheme;
private LayoutInflater mInflater;
@@ -39,13 +38,11 @@ public class ContextThemeWrapper extends ContextWrapper {
public ContextThemeWrapper(Context base, int themeres) {
super(base);
- mBase = base;
mThemeResource = themeres;
}
@Override protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
- mBase = newBase;
}
/**
@@ -109,11 +106,11 @@ public class ContextThemeWrapper extends ContextWrapper {
@Override public Object getSystemService(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
- mInflater = LayoutInflater.from(mBase).cloneInContext(this);
+ mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
- return mBase.getSystemService(name);
+ return getBaseContext().getSystemService(name);
}
/**
@@ -135,7 +132,7 @@ public class ContextThemeWrapper extends ContextWrapper {
final boolean first = mTheme == null;
if (first) {
mTheme = getResources().newTheme();
- Resources.Theme theme = mBase.getTheme();
+ Resources.Theme theme = getBaseContext().getTheme();
if (theme != null) {
mTheme.setTo(theme);
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 3f90f76..5ba5c57 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -41,6 +41,9 @@ interface IBatteryStats {
void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, String historyName,
int type, boolean unimportantForLogging);
+ void noteChangeWakelockFromSource(in WorkSource ws, int pid, String name, int type,
+ in WorkSource newWs, int newPid, String newName,
+ String newHistoryName, int newType, boolean newUnimportantForLogging);
void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type);
void noteVibratorOn(int uid, long durationMillis);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index db21906..10fd2f0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -87,7 +87,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 98 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 99 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -2274,9 +2274,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
- boolean unimportantForLogging) {
+ boolean unimportantForLogging, long elapsedRealtime) {
uid = mapUid(uid);
- final long elapsedRealtime = SystemClock.elapsedRealtime();
if (type == WAKE_TYPE_PARTIAL) {
// Only care about partial wake locks, since full wake locks
// will be canceled when the user puts the screen to sleep.
@@ -2308,9 +2307,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public void noteStopWakeLocked(int uid, int pid, String name, int type) {
+ public void noteStopWakeLocked(int uid, int pid, String name, int type, long elapsedRealtime) {
uid = mapUid(uid);
- final long elapsedRealtime = SystemClock.elapsedRealtime();
if (type == WAKE_TYPE_PARTIAL) {
mWakeLockNesting--;
if (mWakeLockNesting == 0) {
@@ -2328,16 +2326,37 @@ public final class BatteryStatsImpl extends BatteryStats {
public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
String historyName, int type, boolean unimportantForLogging) {
- int N = ws.size();
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final int N = ws.size();
for (int i=0; i<N; i++) {
- noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging);
+ noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
+ elapsedRealtime);
+ }
+ }
+
+ public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, int type,
+ WorkSource newWs, int newPid, String newName,
+ String newHistoryName, int newType, boolean newUnimportantForLogging) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ // For correct semantics, we start the need worksources first, so that we won't
+ // make inappropriate history items as if all wake locks went away and new ones
+ // appeared. This is okay because tracking of wake locks allows nesting.
+ final int NN = ws.size();
+ for (int i=0; i<NN; i++) {
+ noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
+ newUnimportantForLogging, elapsedRealtime);
+ }
+ final int NO = ws.size();
+ for (int i=0; i<NO; i++) {
+ noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime);
}
}
public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
- int N = ws.size();
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final int N = ws.size();
for (int i=0; i<N; i++) {
- noteStopWakeLocked(ws.get(i), pid, name, type);
+ noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime);
}
}
@@ -2466,7 +2485,7 @@ public final class BatteryStatsImpl extends BatteryStats {
if (u != null) {
Uid.Pid p = u.mPids.get(pid);
if (p != null) {
- return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
+ return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
}
}
return 0;
@@ -2562,8 +2581,8 @@ public final class BatteryStatsImpl extends BatteryStats {
// Fake a wake lock, so we consider the device waked as long
// as the screen is on.
- noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false);
-
+ noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false, elapsedRealtime);
+
// Update discharge amounts.
if (mOnBatteryInternal) {
updateDischargeScreenLevelsLocked(false, true);
@@ -2584,7 +2603,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
}
- noteStopWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL);
+ noteStopWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL, elapsedRealtime);
updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
@@ -3999,10 +4018,12 @@ public final class BatteryStatsImpl extends BatteryStats {
mProcessStats.clear();
}
if (mPids.size() > 0) {
- for (int i=0; !active && i<mPids.size(); i++) {
+ for (int i=mPids.size()-1; i>=0; i--) {
Pid pid = mPids.valueAt(i);
- if (pid.mWakeStart != 0) {
+ if (pid.mWakeNesting > 0) {
active = true;
+ } else {
+ mPids.removeAt(i);
}
}
}
@@ -4024,8 +4045,6 @@ public final class BatteryStatsImpl extends BatteryStats {
mPackageStats.clear();
}
- mPids.clear();
-
if (!active) {
if (mWifiRunningTimer != null) {
mWifiRunningTimer.detach();
@@ -4067,6 +4086,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i].detach();
}
}
+ mPids.clear();
}
return !active;
@@ -5304,8 +5324,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Pid p = getPidStatsLocked(pid);
- if (p.mWakeStart == 0) {
- p.mWakeStart = elapsedRealtimeMs;
+ if (p.mWakeNesting++ == 0) {
+ p.mWakeStartMs = elapsedRealtimeMs;
}
}
}
@@ -5317,9 +5337,11 @@ public final class BatteryStatsImpl extends BatteryStats {
}
if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Pid p = mPids.get(pid);
- if (p != null && p.mWakeStart != 0) {
- p.mWakeSum += elapsedRealtimeMs - p.mWakeStart;
- p.mWakeStart = 0;
+ if (p != null && p.mWakeNesting > 0) {
+ if (p.mWakeNesting-- == 1) {
+ p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
+ p.mWakeStartMs = 0;
+ }
}
}
}
@@ -5765,6 +5787,9 @@ public final class BatteryStatsImpl extends BatteryStats {
mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
+ Integer.toHexString(mHistoryCur.states));
+ mHistoryCur.currentTime = System.currentTimeMillis();
+ addHistoryBufferLocked(mSecRealtime, HistoryItem.CMD_CURRENT_TIME);
+ mHistoryCur.currentTime = 0;
addHistoryRecordLocked(mSecRealtime);
mDischargeCurrentLevel = mDischargeUnplugLevel = level;
if (mScreenOn) {
@@ -6414,11 +6439,16 @@ public final class BatteryStatsImpl extends BatteryStats {
Slog.e("BatteryStats", "Error reading battery statistics", e);
}
- long now = SystemClock.elapsedRealtime();
- if (USE_OLD_HISTORY) {
- addHistoryRecordLocked(now, HistoryItem.CMD_START);
+ if (mHistoryBuffer.dataPosition() > 0) {
+ long now = SystemClock.elapsedRealtime();
+ if (USE_OLD_HISTORY) {
+ addHistoryRecordLocked(now, HistoryItem.CMD_START);
+ }
+ addHistoryBufferLocked(now, HistoryItem.CMD_START);
+ mHistoryCur.currentTime = System.currentTimeMillis();
+ addHistoryBufferLocked(now, HistoryItem.CMD_CURRENT_TIME);
+ mHistoryCur.currentTime = 0;
}
- addHistoryBufferLocked(now, HistoryItem.CMD_START);
}
public int describeContents() {
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index cc8ce2c..467d42e 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -126,6 +126,20 @@ public class SwipeDismissLayout extends FrameLayout {
mVelocityTracker.addMovement(ev);
break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ int actionIndex = ev.getActionIndex();
+ mActiveTouchId = ev.getPointerId(actionIndex);
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ actionIndex = ev.getActionIndex();
+ int pointerId = ev.getPointerId(actionIndex);
+ if (pointerId == mActiveTouchId) {
+ // This was our active pointer going up. Choose a new active pointer.
+ int newActionIndex = actionIndex == 0 ? 1 : 0;
+ mActiveTouchId = ev.getPointerId(newActionIndex);
+ }
+ break;
+
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
resetMembers();
@@ -137,6 +151,11 @@ public class SwipeDismissLayout extends FrameLayout {
}
int pointerIndex = ev.findPointerIndex(mActiveTouchId);
+ if (pointerIndex == -1) {
+ Log.e(TAG, "Invalid pointer index: ignoring.");
+ mDiscardIntercept = true;
+ break;
+ }
float dx = ev.getRawX() - mDownX;
float x = ev.getX(pointerIndex);
float y = ev.getY(pointerIndex);
@@ -228,11 +247,11 @@ public class SwipeDismissLayout extends FrameLayout {
}
private void updateDismiss(MotionEvent ev) {
+ float deltaX = ev.getRawX() - mDownX;
if (!mDismissed) {
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
- float deltaX = ev.getRawX() - mDownX;
float velocityX = mVelocityTracker.getXVelocity();
float absVelocityX = Math.abs(velocityX);
float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
@@ -247,6 +266,13 @@ public class SwipeDismissLayout extends FrameLayout {
mDismissed = true;
}
}
+ // Check if the user tried to undo this.
+ if (mDismissed && mSwiping) {
+ // Check if the user's finger is actually back
+ if (deltaX < getWidth() / 2) {
+ mDismissed = false;
+ }
+ }
}
/**
diff --git a/core/jni/android_view_DisplayList.cpp b/core/jni/android_view_DisplayList.cpp
index c8952c1..27345cf 100644
--- a/core/jni/android_view_DisplayList.cpp
+++ b/core/jni/android_view_DisplayList.cpp
@@ -43,7 +43,7 @@ using namespace uirenderer;
static void android_view_DisplayList_setDisplayListName(JNIEnv* env,
jobject clazz, jlong displayListPtr, jstring name) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
if (name != NULL) {
const char* textArray = env->GetStringUTFChars(name, NULL);
displayList->setName(textArray);
@@ -53,19 +53,19 @@ static void android_view_DisplayList_setDisplayListName(JNIEnv* env,
static void android_view_DisplayList_output(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->output();
}
static jlong android_view_DisplayList_create(JNIEnv* env, jobject clazz) {
- DisplayList* displayList = new DisplayList();
+ RenderNode* displayList = new RenderNode();
return reinterpret_cast<jlong>(displayList);
}
static void android_view_DisplayList_destroyDisplayList(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
- DisplayList::destroyDisplayListDeferred(displayList);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+ RenderNode::destroyDisplayListDeferred(displayList);
}
// ----------------------------------------------------------------------------
@@ -74,130 +74,130 @@ static void android_view_DisplayList_destroyDisplayList(JNIEnv* env,
static void android_view_DisplayList_setCaching(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean caching) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setCaching(caching);
}
static void android_view_DisplayList_setStaticMatrix(JNIEnv* env,
jobject clazz, jlong displayListPtr, jlong matrixPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
displayList->setStaticMatrix(matrix);
}
static void android_view_DisplayList_setAnimationMatrix(JNIEnv* env,
jobject clazz, jlong displayListPtr, jlong matrixPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
displayList->setAnimationMatrix(matrix);
}
static void android_view_DisplayList_setClipToBounds(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean clipToBounds) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setClipToBounds(clipToBounds);
}
static void android_view_DisplayList_setIsolatedZVolume(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean shouldIsolate) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setIsolatedZVolume(shouldIsolate);
}
static void android_view_DisplayList_setProjectBackwards(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean shouldProject) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setProjectBackwards(shouldProject);
}
static void android_view_DisplayList_setProjectionReceiver(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean shouldRecieve) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setProjectionReceiver(shouldRecieve);
}
static void android_view_DisplayList_setOutline(JNIEnv* env,
jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
SkPath* outline = reinterpret_cast<SkPath*>(outlinePathPtr);
displayList->setOutline(outline);
}
static void android_view_DisplayList_setClipToOutline(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setClipToOutline(clipToOutline);
}
static void android_view_DisplayList_setCastsShadow(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean castsShadow) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setCastsShadow(castsShadow);
}
static void android_view_DisplayList_setUsesGlobalCamera(JNIEnv* env,
jobject clazz, jlong displayListPtr, jboolean usesGlobalCamera) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setUsesGlobalCamera(usesGlobalCamera);
}
static void android_view_DisplayList_setAlpha(JNIEnv* env,
jobject clazz, jlong displayListPtr, float alpha) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setAlpha(alpha);
}
static void android_view_DisplayList_setHasOverlappingRendering(JNIEnv* env,
jobject clazz, jlong displayListPtr, bool hasOverlappingRendering) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setHasOverlappingRendering(hasOverlappingRendering);
}
static void android_view_DisplayList_setTranslationX(JNIEnv* env,
jobject clazz, jlong displayListPtr, float tx) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setTranslationX(tx);
}
static void android_view_DisplayList_setTranslationY(JNIEnv* env,
jobject clazz, jlong displayListPtr, float ty) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setTranslationY(ty);
}
static void android_view_DisplayList_setTranslationZ(JNIEnv* env,
jobject clazz, jlong displayListPtr, float tz) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setTranslationZ(tz);
}
static void android_view_DisplayList_setRotation(JNIEnv* env,
jobject clazz, jlong displayListPtr, float rotation) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setRotation(rotation);
}
static void android_view_DisplayList_setRotationX(JNIEnv* env,
jobject clazz, jlong displayListPtr, float rx) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setRotationX(rx);
}
static void android_view_DisplayList_setRotationY(JNIEnv* env,
jobject clazz, jlong displayListPtr, float ry) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setRotationY(ry);
}
static void android_view_DisplayList_setScaleX(JNIEnv* env,
jobject clazz, jlong displayListPtr, float sx) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setScaleX(sx);
}
static void android_view_DisplayList_setScaleY(JNIEnv* env,
jobject clazz, jlong displayListPtr, float sy) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setScaleY(sy);
}
@@ -205,7 +205,7 @@ static void android_view_DisplayList_setTransformationInfo(JNIEnv* env,
jobject clazz, jlong displayListPtr, float alpha,
float translationX, float translationY, float translationZ,
float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setAlpha(alpha);
displayList->setTranslationX(translationX);
displayList->setTranslationY(translationY);
@@ -219,158 +219,158 @@ static void android_view_DisplayList_setTransformationInfo(JNIEnv* env,
static void android_view_DisplayList_setPivotX(JNIEnv* env,
jobject clazz, jlong displayListPtr, float px) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setPivotX(px);
}
static void android_view_DisplayList_setPivotY(JNIEnv* env,
jobject clazz, jlong displayListPtr, float py) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setPivotY(py);
}
static void android_view_DisplayList_setCameraDistance(JNIEnv* env,
jobject clazz, jlong displayListPtr, float distance) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setCameraDistance(distance);
}
static void android_view_DisplayList_setLeft(JNIEnv* env,
jobject clazz, jlong displayListPtr, int left) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setLeft(left);
}
static void android_view_DisplayList_setTop(JNIEnv* env,
jobject clazz, jlong displayListPtr, int top) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setTop(top);
}
static void android_view_DisplayList_setRight(JNIEnv* env,
jobject clazz, jlong displayListPtr, int right) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setRight(right);
}
static void android_view_DisplayList_setBottom(JNIEnv* env,
jobject clazz, jlong displayListPtr, int bottom) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setBottom(bottom);
}
static void android_view_DisplayList_setLeftTopRightBottom(JNIEnv* env,
jobject clazz, jlong displayListPtr, int left, int top,
int right, int bottom) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->setLeftTopRightBottom(left, top, right, bottom);
}
static void android_view_DisplayList_offsetLeftAndRight(JNIEnv* env,
jobject clazz, jlong displayListPtr, float offset) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->offsetLeftRight(offset);
}
static void android_view_DisplayList_offsetTopAndBottom(JNIEnv* env,
jobject clazz, jlong displayListPtr, float offset) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
displayList->offsetTopBottom(offset);
}
static jboolean android_view_DisplayList_hasOverlappingRendering(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->hasOverlappingRendering();
}
static jfloat android_view_DisplayList_getAlpha(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getAlpha();
}
static jfloat android_view_DisplayList_getLeft(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getLeft();
}
static jfloat android_view_DisplayList_getTop(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getTop();
}
static jfloat android_view_DisplayList_getRight(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getRight();
}
static jfloat android_view_DisplayList_getBottom(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getBottom();
}
static jfloat android_view_DisplayList_getCameraDistance(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getCameraDistance();
}
static jfloat android_view_DisplayList_getScaleX(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getScaleX();
}
static jfloat android_view_DisplayList_getScaleY(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getScaleY();
}
static jfloat android_view_DisplayList_getTranslationX(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getTranslationX();
}
static jfloat android_view_DisplayList_getTranslationY(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getTranslationY();
}
static jfloat android_view_DisplayList_getRotation(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getRotation();
}
static jfloat android_view_DisplayList_getRotationX(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getRotationX();
}
static jfloat android_view_DisplayList_getRotationY(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getRotationY();
}
static jfloat android_view_DisplayList_getPivotX(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getPivotX();
}
static jfloat android_view_DisplayList_getPivotY(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
return displayList->getPivotY();
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a4e6679..aa6a035 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -879,7 +879,7 @@ static jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
jobject clazz, jlong rendererPtr, jlong displayListPtr,
jobject dirty, jint flags) {
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
android::uirenderer::Rect bounds;
status_t status = renderer->drawDisplayList(displayList, bounds, flags);
if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
@@ -975,7 +975,7 @@ static void
android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
#ifdef USE_OPENGL_RENDERER
int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
- android::uirenderer::DisplayList::outputLogBuffer(fd);
+ android::uirenderer::RenderNode::outputLogBuffer(fd);
#endif // USE_OPENGL_RENDERER
}
diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
index b7e795e..228a92e 100644
--- a/core/jni/android_view_GLRenderer.cpp
+++ b/core/jni/android_view_GLRenderer.cpp
@@ -143,7 +143,7 @@ static void android_view_GLRenderer_destroyLayer(JNIEnv* env, jobject clazz,
static void android_view_GLRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
jlong displayListPtr, jlong newDataPtr) {
using namespace android::uirenderer;
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
displayList->setData(newData);
}
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 5b21e94..ad2e9ff 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -120,7 +120,7 @@ static void android_view_HardwareLayer_updateRenderLayer(JNIEnv* env, jobject cl
jlong layerUpdaterPtr, jlong displayListPtr,
jint left, jint top, jint right, jint bottom) {
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
layer->setDisplayList(displayList, left, top, right, bottom);
}
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 2b20758..28cee4b 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -106,7 +106,7 @@ static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz,
static void android_view_ThreadedRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong displayListPtr, jlong newDataPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
proxy->setDisplayListData(displayList, newData);
}
@@ -115,7 +115,7 @@ static void android_view_ThreadedRenderer_drawDisplayList(JNIEnv* env, jobject c
jlong proxyPtr, jlong displayListPtr, jint dirtyLeft, jint dirtyTop,
jint dirtyRight, jint dirtyBottom) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
proxy->drawDisplayList(displayList, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
}
diff --git a/docs/html/google/auth/api-client.jd b/docs/html/google/auth/api-client.jd
index fda3310..402a95f 100644
--- a/docs/html/google/auth/api-client.jd
+++ b/docs/html/google/auth/api-client.jd
@@ -112,7 +112,7 @@ GoogleApiClient}</a>, you must specify an implementation for the callback interf
href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html"
>{@code ConnectionCallbacks}</a> and <a
href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.OnConnectionFailedListener.html"
->{@code onConnectionFailedListener}</a>. These interfaces receive callbacks in
+>{@code OnConnectionFailedListener}</a>. These interfaces receive callbacks in
response to the asynchronous <a
href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html#connect()"
>{@code connect()}</a> method when the connection to Google Play services
@@ -512,7 +512,7 @@ private void loadFile(String filename) {
new GetFileTask().execute(filename);
}
-private class GetFileTask extends AsyncTask<String, Void, Void> {
+private class GetFileTask extends AsyncTask&lt;String, Void, Void> {
protected void doInBackground(String filename) {
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, filename))
diff --git a/docs/html/guide/topics/ui/controls/button.jd b/docs/html/guide/topics/ui/controls/button.jd
index 02597c8..b52c3e9 100644
--- a/docs/html/guide/topics/ui/controls/button.jd
+++ b/docs/html/guide/topics/ui/controls/button.jd
@@ -113,7 +113,7 @@ android.view.View} that was clicked)</li>
<h3 id="ClickListener">Using an OnClickListener</h3>
-<p>You can also declare the click event handler pragmatically rather than in an XML layout. This
+<p>You can also declare the click event handler programmatically rather than in an XML layout. This
might be necessary if you instantiate the {@link android.widget.Button} at runtime or you need to
declare the click behavior in a {@link android.app.Fragment} subclass.</p>
diff --git a/docs/html/guide/topics/ui/controls/togglebutton.jd b/docs/html/guide/topics/ui/controls/togglebutton.jd
index c57b510..09af516 100644
--- a/docs/html/guide/topics/ui/controls/togglebutton.jd
+++ b/docs/html/guide/topics/ui/controls/togglebutton.jd
@@ -99,7 +99,7 @@ android.widget.CompoundButton#toggle()} method to change the state.</p>
<h3 id="ClickListener">Using an OnCheckedChangeListener</h3>
-<p>You can also declare a click event handler pragmatically rather than in an XML layout. This
+<p>You can also declare a click event handler programmatically rather than in an XML layout. This
might be necessary if you instantiate the {@link android.widget.ToggleButton} or {@link
android.widget.Switch} at runtime or you need to
declare the click behavior in a {@link android.app.Fragment} subclass.</p>
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 4935b34..8327ef7 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -47,9 +47,8 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount
const Vector3& centroid3d, float heightFactor, float geomFactor,
VertexBuffer& shadowVertexBuffer) {
const int rays = SHADOW_RAY_COUNT;
- const int layers = SHADOW_LAYER_COUNT;
// Validate the inputs.
- if (vertexCount < 3 || heightFactor <= 0 || layers <= 0 || rays <= 0
+ if (vertexCount < 3 || heightFactor <= 0 || rays <= 0
|| geomFactor <= 0) {
#if DEBUG_SHADOW
ALOGE("Invalid input for createAmbientShadow(), early return!");
@@ -96,33 +95,32 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount
// calculate the normal N, which should be perpendicular to the edge of the
// polygon (represented by the neighbor intersection points) .
// Shadow's vertices will be generated as : P + N * scale.
- int currentVertexIndex = 0;
- for (int layerIndex = 0; layerIndex <= layers; layerIndex++) {
- for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
-
- Vector2 normal(1.0f, 0.0f);
- calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);
-
- float opacity = 1.0 / (1 + rayHeight[rayIndex] / heightFactor);
-
- // The vertex should be start from rayDist[i] then scale the
- // normalizeNormal!
- Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
- Vector2(centroid3d.x, centroid3d.y);
-
- float layerRatio = layerIndex / (float)(layers);
- // The higher the intersection is, the further the ambient shadow expanded.
- float expansionDist = rayHeight[rayIndex] / heightFactor *
- geomFactor * (1 - layerRatio);
- AlphaVertex::set(&shadowVertices[currentVertexIndex++],
- intersection.x + normal.x * expansionDist,
- intersection.y + normal.y * expansionDist,
- layerRatio * opacity);
- }
-
+ for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+ Vector2 normal(1.0f, 0.0f);
+ calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);
+
+ // The vertex should be start from rayDist[i] then scale the
+ // normalizeNormal!
+ Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
+ Vector2(centroid3d.x, centroid3d.y);
+
+ // outer ring of points, expanded based upon height of each ray intersection
+ float expansionDist = rayHeight[rayIndex] * heightFactor *
+ geomFactor;
+ AlphaVertex::set(&shadowVertices[rayIndex],
+ intersection.x + normal.x * expansionDist,
+ intersection.y + normal.y * expansionDist,
+ 0.0f);
+
+ // inner ring of points
+ float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor);
+ AlphaVertex::set(&shadowVertices[rayIndex + rays],
+ intersection.x,
+ intersection.y,
+ opacity);
}
- float centroidAlpha = 1.0 / (1 + centroid3d.z / heightFactor);
- AlphaVertex::set(&shadowVertices[currentVertexIndex++],
+ float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor);
+ AlphaVertex::set(&shadowVertices[SHADOW_VERTEX_COUNT - 1],
centroid3d.x, centroid3d.y, centroidAlpha);
#if DEBUG_SHADOW
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 1d58d96..2dfc873 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -315,7 +315,7 @@ void Caches::clearGarbage() {
pathCache.clearGarbage();
patchCache.clearGarbage();
- Vector<DisplayList*> displayLists;
+ Vector<RenderNode*> displayLists;
Vector<Layer*> layers;
{ // scope for the lock
@@ -328,7 +328,7 @@ void Caches::clearGarbage() {
size_t count = displayLists.size();
for (size_t i = 0; i < count; i++) {
- DisplayList* displayList = displayLists.itemAt(i);
+ RenderNode* displayList = displayLists.itemAt(i);
delete displayList;
}
@@ -345,7 +345,7 @@ void Caches::deleteLayerDeferred(Layer* layer) {
mLayerGarbage.push(layer);
}
-void Caches::deleteDisplayListDeferred(DisplayList* displayList) {
+void Caches::deleteDisplayListDeferred(RenderNode* displayList) {
Mutex::Autolock _l(mGarbageLock);
mDisplayListGarbage.push(displayList);
}
@@ -702,11 +702,8 @@ TextureVertex* Caches::getRegionMesh() {
///////////////////////////////////////////////////////////////////////////////
void Caches::initTempProperties() {
- propertyDirtyViewport = false;
- propertyEnable3d = false;
- propertyCameraDistance = 1.0f;
- propertyAmbientShadowStrength = 0x3f;
- propertySpotShadowStrength = 0x3f;
+ propertyAmbientShadowStrength = 25;
+ propertySpotShadowStrength = 25;
propertyLightPosXScale = 0.5f;
propertyLightPosYScale = 0.0f;
@@ -715,17 +712,7 @@ void Caches::initTempProperties() {
void Caches::setTempProperty(const char* name, const char* value) {
ALOGD("setting property %s to %s", name, value);
- if (!strcmp(name, "enable3d")) {
- propertyEnable3d = !strcmp(value, "true");
- propertyDirtyViewport = true;
- ALOGD("enable3d = %d", propertyEnable3d);
- return;
- } else if (!strcmp(name, "cameraDistance")) {
- propertyCameraDistance = fmin(fmax(atof(value), 0.001), 10);
- propertyDirtyViewport = true;
- ALOGD("camera dist multiplier = %.2f", propertyCameraDistance);
- return;
- } else if (!strcmp(name, "ambientShadowStrength")) {
+ if (!strcmp(name, "ambientShadowStrength")) {
propertyAmbientShadowStrength = atoi(value);
ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength);
return;
@@ -735,17 +722,14 @@ void Caches::setTempProperty(const char* name, const char* value) {
return;
} else if (!strcmp(name, "lightPosXScale")) {
propertyLightPosXScale = fmin(fmax(atof(value), 0.0), 1.0);
- propertyDirtyViewport = true;
ALOGD("lightPos X Scale = %.2f", propertyLightPosXScale);
return;
} else if (!strcmp(name, "lightPosYScale")) {
propertyLightPosYScale = fmin(fmax(atof(value), 0.0), 1.0);
- propertyDirtyViewport = true;
ALOGD("lightPos Y Scale = %.2f", propertyLightPosXScale);
return;
} else if (!strcmp(name, "lightPosZScale")) {
propertyLightPosZScale = fmin(fmax(atof(value), 0.0), 1.0);
- propertyDirtyViewport = true;
ALOGD("lightPos Z Scale = %.2f", propertyLightPosXScale);
return;
}
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 8c0c508..50c5fef 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -102,7 +102,7 @@ struct CacheLogger {
// Caches
///////////////////////////////////////////////////////////////////////////////
-class DisplayList;
+class RenderNode;
class ANDROID_API Caches: public Singleton<Caches> {
Caches();
@@ -169,7 +169,7 @@ public:
/*
* Can be used to delete a display list from a non EGL thread.
*/
- void deleteDisplayListDeferred(DisplayList* layer);
+ void deleteDisplayListDeferred(RenderNode* layer);
/**
* Binds the VBO used to render simple textured quads.
@@ -356,9 +356,6 @@ public:
// TEMPORARY properties
void initTempProperties();
void setTempProperty(const char* name, const char* value);
- bool propertyEnable3d;
- bool propertyDirtyViewport; // flag set when dirtying the viewport
- float propertyCameraDistance;
// These scaling factors range from 0 to 1, to scale the light position
// within the bound of (screenwidth, screenheight, max(screenwidth, screenheight));
@@ -423,7 +420,7 @@ private:
mutable Mutex mGarbageLock;
Vector<Layer*> mLayerGarbage;
- Vector<DisplayList*> mDisplayListGarbage;
+ Vector<RenderNode*> mDisplayListGarbage;
DebugLevel mDebugLevel;
bool mInitialized;
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 7a2e288..7a83967 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -54,7 +54,7 @@ void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
SkRefCnt_SafeAssign(mColorFilter, colorFilter);
}
-void DeferredLayerUpdater::setDisplayList(DisplayList* displayList,
+void DeferredLayerUpdater::setDisplayList(RenderNode* displayList,
int left, int top, int right, int bottom) {
mDisplayList = displayList;
if (mDirtyRect.isEmpty()) {
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 65f225c..d124cde 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -72,7 +72,7 @@ public:
mTransform = matrix ? new SkMatrix(*matrix) : 0;
}
- ANDROID_API void setDisplayList(DisplayList* displayList,
+ ANDROID_API void setDisplayList(RenderNode* displayList,
int left, int top, int right, int bottom);
ANDROID_API void setPaint(const SkPaint* paint);
@@ -101,7 +101,7 @@ private:
// Layer type specific properties
// displayList and surfaceTexture are mutually exclusive, only 1 may be set
// dirtyRect is only valid if displayList is set
- DisplayList* mDisplayList;
+ RenderNode* mDisplayList;
Rect mDirtyRect;
sp<GLConsumer> mSurfaceTexture;
SkMatrix* mTransform;
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 0f76486..f038427 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -29,7 +29,7 @@
namespace android {
namespace uirenderer {
-void DisplayList::outputLogBuffer(int fd) {
+void RenderNode::outputLogBuffer(int fd) {
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
if (logBuffer.isEmpty()) {
return;
@@ -48,7 +48,7 @@ void DisplayList::outputLogBuffer(int fd) {
fflush(file);
}
-DisplayList::DisplayList() :
+RenderNode::RenderNode() :
mDisplayListData(0), mDestroyed(false), mTransformMatrix(NULL), mTransformCamera(NULL),
mTransformMatrix3D(NULL), mStaticMatrix(NULL), mAnimationMatrix(NULL) {
@@ -87,7 +87,7 @@ DisplayList::DisplayList() :
mCaching = false;
}
-DisplayList::~DisplayList() {
+RenderNode::~RenderNode() {
LOG_ALWAYS_FATAL_IF(mDestroyed, "Double destroyed DisplayList %p", this);
mDestroyed = true;
@@ -99,14 +99,14 @@ DisplayList::~DisplayList() {
delete mAnimationMatrix;
}
-void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
+void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) {
if (displayList) {
DISPLAY_LIST_LOGD("Deferring display list destruction");
Caches::getInstance().deleteDisplayListDeferred(displayList);
}
}
-void DisplayList::setData(DisplayListData* data) {
+void RenderNode::setData(DisplayListData* data) {
delete mDisplayListData;
mDisplayListData = data;
if (mDisplayListData) {
@@ -118,7 +118,7 @@ void DisplayList::setData(DisplayListData* data) {
* This function is a simplified version of replay(), where we simply retrieve and log the
* display list. This function should remain in sync with the replay() function.
*/
-void DisplayList::output(uint32_t level) {
+void RenderNode::output(uint32_t level) {
ALOGD("%*sStart display list (%p, %s, render=%d)", (level - 1) * 2, "", this,
mName.string(), isRenderable());
ALOGD("%*s%s %d", level * 2, "", "Save",
@@ -133,17 +133,17 @@ void DisplayList::output(uint32_t level) {
ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
}
-float DisplayList::getPivotX() {
+float RenderNode::getPivotX() {
updateMatrix();
return mPivotX;
}
-float DisplayList::getPivotY() {
+float RenderNode::getPivotY() {
updateMatrix();
return mPivotY;
}
-void DisplayList::updateMatrix() {
+void RenderNode::updateMatrix() {
if (mMatrixDirty) {
// NOTE: mTransformMatrix won't be up to date if a DisplayList goes from a complex transform
// to a pure translate. This is safe because the matrix isn't read in pure translate cases.
@@ -160,8 +160,8 @@ void DisplayList::updateMatrix() {
mPivotY = mPrevHeight / 2.0f;
}
}
- const bool perspectiveEnabled = Caches::getInstance().propertyEnable3d;
- if (!perspectiveEnabled && (mMatrixFlags & ROTATION_3D) == 0) {
+
+ if ((mMatrixFlags & ROTATION_3D) == 0) {
mTransformMatrix->loadTranslate(
mPivotX + mTranslationX,
mPivotY + mTranslationY,
@@ -170,45 +170,32 @@ void DisplayList::updateMatrix() {
mTransformMatrix->scale(mScaleX, mScaleY, 1);
mTransformMatrix->translate(-mPivotX, -mPivotY);
} else {
- if (perspectiveEnabled) {
- mTransformMatrix->loadTranslate(
- mPivotX + mTranslationX,
- mPivotY + mTranslationY,
- mTranslationZ);
- mTransformMatrix->rotate(mRotationX, 1, 0, 0);
- mTransformMatrix->rotate(mRotationY, 0, 1, 0);
- mTransformMatrix->rotate(mRotation, 0, 0, 1);
- mTransformMatrix->scale(mScaleX, mScaleY, 1);
- mTransformMatrix->translate(-mPivotX, -mPivotY);
- } else {
- /* TODO: support this old transform approach, based on API level */
- if (!mTransformCamera) {
- mTransformCamera = new Sk3DView();
- mTransformMatrix3D = new SkMatrix();
- }
- SkMatrix transformMatrix;
- transformMatrix.reset();
- mTransformCamera->save();
- transformMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
- mTransformCamera->rotateX(mRotationX);
- mTransformCamera->rotateY(mRotationY);
- mTransformCamera->rotateZ(-mRotation);
- mTransformCamera->getMatrix(mTransformMatrix3D);
- mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
- mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
- mPivotY + mTranslationY);
- transformMatrix.postConcat(*mTransformMatrix3D);
- mTransformCamera->restore();
-
- mTransformMatrix->load(transformMatrix);
+ if (!mTransformCamera) {
+ mTransformCamera = new Sk3DView();
+ mTransformMatrix3D = new SkMatrix();
}
+ SkMatrix transformMatrix;
+ transformMatrix.reset();
+ mTransformCamera->save();
+ transformMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+ mTransformCamera->rotateX(mRotationX);
+ mTransformCamera->rotateY(mRotationY);
+ mTransformCamera->rotateZ(-mRotation);
+ mTransformCamera->getMatrix(mTransformMatrix3D);
+ mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
+ mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
+ mPivotY + mTranslationY);
+ transformMatrix.postConcat(*mTransformMatrix3D);
+ mTransformCamera->restore();
+
+ mTransformMatrix->load(transformMatrix);
}
}
mMatrixDirty = false;
}
}
-void DisplayList::outputViewProperties(const int level) {
+void RenderNode::outputViewProperties(const int level) {
updateMatrix();
if (mLeft != 0 || mTop != 0) {
ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
@@ -262,7 +249,7 @@ void DisplayList::outputViewProperties(const int level) {
#define PROPERTY_SAVECOUNT 0
template <class T>
-void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler,
+void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
const int level) {
#if DEBUG_DISPLAY_LIST
outputViewProperties(level);
@@ -278,8 +265,7 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler,
}
if (mMatrixFlags != 0) {
if (mMatrixFlags == TRANSLATION) {
- renderer.translate(mTranslationX, mTranslationY,
- Caches::getInstance().propertyEnable3d ? mTranslationZ : 0.0f); // TODO: necessary?
+ renderer.translate(mTranslationX, mTranslationY);
} else {
renderer.concatMatrix(*mTransformMatrix);
}
@@ -318,8 +304,11 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler,
/**
* Apply property-based transformations to input matrix
+ *
+ * If true3dTransform is set to true, the transform applied to the input matrix will use true 4x4
+ * matrix computation instead of the Skia 3x3 matrix + camera hackery.
*/
-void DisplayList::applyViewPropertyTransforms(mat4& matrix) {
+void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) {
if (mLeft != 0 || mTop != 0) {
matrix.translate(mLeft, mTop);
}
@@ -333,24 +322,39 @@ void DisplayList::applyViewPropertyTransforms(mat4& matrix) {
if (mMatrixFlags != 0) {
updateMatrix();
if (mMatrixFlags == TRANSLATION) {
- matrix.translate(mTranslationX, mTranslationY, mTranslationZ);
+ matrix.translate(mTranslationX, mTranslationY,
+ true3dTransform ? mTranslationZ : 0.0f);
} else {
- matrix.multiply(*mTransformMatrix);
+ if (!true3dTransform) {
+ matrix.multiply(*mTransformMatrix);
+ } else {
+ mat4 true3dMat;
+ true3dMat.loadTranslate(
+ mPivotX + mTranslationX,
+ mPivotY + mTranslationY,
+ mTranslationZ);
+ true3dMat.rotate(mRotationX, 1, 0, 0);
+ true3dMat.rotate(mRotationY, 0, 1, 0);
+ true3dMat.rotate(mRotation, 0, 0, 1);
+ true3dMat.scale(mScaleX, mScaleY, 1);
+ true3dMat.translate(-mPivotX, -mPivotY);
+
+ matrix.multiply(true3dMat);
+ }
}
}
}
/**
- * Organizes the DisplayList hierarchy to prepare for Z-based draw order.
+ * Organizes the DisplayList hierarchy to prepare for background projection reordering.
*
* This should be called before a call to defer() or drawDisplayList()
*
* Each DisplayList that serves as a 3d root builds its list of composited children,
* which are flagged to not draw in the standard draw loop.
*/
-void DisplayList::computeOrdering() {
+void RenderNode::computeOrdering() {
ATRACE_CALL();
- m3dNodes.clear();
mProjectedNodes.clear();
// TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that
@@ -359,40 +363,23 @@ void DisplayList::computeOrdering() {
for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
DrawDisplayListOp* childOp = mDisplayListData->children[i];
childOp->mDisplayList->computeOrderingImpl(childOp,
- &m3dNodes, &mat4::identity(),
&mProjectedNodes, &mat4::identity());
}
}
-void DisplayList::computeOrderingImpl(
+void RenderNode::computeOrderingImpl(
DrawDisplayListOp* opState,
- Vector<ZDrawDisplayListOpPair>* compositedChildrenOf3dRoot,
- const mat4* transformFrom3dRoot,
Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface,
const mat4* transformFromProjectionSurface) {
- m3dNodes.clear();
mProjectedNodes.clear();
if (mDisplayListData == NULL || mDisplayListData->isEmpty()) return;
// TODO: should avoid this calculation in most cases
// TODO: just calculate single matrix, down to all leaf composited elements
- Matrix4 localTransformFrom3dRoot(*transformFrom3dRoot);
- localTransformFrom3dRoot.multiply(opState->mTransformFromParent);
Matrix4 localTransformFromProjectionSurface(*transformFromProjectionSurface);
localTransformFromProjectionSurface.multiply(opState->mTransformFromParent);
- if (mTranslationZ != 0.0f) { // TODO: other signals for 3d compositing, such as custom matrix4
- // composited 3d layer, flag for out of order draw and save matrix...
- opState->mSkipInOrderDraw = true;
- opState->mTransformFromCompositingAncestor.load(localTransformFrom3dRoot);
-
- // ... and insert into current 3d root, keyed with pivot z for later sorting
- Vector3 pivot(mPivotX, mPivotY, 0.0f);
- mat4 totalTransform(localTransformFrom3dRoot);
- applyViewPropertyTransforms(totalTransform);
- totalTransform.mapPoint3d(pivot);
- compositedChildrenOf3dRoot->add(ZDrawDisplayListOpPair(pivot.z, opState));
- } else if (mProjectBackwards) {
+ if (mProjectBackwards) {
// composited projectee, flag for out of order draw, save matrix, and store in proj surface
opState->mSkipInOrderDraw = true;
opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface);
@@ -403,20 +390,11 @@ void DisplayList::computeOrderingImpl(
}
if (mDisplayListData->children.size() > 0) {
- if (mIsolatedZVolume) {
- // create a new 3d space for descendents by collecting them
- compositedChildrenOf3dRoot = &m3dNodes;
- transformFrom3dRoot = &mat4::identity();
- } else {
- applyViewPropertyTransforms(localTransformFrom3dRoot);
- transformFrom3dRoot = &localTransformFrom3dRoot;
- }
-
const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0;
bool haveAppliedPropertiesToProjection = false;
for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
DrawDisplayListOp* childOp = mDisplayListData->children[i];
- DisplayList* child = childOp->mDisplayList;
+ RenderNode* child = childOp->mDisplayList;
Vector<DrawDisplayListOp*>* projectionChildren = NULL;
const mat4* projectionTransform = NULL;
@@ -436,9 +414,7 @@ void DisplayList::computeOrderingImpl(
projectionChildren = compositedChildrenOfProjectionSurface;
projectionTransform = &localTransformFromProjectionSurface;
}
- child->computeOrderingImpl(childOp,
- compositedChildrenOf3dRoot, transformFrom3dRoot,
- projectionChildren, projectionTransform);
+ child->computeOrderingImpl(childOp, projectionChildren, projectionTransform);
}
}
@@ -458,7 +434,7 @@ private:
const int mLevel;
};
-void DisplayList::defer(DeferStateStruct& deferStruct, const int level) {
+void RenderNode::defer(DeferStateStruct& deferStruct, const int level) {
DeferOperationHandler handler(deferStruct, level);
iterate<DeferOperationHandler>(deferStruct.mRenderer, handler, level);
}
@@ -480,7 +456,7 @@ private:
const int mLevel;
};
-void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) {
+void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) {
ReplayOperationHandler handler(replayStruct, level);
replayStruct.mRenderer.startMark(mName.string());
@@ -491,14 +467,36 @@ void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) {
replayStruct.mDrawGlStatus);
}
-#define SHADOW_DELTA 2.0f
+void RenderNode::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes) {
+ if (mDisplayListData == NULL || mDisplayListData->children.size() == 0) return;
+
+ for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
+ DrawDisplayListOp* childOp = mDisplayListData->children[i];
+ RenderNode* child = childOp->mDisplayList;
+ float childZ = child->mTranslationZ;
+
+ if (childZ != 0.0f) {
+ zTranslatedNodes.add(ZDrawDisplayListOpPair(childZ, childOp));
+ childOp->mSkipInOrderDraw = true;
+ } else if (!child->mProjectBackwards) {
+ // regular, in order drawing DisplayList
+ childOp->mSkipInOrderDraw = false;
+ }
+ }
+
+ // Z sort 3d children (stable-ness makes z compare fall back to standard drawing order)
+ std::stable_sort(zTranslatedNodes.begin(), zTranslatedNodes.end());
+}
+
+#define SHADOW_DELTA 0.1f
template <class T>
-void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& renderer,
- T& handler, const int level) {
- if (m3dNodes.size() == 0 ||
- (mode == kNegativeZChildren && m3dNodes[0].key > 0.0f) ||
- (mode == kPositiveZChildren && m3dNodes[m3dNodes.size() - 1].key < 0.0f)) {
+void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
+ ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler) {
+ const int size = zTranslatedNodes.size();
+ if (size == 0
+ || (mode == kNegativeZChildren && zTranslatedNodes[0].key > 0.0f)
+ || (mode == kPositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) {
// no 3d children to draw
return;
}
@@ -516,7 +514,7 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren
* This way, if Views A & B have the same Z height and are both casting shadows, the shadows are
* underneath both, and neither's shadow is drawn on top of the other.
*/
- const size_t nonNegativeIndex = findNonNegativeIndex(m3dNodes);
+ const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes);
size_t drawIndex, shadowIndex, endIndex;
if (mode == kNegativeZChildren) {
drawIndex = 0;
@@ -524,24 +522,29 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren
shadowIndex = endIndex; // draw no shadows
} else {
drawIndex = nonNegativeIndex;
- endIndex = m3dNodes.size();
+ endIndex = size;
shadowIndex = drawIndex; // potentially draw shadow for each pos Z child
}
float lastCasterZ = 0.0f;
while (shadowIndex < endIndex || drawIndex < endIndex) {
if (shadowIndex < endIndex) {
- DrawDisplayListOp* casterOp = m3dNodes[shadowIndex].value;
- DisplayList* caster = casterOp->mDisplayList;
- const float casterZ = m3dNodes[shadowIndex].key;
+ DrawDisplayListOp* casterOp = zTranslatedNodes[shadowIndex].value;
+ RenderNode* caster = casterOp->mDisplayList;
+ const float casterZ = zTranslatedNodes[shadowIndex].key;
// attempt to render the shadow if the caster about to be drawn is its caster,
// OR if its caster's Z value is similar to the previous potential caster
if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) {
if (caster->mCastsShadow && caster->mAlpha > 0.0f) {
- mat4 shadowMatrix(casterOp->mTransformFromCompositingAncestor);
- caster->applyViewPropertyTransforms(shadowMatrix);
+ mat4 shadowMatrixXY(casterOp->mTransformFromParent);
+ caster->applyViewPropertyTransforms(shadowMatrixXY);
- DisplayListOp* shadowOp = new (alloc) DrawShadowOp(shadowMatrix,
+ // Z matrix needs actual 3d transformation, so mapped z values will be correct
+ mat4 shadowMatrixZ(casterOp->mTransformFromParent);
+ caster->applyViewPropertyTransforms(shadowMatrixZ, true);
+
+ DisplayListOp* shadowOp = new (alloc) DrawShadowOp(
+ shadowMatrixXY, shadowMatrixZ,
caster->mAlpha, &(caster->mOutline), caster->mWidth, caster->mHeight);
handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds);
}
@@ -556,10 +559,10 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren
// since it modifies the renderer's matrix
int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
- DrawDisplayListOp* childOp = m3dNodes[drawIndex].value;
- DisplayList* child = childOp->mDisplayList;
+ DrawDisplayListOp* childOp = zTranslatedNodes[drawIndex].value;
+ RenderNode* child = childOp->mDisplayList;
- renderer.concatMatrix(childOp->mTransformFromCompositingAncestor);
+ renderer.concatMatrix(childOp->mTransformFromParent);
childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
handler(childOp, renderer.getSaveCount() - 1, mClipToBounds);
childOp->mSkipInOrderDraw = true;
@@ -571,7 +574,7 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren
}
template <class T>
-void DisplayList::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) {
+void RenderNode::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) {
int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
LinearAllocator& alloc = handler.allocator();
ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight,
@@ -602,7 +605,7 @@ void DisplayList::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler,
* defer vs replay logic, per operation
*/
template <class T>
-void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
+void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
if (CC_UNLIKELY(mDestroyed)) { // temporary debug logging
ALOGW("Error: %s is drawing after destruction", getName());
CRASH();
@@ -631,11 +634,11 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level)
bool quickRejected = mClipToBounds && renderer.quickRejectConservative(0, 0, mWidth, mHeight);
if (!quickRejected) {
- // Z sort 3d children (stable-ness makes z compare fall back to standard drawing order)
- std::stable_sort(m3dNodes.begin(), m3dNodes.end());
+ Vector<ZDrawDisplayListOpPair> zTranslatedNodes;
+ buildZSortedChildList(zTranslatedNodes);
// for 3d root, draw children with negative z values
- iterate3dChildren(kNegativeZChildren, renderer, handler, level);
+ iterate3dChildren(zTranslatedNodes, kNegativeZChildren, renderer, handler);
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
const int saveCountOffset = renderer.getSaveCount() - 1;
@@ -656,7 +659,7 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level)
}
// for 3d root, draw children with positive z values
- iterate3dChildren(kPositiveZChildren, renderer, handler, level);
+ iterate3dChildren(zTranslatedNodes, kPositiveZChildren, renderer, handler);
}
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index a3577d4..7d0e30e 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -160,17 +160,17 @@ private:
* recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay
* attached.
*/
-class DisplayList {
+class RenderNode {
public:
- ANDROID_API DisplayList();
- ANDROID_API ~DisplayList();
+ ANDROID_API RenderNode();
+ ANDROID_API ~RenderNode();
// See flags defined in DisplayList.java
enum ReplayFlag {
kReplayFlag_ClipChildren = 0x1
};
- ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
+ ANDROID_API static void destroyDisplayListDeferred(RenderNode* displayList);
ANDROID_API static void outputLogBuffer(int fd);
ANDROID_API void setData(DisplayListData* newData);
@@ -573,20 +573,20 @@ private:
void outputViewProperties(const int level);
- void applyViewPropertyTransforms(mat4& matrix);
+ void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false);
void computeOrderingImpl(DrawDisplayListOp* opState,
- Vector<ZDrawDisplayListOpPair>* compositedChildrenOf3dRoot,
- const mat4* transformFrom3dRoot,
Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface,
const mat4* transformFromProjectionSurface);
template <class T>
inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level);
+ void buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes);
+
template <class T>
- inline void iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& renderer,
- T& handler, const int level);
+ inline void iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
+ ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler);
template <class T>
inline void iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level);
@@ -657,9 +657,6 @@ private:
* Draw time state - these properties are only set and used during rendering
*/
- // for 3d roots, contains a z sorted list of all children items
- Vector<ZDrawDisplayListOpPair> m3dNodes;
-
// for projection surfaces, contains a list of all children items
Vector<DrawDisplayListOp*> mProjectedNodes;
}; // class DisplayList
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 65eda29..549b786 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1488,9 +1488,9 @@ private:
};
class DrawDisplayListOp : public DrawBoundedOp {
- friend class DisplayList; // grant DisplayList access to info of child
+ friend class RenderNode; // grant DisplayList access to info of child
public:
- DrawDisplayListOp(DisplayList* displayList, int flags, const mat4& transformFromParent)
+ DrawDisplayListOp(RenderNode* displayList, int flags, const mat4& transformFromParent)
: DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0),
mDisplayList(displayList), mFlags(flags), mTransformFromParent(transformFromParent) {}
@@ -1522,7 +1522,7 @@ public:
virtual const char* name() { return "DrawDisplayList"; }
private:
- DisplayList* mDisplayList;
+ RenderNode* mDisplayList;
const int mFlags;
///////////////////////////
@@ -1534,10 +1534,10 @@ private:
const mat4 mTransformFromParent;
/**
- * Holds the transformation between the 3d root OR projection surface ViewGroup and this
- * DisplayList drawing instance. Represents any translations / transformations done within the
- * drawing of the compositing ancestor ViewGroup's draw, before the draw of the View represented
- * by this DisplayList draw instance.
+ * Holds the transformation between the projection surface ViewGroup and this DisplayList
+ * drawing instance. Represents any translations / transformations done within the drawing of
+ * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this
+ * DisplayList draw instance.
*
* Note: doesn't include any transformation recorded within the DisplayList and its properties.
*/
@@ -1550,19 +1550,20 @@ private:
*/
class DrawShadowOp : public DrawOp {
public:
- DrawShadowOp(const mat4& transform, float alpha, const SkPath* outline,
+ DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, const SkPath* outline,
float fallbackWidth, float fallbackHeight)
- : DrawOp(NULL), mTransform(transform), mAlpha(alpha), mOutline(outline),
+ : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ),
+ mAlpha(alpha), mOutline(outline),
mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight) {}
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
- if (!mOutline->isEmpty()) {
- return renderer.drawShadow(mTransform, mAlpha, mOutline);
+ if (mOutline->isEmpty()) {
+ SkPath fakeOutline;
+ fakeOutline.addRect(0, 0, mFallbackWidth, mFallbackHeight);
+ return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &fakeOutline);
}
- SkPath fakeOutline;
- fakeOutline.addRect(0, 0, mFallbackWidth, mFallbackHeight);
- return renderer.drawShadow(mTransform, mAlpha, &fakeOutline);
+ return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, mOutline);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -1572,7 +1573,8 @@ public:
virtual const char* name() { return "DrawShadow"; }
private:
- const mat4 mTransform;
+ const mat4 mTransformXY;
+ const mat4 mTransformZ;
const float mAlpha;
const SkPath* mOutline;
const float mFallbackWidth;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 3b1d567..e69e08e 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -179,7 +179,7 @@ bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
return StatefulBaseRenderer::clipRegion(region, op);
}
-status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
+status_t DisplayListRenderer::drawDisplayList(RenderNode* displayList,
Rect& dirty, int32_t flags) {
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 1fb72ce..65498a5 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -156,7 +156,7 @@ public:
// Canvas draw operations - special
// ----------------------------------------------------------------------------
virtual status_t drawLayer(Layer* layer, float x, float y);
- virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty,
+ virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty,
int32_t replayFlags);
// TODO: rename for consistency
@@ -309,7 +309,7 @@ private:
int mRestoreSaveCount;
- friend class DisplayList;
+ friend class RenderNode;
}; // class DisplayListRenderer
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 8992a13..52176d4 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -194,7 +194,7 @@ void Layer::defer() {
deferredList = new DeferredDisplayList(dirtyRect);
DeferStateStruct deferredState(*deferredList, *renderer,
- DisplayList::kReplayFlag_ClipChildren);
+ RenderNode::kReplayFlag_ClipChildren);
renderer->initViewport(width, height);
renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
@@ -238,7 +238,7 @@ void Layer::render() {
renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
!isBlend());
- renderer->drawDisplayList(displayList, dirtyRect, DisplayList::kReplayFlag_ClipChildren);
+ renderer->drawDisplayList(displayList, dirtyRect, RenderNode::kReplayFlag_ClipChildren);
renderer->finish();
renderer = NULL;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index f6538f2..d8440ea 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -43,7 +43,7 @@ namespace uirenderer {
// Forward declarations
class Caches;
class OpenGLRenderer;
-class DisplayList;
+class RenderNode;
class DeferredDisplayList;
class DeferStateStruct;
@@ -84,7 +84,7 @@ public:
regionRect.translate(layer.left, layer.top);
}
- void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
+ void updateDeferred(OpenGLRenderer* renderer, RenderNode* displayList,
int left, int top, int right, int bottom) {
this->renderer = renderer;
this->displayList = displayList;
@@ -294,7 +294,7 @@ public:
*/
bool deferredUpdateScheduled;
OpenGLRenderer* renderer;
- DisplayList* displayList;
+ RenderNode* displayList;
Rect dirtyRect;
bool debugDrawUpdate;
bool hasDrawnSinceUpdate;
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 4f5cd26..f06106b 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -372,84 +372,6 @@ void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) {
mType = kTypeUnknown;
}
-// translated from android.opengl.Matrix#frustumM()
-void Matrix4::loadFrustum(float left, float top, float right, float bottom, float near, float far) {
- float r_width = 1.0f / (right - left);
- float r_height = 1.0f / (top - bottom);
- float r_depth = 1.0f / (near - far);
- float x = 2.0f * (near * r_width);
- float y = 2.0f * (near * r_height);
- float A = (right + left) * r_width;
- float B = (top + bottom) * r_height;
- float C = (far + near) * r_depth;
- float D = 2.0f * (far * near * r_depth);
-
- memset(&data, 0, sizeof(data));
- mType = kTypeUnknown;
-
- data[kScaleX] = x;
- data[kScaleY] = y;
- data[8] = A;
- data[9] = B;
- data[kScaleZ] = C;
- data[kTranslateZ] = D;
- data[11] = -1.0f;
-}
-
-// translated from android.opengl.Matrix#setLookAtM()
-void Matrix4::loadLookAt(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ) {
- float fx = centerX - eyeX;
- float fy = centerY - eyeY;
- float fz = centerZ - eyeZ;
-
- // Normalize f
- float rlf = 1.0f / sqrt(fx*fx + fy*fy + fz*fz);
- fx *= rlf;
- fy *= rlf;
- fz *= rlf;
-
- // compute s = f x up (x means "cross product")
- float sx = fy * upZ - fz * upY;
- float sy = fz * upX - fx * upZ;
- float sz = fx * upY - fy * upX;
-
- // and normalize s
- float rls = 1.0f / sqrt(sx*sx + sy*sy + sz*sz);
- sx *= rls;
- sy *= rls;
- sz *= rls;
-
- // compute u = s x f
- float ux = sy * fz - sz * fy;
- float uy = sz * fx - sx * fz;
- float uz = sx * fy - sy * fx;
-
- mType = kTypeUnknown;
- data[0] = sx;
- data[1] = ux;
- data[2] = -fx;
- data[3] = 0.0f;
-
- data[4] = sy;
- data[5] = uy;
- data[6] = -fy;
- data[7] = 0.0f;
-
- data[8] = sz;
- data[9] = uz;
- data[10] = -fz;
- data[11] = 0.0f;
-
- data[12] = 0.0f;
- data[13] = 0.0f;
- data[14] = 0.0f;
- data[15] = 1.0f;
-
- translate(-eyeX, -eyeY, -eyeZ);
-}
-
void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
loadIdentity();
@@ -463,9 +385,14 @@ void Matrix4::loadOrtho(float left, float right, float bottom, float top, float
mType = kTypeTranslate | kTypeScale | kTypeRectToRect;
}
+float Matrix4::mapZ(const Vector3& orig) const {
+ // duplicates logic for mapPoint3d's z coordinate
+ return orig.x * data[2] + orig.y * data[6] + orig.z * data[kScaleZ] + data[kTranslateZ];
+}
+
void Matrix4::mapPoint3d(Vector3& vec) const {
//TODO: optimize simple case
- Vector3 orig(vec);
+ const Vector3 orig(vec);
vec.x = orig.x * data[kScaleX] + orig.y * data[kSkewX] + orig.z * data[8] + data[kTranslateX];
vec.y = orig.x * data[kSkewY] + orig.y * data[kScaleY] + orig.z * data[9] + data[kTranslateY];
vec.z = orig.x * data[2] + orig.y * data[6] + orig.z * data[kScaleZ] + data[kTranslateZ];
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 5cd79b1..26cb05f 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -129,10 +129,6 @@ public:
void loadRotate(float angle);
void loadRotate(float angle, float x, float y, float z);
void loadMultiply(const Matrix4& u, const Matrix4& v);
- void loadFrustum(float left, float top, float right, float bottom, float near, float far);
- void loadLookAt(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ);
void loadOrtho(float left, float right, float bottom, float top, float near, float far);
@@ -203,6 +199,7 @@ public:
void copyTo(float* v) const;
void copyTo(SkMatrix& v) const;
+ float mapZ(const Vector3& orig) const;
void mapPoint3d(Vector3& vec) const;
void mapPoint(float& x, float& y) const; // 2d only
void mapRect(Rect& r) const; // 2d only
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b620b80..1475953 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -170,21 +170,7 @@ void OpenGLRenderer::setViewport(int width, int height) {
}
void OpenGLRenderer::initViewport(int width, int height) {
- if (mCaches.propertyEnable3d) {
- // TODO: make view proj app configurable
- float dist = std::max(width, height) * 1.5;
- dist *= mCaches.propertyCameraDistance;
- Matrix4 projection;
- projection.loadFrustum(-width / 2, -height / 2, width / 2, height / 2, dist, 0);
- Matrix4 view;
- view.loadLookAt(0, 0, dist,
- 0, 0, 0,
- 0, 1, 0);
- mViewProjMatrix.loadMultiply(projection, view);
- mViewProjMatrix.translate(-width/2, -height/2);
- } else {
- mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1);
- }
+ mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1);
initializeViewport(width, height);
}
@@ -1926,16 +1912,9 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) {
// Drawing
///////////////////////////////////////////////////////////////////////////////
-status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty,
+status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty,
int32_t replayFlags) {
status_t status;
-
- if (mCaches.propertyDirtyViewport) {
- // force recalc of view/proj matrices
- setViewport(getWidth(), getHeight());
- mCaches.propertyDirtyViewport = false;
- }
-
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
@@ -3211,8 +3190,16 @@ status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint*
return drawColorRects(rects, count, paint, false, true, true);
}
-status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlpha,
- const SkPath* casterOutline) {
+static void mapPointFakeZ(Vector3& point, const mat4& transformXY, const mat4& transformZ) {
+ // map z coordinate with true 3d matrix
+ point.z = transformZ.mapZ(point);
+
+ // map x,y coordinates with draw/Skia matrix
+ transformXY.mapPoint(point.x, point.y);
+}
+
+status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ,
+ float casterAlpha, const SkPath* casterOutline) {
if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
// TODO: use quickRejectWithScissor. For now, always force enable scissor.
@@ -3235,10 +3222,12 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlp
// map 2d caster poly into 3d
const int casterVertexCount = casterVertices2d.size();
Vector3 casterPolygon[casterVertexCount];
+ float minZ = FLT_MAX;
for (int i = 0; i < casterVertexCount; i++) {
const Vertex& point2d = casterVertices2d[i];
casterPolygon[i] = Vector3(point2d.x, point2d.y, 0);
- casterTransform.mapPoint3d(casterPolygon[i]);
+ mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ);
+ minZ = fmin(minZ, casterPolygon[i].z);
}
// map the centroid of the caster into 3d
@@ -3246,7 +3235,16 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlp
reinterpret_cast<const Vector2*>(casterVertices2d.array()),
casterVertexCount);
Vector3 centroid3d(centroid.x, centroid.y, 0);
- casterTransform.mapPoint3d(centroid3d);
+ mapPointFakeZ(centroid3d, casterTransformXY, casterTransformZ);
+
+ // if the caster intersects the z=0 plane, lift it in Z so it doesn't
+ if (minZ < SHADOW_MIN_CASTER_Z) {
+ float casterLift = SHADOW_MIN_CASTER_Z - minZ;
+ for (int i = 0; i < casterVertexCount; i++) {
+ casterPolygon[i].z += casterLift;
+ }
+ centroid3d.z += casterLift;
+ }
// draw caster's shadows
if (mCaches.propertyAmbientShadowStrength > 0) {
@@ -3265,7 +3263,6 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlp
ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount,
lightPosScale, *currentTransform(), getWidth(), getHeight(),
spotShadowVertexBuffer);
-
drawVertexBuffer(kVertexBufferMode_Shadow, spotShadowVertexBuffer, &paint);
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 03beae3..94abfa7 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -54,7 +54,7 @@ namespace android {
namespace uirenderer {
class DeferredDisplayState;
-class DisplayList;
+class RenderNode;
class TextSetupFunctor;
class VertexBuffer;
class SkiaShader;
@@ -165,7 +165,7 @@ public:
int saveLayerDeferred(float left, float top, float right, float bottom,
const SkPaint* paint, int flags);
- virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t replayFlags = 1);
+ virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
virtual status_t drawLayer(Layer* layer, float x, float y);
virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
const SkPaint* paint);
@@ -208,8 +208,8 @@ public:
DrawOpMode drawOpMode = kDrawOpMode_Immediate);
virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
- status_t drawShadow(const mat4& casterTransform, float casterAlpha,
- const SkPath* casterOutline);
+ status_t drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ,
+ float casterAlpha, const SkPath* casterOutline);
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index 4754bad..efcea5f 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -31,7 +31,7 @@ struct Res_png_9patch;
namespace uirenderer {
-class DisplayList;
+class RenderNode;
class Layer;
class Matrix4;
class SkiaColorFilter;
@@ -232,7 +232,7 @@ public:
// Canvas draw operations - special
// ----------------------------------------------------------------------------
virtual status_t drawLayer(Layer* layer, float x, float y) = 0;
- virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty,
+ virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty,
int32_t replayFlags) = 0;
// TODO: rename for consistency
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 5469aad..f138222 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -40,7 +40,7 @@ void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon,
// A bunch of parameters to tweak the shadow.
// TODO: Allow some of these changable by debug settings or APIs.
- const float heightFactor = 128;
+ const float heightFactor = 1.0f / 128;
const float geomFactor = 64;
AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount,
@@ -69,7 +69,7 @@ void ShadowTessellator::tessellateSpotShadow(const Vector3* casterPolygon, int c
reverseReceiverTransform.mapPoint3d(lightCenter);
const float lightSize = maximal / 4;
- const int lightVertexCount = 16;
+ const int lightVertexCount = 8;
SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter,
lightSize, lightVertexCount, shadowVertexBuffer);
@@ -78,26 +78,23 @@ void ShadowTessellator::tessellateSpotShadow(const Vector3* casterPolygon, int c
void ShadowTessellator::generateShadowIndices(uint16_t* shadowIndices) {
int currentIndex = 0;
- const int layers = SHADOW_LAYER_COUNT;
const int rays = SHADOW_RAY_COUNT;
// For the penumbra area.
- for (int i = 0; i < layers; i++) {
- for (int j = 0; j < rays; j++) {
- shadowIndices[currentIndex++] = i * rays + j;
- shadowIndices[currentIndex++] = (i + 1) * rays + j;
- }
- // To close the loop, back to the ray 0.
- shadowIndices[currentIndex++] = i * rays;
- shadowIndices[currentIndex++] = (i + 1) * rays;
+ for (int i = 0; i < rays; i++) {
+ shadowIndices[currentIndex++] = i;
+ shadowIndices[currentIndex++] = rays + i;
}
- uint16_t base = layers * rays;
- uint16_t centroidIndex = (layers + 1) * rays;
+ // To close the loop, back to the ray 0.
+ shadowIndices[currentIndex++] = 0;
+ shadowIndices[currentIndex++] = rays;
+
+ uint16_t centroidIndex = 2 * rays;
// For the umbra area, using strips to simulate the fans.
- for (int k = 0; k < rays; k++) {
- shadowIndices[currentIndex++] = base + k;
+ for (int i = 0; i < rays; i++) {
+ shadowIndices[currentIndex++] = rays + i;
shadowIndices[currentIndex++] = centroidIndex;
}
- shadowIndices[currentIndex++] = base;
+ shadowIndices[currentIndex++] = rays;
#if DEBUG_SHADOW
if (currentIndex != SHADOW_INDEX_COUNT) {
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index c49fdcb..c558460 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -46,17 +46,15 @@ namespace uirenderer {
// The total number of rays starting from the centroid of shadow area, in order
// to generate the shadow geometry.
-#define SHADOW_RAY_COUNT 256
-
-// The total number of layers in the outer shadow area, 1 being the minimum.
-#define SHADOW_LAYER_COUNT 2
+#define SHADOW_RAY_COUNT 128
// The total number of all the vertices representing the shadow.
-#define SHADOW_VERTEX_COUNT ((SHADOW_LAYER_COUNT + 1) * SHADOW_RAY_COUNT + 1)
+#define SHADOW_VERTEX_COUNT (2 * SHADOW_RAY_COUNT + 1)
// The total number of indices used for drawing the shadow geometry as triangle strips.
-#define SHADOW_INDEX_COUNT (2 * SHADOW_RAY_COUNT + 1 + 2 * (SHADOW_RAY_COUNT + 1) * \
- SHADOW_LAYER_COUNT)
+#define SHADOW_INDEX_COUNT (2 * SHADOW_RAY_COUNT + 1 + 2 * (SHADOW_RAY_COUNT + 1))
+
+#define SHADOW_MIN_CASTER_Z 0.001f
class ShadowTessellator {
public:
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index 22d735b..8538b29 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -29,45 +29,46 @@
namespace android {
namespace uirenderer {
+static const double EPSILON = 1e-7;
+
/**
- * Calculate the intersection of a ray with a polygon.
- * It assumes the ray originates inside the polygon.
+ * Calculate the angle between and x and a y coordinate.
+ * The atan2 range from -PI to PI.
+ */
+static float angle(const Vector2& point, const Vector2& center) {
+ return atan2(point.y - center.y, point.x - center.x);
+}
+
+/**
+ * Calculate the intersection of a ray with the line segment defined by two points.
*
- * @param poly The polygon, which is represented in a Vector2 array.
- * @param polyLength The length of caster's polygon in terms of number of
- * vertices.
- * @param point the start of the ray
- * @param dx the x vector of the ray
- * @param dy the y vector of the ray
- * @return the distance along the ray if it intersects with the polygon FP_NAN if otherwise
+ * Returns a negative value in error conditions.
+
+ * @param rayOrigin The start of the ray
+ * @param dx The x vector of the ray
+ * @param dy The y vector of the ray
+ * @param p1 The first point defining the line segment
+ * @param p2 The second point defining the line segment
+ * @return The distance along the ray if it intersects with the line segment, negative if otherwise
*/
-float SpotShadow::rayIntersectPoly(const Vector2* poly, int polyLength,
- const Vector2& point, float dx, float dy) {
- double px = point.x;
- double py = point.y;
- int p1 = polyLength - 1;
- for (int p2 = 0; p2 < polyLength; p2++) {
- double p1x = poly[p1].x;
- double p1y = poly[p1].y;
- double p2x = poly[p2].x;
- double p2y = poly[p2].y;
- // The math below is derived from solving this formula, basically the
- // intersection point should stay on both the ray and the edge of (p1, p2).
- // solve([p1x+t*(p2x-p1x)=dx*t2+px,p1y+t*(p2y-p1y)=dy*t2+py],[t,t2]);
- double div = (dx * (p1y - p2y) + dy * p2x - dy * p1x);
- if (div != 0) {
- double t = (dx * (p1y - py) + dy * px - dy * p1x) / (div);
- if (t >= 0 && t <= 1) {
- double t2 = (p1x * (py - p2y) + p2x * (p1y - py) +
- px * (p2y - p1y)) / div;
- if (t2 > 0) {
- return (float)t2;
- }
- }
- }
- p1 = p2;
- }
- return FP_NAN;
+static float rayIntersectPoints(const Vector2& rayOrigin, float dx, float dy,
+ const Vector2& p1, const Vector2& p2) {
+ // The math below is derived from solving this formula, basically the
+ // intersection point should stay on both the ray and the edge of (p1, p2).
+ // solve([p1x+t*(p2x-p1x)=dx*t2+px,p1y+t*(p2y-p1y)=dy*t2+py],[t,t2]);
+
+ double divisor = (dx * (p1.y - p2.y) + dy * p2.x - dy * p1.x);
+ if (divisor == 0) return -1.0f; // error, invalid divisor
+
+#if DEBUG_SHADOW
+ double interpVal = (dx * (p1.y - rayOrigin.y) + dy * rayOrigin.x - dy * p1.x) / divisor;
+ if (interpVal < 0 || interpVal > 1) return -1.0f; // error, doesn't intersect between points
+#endif
+
+ double distance = (p1.x * (rayOrigin.y - p2.y) + p2.x * (p1.y - rayOrigin.y) +
+ rayOrigin.x * (p2.y - p1.y)) / divisor;
+
+ return distance; // may be negative in error cases
}
/**
@@ -131,30 +132,26 @@ int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) {
lLowerSize--;
}
}
- int count = 0;
+ // output points in CW ordering
+ const int total = lUpperSize + lLowerSize - 2;
+ int outIndex = total - 1;
for (int i = 0; i < lUpperSize; i++) {
- retPoly[count] = lUpper[i];
- count++;
+ retPoly[outIndex] = lUpper[i];
+ outIndex--;
}
for (int i = 1; i < lLowerSize - 1; i++) {
- retPoly[count] = lLower[i];
- count++;
+ retPoly[outIndex] = lLower[i];
+ outIndex--;
}
// TODO: Add test harness which verify that all the points are inside the hull.
- return count;
+ return total;
}
/**
* Test whether the 3 points form a counter clockwise turn.
*
- * @param ax the x coordinate of point a
- * @param ay the y coordinate of point a
- * @param bx the x coordinate of point b
- * @param by the y coordinate of point b
- * @param cx the x coordinate of point c
- * @param cy the y coordinate of point c
* @return true if a right hand turn
*/
bool SpotShadow::ccw(double ax, double ay, double bx, double by,
@@ -303,15 +300,6 @@ void SpotShadow::sort(Vector2* poly, int polyLength, const Vector2& center) {
}
/**
- * Calculate the angle between and x and a y coordinate.
- * The atan2 range from -PI to PI, if we want to sort the vertices as clockwise,
- * we just negate the return angle.
- */
-float SpotShadow::angle(const Vector2& point, const Vector2& center) {
- return -(float)atan2(point.y - center.y, point.x - center.x);
-}
-
-/**
* Swap points pointed to by i and j
*/
void SpotShadow::swap(Vector2* points, int i, int j) {
@@ -329,10 +317,10 @@ void SpotShadow::quicksortCirc(Vector2* points, int low, int high,
int p = low + (high - low) / 2;
float pivot = angle(points[p], center);
while (i <= j) {
- while (angle(points[i], center) < pivot) {
+ while (angle(points[i], center) > pivot) {
i++;
}
- while (angle(points[j], center) > pivot) {
+ while (angle(points[j], center) < pivot) {
j--;
}
@@ -508,8 +496,8 @@ void SpotShadow::computeLightPolygon(int points, const Vector3& lightCenter,
// TODO: Caching all the sin / cos values and store them in a look up table.
for (int i = 0; i < points; i++) {
double angle = 2 * i * M_PI / points;
- ret[i].x = sinf(angle) * size + lightCenter.x;
- ret[i].y = cosf(angle) * size + lightCenter.y;
+ ret[i].x = cosf(angle) * size + lightCenter.x;
+ ret[i].y = sinf(angle) * size + lightCenter.y;
ret[i].z = lightCenter.z;
}
}
@@ -560,14 +548,9 @@ void SpotShadow::computeSpotShadow(const Vector3* lightPoly, int lightPolyLength
// Validate input, receiver is always at z = 0 plane.
bool inputPolyPositionValid = true;
for (int i = 0; i < polyLength; i++) {
- if (poly[i].z <= 0.00001) {
- inputPolyPositionValid = false;
- ALOGE("polygon below the surface");
- break;
- }
if (poly[i].z >= lightPoly[0].z) {
inputPolyPositionValid = false;
- ALOGE("polygon above the light");
+ ALOGW("polygon above the light");
break;
}
}
@@ -657,6 +640,63 @@ void SpotShadow::computeSpotShadow(const Vector3* lightPoly, int lightPolyLength
}
/**
+ * Converts a polygon specified with CW vertices into an array of distance-from-centroid values.
+ *
+ * Returns false in error conditions
+ *
+ * @param poly Array of vertices. Note that these *must* be CW.
+ * @param polyLength The number of vertices in the polygon.
+ * @param polyCentroid The centroid of the polygon, from which rays will be cast
+ * @param rayDist The output array for the calculated distances, must be SHADOW_RAY_COUNT in size
+ */
+bool convertPolyToRayDist(const Vector2* poly, int polyLength, const Vector2& polyCentroid,
+ float* rayDist) {
+ const int rays = SHADOW_RAY_COUNT;
+ const float step = M_PI * 2 / rays;
+
+ const Vector2* lastVertex = &(poly[polyLength - 1]);
+ float startAngle = angle(*lastVertex, polyCentroid);
+
+ // Start with the ray that's closest to and less than startAngle
+ int rayIndex = floor((startAngle - EPSILON) / step);
+ rayIndex = (rayIndex + rays) % rays; // ensure positive
+
+ for (int polyIndex = 0; polyIndex < polyLength; polyIndex++) {
+ /*
+ * For a given pair of vertices on the polygon, poly[i-1] and poly[i], the rays that
+ * intersect these will be those that are between the two angles from the centroid that the
+ * vertices define.
+ *
+ * Because the polygon vertices are stored clockwise, the closest ray with an angle
+ * *smaller* than that defined by angle(poly[i], centroid) will be the first ray that does
+ * not intersect with poly[i-1], poly[i].
+ */
+ float currentAngle = angle(poly[polyIndex], polyCentroid);
+
+ // find first ray that will not intersect the line segment poly[i-1] & poly[i]
+ int firstRayIndexOnNextSegment = floor((currentAngle - EPSILON) / step);
+ firstRayIndexOnNextSegment = (firstRayIndexOnNextSegment + rays) % rays; // ensure positive
+
+ // Iterate through all rays that intersect with poly[i-1], poly[i] line segment.
+ // This may be 0 rays.
+ while (rayIndex != firstRayIndexOnNextSegment) {
+ float distanceToIntersect = rayIntersectPoints(polyCentroid,
+ cos(rayIndex * step),
+ sin(rayIndex * step),
+ *lastVertex, poly[polyIndex]);
+ if (distanceToIntersect < 0) return false; // error case, abort
+
+ rayDist[rayIndex] = distanceToIntersect;
+
+ rayIndex = (rayIndex - 1 + rays) % rays;
+ }
+ lastVertex = &poly[polyIndex];
+ }
+
+ return true;
+}
+
+/**
* Generate a triangle strip given two convex polygons
*
* @param penumbra The outer polygon x,y vertexes
@@ -669,10 +709,9 @@ void SpotShadow::computeSpotShadow(const Vector3* lightPoly, int lightPolyLength
void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
const Vector2* umbra, int umbraLength, VertexBuffer& shadowTriangleStrip) {
const int rays = SHADOW_RAY_COUNT;
- const int layers = SHADOW_LAYER_COUNT;
- int size = rays * (layers + 1);
- float step = M_PI * 2 / rays;
+ const int size = 2 * rays;
+ const float step = M_PI * 2 / rays;
// Centroid of the umbra.
Vector2 centroid = ShadowTessellator::centroid2d(umbra, umbraLength);
#if DEBUG_SHADOW
@@ -683,48 +722,31 @@ void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLeng
// Intersection to the umbra.
float umbraDistPerRay[rays];
- for (int i = 0; i < rays; i++) {
- // TODO: Setup a lookup table for all the sin/cos.
- float dx = sinf(step * i);
- float dy = cosf(step * i);
- umbraDistPerRay[i] = rayIntersectPoly(umbra, umbraLength, centroid,
- dx, dy);
- if (isnan(umbraDistPerRay[i])) {
- ALOGE("rayIntersectPoly returns NAN");
- return;
- }
- penumbraDistPerRay[i] = rayIntersectPoly(penumbra, penumbraLength,
- centroid, dx, dy);
- if (isnan(umbraDistPerRay[i])) {
- ALOGE("rayIntersectPoly returns NAN");
- return;
- }
- }
+ // convert CW polygons to ray distance encoding, aborting on conversion failure
+ if (!convertPolyToRayDist(umbra, umbraLength, centroid, umbraDistPerRay)) return;
+ if (!convertPolyToRayDist(penumbra, penumbraLength, centroid, penumbraDistPerRay)) return;
- int stripSize = getStripSize(rays, layers);
- AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(stripSize);
- int currentIndex = 0;
+ AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(getStripSize(rays));
// Calculate the vertices (x, y, alpha) in the shadow area.
- for (int layerIndex = 0; layerIndex <= layers; layerIndex++) {
- for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
- float dx = sinf(step * rayIndex);
- float dy = cosf(step * rayIndex);
- float layerRatio = layerIndex / (float) layers;
- float deltaDist = layerRatio *
- (umbraDistPerRay[rayIndex] - penumbraDistPerRay[rayIndex]);
- float currentDist = penumbraDistPerRay[rayIndex] + deltaDist;
- float op = calculateOpacity(layerRatio);
- AlphaVertex::set(&shadowVertices[currentIndex++],
- dx * currentDist + centroid.x, dy * currentDist + centroid.y, op);
- }
+ for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+ float dx = cosf(step * rayIndex);
+ float dy = sinf(step * rayIndex);
+
+ // outer ring
+ float currentDist = penumbraDistPerRay[rayIndex];
+ AlphaVertex::set(&shadowVertices[rayIndex],
+ dx * currentDist + centroid.x, dy * currentDist + centroid.y, 0.0f);
+
+ // inner ring
+ float deltaDist = umbraDistPerRay[rayIndex] - penumbraDistPerRay[rayIndex];
+ currentDist += deltaDist;
+ AlphaVertex::set(&shadowVertices[rays + rayIndex],
+ dx * currentDist + centroid.x, dy * currentDist + centroid.y, 1.0f);
}
// The centroid is in the umbra area, so the opacity is considered as 1.0.
- AlphaVertex::set(&shadowVertices[currentIndex++], centroid.x, centroid.y, 1.0);
+ AlphaVertex::set(&shadowVertices[SHADOW_VERTEX_COUNT - 1], centroid.x, centroid.y, 1.0f);
#if DEBUG_SHADOW
- if (currentIndex != SHADOW_VERTEX_COUNT) {
- ALOGE("number of vertex generated for spot shadow is wrong!");
- }
for (int i = 0; i < currentIndex; i++) {
ALOGD("spot shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
shadowVertices[i].y, shadowVertices[i].alpha);
@@ -754,26 +776,14 @@ void SpotShadow::smoothPolygon(int level, int rays, float* rayDist) {
}
/**
- * Calculate the opacity according to the distance. Ideally, the opacity is 1.0
- * in the umbra area, and fall off to 0.0 till the edge of penumbra area.
- *
- * @param layerRatio The distance ratio of current sample between umbra and penumbra area.
- * Penumbra edge is 0 and umbra edge is 1.
- * @return The opacity according to the distance between umbra and penumbra.
- */
-float SpotShadow::calculateOpacity(float layerRatio) {
- return (layerRatio * layerRatio + layerRatio) / 2.0;
-}
-
-/**
* Calculate the number of vertex we will create given a number of rays and layers
*
* @param rays number of points around the polygons you want
* @param layers number of layers of triangle strips you need
* @return number of vertex (multiply by 3 for number of floats)
*/
-int SpotShadow::getStripSize(int rays, int layers) {
- return (2 + rays + ((layers) * 2 * (rays + 1)));
+int SpotShadow::getStripSize(int rays) {
+ return (2 + rays + (2 * (rays + 1)));
}
#if DEBUG_SHADOW
@@ -898,7 +908,3 @@ void SpotShadow::testIntersection(const Vector2* poly1, int poly1Length,
}; // namespace uirenderer
}; // namespace android
-
-
-
-
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
index 6727eac..7839dc3 100644
--- a/libs/hwui/SpotShadow.h
+++ b/libs/hwui/SpotShadow.h
@@ -38,9 +38,8 @@ private:
static void computeLightPolygon(int points, const Vector3& lightCenter,
float size, Vector3* ret);
- static int getStripSize(int rays, int layers);
+ static int getStripSize(int rays);
static void smoothPolygon(int level, int rays, float* rayDist);
- static float calculateOpacity(float jf);
static float rayIntersectPoly(const Vector2* poly, int polyLength,
const Vector2& point, float dx, float dy);
@@ -50,7 +49,6 @@ private:
static int intersection(Vector2* poly1, int poly1length, Vector2* poly2, int poly2length);
static void sort(Vector2* poly, int polyLength, const Vector2& center);
- static float angle(const Vector2& point, const Vector2& center);
static void swap(Vector2* points, int i, int j);
static void quicksortCirc(Vector2* points, int low, int high, const Vector2& center);
static void quicksortX(Vector2* points, int low, int high);
@@ -65,8 +63,6 @@ private:
static void generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
const Vector2* umbra, int umbraLength, VertexBuffer& retstrips);
- static const double EPSILON = 1e-7;
-
#if DEBUG_SHADOW
// Verification utility function.
static bool testConvex(const Vector2* polygon, int polygonLength,
diff --git a/libs/hwui/Vector.h b/libs/hwui/Vector.h
index 15b9d6b..c61cb61 100644
--- a/libs/hwui/Vector.h
+++ b/libs/hwui/Vector.h
@@ -124,6 +124,10 @@ public:
Vector3(float px, float py, float pz) :
x(px), y(py), z(pz) {
}
+
+ void dump() {
+ ALOGD("Vector3[%.2f, %.2f, %.2f]", x, y, z);
+ }
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index ce66d8f..5ed9f1d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -373,7 +373,7 @@ void CanvasContext::setup(int width, int height) {
mCanvas->setViewport(width, height);
}
-void CanvasContext::setDisplayListData(DisplayList* displayList, DisplayListData* newData) {
+void CanvasContext::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
displayList->setData(newData);
}
@@ -388,7 +388,7 @@ void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* lay
}
}
-void CanvasContext::drawDisplayList(DisplayList* displayList, Rect* dirty) {
+void CanvasContext::drawDisplayList(RenderNode* displayList, Rect* dirty) {
LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
"drawDisplayList called on a context with no canvas or surface!");
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 649ffb6..e3fdf97 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -31,7 +31,7 @@ namespace android {
namespace uirenderer {
class DeferredLayerUpdater;
-class DisplayList;
+class RenderNode;
class DisplayListData;
class OpenGLRenderer;
class Rect;
@@ -63,9 +63,9 @@ public:
bool initialize(EGLNativeWindowType window);
void updateSurface(EGLNativeWindowType window);
void setup(int width, int height);
- void setDisplayListData(DisplayList* displayList, DisplayListData* newData);
+ void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters);
- void drawDisplayList(DisplayList* displayList, Rect* dirty);
+ void drawDisplayList(RenderNode* displayList, Rect* dirty);
void destroyCanvas();
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 200c21f..93360fc 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -117,13 +117,13 @@ void RenderProxy::setup(int width, int height) {
post(task);
}
-CREATE_BRIDGE3(setDisplayListData, CanvasContext* context, DisplayList* displayList,
+CREATE_BRIDGE3(setDisplayListData, CanvasContext* context, RenderNode* displayList,
DisplayListData* newData) {
args->context->setDisplayListData(args->displayList, args->newData);
return NULL;
}
-void RenderProxy::setDisplayListData(DisplayList* displayList, DisplayListData* newData) {
+void RenderProxy::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
SETUP_TASK(setDisplayListData);
args->context = mContext;
args->displayList = displayList;
@@ -131,7 +131,7 @@ void RenderProxy::setDisplayListData(DisplayList* displayList, DisplayListData*
post(task);
}
-CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, DisplayList* displayList,
+CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, RenderNode* displayList,
Rect dirty, const Vector<DeferredLayerUpdater*>* layerUpdates) {
Rect* dirty = &args->dirty;
if (dirty->bottom == -1 && dirty->left == -1 &&
@@ -143,7 +143,7 @@ CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, DisplayList* displayList
return NULL;
}
-void RenderProxy::drawDisplayList(DisplayList* displayList,
+void RenderProxy::drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom) {
SETUP_TASK(drawDisplayList);
args->context = mContext;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 83a8a8f..73e9805 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -32,7 +32,7 @@ namespace android {
namespace uirenderer {
class DeferredLayerUpdater;
-class DisplayList;
+class RenderNode;
class DisplayListData;
class Layer;
class Rect;
@@ -60,8 +60,8 @@ public:
ANDROID_API bool initialize(EGLNativeWindowType window);
ANDROID_API void updateSurface(EGLNativeWindowType window);
ANDROID_API void setup(int width, int height);
- ANDROID_API void setDisplayListData(DisplayList* displayList, DisplayListData* newData);
- ANDROID_API void drawDisplayList(DisplayList* displayList,
+ ANDROID_API void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
+ ANDROID_API void drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
ANDROID_API void destroyCanvas();
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index cc464db..2ddbb7d 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -16,15 +16,19 @@
package android.mtp;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContentValues;
import android.content.IContentProvider;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaScanner;
import android.net.Uri;
+import android.os.BatteryManager;
+import android.os.BatteryStats;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;
@@ -113,11 +117,35 @@ public class MtpDatabase {
+ Files.FileColumns.PARENT + "=?";
private final MediaScanner mMediaScanner;
+ private MtpServer mServer;
+
+ // read from native code
+ private int mBatteryLevel;
+ private int mBatteryScale;
static {
System.loadLibrary("media_jni");
}
+ private BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ mBatteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
+ int newLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ if (newLevel != mBatteryLevel) {
+ mBatteryLevel = newLevel;
+ if (mServer != null) {
+ // send device property changed event
+ mServer.sendDevicePropertyChanged(
+ MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL);
+ }
+ }
+ }
+ }
+ };
+
public MtpDatabase(Context context, String volumeName, String storagePath,
String[] subDirectories) {
native_setup();
@@ -171,6 +199,18 @@ public class MtpDatabase {
initDeviceProperties(context);
}
+ public void setServer(MtpServer server) {
+ mServer = server;
+
+ // register for battery notifications when we are connected
+ if (server != null) {
+ mContext.registerReceiver(mBatteryReceiver,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ } else {
+ mContext.unregisterReceiver(mBatteryReceiver);
+ }
+ }
+
@Override
protected void finalize() throws Throwable {
try {
@@ -663,6 +703,7 @@ public class MtpDatabase {
MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,
MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,
MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE,
+ MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL,
};
}
@@ -819,6 +860,8 @@ public class MtpDatabase {
outStringValue[imageSize.length()] = 0;
return MtpConstants.RESPONSE_OK;
+ // DEVICE_PROPERTY_BATTERY_LEVEL is implemented in the JNI code
+
default:
return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
}
diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java
index 266f78e..3814630 100644
--- a/media/java/android/mtp/MtpServer.java
+++ b/media/java/android/mtp/MtpServer.java
@@ -30,6 +30,7 @@ public class MtpServer implements Runnable {
public MtpServer(MtpDatabase database, boolean usePtp) {
native_setup(database, usePtp);
+ database.setServer(this);
}
public void start() {
@@ -51,6 +52,10 @@ public class MtpServer implements Runnable {
native_send_object_removed(handle);
}
+ public void sendDevicePropertyChanged(int property) {
+ native_send_device_property_changed(property);
+ }
+
public void addStorage(MtpStorage storage) {
native_add_storage(storage);
}
@@ -64,6 +69,7 @@ public class MtpServer implements Runnable {
private native final void native_cleanup();
private native final void native_send_object_added(int handle);
private native final void native_send_object_removed(int handle);
+ private native final void native_send_device_property_changed(int property);
private native final void native_add_storage(MtpStorage storage);
private native final void native_remove_storage(int storageId);
}
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 6b0bd0d..ea75a18 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -68,6 +68,8 @@ static jmethodID method_sessionStarted;
static jmethodID method_sessionEnded;
static jfieldID field_context;
+static jfieldID field_batteryLevel;
+static jfieldID field_batteryScale;
// MtpPropertyList fields
static jfieldID field_mCount;
@@ -527,68 +529,75 @@ MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
MtpDataPacket& packet) {
- int type;
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (!getDevicePropertyInfo(property, type))
- return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+ if (property == MTP_DEVICE_PROPERTY_BATTERY_LEVEL) {
+ // special case - implemented here instead of Java
+ packet.putUInt8((uint8_t)env->GetIntField(mDatabase, field_batteryLevel));
+ return MTP_RESPONSE_OK;
+ } else {
+ int type;
+
+ if (!getDevicePropertyInfo(property, type))
+ return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+
+ jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
+ (jint)property, mLongBuffer, mStringBuffer);
+ if (result != MTP_RESPONSE_OK) {
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return result;
+ }
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
- (jint)property, mLongBuffer, mStringBuffer);
- if (result != MTP_RESPONSE_OK) {
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
- return result;
- }
+ jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
+ jlong longValue = longValues[0];
+ env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
- jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
- jlong longValue = longValues[0];
- env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
+ switch (type) {
+ case MTP_TYPE_INT8:
+ packet.putInt8(longValue);
+ break;
+ case MTP_TYPE_UINT8:
+ packet.putUInt8(longValue);
+ break;
+ case MTP_TYPE_INT16:
+ packet.putInt16(longValue);
+ break;
+ case MTP_TYPE_UINT16:
+ packet.putUInt16(longValue);
+ break;
+ case MTP_TYPE_INT32:
+ packet.putInt32(longValue);
+ break;
+ case MTP_TYPE_UINT32:
+ packet.putUInt32(longValue);
+ break;
+ case MTP_TYPE_INT64:
+ packet.putInt64(longValue);
+ break;
+ case MTP_TYPE_UINT64:
+ packet.putUInt64(longValue);
+ break;
+ case MTP_TYPE_INT128:
+ packet.putInt128(longValue);
+ break;
+ case MTP_TYPE_UINT128:
+ packet.putInt128(longValue);
+ break;
+ case MTP_TYPE_STR:
+ {
+ jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
+ packet.putString(str);
+ env->ReleaseCharArrayElements(mStringBuffer, str, 0);
+ break;
+ }
+ default:
+ ALOGE("unsupported type in getDevicePropertyValue\n");
+ return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
+ }
- switch (type) {
- case MTP_TYPE_INT8:
- packet.putInt8(longValue);
- break;
- case MTP_TYPE_UINT8:
- packet.putUInt8(longValue);
- break;
- case MTP_TYPE_INT16:
- packet.putInt16(longValue);
- break;
- case MTP_TYPE_UINT16:
- packet.putUInt16(longValue);
- break;
- case MTP_TYPE_INT32:
- packet.putInt32(longValue);
- break;
- case MTP_TYPE_UINT32:
- packet.putUInt32(longValue);
- break;
- case MTP_TYPE_INT64:
- packet.putInt64(longValue);
- break;
- case MTP_TYPE_UINT64:
- packet.putUInt64(longValue);
- break;
- case MTP_TYPE_INT128:
- packet.putInt128(longValue);
- break;
- case MTP_TYPE_UINT128:
- packet.putInt128(longValue);
- break;
- case MTP_TYPE_STR:
- {
- jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
- packet.putString(str);
- env->ReleaseCharArrayElements(mStringBuffer, str, 0);
- break;
- }
- default:
- ALOGE("unsupported type in getDevicePropertyValue\n");
- return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return MTP_RESPONSE_OK;
}
-
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
- return MTP_RESPONSE_OK;
}
MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
@@ -923,6 +932,7 @@ static const PropertyTableEntry kDevicePropertyTable[] = {
{ MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR },
{ MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
{ MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
+ { MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 },
};
bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
@@ -1046,7 +1056,7 @@ MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
writable = true;
// fall through
- case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
+ case MTP_DEVICE_PROPERTY_IMAGE_SIZE: {
result = new MtpProperty(property, MTP_TYPE_STR, writable);
// get current value
@@ -1063,6 +1073,12 @@ MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
ALOGE("unable to read device property, response: %04X", ret);
}
break;
+ }
+ case MTP_DEVICE_PROPERTY_BATTERY_LEVEL:
+ result = new MtpProperty(property, MTP_TYPE_UINT8);
+ result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1);
+ result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel);
+ break;
}
checkAndClearExceptionFromCallback(env, __FUNCTION__);
@@ -1234,6 +1250,16 @@ int register_android_mtp_MtpDatabase(JNIEnv *env)
ALOGE("Can't find MtpDatabase.mNativeContext");
return -1;
}
+ field_batteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
+ if (field_batteryLevel == NULL) {
+ ALOGE("Can't find MtpDatabase.mBatteryLevel");
+ return -1;
+ }
+ field_batteryScale = env->GetFieldID(clazz, "mBatteryScale", "I");
+ if (field_batteryScale == NULL) {
+ ALOGE("Can't find MtpDatabase.mBatteryScale");
+ return -1;
+ }
// now set up fields for MtpPropertyList class
clazz = env->FindClass("android/mtp/MtpPropertyList");
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp
index 9d7f1c2..2f90dfe 100644
--- a/media/jni/android_mtp_MtpServer.cpp
+++ b/media/jni/android_mtp_MtpServer.cpp
@@ -118,6 +118,18 @@ android_mtp_MtpServer_send_object_removed(JNIEnv *env, jobject thiz, jint handle
}
static void
+android_mtp_MtpServer_send_device_property_changed(JNIEnv *env, jobject thiz, jint property)
+{
+ Mutex::Autolock autoLock(sMutex);
+
+ MtpServer* server = getMtpServer(env, thiz);
+ if (server)
+ server->sendDevicePropertyChanged(property);
+ else
+ ALOGE("server is null in send_object_removed");
+}
+
+static void
android_mtp_MtpServer_add_storage(JNIEnv *env, jobject thiz, jobject jstorage)
{
Mutex::Autolock autoLock(sMutex);
@@ -174,6 +186,8 @@ static JNINativeMethod gMethods[] = {
{"native_cleanup", "()V", (void *)android_mtp_MtpServer_cleanup},
{"native_send_object_added", "(I)V", (void *)android_mtp_MtpServer_send_object_added},
{"native_send_object_removed", "(I)V", (void *)android_mtp_MtpServer_send_object_removed},
+ {"native_send_device_property_changed", "(I)V",
+ (void *)android_mtp_MtpServer_send_device_property_changed},
{"native_add_storage", "(Landroid/mtp/MtpStorage;)V",
(void *)android_mtp_MtpServer_add_storage},
{"native_remove_storage", "(I)V", (void *)android_mtp_MtpServer_remove_storage},
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index eb07d88..a89921f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -931,6 +931,7 @@ public abstract class BaseStatusBar extends SystemUI implements
}
if (contentViewLocal != null) {
+ contentViewLocal.setIsRootNamespace(true);
SizeAdaptiveLayout.LayoutParams params =
new SizeAdaptiveLayout.LayoutParams(contentViewLocal.getLayoutParams());
params.minHeight = minHeight;
@@ -938,6 +939,7 @@ public abstract class BaseStatusBar extends SystemUI implements
expanded.addView(contentViewLocal, params);
}
if (bigContentViewLocal != null) {
+ bigContentViewLocal.setIsRootNamespace(true);
SizeAdaptiveLayout.LayoutParams params =
new SizeAdaptiveLayout.LayoutParams(bigContentViewLocal.getLayoutParams());
params.minHeight = minHeight+1;
@@ -955,6 +957,7 @@ public abstract class BaseStatusBar extends SystemUI implements
expandedPublic, mOnClickHandler);
if (publicViewLocal != null) {
+ publicViewLocal.setIsRootNamespace(true);
SizeAdaptiveLayout.LayoutParams params =
new SizeAdaptiveLayout.LayoutParams(publicViewLocal.getLayoutParams());
params.minHeight = minHeight;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index bda0183..9de3efe 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -426,8 +426,10 @@ class AlarmManagerService extends SystemService {
final Pair<String, ComponentName> mTarget;
final BroadcastStats mBroadcastStats;
final FilterStats mFilterStats;
+ final int mAlarmType;
- InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource) {
+ InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource,
+ int alarmType) {
mPendingIntent = pendingIntent;
mWorkSource = workSource;
Intent intent = pendingIntent.getIntent();
@@ -441,6 +443,7 @@ class AlarmManagerService extends SystemService {
mBroadcastStats.filterStats.put(mTarget, fs);
}
mFilterStats = fs;
+ mAlarmType = alarmType;
}
}
@@ -1280,17 +1283,12 @@ class AlarmManagerService extends SystemService {
// we have an active broadcast so stay awake.
if (mBroadcastRefCount == 0) {
- setWakelockWorkSource(alarm.operation, alarm.workSource);
- mWakeLock.setUnimportantForLogging(
- alarm.operation == mTimeTickSender);
- mWakeLock.setHistoryTag(alarm.operation.getTag(
- alarm.type == ELAPSED_REALTIME_WAKEUP
- || alarm.type == RTC_WAKEUP
- ? "*walarm*:" : "*alarm*:"));
+ setWakelockWorkSource(alarm.operation, alarm.workSource,
+ alarm.type, true);
mWakeLock.acquire();
}
final InFlight inflight = new InFlight(AlarmManagerService.this,
- alarm.operation, alarm.workSource);
+ alarm.operation, alarm.workSource, alarm.type);
mInFlight.add(inflight);
mBroadcastRefCount++;
@@ -1345,9 +1343,17 @@ class AlarmManagerService extends SystemService {
* @param pi PendingIntent to attribute blame to if ws is null.
* @param ws WorkSource to attribute blame.
*/
- void setWakelockWorkSource(PendingIntent pi, WorkSource ws) {
+ void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, boolean first) {
try {
+ mWakeLock.setUnimportantForLogging(pi == mTimeTickSender);
if (ws != null) {
+ if (first) {
+ mWakeLock.setHistoryTag(pi.getTag(
+ type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP
+ ? "*walarm*:" : "*alarm*:"));
+ } else {
+ mWakeLock.setHistoryTag(null);
+ }
mWakeLock.setWorkSource(ws);
return;
}
@@ -1355,6 +1361,7 @@ class AlarmManagerService extends SystemService {
final int uid = ActivityManagerNative.getDefault()
.getUidForIntentSender(pi.getTarget());
if (uid >= 0) {
+ mWakeLock.setHistoryTag(null);
mWakeLock.setWorkSource(new WorkSource(uid));
return;
}
@@ -1579,7 +1586,8 @@ class AlarmManagerService extends SystemService {
// the next of our alarms is now in flight. reattribute the wakelock.
if (mInFlight.size() > 0) {
InFlight inFlight = mInFlight.get(0);
- setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource);
+ setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource,
+ inFlight.mAlarmType, false);
} else {
// should never happen
mLog.w("Alarm wakelock still held but sent queue empty");
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 39bfc23..3414daf 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -29,6 +29,7 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.Process;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.telephony.SignalStrength;
@@ -133,14 +134,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
boolean unimportantForLogging) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging);
+ mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging,
+ SystemClock.elapsedRealtime());
}
}
public void noteStopWakelock(int uid, int pid, String name, int type) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteStopWakeLocked(uid, pid, name, type);
+ mStats.noteStopWakeLocked(uid, pid, name, type, SystemClock.elapsedRealtime());
}
}
@@ -153,6 +155,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
}
+ public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name, int type,
+ WorkSource newWs, int newPid, String newName,
+ String newHistoryName, int newType, boolean newUnimportantForLogging) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, type,
+ newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
+ }
+ }
+
public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, int type) {
enforceCallingPermission();
synchronized (mStats) {
diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java
index 12d51aa..6d3702a 100644
--- a/services/core/java/com/android/server/power/DisplayPowerController.java
+++ b/services/core/java/com/android/server/power/DisplayPowerController.java
@@ -479,7 +479,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
&& mProximity == PROXIMITY_POSITIVE) {
mScreenOffBecauseOfProximity = true;
sendOnProximityPositiveWithWakelock();
- setScreenOn(false);
}
} else if (mWaitingForNegativeProximity
&& mScreenOffBecauseOfProximity
@@ -544,59 +543,62 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mUsingScreenAutoBrightness = false;
}
- // Animate the screen on or off.
- if (!mScreenOffBecauseOfProximity) {
- if (mPowerRequest.wantScreenOnAny()) {
- // Want screen on.
- // Wait for previous off animation to complete beforehand.
- // It is relatively short but if we cancel it and switch to the
- // on animation immediately then the results are pretty ugly.
- if (!mElectronBeamOffAnimator.isStarted()) {
- // Turn the screen on. The contents of the screen may not yet
- // be visible if the electron beam has not been dismissed because
- // its last frame of animation is solid black.
- setScreenOn(true);
-
- if (mPowerRequest.blockScreenOn
- && mPowerState.getElectronBeamLevel() == 0.0f) {
- blockScreenOn();
- } else {
- unblockScreenOn();
- if (USE_ELECTRON_BEAM_ON_ANIMATION) {
- if (!mElectronBeamOnAnimator.isStarted()) {
- if (mPowerState.getElectronBeamLevel() == 1.0f) {
- mPowerState.dismissElectronBeam();
- } else if (mPowerState.prepareElectronBeam(
- mElectronBeamFadesConfig ?
- ElectronBeam.MODE_FADE :
- ElectronBeam.MODE_WARM_UP)) {
- mElectronBeamOnAnimator.start();
- } else {
- mElectronBeamOnAnimator.end();
- }
+ // Animate the screen on or off unless blocked.
+ if (mScreenOffBecauseOfProximity) {
+ // Screen off due to proximity.
+ setScreenOn(false);
+ unblockScreenOn();
+ } else if (mPowerRequest.wantScreenOnAny()) {
+ // Want screen on.
+ // Wait for previous off animation to complete beforehand.
+ // It is relatively short but if we cancel it and switch to the
+ // on animation immediately then the results are pretty ugly.
+ if (!mElectronBeamOffAnimator.isStarted()) {
+ // Turn the screen on. The contents of the screen may not yet
+ // be visible if the electron beam has not been dismissed because
+ // its last frame of animation is solid black.
+ setScreenOn(true);
+
+ if (mPowerRequest.blockScreenOn
+ && mPowerState.getElectronBeamLevel() == 0.0f) {
+ blockScreenOn();
+ } else {
+ unblockScreenOn();
+ if (USE_ELECTRON_BEAM_ON_ANIMATION) {
+ if (!mElectronBeamOnAnimator.isStarted()) {
+ if (mPowerState.getElectronBeamLevel() == 1.0f) {
+ mPowerState.dismissElectronBeam();
+ } else if (mPowerState.prepareElectronBeam(
+ mElectronBeamFadesConfig ?
+ ElectronBeam.MODE_FADE :
+ ElectronBeam.MODE_WARM_UP)) {
+ mElectronBeamOnAnimator.start();
+ } else {
+ mElectronBeamOnAnimator.end();
}
- } else {
- mPowerState.setElectronBeamLevel(1.0f);
- mPowerState.dismissElectronBeam();
}
+ } else {
+ mPowerState.setElectronBeamLevel(1.0f);
+ mPowerState.dismissElectronBeam();
}
}
- } else {
- // Want screen off.
- // Wait for previous on animation to complete beforehand.
- if (!mElectronBeamOnAnimator.isStarted()) {
- if (!mElectronBeamOffAnimator.isStarted()) {
- if (mPowerState.getElectronBeamLevel() == 0.0f) {
- setScreenOn(false);
- } else if (mPowerState.prepareElectronBeam(
- mElectronBeamFadesConfig ?
- ElectronBeam.MODE_FADE :
- ElectronBeam.MODE_COOL_DOWN)
- && mPowerState.isScreenOn()) {
- mElectronBeamOffAnimator.start();
- } else {
- mElectronBeamOffAnimator.end();
- }
+ }
+ } else {
+ // Want screen off.
+ // Wait for previous on animation to complete beforehand.
+ unblockScreenOn();
+ if (!mElectronBeamOnAnimator.isStarted()) {
+ if (!mElectronBeamOffAnimator.isStarted()) {
+ if (mPowerState.getElectronBeamLevel() == 0.0f) {
+ setScreenOn(false);
+ } else if (mPowerState.prepareElectronBeam(
+ mElectronBeamFadesConfig ?
+ ElectronBeam.MODE_FADE :
+ ElectronBeam.MODE_COOL_DOWN)
+ && mPowerState.isScreenOn()) {
+ mElectronBeamOffAnimator.start();
+ } else {
+ mElectronBeamOffAnimator.end();
}
}
}
@@ -641,15 +643,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private void unblockScreenOn() {
if (mScreenOnWasBlocked) {
mScreenOnWasBlocked = false;
- if (DEBUG) {
- Slog.d(TAG, "Unblocked screen on after " +
- (SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime) + " ms");
+ long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
+ if (delay > 1000 || DEBUG) {
+ Slog.d(TAG, "Unblocked screen on after " + delay + " ms");
}
}
}
private void setScreenOn(boolean on) {
- if (!mPowerState.isScreenOn() == on) {
+ if (mPowerState.isScreenOn() != on) {
mPowerState.setScreenOn(on);
if (on) {
mNotifier.onScreenOn();
diff --git a/services/core/java/com/android/server/power/DisplayPowerState.java b/services/core/java/com/android/server/power/DisplayPowerState.java
index 42af4b4..8e331ad 100644
--- a/services/core/java/com/android/server/power/DisplayPowerState.java
+++ b/services/core/java/com/android/server/power/DisplayPowerState.java
@@ -304,8 +304,15 @@ final class DisplayPowerState {
int brightness = mScreenOn && mElectronBeamLevel > 0f ? mScreenBrightness : 0;
if (mPhotonicModulator.setState(mScreenOn, brightness)) {
+ if (DEBUG) {
+ Slog.d(TAG, "Screen ready");
+ }
mScreenReady = true;
invokeCleanListenerIfNeeded();
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, "Screen not ready");
+ }
}
}
};
@@ -355,7 +362,7 @@ final class DisplayPowerState {
AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask);
}
}
- return mChangeInProgress;
+ return !mChangeInProgress;
}
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index e1ccf46..df06bae 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -158,6 +158,39 @@ final class Notifier {
}
/**
+ * Called when a wake lock is changing.
+ */
+ public void onWakeLockChanging(int flags, String tag, String packageName,
+ int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
+ int newFlags, String newTag, String newPackageName, int newOwnerUid,
+ int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
+
+ final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+ final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
+ boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
+ && ownerUid == Process.SYSTEM_UID;
+ if (workSource != null && newWorkSource != null) {
+ if (DEBUG) {
+ Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+ + "\", packageName=" + newPackageName
+ + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
+ + ", workSource=" + newWorkSource);
+ }
+ try {
+ mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, monitorType,
+ newWorkSource, newOwnerPid, newTag, newHistoryTag,
+ newMonitorType, unimportantForLogging);
+ } catch (RemoteException ex) {
+ // Ignore
+ }
+ } else {
+ onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource);
+ onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
+ newWorkSource, newHistoryTag);
+ }
+ }
+
+ /**
* Called when a wake lock is released.
*/
public void onWakeLockReleased(int flags, String tag, String packageName,
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index e7bbf1c..e0a46b9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -646,9 +646,9 @@ public final class PowerManagerService extends com.android.server.SystemService
wakeLock = mWakeLocks.get(index);
if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
// Update existing wake lock. This shouldn't happen but is harmless.
- notifyWakeLockReleasedLocked(wakeLock);
+ notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,
+ uid, pid, ws, historyTag);
wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);
- notifyWakeLockAcquiredLocked(wakeLock);
}
} else {
wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);
@@ -765,9 +765,10 @@ public final class PowerManagerService extends com.android.server.SystemService
}
if (!wakeLock.hasSameWorkSource(ws)) {
- notifyWakeLockReleasedLocked(wakeLock);
+ notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag,
+ wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
+ ws, wakeLock.mHistoryTag);
wakeLock.updateWorkSource(ws);
- notifyWakeLockAcquiredLocked(wakeLock);
}
}
}
@@ -791,6 +792,15 @@ public final class PowerManagerService extends com.android.server.SystemService
}
}
+ private void notifyWakeLockChangingLocked(WakeLock wakeLock, int flags, String tag,
+ String packageName, int uid, int pid, WorkSource ws, String historyTag) {
+ if (mSystemReady && wakeLock.mNotifiedAcquired) {
+ mNotifier.onWakeLockChanging(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
+ wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
+ wakeLock.mHistoryTag, flags, tag, packageName, uid, pid, ws, historyTag);
+ }
+ }
+
private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
if (mSystemReady && wakeLock.mNotifiedAcquired) {
wakeLock.mNotifiedAcquired = false;
@@ -1037,6 +1047,9 @@ public final class PowerManagerService extends com.android.server.SystemService
if (!mSystemReady || mDirty == 0) {
return;
}
+ if (!Thread.holdsLock(mLock)) {
+ Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
+ }
// Phase 0: Basic state updates.
updateIsPoweredLocked(mDirty);