Merge "More lint checks." into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index f7a316d..f1647d0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26859,7 +26859,8 @@
method public static void glGetSynciv(long, int, int, int[], int, int[], int);
method public static void glGetSynciv(long, int, int, java.nio.IntBuffer, java.nio.IntBuffer);
method public static void glGetTransformFeedbackVarying(int, int, int, int[], int, int[], int, int[], int, byte[], int);
- method public static void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
+ method public static deprecated void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
+ method public static void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.ByteBuffer);
method public static java.lang.String glGetTransformFeedbackVarying(int, int, int[], int, int[], int);
method public static java.lang.String glGetTransformFeedbackVarying(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
method public static int glGetUniformBlockIndex(int, java.lang.String);
@@ -36419,6 +36420,7 @@
public class TelecomManager {
method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
method public void cancelMissedCallsNotification();
+ method public android.content.Intent createManageBlockedNumbersIntent();
method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
method public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts();
method public java.lang.String getDefaultDialerPackage();
diff --git a/api/system-current.txt b/api/system-current.txt
index b2b5982..61a8953 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -29161,7 +29161,8 @@
method public static void glGetSynciv(long, int, int, int[], int, int[], int);
method public static void glGetSynciv(long, int, int, java.nio.IntBuffer, java.nio.IntBuffer);
method public static void glGetTransformFeedbackVarying(int, int, int, int[], int, int[], int, int[], int, byte[], int);
- method public static void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
+ method public static deprecated void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
+ method public static void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.ByteBuffer);
method public static java.lang.String glGetTransformFeedbackVarying(int, int, int[], int, int[], int);
method public static java.lang.String glGetTransformFeedbackVarying(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
method public static int glGetUniformBlockIndex(int, java.lang.String);
@@ -39118,6 +39119,7 @@
method public void cancelMissedCallsNotification();
method public deprecated void clearAccounts();
method public void clearPhoneAccounts();
+ method public android.content.Intent createManageBlockedNumbersIntent();
method public java.util.List<android.telecom.ParcelableCallAnalytics> dumpAnalytics();
method public void enablePhoneAccount(android.telecom.PhoneAccountHandle, boolean);
method public boolean endCall();
diff --git a/api/test-current.txt b/api/test-current.txt
index 472daf6..d2d470b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -26868,7 +26868,8 @@
method public static void glGetSynciv(long, int, int, int[], int, int[], int);
method public static void glGetSynciv(long, int, int, java.nio.IntBuffer, java.nio.IntBuffer);
method public static void glGetTransformFeedbackVarying(int, int, int, int[], int, int[], int, int[], int, byte[], int);
- method public static void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
+ method public static deprecated void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
+ method public static void glGetTransformFeedbackVarying(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.ByteBuffer);
method public static java.lang.String glGetTransformFeedbackVarying(int, int, int[], int, int[], int);
method public static java.lang.String glGetTransformFeedbackVarying(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
method public static int glGetUniformBlockIndex(int, java.lang.String);
@@ -36434,6 +36435,7 @@
public class TelecomManager {
method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
method public void cancelMissedCallsNotification();
+ method public android.content.Intent createManageBlockedNumbersIntent();
method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
method public java.util.List<android.telecom.PhoneAccountHandle> getCallCapablePhoneAccounts();
method public java.lang.String getDefaultDialerPackage();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0d852e5..f2a8ea5 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -978,18 +978,19 @@
@Override
public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
- boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, String[] args) {
+ boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
+ boolean dumpUnreachable, String[] args) {
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new FastPrintWriter(fout);
try {
- dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly);
+ dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
} finally {
pw.flush();
}
}
private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
- boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly) {
+ boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable) {
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -1103,6 +1104,16 @@
pw.println(" Asset Allocations");
pw.print(assetAlloc);
}
+
+ // Unreachable native memory
+ if (dumpUnreachable) {
+ boolean showContents = ((mBoundApplication != null)
+ && ((mBoundApplication.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0))
+ || android.os.Build.IS_DEBUGGABLE;
+ pw.println(" ");
+ pw.println(" Unreachable memory");
+ pw.print(Debug.getUnreachableMemory(100, showContents));
+ }
}
@Override
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 59ecc03..744ddf7 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -548,11 +548,12 @@
boolean dumpInfo = data.readInt() != 0;
boolean dumpDalvik = data.readInt() != 0;
boolean dumpSummaryOnly = data.readInt() != 0;
+ boolean dumpUnreachable = data.readInt() != 0;
String[] args = data.readStringArray();
if (fd != null) {
try {
dumpMemInfo(fd.getFileDescriptor(), mi, checkin, dumpInfo,
- dumpDalvik, dumpSummaryOnly, args);
+ dumpDalvik, dumpSummaryOnly, dumpUnreachable, args);
} finally {
try {
fd.close();
@@ -1328,7 +1329,8 @@
}
public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
- boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, String[] args) throws RemoteException {
+ boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
+ boolean dumpUnreachable, String[] args) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -1338,6 +1340,7 @@
data.writeInt(dumpInfo ? 1 : 0);
data.writeInt(dumpDalvik ? 1 : 0);
data.writeInt(dumpSummaryOnly ? 1 : 0);
+ data.writeInt(dumpUnreachable ? 1 : 0);
data.writeStringArray(args);
mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0);
reply.readException();
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index b55da88..a3c9591 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -133,7 +133,8 @@
void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
void scheduleTrimMemory(int level) throws RemoteException;
void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, boolean dumpInfo,
- boolean dumpDalvik, boolean dumpSummaryOnly, String[] args) throws RemoteException;
+ boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable,
+ String[] args) throws RemoteException;
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
void unstableProviderDied(IBinder provider) throws RemoteException;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a9150e8..a54f40f 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -68,6 +68,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.util.Arrays;
import java.util.Locale;
/**
@@ -119,6 +120,9 @@
private static final LongSparseArray<android.content.res.ConstantState<ComplexColor>>
sPreloadedComplexColors = new LongSparseArray<>();
+ /** Size of the cyclical cache used to map XML files to blocks. */
+ private static final int XML_BLOCK_CACHE_SIZE = 4;
+
// Pool of TypedArrays targeted to this Resources object.
final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<>(5);
@@ -154,8 +158,9 @@
// Cyclical cache used for recently-accessed XML files.
private int mLastCachedXmlBlockIndex = -1;
- private final String[] mCachedXmlBlockFiles = new String[4];
- private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[4];
+ private final int[] mCachedXmlBlockCookies = new int[XML_BLOCK_CACHE_SIZE];
+ private final String[] mCachedXmlBlockFiles = new String[XML_BLOCK_CACHE_SIZE];
+ private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[XML_BLOCK_CACHE_SIZE];
final AssetManager mAssets;
final ClassLoader mClassLoader;
@@ -2339,18 +2344,18 @@
* tools.
*/
public final void flushLayoutCache() {
- final String[] cachedXmlBlockFiles = mCachedXmlBlockFiles;
- final XmlBlock[] cachedXmlBlocks = mCachedXmlBlocks;
- synchronized (cachedXmlBlockFiles) {
- final int num = cachedXmlBlockFiles.length;
- for (int i = 0; i < num; i++) {
+ synchronized (mCachedXmlBlocks) {
+ Arrays.fill(mCachedXmlBlockCookies, 0);
+ Arrays.fill(mCachedXmlBlockFiles, null);
+
+ final XmlBlock[] cachedXmlBlocks = mCachedXmlBlocks;
+ for (int i = 0; i < XML_BLOCK_CACHE_SIZE; i++) {
final XmlBlock oldBlock = cachedXmlBlocks[i];
if (oldBlock != null) {
oldBlock.close();
}
- cachedXmlBlockFiles[i] = null;
- cachedXmlBlocks[i] = null;
}
+ Arrays.fill(cachedXmlBlocks, null);
}
}
@@ -2852,13 +2857,14 @@
int assetCookie, @NonNull String type) throws NotFoundException {
if (id != 0) {
try {
- final String[] cachedXmlBlockFiles = mCachedXmlBlockFiles;
- final XmlBlock[] cachedXmlBlocks = mCachedXmlBlocks;
- synchronized (cachedXmlBlockFiles) {
+ synchronized (mCachedXmlBlocks) {
+ final int[] cachedXmlBlockCookies = mCachedXmlBlockCookies;
+ final String[] cachedXmlBlockFiles = mCachedXmlBlockFiles;
+ final XmlBlock[] cachedXmlBlocks = mCachedXmlBlocks;
// First see if this block is in our cache.
final int num = cachedXmlBlockFiles.length;
for (int i = 0; i < num; i++) {
- if (cachedXmlBlockFiles[i] != null
+ if (cachedXmlBlockCookies[i] == assetCookie && cachedXmlBlockFiles[i] != null
&& cachedXmlBlockFiles[i].equals(file)) {
return cachedXmlBlocks[i].newParser();
}
@@ -2874,6 +2880,7 @@
if (oldBlock != null) {
oldBlock.close();
}
+ cachedXmlBlockCookies[pos] = assetCookie;
cachedXmlBlockFiles[pos] = file;
cachedXmlBlocks[pos] = block;
return block.newParser();
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index fb16150..f382241 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -2160,6 +2160,14 @@
public static native void dumpNativeBacktraceToFile(int pid, String file);
/**
+ * Get description of unreachable native memory.
+ * @param limit the number of leaks to provide info on, 0 to only get a summary.
+ * @param contents true to include a hex dump of the contents of unreachable memory.
+ * @return the String containing a description of unreachable memory.
+ * @hide */
+ public static native String getUnreachableMemory(int limit, boolean contents);
+
+ /**
* Return a String describing the calling method and location at a particular stack depth.
* @param callStack the Thread stack
* @param depth the depth of stack to return information for.
diff --git a/core/java/android/os/HardwarePropertiesManager.java b/core/java/android/os/HardwarePropertiesManager.java
index c72a6481..f48306a 100644
--- a/core/java/android/os/HardwarePropertiesManager.java
+++ b/core/java/android/os/HardwarePropertiesManager.java
@@ -69,7 +69,6 @@
* @return an array of requested float device temperatures.
* Empty if platform doesn't provide the queried temperature.
*
- * @throws IllegalArgumentException if an incorrect temperature type is queried.
* @throws SecurityException if a non profile or device owner tries to call this method.
*/
public @NonNull float[] getDeviceTemperatures(@DeviceTemperatureType int type) {
@@ -84,7 +83,8 @@
return new float[0];
}
default:
- throw new IllegalArgumentException();
+ Log.w(TAG, "Unknown device temperature type.");
+ return new float[0];
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c5b1653..afe2f10 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -4398,8 +4398,14 @@
private boolean updatePointerIcon(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
+ if (mView == null) {
+ // E.g. click outside a popup to dismiss it
+ Slog.d(mTag, "updatePointerIcon called after view was removed");
+ return false;
+ }
if (x < 0 || x >= mView.getWidth() || y < 0 || y >= mView.getHeight()) {
- Slog.e(mTag, "updatePointerIcon called with position out of bounds");
+ // E.g. when moving window divider with mouse
+ Slog.d(mTag, "updatePointerIcon called with position out of bounds");
return false;
}
final PointerIcon pointerIcon = mView.getPointerIcon(event, x, y);
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 3796df7..9a4d69f 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1358,6 +1358,17 @@
+ Integer.toHexString(System.identityHashCode(this))
+ " isIconified=" + isIconified + "}";
}
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
}
@Override
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index a8d684d..d5f080a 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -260,7 +260,8 @@
libprocessgroup \
libnativebridge \
libradio_metadata \
- libnativeloader
+ libnativeloader \
+ libmemunreachable \
LOCAL_SHARED_LIBRARIES += \
libhwui \
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 8b248b0..29c1075 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -555,6 +555,12 @@
std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file,
SkFILEStream::kCallerPasses_Ownership));
+ // If there is no offset for the file descriptor, we use SkFILEStream directly.
+ if (::lseek(descriptor, 0, SEEK_CUR) == 0) {
+ assert(isSeekable(dupDescriptor));
+ return doDecode(env, fileStream.release(), padding, bitmapFactoryOptions);
+ }
+
// Use a buffered stream. Although an SkFILEStream can be rewound, this
// ensures that SkImageDecoder::Factory never rewinds beyond the
// current position of the file descriptor.
@@ -584,7 +590,7 @@
static jboolean nativeIsSeekable(JNIEnv* env, jobject, jobject fileDescriptor) {
jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);
- return ::lseek64(descriptor, 0, SEEK_CUR) != -1 ? JNI_TRUE : JNI_FALSE;
+ return isSeekable(descriptor) ? JNI_TRUE : JNI_FALSE;
}
jobject decodeBitmap(JNIEnv* env, void* data, size_t size) {
diff --git a/core/jni/android/graphics/Utils.cpp b/core/jni/android/graphics/Utils.cpp
index 4f9ce8b..5fa445e 100644
--- a/core/jni/android/graphics/Utils.cpp
+++ b/core/jni/android/graphics/Utils.cpp
@@ -116,3 +116,7 @@
}
return NULL;
}
+
+bool android::isSeekable(int descriptor) {
+ return ::lseek64(descriptor, 0, SEEK_CUR) != -1;
+}
diff --git a/core/jni/android/graphics/Utils.h b/core/jni/android/graphics/Utils.h
index c0b9410..d1a74a0 100644
--- a/core/jni/android/graphics/Utils.h
+++ b/core/jni/android/graphics/Utils.h
@@ -68,6 +68,10 @@
jobject nullObjectReturn(const char msg[]);
+/** Check if the file descriptor is seekable.
+ */
+bool isSeekable(int descriptor);
+
}; // namespace android
#endif // _ANDROID_GRAPHICS_UTILS_H_
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 2d69eaa..59b8911 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -2012,22 +2012,35 @@
static void
android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
(JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
+ jniThrowException(_env, "java/lang/UnsupportedOperationException", "deprecated");
+}
+
+/* void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name ) */
+static void
+android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_ByteBuffer_2
+ (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jobject name_buf) {
jintArray _lengthArray = (jintArray) 0;
jint _lengthBufferOffset = (jint) 0;
jintArray _sizeArray = (jintArray) 0;
jint _sizeBufferOffset = (jint) 0;
jintArray _typeArray = (jintArray) 0;
jint _typeBufferOffset = (jint) 0;
+ jbyteArray _nameArray = (jbyteArray)0;
+ jint _nameBufferOffset = (jint)0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
jint _sizeRemaining;
GLint *size = (GLint *) 0;
jint _typeRemaining;
GLenum *type = (GLenum *) 0;
+ jint _nameRemaining;
+ GLchar* name = (GLchar*)0;
+
length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
+ name = (GLchar*)getPointer(_env, name_buf, (jarray*)&_nameArray, &_nameRemaining, &_nameBufferOffset);
if (length == NULL) {
char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
@@ -2040,6 +2053,10 @@
char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
type = (GLenum *) (_typeBase + _typeBufferOffset);
}
+ if (name == NULL) {
+ char* _nameBase = (char *)_env->GetByteArrayElements(_nameArray, (jboolean*)0);
+ name = (GLchar *) (_nameBase + _nameBufferOffset);
+ }
glGetTransformFeedbackVarying(
(GLuint)program,
(GLuint)index,
@@ -2047,11 +2064,7 @@
(GLsizei *)length,
(GLint *)size,
(GLenum *)type,
- // The cast below is incorrect. The driver will end up writing to the
- // address specified by name, which will always crash the process since
- // it is guaranteed to be in low memory. The additional static_cast
- // suppresses the warning for now. http://b/19478262
- (char *)static_cast<uintptr_t>(name)
+ (GLchar*)name
);
if (_typeArray) {
releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
@@ -2062,6 +2075,9 @@
if (_lengthArray) {
releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _lengthArray, (jint*)length, JNI_TRUE);
}
+ if (_nameArray) {
+ releaseArrayPointer<jbyteArray, jbyte*, ByteArrayReleaser>(_env, _nameArray, (jbyte*)name, JNI_TRUE);
+ }
}
/* void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name ) */
@@ -5233,6 +5249,7 @@
{"glTransformFeedbackVaryings", "(I[Ljava/lang/String;I)V", (void *) android_glTransformFeedbackVaryings },
{"glGetTransformFeedbackVarying", "(III[II[II[II[BI)V", (void *) android_glGetTransformFeedbackVarying__III_3II_3II_3II_3BI },
{"glGetTransformFeedbackVarying", "(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;B)V", (void *) android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B },
+{"glGetTransformFeedbackVarying", "(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/ByteBuffer;)V", (void *) android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_ByteBuffer_2 },
{"glGetTransformFeedbackVarying", "(II[II[II)Ljava/lang/String;", (void *) android_glGetTransformFeedbackVarying1 },
{"glGetTransformFeedbackVarying", "(IILjava/nio/IntBuffer;Ljava/nio/IntBuffer;)Ljava/lang/String;", (void *) android_glGetTransformFeedbackVarying2 },
{"glVertexAttribIPointerBounds", "(IIIILjava/nio/Buffer;I)V", (void *) android_glVertexAttribIPointerBounds__IIIILjava_nio_Buffer_2I },
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 03a1e71..3df0876 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -21,6 +21,7 @@
#include "utils/misc.h"
#include "cutils/debugger.h"
#include <memtrack/memtrack.h>
+#include <memunreachable/memunreachable.h>
#include <cutils/log.h>
#include <fcntl.h>
@@ -36,6 +37,9 @@
#include <ctype.h>
#include <malloc.h>
+#include <iomanip>
+#include <string>
+
namespace android
{
@@ -1023,6 +1027,13 @@
close(fd);
}
+static jstring android_os_Debug_getUnreachableMemory(JNIEnv* env, jobject clazz,
+ jint limit, jboolean contents)
+{
+ std::string s = GetUnreachableMemoryString(contents, limit);
+ return env->NewStringUTF(s.c_str());
+}
+
/*
* JNI registration.
*/
@@ -1058,6 +1069,8 @@
(void*)android_os_Debug_getDeathObjectCount },
{ "dumpNativeBacktraceToFile", "(ILjava/lang/String;)V",
(void*)android_os_Debug_dumpNativeBacktraceToFile },
+ { "getUnreachableMemory", "(IZ)Ljava/lang/String;",
+ (void*)android_os_Debug_getUnreachableMemory },
};
int register_android_os_Debug(JNIEnv *env)
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index ae109c6..abc6c4b 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -556,7 +556,7 @@
}
// For the rest of the function we will hold this lock, to serialize
- // looking/creation of Java proxies for native Binder proxies.
+ // looking/creation/destruction of Java proxies for native Binder proxies.
AutoMutex _l(mProxyLock);
// Someone else's... do we know about it?
@@ -1225,16 +1225,21 @@
static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj)
{
+ // Don't race with construction/initialization
+ AutoMutex _l(mProxyLock);
+
IBinder* b = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
DeathRecipientList* drl = (DeathRecipientList*)
env->GetLongField(obj, gBinderProxyOffsets.mOrgue);
LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl);
- env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
- env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
- drl->decStrong((void*)javaObjectForIBinder);
- b->decStrong((void*)javaObjectForIBinder);
+ if (b != nullptr) {
+ env->SetLongField(obj, gBinderProxyOffsets.mObject, 0);
+ env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0);
+ drl->decStrong((void*)javaObjectForIBinder);
+ b->decStrong((void*)javaObjectForIBinder);
+ }
IPCThreadState::self()->flushCommands();
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index d4f745d..af99f79 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -91,8 +91,11 @@
// a Canvas object.
private static final long NATIVE_ALLOCATION_SIZE = 525;
- private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
- getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
+ // Use a Holder to allow static initialization of Canvas in the boot image.
+ private static class NoImagePreloadHolder {
+ public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+ getNativeFinalizer(), NATIVE_ALLOCATION_SIZE);
+ }
// This field is used to finalize the native Canvas properly
private Runnable mFinalizer;
@@ -107,7 +110,8 @@
if (!isHardwareAccelerated()) {
// 0 means no native bitmap
mNativeCanvasWrapper = initRaster(null);
- mFinalizer = sRegistry.registerNativeAllocation(this, mNativeCanvasWrapper);
+ mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+ this, mNativeCanvasWrapper);
} else {
mFinalizer = null;
}
@@ -128,7 +132,8 @@
}
throwIfCannotDraw(bitmap);
mNativeCanvasWrapper = initRaster(bitmap);
- mFinalizer = sRegistry.registerNativeAllocation(this, mNativeCanvasWrapper);
+ mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+ this, mNativeCanvasWrapper);
mBitmap = bitmap;
mDensity = bitmap.mDensity;
}
@@ -139,7 +144,8 @@
throw new IllegalStateException();
}
mNativeCanvasWrapper = nativeCanvas;
- mFinalizer = sRegistry.registerNativeAllocation(this, mNativeCanvasWrapper);
+ mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+ this, mNativeCanvasWrapper);
mDensity = Bitmap.getDefaultDensity();
}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 534121a..291fdc4 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -44,8 +44,11 @@
// The approximate size of a native paint object.
private static final long NATIVE_PAINT_SIZE = 98;
- private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
- nGetNativeFinalizer(), NATIVE_PAINT_SIZE);
+ // Use a Holder to allow static initialization of Paint in the boot image.
+ private static class NoImagePreloadHolder {
+ public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+ nGetNativeFinalizer(), NATIVE_PAINT_SIZE);
+ }
/**
* @hide
@@ -452,7 +455,7 @@
*/
public Paint(int flags) {
mNativePaint = nInit();
- sRegistry.registerNativeAllocation(this, mNativePaint);
+ NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativePaint);
setFlags(flags | HIDDEN_DEFAULT_PAINT_FLAGS);
// TODO: Turning off hinting has undesirable side effects, we need to
// revisit hinting once we add support for subpixel positioning
@@ -471,7 +474,7 @@
*/
public Paint(Paint paint) {
mNativePaint = nInitWithPaint(paint.getNativeInstance());
- sRegistry.registerNativeAllocation(this, mNativePaint);
+ NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativePaint);
setClassVariablesFrom(paint);
}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 8831baf..54b453d 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -242,6 +242,7 @@
tests/unit/GpuMemoryTrackerTests.cpp \
tests/unit/LayerUpdateQueueTests.cpp \
tests/unit/LinearAllocatorTests.cpp \
+ tests/unit/MatrixTests.cpp \
tests/unit/OffscreenBufferPoolTests.cpp \
tests/unit/SkiaBehaviorTests.cpp \
tests/unit/StringUtilsTests.cpp \
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index 2198fcc..f170e9c 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -95,11 +95,11 @@
class AnimateFunctor {
public:
- AnimateFunctor(TreeInfo& info, AnimationContext& context)
- : dirtyMask(0), mInfo(info), mContext(context) {}
+ AnimateFunctor(TreeInfo& info, AnimationContext& context, uint32_t* outDirtyMask)
+ : mInfo(info), mContext(context), mDirtyMask(outDirtyMask) {}
bool operator() (sp<BaseRenderNodeAnimator>& animator) {
- dirtyMask |= animator->dirtyMask();
+ *mDirtyMask |= animator->dirtyMask();
bool remove = animator->animate(mContext);
if (remove) {
animator->detach();
@@ -114,11 +114,10 @@
return remove;
}
- uint32_t dirtyMask;
-
private:
TreeInfo& mInfo;
AnimationContext& mContext;
+ uint32_t* mDirtyMask;
};
uint32_t AnimatorManager::animate(TreeInfo& info) {
@@ -143,12 +142,13 @@
}
uint32_t AnimatorManager::animateCommon(TreeInfo& info) {
- AnimateFunctor functor(info, mAnimationHandle->context());
+ uint32_t dirtyMask;
+ AnimateFunctor functor(info, mAnimationHandle->context(), &dirtyMask);
auto newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
mAnimators.erase(newEnd, mAnimators.end());
mAnimationHandle->notifyAnimationsRan();
mParent.mProperties.updateMatrix();
- return functor.dirtyMask;
+ return dirtyMask;
}
static void endStagingAnimator(sp<BaseRenderNodeAnimator>& animator) {
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 78764b5..1aab3c7 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -368,7 +368,7 @@
op.startAngle, op.sweepAngle, op.useCenter, op.paint);
const AutoTexture holder(texture);
if (CC_LIKELY(holder.texture)) {
- renderPathTexture(renderer, state, op.unmappedBounds.left, op.unmappedBounds.right,
+ renderPathTexture(renderer, state, op.unmappedBounds.left, op.unmappedBounds.top,
*texture, *(op.paint));
}
} else {
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index e368537..501cbe5 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -404,11 +404,17 @@
return currentRectCount + recordedRectCount > RectangleList::kMaxTransformedRectangles;
}
+static const ClipRect sEmptyClipRect(Rect(0, 0));
+
const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator,
const ClipBase* recordedClip, const Matrix4& recordedClipTransform) {
+
// if no recordedClip passed, just serialize current state
if (!recordedClip) return serializeClip(allocator);
+ // if either is empty, clip is empty
+ if (CC_UNLIKELY(recordedClip->rect.isEmpty())|| mClipRect.isEmpty()) return &sEmptyClipRect;
+
if (!mLastResolutionResult
|| recordedClip != mLastResolutionClip
|| recordedClipTransform != mLastResolutionTransform) {
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 73ebd1304..deab956 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -438,7 +438,7 @@
}
void Matrix4::mapRect(Rect& r) const {
- if (isIdentity()) return;
+ if (isIdentity() || r.isEmpty()) return;
if (isSimple()) {
MUL_ADD_STORE(r.left, data[kScaleX], data[kTranslateX]);
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 31de305..9ae2212 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -594,7 +594,14 @@
}
size_t RecordingCanvas::addOp(RecordedOp* op) {
- // TODO: validate if "addDrawOp" quickrejection logic is useful before adding
+ // skip op with empty clip
+ if (op->localClip && op->localClip->rect.isEmpty()) {
+ // NOTE: this rejection happens after op construction/content ref-ing, so content ref'd
+ // and held by renderthread isn't affected by clip rejection.
+ // Could rewind alloc here if desired, but callers would have to not touch op afterwards.
+ return -1;
+ }
+
int insertIndex = mDisplayList->ops.size();
mDisplayList->ops.push_back(op);
if (mDeferredBarrierType != DeferredBarrierType::None) {
diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
index 679569e..dc2ea07 100644
--- a/libs/hwui/tests/unit/ClipAreaTests.cpp
+++ b/libs/hwui/tests/unit/ClipAreaTests.cpp
@@ -228,6 +228,7 @@
ClipRegion recordedClip;
recordedClip.region.setPath(ovalPath, SkRegion(SkIRect::MakeWH(200, 200)));
+ recordedClip.rect = Rect(200, 200);
Matrix4 translate10x20;
translate10x20.loadTranslate(10, 20, 0);
diff --git a/libs/hwui/tests/unit/MatrixTests.cpp b/libs/hwui/tests/unit/MatrixTests.cpp
new file mode 100644
index 0000000..da22637
--- /dev/null
+++ b/libs/hwui/tests/unit/MatrixTests.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "Matrix.h"
+#include "Rect.h"
+
+using namespace android::uirenderer;
+
+TEST(Matrix, mapRect) {
+ // Skew, so we don't hit identity/translate/simple fast paths
+ Matrix4 matrix;
+ matrix.skew(0.1f, 0.1f);
+
+ // non-zero empty rect, so sorting x/y would make rect non-empty
+ Rect empty(100, 100, -100, -100);
+ ASSERT_TRUE(empty.isEmpty());
+ matrix.mapRect(empty);
+ EXPECT_TRUE(empty.isEmpty())
+ << "Empty rect should always remain empty, regardless of mapping.";
+}
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index f988da3..c39047c 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -58,6 +58,17 @@
<< "Clip should be serialized once";
}
+TEST(RecordingCanvas, emptyClipRect) {
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
+ canvas.save(SaveFlags::MatrixClip);
+ canvas.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op);
+ canvas.clipRect(100, 100, 200, 200, SkRegion::kIntersect_Op);
+ canvas.drawRect(0, 0, 50, 50, SkPaint()); // rejected at record time
+ canvas.restore();
+ });
+ ASSERT_EQ(0u, dl->getOps().size()) << "Must be zero ops. Rect should be rejected.";
+}
+
TEST(RecordingCanvas, drawArc) {
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
canvas.drawArc(0, 0, 200, 200, 0, 180, true, SkPaint());
diff --git a/opengl/java/android/opengl/GLES30.java b/opengl/java/android/opengl/GLES30.java
index 9c3b505..74181c5 100644
--- a/opengl/java/android/opengl/GLES30.java
+++ b/opengl/java/android/opengl/GLES30.java
@@ -889,7 +889,10 @@
);
// C function void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name )
-
+ /**
+ * @deprecated
+ * Use the version that takes a ByteBuffer as the last argument, or the versions that return a String.
+ * */
public static native void glGetTransformFeedbackVarying(
int program,
int index,
@@ -902,6 +905,18 @@
// C function void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name )
+ public static native void glGetTransformFeedbackVarying(
+ int program,
+ int index,
+ int bufsize,
+ java.nio.IntBuffer length,
+ java.nio.IntBuffer size,
+ java.nio.IntBuffer type,
+ java.nio.ByteBuffer name
+ );
+
+ // C function void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name )
+
public static native String glGetTransformFeedbackVarying(
int program,
int index,
diff --git a/packages/DocumentsUI/Android.mk b/packages/DocumentsUI/Android.mk
index e1650e1..6dfc3bb 100644
--- a/packages/DocumentsUI/Android.mk
+++ b/packages/DocumentsUI/Android.mk
@@ -30,6 +30,10 @@
--extra-packages android.support.design \
--extra-packages android.support.v7.recyclerview
+LOCAL_JACK_FLAGS := \
+ -D jack.assert.policy=enable \
+ -D jack.optimization.inner-class.accessors=true
+
LOCAL_PACKAGE_NAME := DocumentsUI
LOCAL_CERTIFICATE := platform
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 95c49ff..46cbbdf 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -22,8 +22,6 @@
import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_LEAVE;
import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_SIDE;
-import static com.android.internal.util.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
import android.app.Activity;
import android.app.Fragment;
@@ -54,7 +52,6 @@
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.RootInfo;
-import com.android.internal.util.Preconditions;
import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -330,7 +327,8 @@
}
void openContainerDocument(DocumentInfo doc) {
- checkArgument(doc.isContainer());
+ assert(doc.isContainer());
+
mState.pushDocument(doc);
// Show an opening animation only if pressing "back" would get us back to the
// previous directory. Especially after opening a root document, pressing
@@ -373,7 +371,8 @@
@Override
public void onSearchChanged(@Nullable String query) {
// We should not get here if root is not searchable
- checkState(canSearchRoot());
+ assert(canSearchRoot());
+
reloadSearch(query);
}
@@ -673,7 +672,8 @@
@Override
protected RootInfo run(RootInfo... roots) {
- checkArgument(roots.length == 1);
+ assert(roots.length == 1);
+
final RootInfo currentRoot = roots[0];
final Collection<RootInfo> cachedRoots = mOwner.mRoots.getRootsBlocking();
RootInfo homeRoot = null;
@@ -686,7 +686,7 @@
return null;
}
}
- Preconditions.checkNotNull(homeRoot);
+ assert(homeRoot != null);
mHome = mOwner.getRootDocumentBlocking(homeRoot);
return homeRoot;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
index b3c2846..15bfc3b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
@@ -28,7 +28,6 @@
import android.util.Log;
import com.android.documentsui.model.DocumentInfo;
-import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
@@ -85,7 +84,7 @@
* This should be run from inside an AsyncTask.
*/
public List<DocumentInfo> getDocumentsFromClipData(ClipData clipData) {
- Preconditions.checkNotNull(clipData);
+ assert(clipData != null);
final List<DocumentInfo> srcDocs = new ArrayList<>();
int count = clipData.getItemCount();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index ed531a8..12a4186 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -23,7 +23,6 @@
import static com.android.documentsui.State.ACTION_OPEN_TREE;
import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION;
import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
-import static com.android.internal.util.Preconditions.checkArgument;
import android.app.Activity;
import android.app.Fragment;
@@ -333,7 +332,7 @@
@Override
void onDirectoryCreated(DocumentInfo doc) {
- checkArgument(doc.isDirectory());
+ assert(doc.isDirectory());
openContainerDocument(doc);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
index 536feeb..b5d3ea0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
@@ -16,10 +16,8 @@
package com.android.documentsui;
-import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.State.ACTION_MANAGE;
import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
-import static com.android.internal.util.Preconditions.checkState;
import android.app.Activity;
import android.app.Fragment;
@@ -41,7 +39,6 @@
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
-import com.android.internal.util.Preconditions;
import java.util.Arrays;
import java.util.List;
@@ -121,11 +118,11 @@
final RootInfo root = getCurrentRoot();
final DocumentInfo cwd = getCurrentDirectory();
- if (DEBUG) checkState(!mSearchManager.isSearching());
+ assert(!mSearchManager.isSearching());
// If started in manage roots mode, there has to be a cwd (i.e. the root dir of the managed
// root).
- Preconditions.checkNotNull(cwd);
+ assert(cwd != null);
// Normal boring directory
DirectoryFragment.showDirectory(fm, root, cwd, anim);
@@ -133,7 +130,8 @@
@Override
public void onDocumentPicked(DocumentInfo doc, Model model) {
- Preconditions.checkArgument(!doc.isDirectory());
+ assert(!doc.isDirectory());
+
// First try managing the document; we expect manager to filter
// based on authority, so we don't grant.
final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
index bcf69c4..9fceff5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
@@ -16,8 +16,6 @@
package com.android.documentsui;
-import static com.android.internal.util.Preconditions.checkArgument;
-
import android.app.Activity;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
@@ -83,7 +81,7 @@
DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle,
Toolbar drawerToolbar) {
mToolbar = drawerToolbar;
- checkArgument(layout != null);
+ assert(layout != null);
mLayout = layout;
mDrawer = drawer;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index a3378ad..c17be06 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -19,8 +19,6 @@
import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN;
import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
-import static com.android.internal.util.Preconditions.checkArgument;
-import static com.android.internal.util.Preconditions.checkState;
import android.app.Activity;
import android.app.FragmentManager;
@@ -97,11 +95,11 @@
// Launch URIs support sensible activity management, but don't specify a real
// content target.
if (DEBUG) Log.d(TAG, "Launching with non-empty stack.");
- checkState(uri == null || uri.getAuthority() == null ||
+ assert(uri == null || uri.getAuthority() == null ||
LauncherActivity.isLaunchUri(uri));
refreshCurrentRootAndDirectory(ANIM_NONE);
} else if (intent.getAction() == Intent.ACTION_VIEW) {
- checkArgument(uri != null);
+ assert(uri != null);
new OpenUriForViewTask(this).executeOnExecutor(
ProviderExecutor.forAuthority(uri.getAuthority()), uri);
} else if (DocumentsContract.isRootUri(this, uri)) {
@@ -143,7 +141,7 @@
state.allowMultiple = true;
// Options specific to the DocumentsActivity.
- checkArgument(!intent.hasExtra(Intent.EXTRA_LOCAL_ONLY));
+ assert(!intent.hasExtra(Intent.EXTRA_LOCAL_ONLY));
final DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
if (stack != null) {
@@ -212,7 +210,7 @@
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_create_dir:
- checkState(canCreateDirectory());
+ assert(canCreateDirectory());
showCreateDirectoryDialog();
return true;
case R.id.menu_new_window:
@@ -250,7 +248,7 @@
final RootInfo root = getCurrentRoot();
final DocumentInfo cwd = getCurrentDirectory();
- if (DEBUG) checkState(!mSearchManager.isSearching());
+ assert(!mSearchManager.isSearching());
if (cwd == null) {
DirectoryFragment.showRecentsOpen(fm, anim);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
index 4bffc49..170fb89 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/LocalPreferences.java
@@ -17,7 +17,6 @@
package com.android.documentsui;
import static com.android.documentsui.State.MODE_UNKNOWN;
-import static com.android.internal.util.Preconditions.checkArgument;
import android.content.Context;
import android.preference.PreferenceManager;
@@ -59,7 +58,8 @@
}
public static void setViewMode(Context context, RootInfo root, @ViewMode int viewMode) {
- checkArgument(viewMode != MODE_UNKNOWN);
+ assert(viewMode != MODE_UNKNOWN);
+
PreferenceManager.getDefaultSharedPreferences(context).edit()
.putInt(createKey(root), viewMode).apply();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index 699605f..bff65d5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -17,7 +17,6 @@
package com.android.documentsui;
import static com.android.documentsui.Shared.DEBUG;
-import static com.android.internal.util.Preconditions.checkArgument;
import android.annotation.IntDef;
import android.annotation.Nullable;
@@ -363,7 +362,7 @@
if (operationType == FileOperationService.OPERATION_DELETE) {
logHistogram(context, histogram, FILEOP_DELETE);
} else {
- checkArgument(dst != null);
+ assert(dst != null);
@Provider int providerType =
isSystemProvider(dst.authority) ? PROVIDER_SYSTEM : PROVIDER_EXTERNAL;
logHistogram(context, histogram, getOpCode(operationType, providerType));
diff --git a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
index 32543c8..933506c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
@@ -19,7 +19,6 @@
import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
-import static com.android.internal.util.Preconditions.checkArgument;
import android.app.Activity;
import android.app.Fragment;
@@ -101,7 +100,8 @@
*/
public void setPickTarget(
int action, @OpType int copyOperationSubType, DocumentInfo pickTarget) {
- checkArgument(copyOperationSubType != OPERATION_DELETE);
+ assert(copyOperationSubType != OPERATION_DELETE);
+
mAction = action;
mCopyOperationSubType = copyOperationSubType;
mPickTarget = pickTarget;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
index b0e332f..8145edc 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
@@ -19,7 +19,6 @@
import android.os.AsyncTask;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -85,7 +84,7 @@
private Executor mNonPreemptingExecutor = new Executor() {
@Override
public void execute(Runnable command) {
- Preconditions.checkNotNull(command);
+ assert(command != null);
mQueue.add(command);
}
};
@@ -93,7 +92,7 @@
@Override
public void execute(Runnable command) {
preempt();
- Preconditions.checkNotNull(command);
+ assert(command != null);
mQueue.add(command);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index c4c5124..ab67a51 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -18,7 +18,6 @@
import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.Shared.TAG;
-import static com.android.internal.util.Preconditions.checkState;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -41,7 +40,6 @@
import com.android.documentsui.model.RootInfo;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
@@ -118,17 +116,16 @@
*/
public void updateAsync() {
// Verifying an assumption about the recents root being immutable.
- if (DEBUG) {
- checkState(mRecentsRoot.authority == null);
- checkState(mRecentsRoot.rootId == null);
- checkState(mRecentsRoot.derivedIcon == R.drawable.ic_root_recent);
- checkState(mRecentsRoot.derivedType == RootInfo.TYPE_RECENTS);
- checkState(mRecentsRoot.flags == (Root.FLAG_LOCAL_ONLY
- | Root.FLAG_SUPPORTS_IS_CHILD
- | Root.FLAG_SUPPORTS_CREATE));
- checkState(mRecentsRoot.title == mContext.getString(R.string.root_recent));
- checkState(mRecentsRoot.availableBytes == -1);
- }
+ assert(mRecentsRoot.authority == null);
+ assert(mRecentsRoot.rootId == null);
+ assert(mRecentsRoot.derivedIcon == R.drawable.ic_root_recent);
+ assert(mRecentsRoot.derivedType == RootInfo.TYPE_RECENTS);
+ assert(mRecentsRoot.flags == (Root.FLAG_LOCAL_ONLY
+ | Root.FLAG_SUPPORTS_IS_CHILD
+ | Root.FLAG_SUPPORTS_CREATE));
+ assert(mRecentsRoot.title == mContext.getString(R.string.root_recent));
+ assert(mRecentsRoot.availableBytes == -1);
+
new UpdateTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
index 8beb245..63dc2ee 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
@@ -61,7 +61,8 @@
}
public void install(DocumentsToolbar actionBar) {
- assert (mActionBar == null);
+ // assert(mActionBar == null);
+
mActionBar = actionBar;
mMenu = actionBar.getSearchMenu();
mView = (SearchView) mMenu.getActionView();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index a288fe8..99c2d80 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -28,6 +28,10 @@
/** @hide */
public final class Shared {
+ public static final String TAG = "Documents";
+
+ public static final boolean DEBUG = true;
+
/** Intent action name to pick a copy destination. */
public static final String ACTION_PICK_COPY_DESTINATION =
"com.android.documentsui.PICK_COPY_DESTINATION";
@@ -79,9 +83,6 @@
*/
public static final String EXTRA_IGNORE_STATE = "ignoreState";
- public static final boolean DEBUG = true;
- public static final String TAG = "Documents";
-
/**
* String prefix used to indicate the document is a directory.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java b/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java
index 48c1a73..b4d7971 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java
@@ -16,8 +16,6 @@
package com.android.documentsui;
-import static com.android.internal.util.Preconditions.checkNotNull;
-
import android.app.Activity;
import android.support.design.widget.Snackbar;
import android.view.View;
@@ -26,12 +24,13 @@
private Snackbars() {}
public static final Snackbar makeSnackbar(Activity activity, int messageId, int duration) {
- return Snackbars.makeSnackbar(activity, activity.getResources().getText(messageId), duration);
+ return Snackbars.makeSnackbar(
+ activity, activity.getResources().getText(messageId), duration);
}
- public static final Snackbar makeSnackbar(Activity activity, CharSequence message, int duration)
- {
- final View view = checkNotNull(activity.findViewById(R.id.coordinator_layout));
+ public static final Snackbar makeSnackbar(
+ Activity activity, CharSequence message, int duration) {
+ final View view = activity.findViewById(R.id.coordinator_layout);
return Snackbar.make(view, message, duration);
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index d1b2264..dfceff8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -23,9 +23,6 @@
import static com.android.documentsui.State.SORT_ORDER_UNKNOWN;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.internal.util.Preconditions.checkState;
-import static com.google.common.base.Preconditions.checkArgument;
import android.annotation.IntDef;
import android.annotation.StringRes;
@@ -102,6 +99,7 @@
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.services.FileOperationService.OpType;
import com.android.documentsui.services.FileOperations;
+
import com.google.common.collect.Lists;
import java.lang.annotation.Retention;
@@ -359,7 +357,9 @@
private boolean handleViewItem(String id) {
final Cursor cursor = mModel.getItem(id);
- checkNotNull(cursor, "Cursor cannot be null.");
+
+ assert(cursor != null);
+
final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
if (mTuner.isDocumentEnabled(docMimeType, docFlags)) {
@@ -430,7 +430,8 @@
int cellMargin = 2 * getResources().getDimensionPixelSize(R.dimen.grid_item_margin);
int viewPadding = mRecView.getPaddingLeft() + mRecView.getPaddingRight();
- checkState(mRecView.getWidth() > 0);
+ assert(mRecView.getWidth() > 0);
+
int columnCount = Math.max(1,
(mRecView.getWidth() - viewPadding) / (cellWidth + cellMargin));
@@ -471,7 +472,9 @@
public boolean onBeforeItemStateChange(String modelId, boolean selected) {
if (selected) {
final Cursor cursor = mModel.getItem(modelId);
- checkNotNull(cursor, "Cursor cannot be null.");
+
+ assert(cursor != null);
+
final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
return mTuner.canSelectType(docMimeType, docFlags);
@@ -564,7 +567,7 @@
}
private void updateActionMenu() {
- checkNotNull(mMenu);
+ assert(mMenu != null);
// Delegate update logic to our owning action, since specialized logic is desired.
mTuner.updateActionMenu(mMenu, mType, canDeleteSelection(), canRenameSelection());
@@ -699,8 +702,8 @@
}
private void deleteDocuments(final Selection selected) {
+ assert(!selected.isEmpty());
- checkArgument(!selected.isEmpty());
final DocumentInfo srcParent = getDisplayState().stack.peek();
new GetDocumentsTask() {
@Override
@@ -777,7 +780,7 @@
private void renameDocuments(Selection selected) {
// Batch renaming not supported
// Rename option is only available in menu when 1 document selected
- checkArgument(selected.size() == 1);
+ assert(selected.size() == 1);
new GetDocumentsTask() {
@Override
@@ -890,7 +893,8 @@
}
private void copyFromClipData(final ClipData clipData, final DocumentInfo destination) {
- checkNotNull(clipData);
+ assert(clipData != null);
+
new AsyncTask<Void, Void, List<DocumentInfo>>() {
@Override
@@ -941,7 +945,7 @@
}
void copySelectionToClipboard(Selection selection) {
- checkArgument(!selection.isEmpty());
+ assert(!selection.isEmpty());
new GetDocumentsTask() {
@Override
void onDocumentsReady(List<DocumentInfo> docs) {
@@ -1059,7 +1063,7 @@
String id = getModelId(v);
if (id != null) {
Cursor dstCursor = mModel.getItem(id);
- checkNotNull(dstCursor, "Cursor cannot be null.");
+ assert(dstCursor != null);
return DocumentInfo.fromDirectoryCursor(dstCursor);
}
@@ -1132,10 +1136,11 @@
}
final Cursor cursor = mModel.getItem(modelId);
- checkNotNull(cursor, "Cursor cannot be null.");
- final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
- return Lists.newArrayList(doc);
+ assert(cursor != null);
+
+ return Lists.newArrayList(
+ DocumentInfo.fromDirectoryCursor(cursor));
}
private Drawable getDragShadowIcon(List<DocumentInfo> docs) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
index 2967a90..3b5ce87 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
@@ -16,9 +16,6 @@
package com.android.documentsui.dirlist;
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.internal.util.Preconditions.checkState;
-
import android.content.Context;
import android.database.Cursor;
import android.graphics.Rect;
@@ -97,19 +94,20 @@
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// Event listener should always be set.
- checkNotNull(mEventListener);
+ assert(mEventListener != null);
+
return mEventListener.onKey(this, keyCode, event);
}
public void addEventListener(DocumentHolder.EventListener listener) {
// Just handle one for now; switch to a list if necessary.
- checkState(mEventListener == null);
+ assert(mEventListener == null);
mEventListener = listener;
}
public void addOnKeyListener(View.OnKeyListener listener) {
// Just handle one for now; switch to a list if necessary.
- checkState(mKeyListener == null);
+ assert(mKeyListener == null);
mKeyListener = listener;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index 8ef89103..f99ec85c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -22,7 +22,6 @@
import static com.android.documentsui.State.ACTION_MANAGE;
import static com.android.documentsui.State.ACTION_OPEN;
import static com.android.documentsui.State.ACTION_OPEN_TREE;
-import static com.android.internal.util.Preconditions.checkArgument;
import android.content.Context;
import android.provider.DocumentsContract.Document;
@@ -172,7 +171,7 @@
@Override
public void updateActionMenu(
Menu menu, @ResultType int resultType, boolean canDelete, boolean canRename) {
- checkArgument(resultType != DirectoryFragment.TYPE_RECENT_OPEN);
+ assert(resultType != DirectoryFragment.TYPE_RECENT_OPEN);
MenuItem open = menu.findItem(R.id.menu_open);
MenuItem delete = menu.findItem(R.id.menu_delete);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDirectoryHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
index a0ff1b5..90b2341 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDirectoryHolder.java
@@ -17,7 +17,6 @@
package com.android.documentsui.dirlist;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
-import static com.android.internal.util.Preconditions.checkNotNull;
import android.content.Context;
import android.database.Cursor;
@@ -58,7 +57,7 @@
* @param state Current display state.
*/
public void bind(Cursor cursor, String modelId, State state) {
- checkNotNull(cursor, "Cursor cannot be null.");
+ assert(cursor != null);
this.modelId = modelId;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
index 8eaed17e..a4bce16 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
@@ -19,7 +19,6 @@
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
-import static com.android.internal.util.Preconditions.checkNotNull;
import android.content.Context;
import android.database.Cursor;
@@ -79,9 +78,9 @@
* @param state Current display state.
*/
public void bind(Cursor cursor, String modelId, State state) {
- this.modelId = modelId;
+ assert(cursor != null);
- checkNotNull(cursor, "Cursor cannot be null.");
+ this.modelId = modelId;
final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
index be6413b..b940ffb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
@@ -19,7 +19,6 @@
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
-import static com.android.internal.util.Preconditions.checkNotNull;
import android.content.Context;
import android.database.Cursor;
@@ -79,9 +78,9 @@
*/
@Override
public void bind(Cursor cursor, String modelId, State state) {
- this.modelId = modelId;
+ assert(cursor != null);
- checkNotNull(cursor, "Cursor cannot be null.");
+ this.modelId = modelId;
final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
index 9684a5a..5e55e1a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
@@ -22,11 +22,9 @@
import static com.android.documentsui.State.SORT_ORDER_SIZE;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
-import static com.android.internal.util.Preconditions.checkNotNull;
import android.database.Cursor;
import android.os.Bundle;
-import android.os.Looper;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.support.annotation.Nullable;
@@ -381,9 +379,9 @@
final List<DocumentInfo> docs = new ArrayList<>(size);
for (String modelId: items.getAll()) {
final Cursor cursor = getItem(modelId);
- checkNotNull(cursor, "Cursor cannot be null.");
- final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
- docs.add(doc);
+ assert(cursor != null);
+
+ docs.add(DocumentInfo.fromDirectoryCursor(cursor));
}
return docs;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
index 4cf1048..b0cc09a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
@@ -19,9 +19,6 @@
import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.dirlist.ModelBackedDocumentsAdapter.ITEM_TYPE_DIRECTORY;
import static com.android.documentsui.dirlist.ModelBackedDocumentsAdapter.ITEM_TYPE_DOCUMENT;
-import static com.android.internal.util.Preconditions.checkArgument;
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.internal.util.Preconditions.checkState;
import android.annotation.IntDef;
import android.graphics.Point;
@@ -134,8 +131,12 @@
@SelectionMode int mode,
@Nullable Selection initialSelection) {
- mEnvironment = checkNotNull(environment, "'environment' cannot be null.");
- mAdapter = checkNotNull(adapter, "'adapter' cannot be null.");
+ assert(environment != null);
+ assert(adapter != null);
+
+ mEnvironment = environment;
+ mAdapter = adapter;
+
mSingleSelect = mode == MODE_SINGLE;
if (initialSelection != null) {
mSelection.copyFrom(initialSelection);
@@ -168,8 +169,8 @@
@Override
public void onItemRangeRemoved(int startPosition, int itemCount) {
- checkState(startPosition >= 0);
- checkState(itemCount > 0);
+ assert(startPosition >= 0);
+ assert(itemCount > 0);
mSelection.cancelProvisionalSelection();
// Remove any disappeared IDs from the selection.
@@ -356,7 +357,8 @@
* @param modelId
*/
public void toggleSelection(String modelId) {
- checkNotNull(modelId);
+ assert(modelId != null);
+
boolean changed = false;
if (mSelection.contains(modelId)) {
changed = attemptDeselect(modelId);
@@ -389,7 +391,8 @@
* @param pos The new end position for the selection range.
*/
void snapRangeSelection(int pos) {
- checkNotNull(mRanger);
+ assert(mRanger != null);
+
mRanger.snapSelection(pos);
notifySelectionChanged();
}
@@ -436,7 +439,7 @@
* @param selected New selection state.
*/
private void updateRange(int begin, int end, boolean selected) {
- checkState(end >= begin);
+ assert(end >= begin);
for (int i = begin; i <= end; i++) {
String id = mAdapter.getModelId(i);
if (id == null) {
@@ -474,7 +477,7 @@
* @return True if the update was applied.
*/
private boolean attemptDeselect(String id) {
- checkArgument(id != null);
+ assert(id != null);
if (notifyBeforeItemStateChange(id, false)) {
mSelection.remove(id);
notifyItemStateChanged(id, false);
@@ -491,7 +494,7 @@
* @return True if the update was applied.
*/
private boolean attemptSelect(String id) {
- checkArgument(id != null);
+ assert(id != null);
boolean canSelect = notifyBeforeItemStateChange(id, true);
if (!canSelect) {
return false;
@@ -519,7 +522,7 @@
* (identified by {@code position}) changes.
*/
private void notifyItemStateChanged(String id, boolean selected) {
- checkArgument(id != null);
+ assert(id != null);
int lastListener = mCallbacks.size() - 1;
for (int i = lastListener; i > -1; i--) {
mCallbacks.get(i).onItemStateChanged(id, selected);
@@ -555,8 +558,8 @@
}
private void snapSelection(int position) {
- checkState(mRanger != null);
- checkArgument(position != RecyclerView.NO_POSITION);
+ assert(mRanger != null);
+ assert(position != RecyclerView.NO_POSITION);
if (mEnd == UNDEFINED || mEnd == mBegin) {
// Reset mEnd so it can be established in establishRange.
@@ -568,7 +571,7 @@
}
private void establishRange(int position) {
- checkState(mRanger.mEnd == UNDEFINED);
+ assert(mRanger.mEnd == UNDEFINED);
if (position == mBegin) {
mEnd = position;
@@ -584,8 +587,8 @@
}
private void reviseRange(int position) {
- checkState(mEnd != UNDEFINED);
- checkState(mBegin != mEnd);
+ assert(mEnd != UNDEFINED);
+ assert(mBegin != mEnd);
if (position == mEnd) {
if (DEBUG) Log.i(TAG, "Skipping no-op revision click on mEndRange.");
@@ -1185,7 +1188,7 @@
* @param input
*/
private void processInputEvent(InputEvent input) {
- checkArgument(input.isMouseEvent());
+ assert(input.isMouseEvent());
if (shouldStop(input)) {
endBandSelect();
@@ -1199,7 +1202,6 @@
}
mCurrentPosition = input.getOrigin();
- mModel.resizeSelection(input.getOrigin());
scrollViewIfNecessary();
resizeBandSelectRectangle();
}
@@ -1488,6 +1490,7 @@
* top-left of the viewport would have a relative origin of (0, 0), even though its
* absolute point has a higher y-value.
*/
+ @VisibleForTesting
void resizeSelection(Point relativePointer) {
mPointer = mHelper.createAbsolutePoint(relativePointer);
updateModel();
@@ -1615,7 +1618,7 @@
private void updateSelection(Rect rect) {
int columnStart =
Collections.binarySearch(mColumnBounds, new Limits(rect.left, rect.left));
- checkState(columnStart >= 0);
+ assert(columnStart >= 0);
int columnEnd = columnStart;
for (int i = columnStart; i < mColumnBounds.size()
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
index 38a71ec..0018d01 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -17,7 +17,6 @@
package com.android.documentsui.dirlist;
import static com.android.documentsui.Shared.TAG;
-import static com.android.internal.util.Preconditions.checkArgument;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -36,9 +35,9 @@
import android.support.design.widget.Snackbar;
import android.util.Log;
import android.view.KeyEvent;
-import android.view.inputmethod.EditorInfo;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -205,7 +204,7 @@
@Override
protected DocumentInfo doInBackground(DocumentInfo... document) {
- checkArgument(document.length == 1);
+ assert(document.length == 1);
final ContentResolver resolver = mActivity.getContentResolver();
ContentProviderClient client = null;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
index 2485ad9..3ee5cfc 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
@@ -16,8 +16,6 @@
package com.android.documentsui.dirlist;
-import static com.android.internal.util.Preconditions.checkArgument;
-
import android.content.Context;
import android.database.Cursor;
import android.support.v7.widget.GridLayoutManager;
@@ -204,12 +202,12 @@
}
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
- checkArgument(itemCount == 1);
+ assert(itemCount == 1);
notifyItemRangeChanged(toViewPosition(positionStart), itemCount, payload);
}
public void onItemRangeInserted(int positionStart, int itemCount) {
- checkArgument(itemCount == 1);
+ assert(itemCount == 1);
if (positionStart < mBreakPosition) {
mBreakPosition++;
}
@@ -217,7 +215,7 @@
}
public void onItemRangeRemoved(int positionStart, int itemCount) {
- checkArgument(itemCount == 1);
+ assert(itemCount == 1);
if (positionStart < mBreakPosition) {
mBreakPosition--;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
index faedd5e..ad48a70 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
@@ -29,7 +29,6 @@
import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
-import static com.google.common.base.Preconditions.checkArgument;
import android.annotation.StringRes;
import android.app.Notification;
@@ -95,7 +94,7 @@
String id, DocumentStack stack, List<DocumentInfo> srcs) {
super(service, appContext, listener, OPERATION_COPY, id, stack);
- checkArgument(!srcs.isEmpty());
+ assert(!srcs.isEmpty());
this.mSrcs = srcs;
}
@@ -108,7 +107,7 @@
@OpType int opType, String id, DocumentStack destination, List<DocumentInfo> srcs) {
super(service, appContext, listener, opType, id, destination);
- checkArgument(!srcs.isEmpty());
+ assert(!srcs.isEmpty());
this.mSrcs = srcs;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
index 05a3f11..580fa38 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
@@ -17,9 +17,6 @@
package com.android.documentsui.services;
import static com.android.documentsui.Shared.DEBUG;
-import static com.android.internal.util.Preconditions.checkArgument;
-import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.internal.util.Preconditions.checkState;
import android.annotation.IntDef;
import android.app.NotificationManager;
@@ -136,12 +133,12 @@
String jobId = intent.getStringExtra(EXTRA_JOB_ID);
@OpType int operationType = intent.getIntExtra(EXTRA_OPERATION, OPERATION_UNKNOWN);
- checkArgument(jobId != null);
+ assert(jobId != null);
if (intent.hasExtra(EXTRA_CANCEL)) {
handleCancel(intent);
} else {
- checkArgument(operationType != OPERATION_UNKNOWN);
+ assert(operationType != OPERATION_UNKNOWN);
handleOperation(intent, serviceId, jobId, operationType);
}
@@ -173,9 +170,9 @@
mWakeLock.acquire();
}
- checkState(job != null);
+ assert(job != null);
int delay = intent.getIntExtra(EXTRA_DELAY, DEFAULT_DELAY);
- checkArgument(delay <= MAX_DELAY);
+ assert(delay <= MAX_DELAY);
if (DEBUG) Log.d(
TAG, "Scheduling job " + job.id + " to run in " + delay + " milliseconds.");
ScheduledFuture<?> future = executor.schedule(job, delay, TimeUnit.MILLISECONDS);
@@ -188,8 +185,10 @@
* @param intent The cancellation intent.
*/
private void handleCancel(Intent intent) {
- checkArgument(intent.hasExtra(EXTRA_CANCEL));
- String jobId = checkNotNull(intent.getStringExtra(EXTRA_JOB_ID));
+ assert(intent.hasExtra(EXTRA_CANCEL));
+ assert(intent.getStringExtra(EXTRA_JOB_ID) != null);
+
+ String jobId = intent.getStringExtra(EXTRA_JOB_ID);
if (DEBUG) Log.d(TAG, "handleCancel: " + jobId);
@@ -253,7 +252,8 @@
throw new UnsupportedOperationException();
}
- return checkNotNull(job);
+ assert(job != null);
+ return job;
}
@GuardedBy("mRunning")
@@ -261,7 +261,7 @@
if (DEBUG) Log.d(TAG, "deleteJob: " + job.id);
JobRecord record = mRunning.remove(job.id);
- checkArgument(record != null);
+ assert(record != null);
record.job.cleanup();
if (mRunning.isEmpty()) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
index a158654..c723ac6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
@@ -23,8 +23,6 @@
import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
-import static com.android.internal.util.Preconditions.checkArgument;
-import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.DrawableRes;
import android.annotation.PluralsRes;
@@ -98,7 +96,7 @@
Job(Context service, Context appContext, Listener listener,
@OpType int operationType, String id, DocumentStack stack) {
- checkArgument(operationType != OPERATION_UNKNOWN);
+ assert(operationType != OPERATION_UNKNOWN);
this.service = service;
this.appContext = appContext;
@@ -150,7 +148,8 @@
mClients.put(doc.authority, client);
}
- return checkNotNull(client);
+ assert(client != null);
+ return client;
}
final void cleanup() {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
index b5826a4..dc39235 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
@@ -21,11 +21,9 @@
import android.app.Notification;
import android.app.Notification.Builder;
import android.content.Context;
-import android.net.Uri;
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
-import android.util.Log;
import com.android.documentsui.R;
import com.android.documentsui.model.DocumentInfo;
@@ -36,7 +34,6 @@
// TODO: Stop extending CopyJob.
final class MoveJob extends CopyJob {
- private static final String TAG = "MoveJob";
final DocumentInfo mSrcParent;
/**
diff --git a/packages/SystemUI/res/drawable/tv_pip_play_button.xml b/packages/SystemUI/res/drawable/tv_pip_play_button.xml
new file mode 100644
index 0000000..fecdc09
--- /dev/null
+++ b/packages/SystemUI/res/drawable/tv_pip_play_button.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:constantSize="true">
+ <item android:state_focused="true">
+ <layer-list>
+ <item android:drawable="@drawable/tv_pip_button_focused" />
+ <item android:drawable="@drawable/ic_play_arrow_white_24dp" />
+ </layer-list>
+ </item>
+ <item android:drawable="@drawable/ic_play_arrow_white_24dp" />
+</selector>
diff --git a/packages/SystemUI/res/layout/tv_pip_menu.xml b/packages/SystemUI/res/layout/tv_pip_menu.xml
index 0b98d0e..1fec49e 100644
--- a/packages/SystemUI/res/layout/tv_pip_menu.xml
+++ b/packages/SystemUI/res/layout/tv_pip_menu.xml
@@ -34,7 +34,7 @@
android:gravity="center"
android:clipChildren="false">
- <ImageView android:id="@+id/full"
+ <ImageView android:id="@+id/full_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
@@ -53,17 +53,16 @@
android:clipChildren="false" />
</LinearLayout>
- <LinearLayout
+ <LinearLayout android:id="@+id/play_pause"
android:layout_width="34dp"
android:layout_height="wrap_content"
android:layout_marginStart="3dp"
android:layout_marginEnd="3dp"
android:orientation="vertical"
android:gravity="center"
- android:visibility="gone"
android:clipChildren="false">
- <ImageView android:id="@+id/play_pause"
+ <ImageView android:id="@+id/play_pause_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
@@ -90,7 +89,7 @@
android:gravity="center"
android:clipChildren="false">
- <ImageView android:id="@+id/close"
+ <ImageView android:id="@+id/close_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index c31bb33..c643d67 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -54,8 +54,7 @@
mQsContainer = container;
mQuickQsPanel = quickPanel;
mQsPanel = panel;
- mQuickQsPanel.addOnLayoutChangeListener(this);
- mQsPanel.addOnLayoutChangeListener(this);
+ container.addOnLayoutChangeListener(this);
QSTileLayout tileLayout = mQsPanel.getTileLayout();
if (tileLayout instanceof PagedTileLayout) {
((PagedTileLayout) tileLayout).setPageListener(this);
@@ -161,6 +160,7 @@
@Override
public void onAnimationAtStart() {
+ mQuickQsPanel.setVisibility(View.VISIBLE);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
index 026dd0e..35ade58 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
@@ -38,7 +38,7 @@
private final float mSpan;
private final Interpolator mInterpolator;
private final Listener mListener;
- private float mLastT;
+ private float mLastT = -1;
private TouchAnimator(Object[] targets, KeyframeSet[] keyframeSets,
float startDelay, float endDelay, Interpolator interpolator, Listener listener) {
@@ -56,15 +56,16 @@
if (mInterpolator != null) {
t = mInterpolator.getInterpolation(t);
}
+ if (t == mLastT) {
+ return;
+ }
if (mListener != null) {
- if (mLastT == 0 || mLastT == 1) {
- if (t != mLastT) {
- mListener.onAnimationStarted();
- }
- } else if (t == 1) {
+ if (t == 1) {
mListener.onAnimationAtEnd();
} else if (t == 0) {
mListener.onAnimationAtStart();
+ } else if (mLastT <= 0 || mLastT == 1) {
+ mListener.onAnimationStarted();
}
mLastT = t;
}
@@ -114,12 +115,12 @@
private Listener mListener;
public Builder addFloat(Object target, String property, float... values) {
- add(target, KeyframeSet.ofFloat(getProperty(target, property), values));
+ add(target, KeyframeSet.ofFloat(getProperty(target, property, float.class), values));
return this;
}
public Builder addInt(Object target, String property, int... values) {
- add(target, KeyframeSet.ofInt(getProperty(target, property), values));
+ add(target, KeyframeSet.ofInt(getProperty(target, property, int.class), values));
return this;
}
@@ -128,7 +129,7 @@
mValues.add(keyframeSet);
}
- private static Property getProperty(Object target, String property) {
+ private static Property getProperty(Object target, String property, Class<?> cls) {
if (target instanceof View) {
switch (property) {
case "translationX":
@@ -151,7 +152,7 @@
return View.SCALE_Y;
}
}
- return Property.of(target.getClass(), float.class, property);
+ return Property.of(target.getClass(), cls, property);
}
public Builder setStartDelay(float startDelay) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 67fe8e5e..225c10f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -77,11 +77,10 @@
TypedValue value = new TypedValue();
mContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true);
mToolbar.setNavigationIcon(
- getResources().getDrawable(R.drawable.ic_close_white, mContext.getTheme()));
+ getResources().getDrawable(value.resourceId, mContext.getTheme()));
mToolbar.setNavigationOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- save();
hide((int) v.getX() + v.getWidth() / 2, (int) v.getY() + v.getHeight() / 2);
}
});
@@ -115,6 +114,7 @@
public void hide(int x, int y) {
if (isShown) {
isShown = false;
+ save();
mClipper.animateCircularClip(x, y, false, mCollapseAnimationListener);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index c6c497f..d1953b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -27,7 +27,6 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
-import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.android.systemui.R;
@@ -159,13 +158,6 @@
TileInfo info = mTiles.get(position);
holder.mTileView.onStateChanged(info.state);
- holder.mTileView.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- mItemTouchHelper.startDrag(holder);
- return true;
- }
- });
}
public SpanSizeLookup getSizeLookup() {
@@ -179,6 +171,7 @@
super(itemView);
if (itemView instanceof FrameLayout) {
mTileView = (QSTileView) ((FrameLayout) itemView).getChildAt(0);
+ mTileView.setBackground(null);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index e4e3790..12c8c44 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -69,6 +69,11 @@
}
@Override
+ public boolean isAvailable() {
+ return mFlashlightController.hasFlashlight();
+ }
+
+ @Override
protected void handleClick() {
if (ActivityManager.isUserAMonkey()) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index 9450287..0c48cf7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -97,6 +97,9 @@
@Override
public void onPipResizeAboutToStart() { }
+
+ @Override
+ public void onMediaControllerChanged() { }
};
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 9bd645d..d0358f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -959,7 +959,7 @@
}, false /* afterKeyguardGone */);
}
- private void bindGuts(ExpandableNotificationRow row) {
+ private void bindGuts(final ExpandableNotificationRow row) {
row.inflateGuts();
final StatusBarNotification sbn = row.getStatusBarNotification();
PackageManager pmUser = getPackageManagerForUser(mContext, sbn.getUser().getIdentifier());
@@ -1003,7 +1003,17 @@
@Override
public void onClick(View v) {
guts.saveImportance(sbn);
- dismissPopups();
+
+ int[] rowLocation = new int[2];
+ int[] doneLocation = new int[2];
+ row.getLocationOnScreen(rowLocation);
+ v.getLocationOnScreen(doneLocation);
+
+ final int centerX = v.getWidth() / 2;
+ final int centerY = v.getHeight() / 2;
+ final int x = doneLocation[0] - rowLocation[0] + centerX;
+ final int y = doneLocation[1] - rowLocation[1] + centerY;
+ dismissPopups(x, y);
}
});
@@ -1049,7 +1059,7 @@
// Post to ensure the the guts are properly laid out.
guts.post(new Runnable() {
public void run() {
- dismissPopups();
+ dismissPopups(-1 /* x */, -1 /* y */, false /* resetGear */);
guts.setVisibility(View.VISIBLE);
final double horz = Math.max(guts.getWidth() - x, x);
final double vert = Math.max(guts.getHeight() - y, y);
@@ -1083,10 +1093,14 @@
}
public void dismissPopups() {
- dismissPopups(-1, -1);
+ dismissPopups(-1 /* x */, -1 /* y */, true /* resetGear */);
}
private void dismissPopups(int x, int y) {
+ dismissPopups(x, y, true /* resetGear */);
+ }
+
+ public void dismissPopups(int x, int y, boolean resetGear) {
if (mNotificationGutsExposed != null) {
final NotificationGuts v = mNotificationGutsExposed;
mNotificationGutsExposed = null;
@@ -1114,8 +1128,7 @@
v.setExposed(false);
mStackScroller.onHeightChanged(null, true /* needsAnimation */);
}
-
- if (mNotificationGearDisplayed != null) {
+ if (resetGear && mNotificationGearDisplayed != null) {
mNotificationGearDisplayed.resetTranslation();
mNotificationGearDisplayed = null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index da125d8..e109b09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -656,7 +656,6 @@
mGuts = (NotificationGuts) inflated;
mGuts.setClipTopAmount(getClipTopAmount());
mGuts.setActualHeight(getActualHeight());
- mTranslateableViews.add(mGuts);
mGutsStub = null;
}
});
@@ -1175,6 +1174,10 @@
@Override
public void setActualHeight(int height, boolean notifyListeners) {
super.setActualHeight(height, notifyListeners);
+ if (mGuts != null && mGuts.areGutsExposed()) {
+ mGuts.setActualHeight(height);
+ return;
+ }
int contentHeight = Math.max(getMinHeight(), height);
mPrivateLayout.setContentHeight(contentHeight);
mPublicLayout.setContentHeight(contentHeight);
@@ -1184,7 +1187,6 @@
if (mGuts != null) {
mGuts.setActualHeight(height);
}
- invalidate();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java
index 4491ebd..476e146 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java
@@ -33,7 +33,7 @@
/**
* Called when the gear behind a notification is touched.
*/
- public void onGearTouched(ExpandableNotificationRow row);
+ public void onGearTouched(ExpandableNotificationRow row, int x, int y);
}
private ExpandableNotificationRow mParent;
@@ -45,6 +45,8 @@
private boolean mSettingsFadedIn = false;
private boolean mAnimating = false;
private boolean mOnLeft = true;
+ private int[] mGearLocation = new int[2];
+ private int[] mParentLocation = new int[2];
public NotificationSettingsIconRow(Context context) {
this(context, null);
@@ -74,6 +76,12 @@
resetState();
}
+ public void resetState() {
+ setGearAlpha(0f);
+ mAnimating = false;
+ setIconLocation(true /* on left */);
+ }
+
public void setGearListener(SettingsIconRowListener listener) {
mListener = listener;
}
@@ -86,12 +94,6 @@
return mParent;
}
- public void resetState() {
- setGearAlpha(0f);
- mAnimating = false;
- setIconLocation(true /* on left */);
- }
-
private void setGearAlpha(float alpha) {
if (alpha == 0) {
mSettingsFadedIn = false; // Can fade in again once it's gone.
@@ -200,7 +202,16 @@
public void onClick(View v) {
if (v.getId() == R.id.gear_icon) {
if (mListener != null) {
- mListener.onGearTouched(mParent);
+ mGearIcon.getLocationOnScreen(mGearLocation);
+ mParent.getLocationOnScreen(mParentLocation);
+
+ final int centerX = (int) (mHorizSpaceForGear / 2);
+ // Top / bottom padding are not equal, need to subtract them to get center of gear.
+ final int centerY = (int) (mGearIcon.getHeight() - mGearIcon.getPaddingTop()
+ - mGearIcon.getPaddingBottom()) / 2 + mGearIcon.getPaddingTop();
+ final int x = mGearLocation[0] - mParentLocation[0] + centerX;
+ final int y = mGearLocation[1] - mParentLocation[1] + centerY;
+ mListener.onGearTouched(mParent, x, y);
}
} else {
// Do nothing when the background is touched.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index cf5531f..b549d59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -38,7 +38,6 @@
import com.android.systemui.qs.QSTile;
import com.android.systemui.qs.QuickQSPanel;
import com.android.systemui.qs.TouchAnimator;
-import com.android.systemui.qs.TouchAnimator.Listener;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
@@ -46,7 +45,7 @@
import com.android.systemui.tuner.TunerService;
public class QuickStatusBarHeader extends BaseStatusBarHeader implements
- NextAlarmChangeCallback, OnClickListener, Listener {
+ NextAlarmChangeCallback, OnClickListener {
private static final String TAG = "QuickStatusBarHeader";
@@ -157,7 +156,6 @@
mAnimator = new TouchAnimator.Builder()
.addFloat(mSettingsContainer, "translationY", -mGearTranslation, 0)
.addFloat(mMultiUserSwitch, "translationY", -mGearTranslation, 0)
- .setListener(this)
.build();
mSecondHalfAnimator = new TouchAnimator.Builder()
.addFloat(mSettingsButton, "rotation", -180, 0)
@@ -224,20 +222,6 @@
mExpandIndicator.setExpanded(headerExpansionFraction > EXPAND_INDICATOR_THRESHOLD);
}
- @Override
- public void onAnimationAtStart() {
- }
-
- @Override
- public void onAnimationAtEnd() {
- mHeaderQsPanel.setVisibility(View.INVISIBLE);
- }
-
- @Override
- public void onAnimationStarted() {
- mHeaderQsPanel.setVisibility(View.VISIBLE);
- }
-
private void updateAlarmVisibilities() {
mAlarmStatus.setVisibility(mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
mAlarmStatusCollapsed.setVisibility(mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index 29a8f67..9a21a1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -93,6 +93,10 @@
}
}
+ public boolean hasFlashlight() {
+ return mCameraId != null;
+ }
+
public synchronized boolean isEnabled() {
return mFlashlightEnabled;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 340ebb4..85b1426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -361,9 +361,9 @@
}
@Override
- public void onGearTouched(ExpandableNotificationRow row) {
+ public void onGearTouched(ExpandableNotificationRow row, int x, int y) {
if (mLongPressListener != null) {
- mLongPressListener.onLongPress(row, 0, 0);
+ mLongPressListener.onLongPress(row, x, y);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index 0925638..123165e 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -23,11 +23,14 @@
import android.app.IActivityManager;
import android.app.ITaskStackListener;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.Rect;
+import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
import android.os.Debug;
import android.os.Handler;
import android.os.RemoteException;
@@ -69,6 +72,7 @@
private Context mContext;
private IActivityManager mActivityManager;
+ private MediaSessionManager mMediaSessionManager;
private int mState = STATE_NO_PIP;
private final Handler mHandler = new Handler();
private List<Listener> mListeners = new ArrayList<>();
@@ -79,6 +83,8 @@
private Rect mRecentsFocusedPipBounds;
private boolean mInitialized;
private int mPipTaskId = TASK_ID_NO_PIP;
+ private ComponentName mPipComponentName;
+ private MediaController mPipMediaController;
private boolean mOnboardingShown;
private boolean mIsRecentsShown;
@@ -100,10 +106,15 @@
}
if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
+ mPipComponentName = ComponentName.unflattenFromString(
+ stackInfo.taskNames[stackInfo.taskNames.length - 1]);
// Set state to overlay so we show it when the pinned stack animation ends.
mState = STATE_PIP_OVERLAY;
mCurrentPipBounds = mPipBounds;
launchPipOnboardingActivityIfNeeded();
+ mMediaSessionManager.addOnActiveSessionsChangedListener(
+ mActiveMediaSessionListener, null);
+ updateMediaController(mMediaSessionManager.getActiveSessions(null));
}
};
private final Runnable mOnTaskStackChanged = new Runnable() {
@@ -176,6 +187,13 @@
}
};
+ private final MediaSessionManager.OnActiveSessionsChangedListener mActiveMediaSessionListener =
+ new MediaSessionManager.OnActiveSessionsChangedListener() {
+ @Override
+ public void onActiveSessionsChanged(List<MediaController> controllers) {
+ updateMediaController(controllers);
+ }
+ };
private PipManager() { }
@@ -215,6 +233,9 @@
mContext.registerReceiver(mBroadcastReceiver, intentFilter);
mOnboardingShown = Prefs.getBoolean(
mContext, TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN, false);
+
+ mMediaSessionManager =
+ (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
}
/**
@@ -248,6 +269,8 @@
private void closePipInternal(boolean removePipStack) {
mState = STATE_NO_PIP;
mPipTaskId = TASK_ID_NO_PIP;
+ mPipMediaController = null;
+ mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveMediaSessionListener);
if (removePipStack) {
try {
mActivityManager.removeStack(PINNED_STACK_ID);
@@ -502,6 +525,34 @@
}
}
+ private void updateMediaController(List<MediaController> controllers) {
+ MediaController mediaController = null;
+ if (controllers != null && mState != STATE_NO_PIP && mPipComponentName != null) {
+ for (int i = controllers.size() - 1; i >= 0; i--) {
+ MediaController controller = controllers.get(i);
+ // We assumes that an app with PIPable activity
+ // keeps the single instance of media controller especially when PIP is on.
+ if (controller.getPackageName().equals(mPipComponentName.getPackageName())) {
+ mediaController = controller;
+ break;
+ }
+ }
+ }
+ if (mPipMediaController != mediaController) {
+ mPipMediaController = mediaController;
+ for (int i = mListeners.size() - 1; i >= 0; i--) {
+ mListeners.get(i).onMediaControllerChanged();
+ }
+ }
+ }
+
+ /**
+ * Gets the {@link android.media.session.MediaController} for the PIPed activity.
+ */
+ MediaController getMediaController() {
+ return mPipMediaController;
+ }
+
private class TaskStackListener extends ITaskStackListener.Stub {
@Override
public void onTaskStackChanged() throws RemoteException {
@@ -542,6 +593,8 @@
void onMoveToFullscreen();
/** Invoked when we are above to start resizing the Pip. */
void onPipResizeAboutToStart();
+ /** Invoked when the MediaController on PIPed activity is changed. */
+ void onMediaControllerChanged();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
index a392bec..fb7fa4d 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
@@ -18,34 +18,49 @@
import android.app.Activity;
import android.media.session.MediaController;
+import android.media.session.PlaybackState;
import android.os.Bundle;
import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.android.systemui.R;
+import static android.content.pm.PackageManager.FEATURE_LEANBACK;
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+import static android.media.session.PlaybackState.ACTION_PAUSE;
+import static android.media.session.PlaybackState.ACTION_PLAY;
+
/**
* Activity to show the PIP menu to control PIP.
*/
public class PipMenuActivity extends Activity implements PipManager.Listener {
private static final String TAG = "PipMenuActivity";
- private static final boolean DEBUG = false;
private final PipManager mPipManager = PipManager.getInstance();
private MediaController mMediaController;
private View mFullButtonView;
private View mFullDescriptionView;
- private View mPlayPauseButtonView;
- private View mPlayPauseDescriptionView;
+ private View mPlayPauseView;
+ private ImageView mPlayPauseButtonImageView;
+ private TextView mPlayPauseDescriptionTextView;
private View mCloseButtonView;
private View mCloseDescriptionView;
+ private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
+ @Override
+ public void onPlaybackStateChanged(PlaybackState state) {
+ updatePlayPauseView(state);
+ }
+ };
+
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.tv_pip_menu);
mPipManager.addListener(this);
- mFullButtonView = findViewById(R.id.full);
+ mFullButtonView = findViewById(R.id.full_button);
mFullDescriptionView = findViewById(R.id.full_desc);
mFullButtonView.setOnClickListener(new View.OnClickListener() {
@Override
@@ -61,22 +76,33 @@
}
});
- mPlayPauseButtonView = findViewById(R.id.play_pause);
- mPlayPauseDescriptionView = findViewById(R.id.play_pause_desc);
- mPlayPauseButtonView.setOnClickListener(new View.OnClickListener() {
+ mPlayPauseView = findViewById(R.id.play_pause);
+ mPlayPauseButtonImageView = (ImageView) findViewById(R.id.play_pause_button);
+ mPlayPauseDescriptionTextView = (TextView) findViewById(R.id.play_pause_desc);
+ mPlayPauseButtonImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- // TODO: Implement play/pause.
+ if (mMediaController == null || mMediaController.getPlaybackState() == null) {
+ return;
+ }
+ long actions = mMediaController.getPlaybackState().getActions();
+ int state = mMediaController.getPlaybackState().getState();
+ if (((actions & ACTION_PLAY) != 0) && !isPlaying(state)) {
+ mMediaController.getTransportControls().play();
+ } else if ((actions & ACTION_PAUSE) != 0 && isPlaying(state)) {
+ mMediaController.getTransportControls().pause();
+ }
+ // View will be updated later in {@link mMediaControllerCallback}
}
});
- mPlayPauseButtonView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+ mPlayPauseButtonImageView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
- mPlayPauseDescriptionView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
+ mPlayPauseDescriptionTextView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
}
});
- mCloseButtonView = findViewById(R.id.close);
+ mCloseButtonView = findViewById(R.id.close_button);
mCloseDescriptionView = findViewById(R.id.close_desc);
mCloseButtonView.setOnClickListener(new View.OnClickListener() {
@Override
@@ -91,6 +117,50 @@
mCloseDescriptionView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
}
});
+ updateMediaController();
+ }
+
+ private void updateMediaController() {
+ MediaController newController = mPipManager.getMediaController();
+ if (mMediaController == newController) {
+ return;
+ }
+ if (mMediaController != null) {
+ mMediaController.unregisterCallback(mMediaControllerCallback);
+ }
+ mMediaController = newController;
+ if (mMediaController != null) {
+ mMediaController.registerCallback(mMediaControllerCallback);
+ updatePlayPauseView(mMediaController.getPlaybackState());
+ } else {
+ updatePlayPauseView(null);
+ }
+ }
+
+ private void updatePlayPauseView(PlaybackState playbackState) {
+ if (playbackState != null
+ && (playbackState.getActions() & (ACTION_PLAY | ACTION_PAUSE)) != 0) {
+ mPlayPauseView.setVisibility(View.VISIBLE);
+ if (isPlaying(playbackState.getState())) {
+ mPlayPauseButtonImageView.setImageResource(R.drawable.tv_pip_pause_button);
+ mPlayPauseDescriptionTextView.setText(R.string.pip_pause);
+ } else {
+ mPlayPauseButtonImageView.setImageResource(R.drawable.tv_pip_play_button);
+ mPlayPauseDescriptionTextView.setText(R.string.pip_play);
+ }
+ } else {
+ mPlayPauseView.setVisibility(View.GONE);
+ }
+ }
+
+ private boolean isPlaying(int state) {
+ return state == PlaybackState.STATE_BUFFERING
+ || state == PlaybackState.STATE_CONNECTING
+ || state == PlaybackState.STATE_PLAYING
+ || state == PlaybackState.STATE_FAST_FORWARDING
+ || state == PlaybackState.STATE_REWINDING
+ || state == PlaybackState.STATE_SKIPPING_TO_PREVIOUS
+ || state == PlaybackState.STATE_SKIPPING_TO_NEXT;
}
private void restorePipAndFinish() {
@@ -107,6 +177,9 @@
@Override
protected void onDestroy() {
super.onDestroy();
+ if (mMediaController != null) {
+ mMediaController.unregisterCallback(mMediaControllerCallback);
+ }
mPipManager.removeListener(this);
mPipManager.resumePipResizing(
PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
@@ -131,6 +204,11 @@
}
@Override
+ public void onMediaControllerChanged() {
+ updateMediaController();
+ }
+
+ @Override
public void onPipResizeAboutToStart() {
finish();
mPipManager.suspendPipResizing(
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
index e5c07d2..ad45625b 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
@@ -82,6 +82,8 @@
}
@Override
- public void onPipResizeAboutToStart() {
- }
+ public void onPipResizeAboutToStart() { }
+
+ @Override
+ public void onMediaControllerChanged() { }
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
index cfeab6d..95d655c 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
@@ -103,4 +103,8 @@
mPipManager.suspendPipResizing(
PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH);
}
+
+ @Override
+ public void onMediaControllerChanged() {
+ }
}
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 2825601..5389c804 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -20,6 +20,8 @@
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<application>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TouchAnimatorTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TouchAnimatorTests.java
new file mode 100644
index 0000000..1d81fd4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TouchAnimatorTests.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import android.view.View;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.qs.TouchAnimator.Listener;
+import org.mockito.Mockito;
+
+public class TouchAnimatorTests extends SysuiTestCase {
+
+ private Listener mTouchListener;
+ private View mTestView;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mTestView = new View(getContext());
+ mTouchListener = Mockito.mock(Listener.class);
+ }
+
+ public void testSetValueFloat() {
+ TouchAnimator animator = new TouchAnimator.Builder()
+ .addFloat(mTestView, "x", 0, 50)
+ .build();
+
+ animator.setPosition(0);
+ assertEquals(0f, mTestView.getX());
+
+ animator.setPosition(.5f);
+ assertEquals(25f, mTestView.getX());
+
+ animator.setPosition(1);
+ assertEquals(50f, mTestView.getX());
+ }
+
+ public void testSetValueInt() {
+ TouchAnimator animator = new TouchAnimator.Builder()
+ .addInt(mTestView, "top", 0, 50)
+ .build();
+
+ animator.setPosition(0);
+ assertEquals(0, mTestView.getTop());
+
+ animator.setPosition(.5f);
+ assertEquals(25, mTestView.getTop());
+
+ animator.setPosition(1);
+ assertEquals(50, mTestView.getTop());
+ }
+
+ public void testStartDelay() {
+ TouchAnimator animator = new TouchAnimator.Builder()
+ .addFloat(mTestView, "x", 0, 50)
+ .setStartDelay(.5f)
+ .build();
+
+ animator.setPosition(0);
+ assertEquals(0f, mTestView.getX());
+
+ animator.setPosition(.5f);
+ assertEquals(0f, mTestView.getX());
+
+ animator.setPosition(.75f);
+ assertEquals(25f, mTestView.getX());
+
+ animator.setPosition(1);
+ assertEquals(50f, mTestView.getX());
+ }
+
+ public void testEndDelay() {
+ TouchAnimator animator = new TouchAnimator.Builder()
+ .addFloat(mTestView, "x", 0, 50)
+ .setEndDelay(.5f)
+ .build();
+
+ animator.setPosition(0);
+ assertEquals(0f, mTestView.getX());
+
+ animator.setPosition(.25f);
+ assertEquals(25f, mTestView.getX());
+
+ animator.setPosition(.5f);
+ assertEquals(50f, mTestView.getX());
+
+ animator.setPosition(1);
+ assertEquals(50f, mTestView.getX());
+ }
+
+ public void testOnAnimationAtStartCallback() {
+ TouchAnimator animator = new TouchAnimator.Builder()
+ .setListener(mTouchListener)
+ .build();
+
+ // Called on init.
+ animator.setPosition(0);
+ verifyOnAnimationAtStart(1);
+
+ // Not called from same state.
+ animator.setPosition(0);
+ verifyOnAnimationAtStart(1);
+
+ // Called after starting and moving back to start.
+ animator.setPosition(.5f);
+ animator.setPosition(0);
+ verifyOnAnimationAtStart(2);
+
+ // Called when move from end to end.
+ animator.setPosition(1);
+ animator.setPosition(0);
+ verifyOnAnimationAtStart(3);
+ }
+
+ public void testOnAnimationAtEndCallback() {
+ TouchAnimator animator = new TouchAnimator.Builder()
+ .setListener(mTouchListener)
+ .build();
+
+ // Called on init.
+ animator.setPosition(1);
+ verifyOnAnimationAtEnd(1);
+
+ // Not called from same state.
+ animator.setPosition(1);
+ verifyOnAnimationAtEnd(1);
+
+ // Called after starting and moving back to end.
+ animator.setPosition(.5f);
+ animator.setPosition(1);
+ verifyOnAnimationAtEnd(2);
+
+ // Called when move from end to end.
+ animator.setPosition(0);
+ animator.setPosition(1);
+ verifyOnAnimationAtEnd(3);
+ }
+
+ public void testOnAnimationStartedCallback() {
+ TouchAnimator animator = new TouchAnimator.Builder()
+ .setListener(mTouchListener)
+ .build();
+
+ // Called on init.
+ animator.setPosition(.5f);
+ verifyOnAnimationStarted(1);
+
+ // Not called from same state.
+ animator.setPosition(.6f);
+ verifyOnAnimationStarted(1);
+
+ // Called after going to end then moving again.
+ animator.setPosition(1);
+ animator.setPosition(.5f);
+ verifyOnAnimationStarted(2);
+
+ // Called after moving to start then moving again.
+ animator.setPosition(0);
+ animator.setPosition(.5f);
+ verifyOnAnimationStarted(3);
+ }
+
+ // TODO: Add test for interpolator.
+
+ private void verifyOnAnimationAtStart(int times) {
+ Mockito.verify(mTouchListener, Mockito.times(times)).onAnimationAtStart();
+ }
+
+ private void verifyOnAnimationAtEnd(int times) {
+ Mockito.verify(mTouchListener, Mockito.times(times)).onAnimationAtEnd();
+ }
+
+ private void verifyOnAnimationStarted(int times) {
+ Mockito.verify(mTouchListener, Mockito.times(times)).onAnimationStarted();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
index c4ca039..1841251 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java
@@ -19,6 +19,9 @@
import android.os.Looper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.phone.QSTileHost;
+import com.android.systemui.statusbar.policy.DataSaverController;
+import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.NetworkController;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -34,7 +37,12 @@
protected void setUp() throws Exception {
super.setUp();
mManagers = new ArrayList<>();
- QSTileHost host = new QSTileHost(mContext, null, null, null, null, null, null, null, null,
+ final NetworkController networkController = Mockito.mock(NetworkController.class);
+ Mockito.when(networkController.getDataSaverController()).thenReturn(
+ Mockito.mock(DataSaverController.class));
+ QSTileHost host = new QSTileHost(mContext, null, null, null, null,
+ networkController, null,
+ Mockito.mock(HotspotController.class), null,
null, null, null, null, null, null, null);
mTileService = new TestTileServices(host, Looper.myLooper());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 5cf3767..ebd5384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -16,9 +16,6 @@
package com.android.systemui.statusbar.policy;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
@@ -31,14 +28,12 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
-
import com.android.internal.telephony.cdma.EriInfo;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
-
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -47,6 +42,9 @@
import java.util.ArrayList;
import java.util.List;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
public class NetworkControllerBaseTest extends SysuiTestCase {
private static final String TAG = "NetworkControllerBaseTest";
protected static final int DEFAULT_LEVEL = 2;
@@ -109,6 +107,7 @@
protected void setupNetworkController() {
// For now just pretend to be the data sim, so we can test that too.
mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+ when(mMockTm.getDataEnabled(mSubId)).thenReturn(true);
setDefaultSubId(mSubId);
setSubscriptions(mSubId);
mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5f40e5c..71a0f49 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15150,6 +15150,7 @@
boolean dumpFullDetails = false;
boolean dumpDalvik = false;
boolean dumpSummaryOnly = false;
+ boolean dumpUnreachable = false;
boolean oomOnly = false;
boolean isCompact = false;
boolean localOnly = false;
@@ -15178,6 +15179,8 @@
dumpSummaryOnly = true;
} else if ("-S".equals(opt)) {
dumpSwapPss = true;
+ } else if ("--unreachable".equals(opt)) {
+ dumpUnreachable = true;
} else if ("--oom".equals(opt)) {
oomOnly = true;
} else if ("--local".equals(opt)) {
@@ -15339,7 +15342,7 @@
try {
pw.flush();
thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
- dumpDalvik, dumpSummaryOnly, innerArgs);
+ dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
} catch (RemoteException e) {
if (!isCheckinRequest) {
pw.println("Got RemoteException!");
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 0181640..bcdc800 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1416,7 +1416,7 @@
}
intentActivity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
mStartActivity.launchedFromPackage);
- } else if (!mStartActivity.intent.filterEquals(intentActivity.intent)) {
+ } else if (!intentActivity.task.isSameIntentResolution(mStartActivity)) {
// In this case we are launching the root activity of the task, but with a
// different intent. We should start a new instance on top.
mAddingToTask = true;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 37a549a..62275a9 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -469,6 +469,19 @@
setLockTaskAuth();
}
+ /**
+ * Return true if the input activity has the same intent resolution as the intent this task
+ * record is based on (normally the root activity intent).
+ */
+ boolean isSameIntentResolution(ActivityRecord r) {
+ final Intent intent = new Intent(r.intent);
+ // Correct the activity intent for aliasing. The task record intent will always be based on
+ // the real activity that will be launched not the alias, so we need to use an intent with
+ // the component name pointing to the real activity not the alias in the activity record.
+ intent.setComponent(r.realActivity);
+ return this.intent.filterEquals(intent);
+ }
+
void setTaskToReturnTo(int taskToReturnTo) {
mTaskToReturnTo = (taskToReturnTo == RECENTS_ACTIVITY_TYPE)
? HOME_ACTIVITY_TYPE : taskToReturnTo;
diff --git a/services/core/java/com/android/server/pm/EphemeralApplicationRegistry.java b/services/core/java/com/android/server/pm/EphemeralApplicationRegistry.java
index 8786350..389e0a1 100644
--- a/services/core/java/com/android/server/pm/EphemeralApplicationRegistry.java
+++ b/services/core/java/com/android/server/pm/EphemeralApplicationRegistry.java
@@ -210,6 +210,9 @@
}
public void onPackageUninstalledLPw(PackageParser.Package pkg) {
+ if (pkg == null) {
+ return;
+ }
PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6cfa1c9..9988694 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13303,18 +13303,21 @@
return null;
}
- private void removeNativeBinariesLI(PackageParser.Package pkg) {
+ private void removeNativeBinariesLI(PackageSetting ps) {
// Remove the lib path for the parent package
- PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps != null) {
NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
- }
- // Remove the lib path for the child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- ps = (PackageSetting) pkg.childPackages.get(i).mExtras;
- if (ps != null) {
- NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
+ // Remove the lib path for the child packages
+ final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
+ for (int i = 0; i < childCount; i++) {
+ PackageSetting childPs = null;
+ synchronized (mPackages) {
+ childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
+ }
+ if (childPs != null) {
+ NativeLibraryHelper.removeNativeBinariesLI(childPs
+ .legacyNativeLibraryPathString);
+ }
}
}
}
@@ -14437,7 +14440,7 @@
private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg,
PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
boolean writeSettings) {
- if (deletedPkg.parentPackage != null) {
+ if (deletedPs.parentPackageName != null) {
Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
return false;
}
@@ -14450,7 +14453,7 @@
// the system pkg from system partition
// reader
synchronized (mPackages) {
- disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPkg.packageName);
+ disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
}
if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
@@ -14476,10 +14479,10 @@
// Delete the updated package
outInfo.isRemovedPackageSystemUpdate = true;
if (outInfo.removedChildPackages != null) {
- final int childCount = (deletedPkg.childPackages != null)
- ? deletedPkg.childPackages.size() : 0;
+ final int childCount = (deletedPs.childPackageNames != null)
+ ? deletedPs.childPackageNames.size() : 0;
for (int i = 0; i < childCount; i++) {
- String childPackageName = deletedPkg.childPackages.get(i).packageName;
+ String childPackageName = deletedPs.childPackageNames.get(i);
if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
.contains(childPackageName)) {
PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
@@ -14499,7 +14502,7 @@
flags |= PackageManager.DELETE_KEEP_DATA;
}
- boolean ret = deleteInstalledPackageLI(deletedPkg, true, flags, allUserHandles,
+ boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles,
outInfo, writeSettings, disabledPs.pkg);
if (!ret) {
return false;
@@ -14510,7 +14513,7 @@
// Reinstate the old system package
enableSystemPackageLPw(disabledPs.pkg);
// Remove any native libraries from the upgraded package.
- removeNativeBinariesLI(deletedPkg);
+ removeNativeBinariesLI(deletedPs);
}
// Install the system package
@@ -14567,29 +14570,18 @@
return true;
}
- private boolean deleteInstalledPackageLI(PackageParser.Package pkg,
+ private boolean deleteInstalledPackageLI(PackageSetting ps,
boolean deleteCodeAndResources, int flags, int[] allUserHandles,
PackageRemovedInfo outInfo, boolean writeSettings,
PackageParser.Package replacingPackage) {
- PackageSetting ps = null;
-
synchronized (mPackages) {
- pkg = mPackages.get(pkg.packageName);
- if (pkg == null) {
- return false;
- }
-
- ps = mSettings.mPackages.get(pkg.packageName);
- if (ps == null) {
- return false;
- }
-
if (outInfo != null) {
outInfo.uid = ps.appId;
}
if (outInfo != null && outInfo.removedChildPackages != null) {
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ final int childCount = (ps.childPackageNames != null)
+ ? ps.childPackageNames.size() : 0;
for (int i = 0; i < childCount; i++) {
String childPackageName = ps.childPackageNames.get(i);
PackageSetting childPs = mSettings.mPackages.get(childPackageName);
@@ -14609,11 +14601,11 @@
removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings);
// Delete the child packages data
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+ final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageSetting childPs;
synchronized (mPackages) {
- childPs = mSettings.peekPackageLPr(pkg.childPackages.get(i).packageName);
+ childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
}
if (childPs != null) {
PackageRemovedInfo childOutInfo = (outInfo != null
@@ -14629,7 +14621,7 @@
}
// Delete application code and resources only for parent packages
- if (ps.pkg.parentPackage == null) {
+ if (ps.parentPackageName == null) {
if (deleteCodeAndResources && (outInfo != null)) {
outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
@@ -14720,7 +14712,7 @@
return false;
}
- if (ps.pkg != null && ps.pkg.parentPackage != null && (!isSystemApp(ps)
+ if (ps.parentPackageName != null && (!isSystemApp(ps)
|| (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
@@ -14808,7 +14800,7 @@
if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
// Kill application pre-emptively especially for apps on sd.
killApplication(packageName, ps.appId, "uninstall pkg");
- ret = deleteInstalledPackageLI(ps.pkg, deleteCodeAndResources, flags, allUserHandles,
+ ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles,
outInfo, writeSettings, replacingPackage);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 60c3a35..0252ea4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -769,7 +769,7 @@
out.attribute(null, ATTR_VALUE, Boolean.toString(disableContactsSearch));
out.endTag(null, TAG_DISABLE_CONTACTS_SEARCH);
}
- if (disableBluetoothContactSharing) {
+ if (!disableBluetoothContactSharing) {
out.startTag(null, TAG_DISABLE_BLUETOOTH_CONTACT_SHARING);
out.attribute(null, ATTR_VALUE,
Boolean.toString(disableBluetoothContactSharing));
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 094b3a9..1b70d65 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -181,7 +181,10 @@
* @hide
*/
public void removeCapability(int capability) {
- mConnectionCapabilities &= ~capability;
+ int newCapabilities = mConnectionCapabilities;
+ newCapabilities &= ~capability;
+
+ setConnectionCapabilities(newCapabilities);
}
/**
@@ -191,7 +194,10 @@
* @hide
*/
public void addCapability(int capability) {
- mConnectionCapabilities |= capability;
+ int newCapabilities = mConnectionCapabilities;
+ newCapabilities |= capability;
+
+ setConnectionCapabilities(newCapabilities);
}
/**
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 9f478df..857d2df 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1426,6 +1426,7 @@
* {@link android.provider.BlockedNumberContract#canCurrentUserBlockNumbers(Context)} returns
* {@code true} for the current user.
*/
+ // TODO: Delete this.
public void launchManageBlockedNumbersActivity() {
ITelecomService service = getTelecomService();
if (service != null) {
@@ -1437,6 +1438,26 @@
}
}
+ /**
+ * Creates the {@link Intent} which can be used with {@link Context#startActivity(Intent)} to
+ * launch the activity to manage blocked numbers.
+ * <p> This method displays the UI to manage blocked numbers only if
+ * {@link android.provider.BlockedNumberContract#canCurrentUserBlockNumbers(Context)} returns
+ * {@code true} for the current user.
+ */
+ public Intent createManageBlockedNumbersIntent() {
+ ITelecomService service = getTelecomService();
+ Intent result = null;
+ if (service != null) {
+ try {
+ result = service.createManageBlockedNumbersIntent();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecomService#createManageBlockedNumbersIntent", e);
+ }
+ }
+ return result;
+ }
+
private ITelecomService getTelecomService() {
if (mTelecomServiceOverride != null) {
return mTelecomServiceOverride;
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 95c8db5..3c250f1 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -17,6 +17,7 @@
package com.android.internal.telecom;
import android.content.ComponentName;
+import android.content.Intent;
import android.telecom.ParcelableCallAnalytics;
import android.telecom.PhoneAccountHandle;
import android.net.Uri;
@@ -247,5 +248,11 @@
/**
* @see TelecomServiceImpl#launchManageBlockedNumbersActivity
**/
+ // TODO: Delete this.
void launchManageBlockedNumbersActivity(in String callingPackageName);
+
+ /**
+ * @see TelecomServiceImpl#createManageBlockedNumbersIntent
+ **/
+ Intent createManageBlockedNumbersIntent();
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
index 91161f5..024e32f 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
@@ -16,9 +16,11 @@
package com.android.tools.layoutlib.create;
+import java.util.Arrays;
import java.util.HashMap;
import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
public class RefactorClassAdapter extends AbstractClassAdapter {
@@ -30,6 +32,14 @@
}
@Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature,
+ String[] exceptions) {
+ MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
+
+ return new RefactorStackMapAdapter(mw);
+ }
+
+ @Override
protected String renameInternalType(String oldClassName) {
if (oldClassName != null) {
String newName = mRefactorClasses.get(oldClassName);
@@ -46,4 +56,49 @@
}
return oldClassName;
}
+
+ /**
+ * A method visitor that renames all references from an old class name to a new class name in
+ * the stackmap of the method.
+ */
+ private class RefactorStackMapAdapter extends MethodVisitor {
+
+ private RefactorStackMapAdapter(MethodVisitor mv) {
+ super(Main.ASM_VERSION, mv);
+ }
+
+
+ private Object[] renameFrame(Object[] elements) {
+ if (elements == null) {
+ return null;
+ }
+
+ // The input array cannot be modified. We only copy the source array on write
+ boolean copied = false;
+ for (int i = 0; i < elements.length; i++) {
+ if (!(elements[i] instanceof String)) {
+ continue;
+ }
+
+ if (!copied) {
+ elements = Arrays.copyOf(elements, elements.length);
+ copied = true;
+ }
+
+ String type = (String)elements[i];
+ if (type.indexOf(';') > 0) {
+ elements[i] = renameTypeDesc(type);
+ } else {
+ elements[i] = renameInternalType(type);
+ }
+ }
+
+ return elements;
+ }
+
+ @Override
+ public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
+ super.visitFrame(type, nLocal, renameFrame(local), nStack, renameFrame(stack));
+ }
+ }
}