Merge "Turn off HWUI_ENABLE_OPENGL_VALIDATION" into nyc-dev
diff --git a/api/system-current.txt b/api/system-current.txt
index 915ceb2..39b1c2c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25315,6 +25315,41 @@
method public void onTetheringStarted();
}
+ public final class ConnectivityMetricsEvent implements android.os.Parcelable {
+ ctor public ConnectivityMetricsEvent(long, int, int, android.os.Parcelable);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.ConnectivityMetricsEvent> CREATOR;
+ field public final int componentTag;
+ field public final android.os.Parcelable data;
+ field public final int eventTag;
+ field public final long timestamp;
+ }
+
+ public static final class ConnectivityMetricsEvent.Reference implements android.os.Parcelable {
+ ctor public ConnectivityMetricsEvent.Reference(long);
+ method public int describeContents();
+ method public long getValue();
+ method public void readFromParcel(android.os.Parcel);
+ method public void setValue(long);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.ConnectivityMetricsEvent.Reference> CREATOR;
+ }
+
+ public class ConnectivityMetricsLogger {
+ ctor public ConnectivityMetricsLogger();
+ method public void logEvent(long, int, int, android.os.Parcelable);
+ field public static final int COMPONENT_TAG_BLUETOOTH = 1; // 0x1
+ field public static final int COMPONENT_TAG_CONNECTIVITY = 0; // 0x0
+ field public static final int COMPONENT_TAG_TELECOM = 3; // 0x3
+ field public static final int COMPONENT_TAG_TELEPHONY = 4; // 0x4
+ field public static final int COMPONENT_TAG_WIFI = 2; // 0x2
+ field public static final java.lang.String CONNECTIVITY_METRICS_LOGGER_SERVICE = "connectivity_metrics_logger";
+ field public static final java.lang.String DATA_KEY_EVENTS_COUNT = "count";
+ field public static final int NUMBER_OF_COMPONENTS = 5; // 0x5
+ field public static final int TAG_SKIPPED_EVENTS = -1; // 0xffffffff
+ }
+
public class Credentials {
ctor public Credentials(int, int, int);
method public int getGid();
@@ -26387,9 +26422,11 @@
field public int bwSupported;
field public boolean lciSupported;
field public boolean lcrSupported;
+ field public int mcVersion;
field public boolean oneSidedRttSupported;
field public int preambleSupported;
field public boolean responderSupported;
+ field public boolean secureRttSupported;
field public deprecated boolean supportedPeerType;
field public deprecated boolean supportedType;
field public boolean twoSided11McRttSupported;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index aa1e372..4108f6d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1210,7 +1210,7 @@
// For those APKs we only care about extracting signer certificates, and don't care
// about verifying integrity.
boolean signatureSchemeRollbackProtectionsEnforced =
- (parseFlags & PARSE_IS_SYSTEM) == 0;
+ (parseFlags & PARSE_IS_SYSTEM_DIR) == 0;
jarFile = new StrictJarFile(
apkPath,
!verified, // whether to verify JAR signature
@@ -1239,7 +1239,7 @@
toVerify.add(manifestEntry);
// If we're parsing an untrusted package, verify all contents
- if ((parseFlags & PARSE_IS_SYSTEM) == 0) {
+ if ((parseFlags & PARSE_IS_SYSTEM_DIR) == 0) {
final Iterator<ZipEntry> i = jarFile.iterator();
while (i.hasNext()) {
final ZipEntry entry = i.next();
@@ -1679,7 +1679,6 @@
private Package parseBaseApkCommon(Package pkg, Set<String> acceptedTags, Resources res,
XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException,
IOException {
- final boolean trustedOverlay = (flags & PARSE_TRUSTED_OVERLAY) != 0;
mParseInstrumentationArgs = null;
mParseActivityArgs = null;
mParseServiceArgs = null;
@@ -1769,8 +1768,6 @@
return null;
}
} else if (tagName.equals(TAG_OVERLAY)) {
- pkg.mTrustedOverlay = trustedOverlay;
-
sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestResourceOverlay);
pkg.mOverlayTarget = sa.getString(
@@ -2924,12 +2921,14 @@
ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
}
- if (sa.getBoolean(R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage,
- false) && (flags & PARSE_IS_SYSTEM) != 0) {
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage,
+ false)) {
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
}
- if (sa.getBoolean(R.styleable.AndroidManifestApplication_directBootAware, false)
- && (flags & PARSE_IS_SYSTEM) != 0) {
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestApplication_directBootAware,
+ false)) {
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
}
@@ -3554,7 +3553,7 @@
a.info.encryptionAware = a.info.directBootAware = sa.getBoolean(
R.styleable.AndroidManifestActivity_directBootAware,
- owner.applicationInfo.isDirectBootAware());
+ false);
} else {
a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
a.info.configChanges = 0;
@@ -3572,7 +3571,7 @@
a.info.encryptionAware = a.info.directBootAware = sa.getBoolean(
R.styleable.AndroidManifestActivity_directBootAware,
- owner.applicationInfo.isDirectBootAware());
+ false);
}
if (a.info.directBootAware) {
@@ -3985,7 +3984,7 @@
p.info.encryptionAware = p.info.directBootAware = sa.getBoolean(
R.styleable.AndroidManifestProvider_directBootAware,
- owner.applicationInfo.isDirectBootAware());
+ false);
if (p.info.directBootAware) {
owner.applicationInfo.privateFlags |=
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
@@ -4277,7 +4276,7 @@
s.info.encryptionAware = s.info.directBootAware = sa.getBoolean(
R.styleable.AndroidManifestService_directBootAware,
- owner.applicationInfo.isDirectBootAware());
+ false);
if (s.info.directBootAware) {
owner.applicationInfo.privateFlags |=
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java
index b5d67d3..5153ba9 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.java
+++ b/core/java/android/net/ConnectivityMetricsEvent.java
@@ -16,10 +16,12 @@
package android.net;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
/** {@hide} */
+@SystemApi
public final class ConnectivityMetricsEvent implements Parcelable {
/** The time when this event was collected, as returned by System.currentTimeMillis(). */
@@ -80,12 +82,13 @@
}
/** {@hide} */
- public static class Reference implements Parcelable {
+ @SystemApi
+ public final static class Reference implements Parcelable {
- public long value;
+ private long mValue;
public Reference(long ref) {
- this.value = ref;
+ this.mValue = ref;
}
/** Implement the Parcelable interface */
@@ -109,11 +112,19 @@
/** Implement the Parcelable interface */
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(value);
+ dest.writeLong(mValue);
}
public void readFromParcel(Parcel in) {
- value = in.readLong();
+ mValue = in.readLong();
+ }
+
+ public long getValue() {
+ return mValue;
+ }
+
+ public void setValue(long val) {
+ mValue = val;
}
}
}
diff --git a/core/java/android/net/ConnectivityMetricsLogger.java b/core/java/android/net/ConnectivityMetricsLogger.java
index eafb8ac..b49cc2b 100644
--- a/core/java/android/net/ConnectivityMetricsLogger.java
+++ b/core/java/android/net/ConnectivityMetricsLogger.java
@@ -15,6 +15,7 @@
*/
package android.net;
+import android.annotation.SystemApi;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.RemoteException;
@@ -22,6 +23,7 @@
import android.util.Log;
/** {@hide} */
+@SystemApi
public class ConnectivityMetricsLogger {
private static String TAG = "ConnectivityMetricsLogger";
private static final boolean DBG = true;
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 080ed9a..2481e04 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -163,17 +163,33 @@
///////////////////////////////////////////////////////////////////////////
/**
- * Calls the function specified with the drawGLFunction function pointer. This is
- * functionality used by webkit for calling into their renderer from our display lists.
- * This function may return true if an invalidation is needed after the call.
+ * Records the functor specified with the drawGLFunction function pointer. This is
+ * functionality used by webview for calling into their renderer from our display lists.
*
* @param drawGLFunction A native function pointer
*/
public void callDrawGLFunction2(long drawGLFunction) {
- nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction);
+ nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
}
- private static native void nCallDrawGLFunction(long renderer, long drawGLFunction);
+ /**
+ * Records the functor specified with the drawGLFunction function pointer. This is
+ * functionality used by webview for calling into their renderer from our display lists.
+ *
+ * @param drawGLFunction A native function pointer
+ * @param releasedCallback Called when the display list is destroyed, and thus
+ * the functor is no longer referenced by this canvas's display list.
+ *
+ * NOTE: The callback does *not* necessarily mean that there are no longer
+ * any references to the functor, just that the reference from this specific
+ * canvas's display list has been released.
+ */
+ public void drawGLFunctor2(long drawGLFunctor, Runnable releasedCallback) {
+ nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
+ }
+
+ private static native void nCallDrawGLFunction(long renderer,
+ long drawGLFunction, Runnable releasedCallback);
///////////////////////////////////////////////////////////////////////////
// Display list
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 6aac0e4..cadfd3d 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -22,12 +22,12 @@
#include <android_runtime/AndroidRuntime.h>
+#include <utils/Looper.h>
#include <cutils/properties.h>
#include <SkBitmap.h>
#include <SkRegion.h>
-
#include <Rect.h>
#include <RenderNode.h>
#include <CanvasProperty.h>
@@ -41,6 +41,52 @@
using namespace uirenderer;
+jmethodID gRunnableMethodId;
+
+static JNIEnv* jnienv(JavaVM* vm) {
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
+ }
+ return env;
+}
+
+class InvokeRunnableMessage : public MessageHandler {
+public:
+ InvokeRunnableMessage(JNIEnv* env, jobject runnable) {
+ mRunnable = env->NewGlobalRef(runnable);
+ env->GetJavaVM(&mVm);
+ }
+
+ virtual ~InvokeRunnableMessage() {
+ jnienv(mVm)->DeleteGlobalRef(mRunnable);
+ }
+
+ virtual void handleMessage(const Message&) {
+ jnienv(mVm)->CallVoidMethod(mRunnable, gRunnableMethodId);
+ }
+
+private:
+ JavaVM* mVm;
+ jobject mRunnable;
+};
+
+class GlFunctorReleasedCallbackBridge : public GlFunctorLifecycleListener {
+public:
+ GlFunctorReleasedCallbackBridge(JNIEnv* env, jobject javaCallback) {
+ mLooper = Looper::getForThread();
+ mMessage = new InvokeRunnableMessage(env, javaCallback);
+ }
+
+ virtual void onGlFunctorReleased(Functor* functor) override {
+ mLooper->sendMessage(mMessage, 0);
+ }
+
+private:
+ sp<Looper> mLooper;
+ sp<InvokeRunnableMessage> mMessage;
+};
+
// ----------------------------------------------------------------------------
// Setup
// ----------------------------------------------------------------------------
@@ -56,10 +102,12 @@
// ----------------------------------------------------------------------------
static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
- jlong canvasPtr, jlong functorPtr) {
+ jlong canvasPtr, jlong functorPtr, jobject releasedCallback) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
- canvas->callDrawGLFunction(functor);
+ sp<GlFunctorReleasedCallbackBridge> bridge(new GlFunctorReleasedCallbackBridge(
+ env, releasedCallback));
+ canvas->callDrawGLFunction(functor, bridge.get());
}
// ----------------------------------------------------------------------------
@@ -184,7 +232,8 @@
{ "nIsAvailable", "!()Z", (void*) android_view_DisplayListCanvas_isAvailable },
{ "nInsertReorderBarrier","!(JZ)V", (void*) android_view_DisplayListCanvas_insertReorderBarrier },
- { "nCallDrawGLFunction", "!(JJ)V", (void*) android_view_DisplayListCanvas_callDrawGLFunction },
+ { "nCallDrawGLFunction", "!(JJLjava/lang/Runnable;)V",
+ (void*) android_view_DisplayListCanvas_callDrawGLFunction },
{ "nDrawRoundRect", "!(JJJJJJJJ)V", (void*) android_view_DisplayListCanvas_drawRoundRectProps },
{ "nDrawCircle", "!(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps },
@@ -207,6 +256,9 @@
};
int register_android_view_DisplayListCanvas(JNIEnv* env) {
+ jclass runnableClass = FindClassOrDie(env, "java/lang/Runnable");
+ gRunnableMethodId = GetMethodIDOrDie(env, runnableClass, "run", "()V");
+
return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
}
diff --git a/core/res/res/layout/floating_popup_overflow_button.xml b/core/res/res/layout/floating_popup_overflow_button.xml
index 7053f3e..12e2000 100644
--- a/core/res/res/layout/floating_popup_overflow_button.xml
+++ b/core/res/res/layout/floating_popup_overflow_button.xml
@@ -24,5 +24,5 @@
android:paddingEnd="@dimen/floating_toolbar_menu_button_side_padding"
android:paddingBottom="@dimen/floating_toolbar_menu_image_button_vertical_padding"
android:scaleType="centerInside"
- android:background="?attr/selectableItemBackgroundBorderless"
+ android:background="?attr/actionBarItemBackground"
android:tint="?attr/floatingToolbarForegroundColor" />
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 181b343..b572bda 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -73,6 +73,12 @@
delete path;
}
+ for (auto& iter : functors) {
+ if (iter.listener) {
+ iter.listener->onGlFunctorReleased(iter.functor);
+ }
+ }
+
patchResources.clear();
pathResources.clear();
paints.clear();
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index aba5d4b..5b3227b 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -35,6 +35,7 @@
#include "Debug.h"
#include "CanvasProperty.h"
#include "DeferredDisplayList.h"
+#include "GlFunctorLifecycleListener.h"
#include "Matrix.h"
#include "RenderProperties.h"
@@ -119,6 +120,11 @@
virtual void operator ()() {}
};
+struct FunctorContainer {
+ Functor* functor;
+ GlFunctorLifecycleListener* listener;
+};
+
/**
* Data structure that holds the list of commands used in display list stream
*/
@@ -154,7 +160,7 @@
const LsaVector<NodeOpType*>& getChildren() const { return children; }
const LsaVector<const SkBitmap*>& getBitmapResources() const { return bitmapResources; }
- const LsaVector<Functor*>& getFunctors() const { return functors; }
+ const LsaVector<FunctorContainer>& getFunctors() const { return functors; }
const LsaVector<PushStagingFunctor*>& getPushStagingFunctors() { return pushStagingFunctors; }
size_t addChild(NodeOpType* childOp);
@@ -195,7 +201,7 @@
LsaVector< sp<VirtualLightRefBase> > referenceHolders;
// List of functors
- LsaVector<Functor*> functors;
+ LsaVector<FunctorContainer> functors;
// List of functors that need to be notified of pushStaging. Note that this list gets nothing
// but a callback during sync DisplayList, unlike the list of functors defined above, which
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index c6e92ab..ca968ce 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -81,9 +81,11 @@
return displayList;
}
-void DisplayListCanvas::callDrawGLFunction(Functor *functor) {
+void DisplayListCanvas::callDrawGLFunction(Functor* functor,
+ GlFunctorLifecycleListener* listener) {
addDrawOp(new (alloc()) DrawFunctorOp(functor));
- mDisplayList->functors.push_back(functor);
+ mDisplayList->functors.push_back({functor, listener});
+ mDisplayList->ref(listener);
}
SkCanvas* DisplayListCanvas::asSkCanvas() {
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index d6a5794..664f79e 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -93,7 +93,8 @@
// ----------------------------------------------------------------------------
virtual void drawLayer(DeferredLayerUpdater* layerHandle) override;
virtual void drawRenderNode(RenderNode* renderNode) override;
- virtual void callDrawGLFunction(Functor* functor) override;
+ virtual void callDrawGLFunction(Functor* functor,
+ GlFunctorLifecycleListener* listener) override;
// ----------------------------------------------------------------------------
// CanvasStateClient interface
diff --git a/libs/hwui/GlFunctorLifecycleListener.h b/libs/hwui/GlFunctorLifecycleListener.h
new file mode 100644
index 0000000..357090e
--- /dev/null
+++ b/libs/hwui/GlFunctorLifecycleListener.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <utils/Functor.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace uirenderer {
+
+class GlFunctorLifecycleListener : public VirtualLightRefBase {
+public:
+ virtual ~GlFunctorLifecycleListener() {}
+ virtual void onGlFunctorReleased(Functor* functor) = 0;
+};
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index ab733f1..b49f9b5 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -594,8 +594,10 @@
layerHandle->backingLayer()));
}
-void RecordingCanvas::callDrawGLFunction(Functor* functor) {
- mDisplayList->functors.push_back(functor);
+void RecordingCanvas::callDrawGLFunction(Functor* functor,
+ GlFunctorLifecycleListener* listener) {
+ mDisplayList->functors.push_back({functor, listener});
+ mDisplayList->ref(listener);
addOp(alloc().create_trivial<FunctorOp>(
*(mState.currentSnapshot()->transform),
getRecordedClip(),
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 219296c..372be24 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -59,7 +59,8 @@
virtual void drawLayer(DeferredLayerUpdater* layerHandle) override;
virtual void drawRenderNode(RenderNode* renderNode) override;
- virtual void callDrawGLFunction(Functor* functor) override;
+ virtual void callDrawGLFunction(Functor* functor,
+ GlFunctorLifecycleListener* listener) override;
// ----------------------------------------------------------------------------
// CanvasStateClient interface
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index ea06fcd..6e848fd 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -474,8 +474,8 @@
mDisplayList = mStagingDisplayList;
mStagingDisplayList = nullptr;
if (mDisplayList) {
- for (size_t i = 0; i < mDisplayList->getFunctors().size(); i++) {
- (*mDisplayList->getFunctors()[i])(DrawGlInfo::kModeSync, nullptr);
+ for (auto& iter : mDisplayList->getFunctors()) {
+ (*iter.functor)(DrawGlInfo::kModeSync, nullptr);
}
for (size_t i = 0; i < mDisplayList->getPushStagingFunctors().size(); i++) {
(*mDisplayList->getPushStagingFunctors()[i])();
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 1b459c1..ce67554 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -160,7 +160,8 @@
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
- virtual void callDrawGLFunction(Functor* functor) override;
+ virtual void callDrawGLFunction(Functor* functor,
+ uirenderer::GlFunctorLifecycleListener* listener) override;
protected:
virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
@@ -846,6 +847,7 @@
void SkiaCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) { }
-void SkiaCanvas::callDrawGLFunction(Functor* functor) { }
+void SkiaCanvas::callDrawGLFunction(Functor* functor,
+ uirenderer::GlFunctorLifecycleListener* listener) { }
} // namespace android
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 691cfa0..1c6f48e 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -219,22 +219,24 @@
int fillType = 0; /* non-zero or kWinding_FillType in Skia */
};
FullPathProperties(Node* mNode) : Properties(mNode), mTrimDirty(false) {}
+ ~FullPathProperties() {
+ SkSafeUnref(fillGradient);
+ SkSafeUnref(strokeGradient);
+ }
void syncProperties(const FullPathProperties& prop) {
mPrimitiveFields = prop.mPrimitiveFields;
mTrimDirty = true;
- fillGradient.reset(prop.fillGradient);
- strokeGradient.reset(prop.strokeGradient);
+ UPDATE_SKPROP(fillGradient, prop.fillGradient);
+ UPDATE_SKPROP(strokeGradient, prop.strokeGradient);
onPropertyChanged();
}
void setFillGradient(SkShader* gradient) {
- if(fillGradient != gradient){
- fillGradient.reset(gradient);
+ if(UPDATE_SKPROP(fillGradient, gradient)) {
onPropertyChanged();
}
}
void setStrokeGradient(SkShader* gradient) {
- if(strokeGradient != gradient){
- strokeGradient.reset(gradient);
+ if(UPDATE_SKPROP(strokeGradient, gradient)) {
onPropertyChanged();
}
}
@@ -346,8 +348,8 @@
count,
};
PrimitiveFields mPrimitiveFields;
- SkAutoTUnref<SkShader> fillGradient;
- SkAutoTUnref<SkShader> strokeGradient;
+ SkShader* fillGradient = nullptr;
+ SkShader* strokeGradient = nullptr;
};
// Called from UI thread
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 5dbda43..55af33e 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -20,6 +20,7 @@
#include <cutils/compiler.h>
#include <utils/Functor.h>
+#include "GlFunctorLifecycleListener.h"
#include "utils/NinePatch.h"
#include <SkBitmap.h>
@@ -124,7 +125,8 @@
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0;
- virtual void callDrawGLFunction(Functor* functor) = 0;
+ virtual void callDrawGLFunction(Functor* functor,
+ uirenderer::GlFunctorLifecycleListener* listener) = 0;
// ----------------------------------------------------------------------------
// Canvas state operations
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 209a104..ebc1c80 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -581,7 +581,7 @@
auto scrolledFunctorView = TestUtils::createNode(0, 0, 400, 1000000,
[&noopFunctor](RenderProperties& props, RecordingCanvas& canvas) {
canvas.translate(0, -800000);
- canvas.callDrawGLFunction(&noopFunctor);
+ canvas.callDrawGLFunction(&noopFunctor, nullptr);
});
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
diff --git a/libs/hwui/tests/unit/RenderNodeTests.cpp b/libs/hwui/tests/unit/RenderNodeTests.cpp
index 7c57a50..b2997df 100644
--- a/libs/hwui/tests/unit/RenderNodeTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeTests.cpp
@@ -51,3 +51,41 @@
EXPECT_FALSE(child->hasParents()) << "Child should be removed";
EXPECT_FALSE(parent->hasParents()) << "Root node shouldn't have any parents";
}
+
+TEST(RenderNode, releasedCallback) {
+ class DecRefOnReleased : public GlFunctorLifecycleListener {
+ public:
+ DecRefOnReleased(int* refcnt) : mRefCnt(refcnt) {}
+ void onGlFunctorReleased(Functor* functor) override {
+ *mRefCnt -= 1;
+ }
+ private:
+ int* mRefCnt;
+ };
+
+ int refcnt = 0;
+ sp<DecRefOnReleased> listener(new DecRefOnReleased(&refcnt));
+ Functor noopFunctor;
+
+ auto node = TestUtils::createNode(0, 0, 200, 400,
+ [&](RenderProperties& props, TestCanvas& canvas) {
+ refcnt++;
+ canvas.callDrawGLFunction(&noopFunctor, listener.get());
+ });
+ TestUtils::syncHierarchyPropertiesAndDisplayList(node);
+ EXPECT_EQ(1, refcnt);
+
+ TestUtils::recordNode(*node, [&](TestCanvas& canvas) {
+ refcnt++;
+ canvas.callDrawGLFunction(&noopFunctor, listener.get());
+ });
+ EXPECT_EQ(2, refcnt);
+
+ TestUtils::syncHierarchyPropertiesAndDisplayList(node);
+ EXPECT_EQ(1, refcnt);
+
+ TestUtils::recordNode(*node, [](TestCanvas& canvas) {});
+ EXPECT_EQ(1, refcnt);
+ TestUtils::syncHierarchyPropertiesAndDisplayList(node);
+ EXPECT_EQ(0, refcnt);
+}
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 7c6adad..2cd9872 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -27,6 +27,7 @@
import android.media.MediaDescription;
import android.media.session.MediaController;
import android.media.session.MediaSession;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -475,14 +476,8 @@
// the service will be told when we connect.
if (mState == CONNECT_STATE_CONNECTED) {
try {
- // NOTE: Do not call addSubscriptionWithOptions when options are null. Otherwise,
- // it will break the action of support library which expects addSubscription will
- // be called when options are null.
- if (options == null) {
- mServiceBinder.addSubscription(parentId, mServiceCallbacks);
- } else {
- mServiceBinder.addSubscriptionWithOptions(parentId, options, mServiceCallbacks);
- }
+ mServiceBinder.addSubscription(parentId, callback.mToken, options,
+ mServiceCallbacks);
} catch (RemoteException ex) {
// Process is crashing. We will disconnect, and upon reconnect we will
// automatically reregister. So nothing to do here.
@@ -497,34 +492,37 @@
throw new IllegalArgumentException("parentId is empty.");
}
- // Remove from our list.
Subscription sub = mSubscriptions.get(parentId);
-
+ if (sub == null) {
+ return;
+ }
// Tell the service if necessary.
- if (mState == CONNECT_STATE_CONNECTED && sub != null) {
- try {
- if (callback == null) {
- mServiceBinder.removeSubscription(parentId, mServiceCallbacks);
- } else {
- final List<SubscriptionCallback> callbacks = sub.getCallbacks();
- final List<Bundle> optionsList = sub.getOptionsList();
- for (int i = callbacks.size() - 1; i >= 0; --i) {
- if (callbacks.get(i) == callback) {
- mServiceBinder.removeSubscriptionWithOptions(
- parentId, optionsList.get(i), mServiceCallbacks);
- callbacks.remove(i);
- optionsList.remove(i);
+ try {
+ if (callback == null) {
+ if (mState == CONNECT_STATE_CONNECTED) {
+ mServiceBinder.removeSubscription(parentId, null, mServiceCallbacks);
+ }
+ } else {
+ final List<SubscriptionCallback> callbacks = sub.getCallbacks();
+ final List<Bundle> optionsList = sub.getOptionsList();
+ for (int i = callbacks.size() - 1; i >= 0; --i) {
+ if (callbacks.get(i) == callback) {
+ if (mState == CONNECT_STATE_CONNECTED) {
+ mServiceBinder.removeSubscription(
+ parentId, callback.mToken, mServiceCallbacks);
}
+ callbacks.remove(i);
+ optionsList.remove(i);
}
}
- } catch (RemoteException ex) {
- // Process is crashing. We will disconnect, and upon reconnect we will
- // automatically reregister. So nothing to do here.
- Log.d(TAG, "removeSubscription failed with RemoteException parentId=" + parentId);
}
+ } catch (RemoteException ex) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reregister. So nothing to do here.
+ Log.d(TAG, "removeSubscription failed with RemoteException parentId=" + parentId);
}
- if (sub != null && (sub.isEmpty() || callback == null)) {
+ if (sub.isEmpty() || callback == null) {
mSubscriptions.remove(parentId);
}
}
@@ -579,17 +577,12 @@
for (Entry<String, Subscription> subscriptionEntry : mSubscriptions.entrySet()) {
String id = subscriptionEntry.getKey();
Subscription sub = subscriptionEntry.getValue();
- for (Bundle options : sub.getOptionsList()) {
+ List<SubscriptionCallback> callbackList = sub.getCallbacks();
+ List<Bundle> optionsList = sub.getOptionsList();
+ for (int i = 0; i < callbackList.size(); ++i) {
try {
- // NOTE: Do not call addSubscriptionWithOptions when options are null.
- // Otherwise, it will break the action of support library which expects
- // addSubscription will be called when options are null.
- if (options == null) {
- mServiceBinder.addSubscription(id, mServiceCallbacks);
- } else {
- mServiceBinder.addSubscriptionWithOptions(
- id, options, mServiceCallbacks);
- }
+ mServiceBinder.addSubscription(id, callbackList.get(i).mToken,
+ optionsList.get(i), mServiceCallbacks);
} catch (RemoteException ex) {
// Process is crashing. We will disconnect, and upon reconnect we will
// automatically reregister. So nothing to do here.
@@ -859,6 +852,12 @@
* Callbacks for subscription related events.
*/
public static abstract class SubscriptionCallback {
+ Binder mToken;
+
+ public SubscriptionCallback() {
+ mToken = new Binder();
+ }
+
/**
* Called when the list of children is loaded or updated.
*
@@ -1071,12 +1070,7 @@
}
@Override
- public void onLoadChildren(String parentId, ParceledListSlice list) {
- onLoadChildrenWithOptions(parentId, list, null);
- }
-
- @Override
- public void onLoadChildrenWithOptions(String parentId, ParceledListSlice list,
+ public void onLoadChildren(String parentId, ParceledListSlice list,
final Bundle options) {
MediaBrowser mediaBrowser = mMediaBrowser.get();
if (mediaBrowser != null) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index e134635..21211d7 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -839,9 +839,11 @@
public abstract boolean onTune(Uri channelUri);
/**
- * Calls {@link #onTune(Uri)}. Override this method in order to handle domain-specific
+ * Tunes to a given channel. Override this method in order to handle domain-specific
* features that are only known between certain TV inputs and their clients.
*
+ * <p>The default implementation calls {@link #onTune(Uri)}.
+ *
* @param channelUri The URI of the channel.
* @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
* name, i.e. prefixed with a package name you own, so that different developers
@@ -1693,11 +1695,12 @@
public abstract void onTune(Uri channelUri);
/**
- * Calls {@link #onTune(Uri)}. Override this method in order to handle domain-specific
- * features that are only known between certain TV inputs and their clients.
+ * Called when the application requests to tune to a given channel for TV program recording.
+ * Override this method in order to handle domain-specific features that are only known
+ * between certain TV inputs and their clients.
*
* <p>The application may call this method before starting or after stopping recording, but
- * not during recording.
+ * not during recording. The default implementation calls {@link #onTune(Uri)}.
*
* <p>The session must call {@link #notifyTuned(Uri)} if the tune request was fulfilled, or
* {@link #notifyError(int)} otherwise.
diff --git a/media/java/android/service/media/IMediaBrowserService.aidl b/media/java/android/service/media/IMediaBrowserService.aidl
index 6ca5ac5..eef5a7c 100644
--- a/media/java/android/service/media/IMediaBrowserService.aidl
+++ b/media/java/android/service/media/IMediaBrowserService.aidl
@@ -14,19 +14,11 @@
* @hide
*/
oneway interface IMediaBrowserService {
-
- // Warning: DO NOT CHANGE the methods signature and order of methods.
- // A change of the order or the method signatures could break the support library.
-
void connect(String pkg, in Bundle rootHints, IMediaBrowserServiceCallbacks callbacks);
void disconnect(IMediaBrowserServiceCallbacks callbacks);
- void addSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
- void removeSubscription(String uri, IMediaBrowserServiceCallbacks callbacks);
+ void addSubscription(String uri, in IBinder token, in Bundle options,
+ IMediaBrowserServiceCallbacks callbacks);
+ void removeSubscription(String uri, in IBinder token, IMediaBrowserServiceCallbacks callbacks);
void getMediaItem(String uri, in ResultReceiver cb);
-
- void addSubscriptionWithOptions(String uri, in Bundle options,
- IMediaBrowserServiceCallbacks callbacks);
- void removeSubscriptionWithOptions(String uri, in Bundle options,
- IMediaBrowserServiceCallbacks callbacks);
}
diff --git a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index e6b0e8c..dadb025 100644
--- a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
@@ -13,10 +13,6 @@
* @hide
*/
oneway interface IMediaBrowserServiceCallbacks {
-
- // Warning: DO NOT CHANGE the methods signature and order of methods.
- // A change of the order or the method signatures could break the support library.
-
/**
* Invoked when the connected has been established.
* @param root The root media id for browsing.
@@ -26,6 +22,5 @@
*/
void onConnect(String root, in MediaSession.Token session, in Bundle extras);
void onConnectFailed();
- void onLoadChildren(String mediaId, in ParceledListSlice list);
- void onLoadChildrenWithOptions(String mediaId, in ParceledListSlice list, in Bundle options);
+ void onLoadChildren(String mediaId, in ParceledListSlice list, in Bundle options);
}
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 6954045..ddc0e88 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -39,6 +39,7 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Pair;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -108,7 +109,7 @@
Bundle rootHints;
IMediaBrowserServiceCallbacks callbacks;
BrowserRoot root;
- HashMap<String, List<Bundle>> subscriptions = new HashMap<>();
+ HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>();
}
/**
@@ -247,13 +248,7 @@
}
@Override
- public void addSubscription(final String id,
- final IMediaBrowserServiceCallbacks callbacks) {
- addSubscriptionWithOptions(id, null, callbacks);
- }
-
- @Override
- public void addSubscriptionWithOptions(final String id, final Bundle options,
+ public void addSubscription(final String id, final IBinder token, final Bundle options,
final IMediaBrowserServiceCallbacks callbacks) {
mHandler.post(new Runnable() {
@Override
@@ -268,19 +263,13 @@
return;
}
- MediaBrowserService.this.addSubscription(id, connection, options);
+ MediaBrowserService.this.addSubscription(id, connection, token, options);
}
});
}
@Override
- public void removeSubscription(final String id,
- final IMediaBrowserServiceCallbacks callbacks) {
- removeSubscriptionWithOptions(id, null, callbacks);
- }
-
- @Override
- public void removeSubscriptionWithOptions(final String id, final Bundle options,
+ public void removeSubscription(final String id, final IBinder token,
final IMediaBrowserServiceCallbacks callbacks) {
mHandler.post(new Runnable() {
@Override
@@ -293,7 +282,7 @@
+ id);
return;
}
- if (!MediaBrowserService.this.removeSubscription(id, connection, options)) {
+ if (!MediaBrowserService.this.removeSubscription(id, connection, token)) {
Log.w(TAG, "removeSubscription called for " + id
+ " which is not subscribed");
}
@@ -519,11 +508,12 @@
public void run() {
for (IBinder binder : mConnections.keySet()) {
ConnectionRecord connection = mConnections.get(binder);
- List<Bundle> optionsList = connection.subscriptions.get(parentId);
- if (optionsList != null) {
- for (Bundle bundle : optionsList) {
- if (MediaBrowserUtils.hasDuplicatedItems(options, bundle)) {
- performLoadChildren(parentId, connection, bundle);
+ List<Pair<IBinder, Bundle>> callbackList =
+ connection.subscriptions.get(parentId);
+ if (callbackList != null) {
+ for (Pair<IBinder, Bundle> callback : callbackList) {
+ if (MediaBrowserUtils.hasDuplicatedItems(options, callback.second)) {
+ performLoadChildren(parentId, connection, callback.second);
}
}
}
@@ -553,19 +543,21 @@
/**
* Save the subscription and if it is a new subscription send the results.
*/
- private void addSubscription(String id, ConnectionRecord connection, Bundle options) {
+ private void addSubscription(String id, ConnectionRecord connection, IBinder token,
+ Bundle options) {
// Save the subscription
- List<Bundle> optionsList = connection.subscriptions.get(id);
- if (optionsList == null) {
- optionsList = new ArrayList<>();
+ List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id);
+ if (callbackList == null) {
+ callbackList = new ArrayList<>();
}
- for (Bundle bundle : optionsList) {
- if (MediaBrowserUtils.areSameOptions(options, bundle)) {
+ for (Pair<IBinder, Bundle> callback : callbackList) {
+ if (token == callback.first
+ && MediaBrowserUtils.areSameOptions(options, callback.second)) {
return;
}
}
- optionsList.add(options);
- connection.subscriptions.put(id, optionsList);
+ callbackList.add(new Pair<>(token, options));
+ connection.subscriptions.put(id, callbackList);
// send the results
performLoadChildren(id, connection, options);
}
@@ -573,21 +565,20 @@
/**
* Remove the subscription.
*/
- private boolean removeSubscription(String id, ConnectionRecord connection, Bundle options) {
- if (options == null) {
+ private boolean removeSubscription(String id, ConnectionRecord connection, IBinder token) {
+ if (token == null) {
return connection.subscriptions.remove(id) != null;
}
boolean removed = false;
- List<Bundle> optionsList = connection.subscriptions.get(id);
- if (optionsList != null) {
- for (Bundle bundle : optionsList) {
- if (MediaBrowserUtils.areSameOptions(options, bundle)) {
+ List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id);
+ if (callbackList != null) {
+ for (Pair<IBinder, Bundle> callback : callbackList) {
+ if (token == callback.first) {
removed = true;
- optionsList.remove(bundle);
- break;
+ callbackList.remove(callback);
}
}
- if (optionsList.size() == 0) {
+ if (callbackList.size() == 0) {
connection.subscriptions.remove(id);
}
}
@@ -619,14 +610,7 @@
final ParceledListSlice<MediaBrowser.MediaItem> pls =
filteredList == null ? null : new ParceledListSlice<>(filteredList);
try {
- // NOTE: Do not call onLoadChildrenWithOptions when options are null. Otherwise,
- // it will break the action of support library which expects onLoadChildren will
- // be called when options are null.
- if (options == null) {
- connection.callbacks.onLoadChildren(parentId, pls);
- } else {
- connection.callbacks.onLoadChildrenWithOptions(parentId, pls, options);
- }
+ connection.callbacks.onLoadChildren(parentId, pls, options);
} catch (RemoteException ex) {
// The other side is in the process of crashing.
Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 64b4842..7b3fd66 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2158,6 +2158,17 @@
// System UI Tuner > Other > Power notification controls > Toggle on/off
ACTION_TUNER_POWER_NOTIFICATION_CONTROLS = 393;
+ // Action: user enable / disabled data saver using Settings. Arguments:
+ // 0: Data Saver mode is disabled.
+ // 1: Data Saver mode is enabled.
+ ACTION_DATA_SAVER_MODE = 394;
+
+ // User whitelisted an app for Data Saver mode; action pass package name of app.
+ ACTION_DATA_SAVER_WHITELIST = 395;
+
+ // User blacklisted an app for Data Saver mode; action pass package name of app.
+ ACTION_DATA_SAVER_BLACKLIST = 396;
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c971262..40430b4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1471,6 +1471,7 @@
static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
+ static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -2241,6 +2242,17 @@
}
vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
} break;
+ case VR_MODE_APPLY_IF_NEEDED_MSG: {
+ final ActivityRecord r = (ActivityRecord) msg.obj;
+ final boolean needsVrMode = r != null && r.requestedVrComponent != null;
+ if (needsVrMode) {
+ VrManagerInternal vrService =
+ LocalServices.getService(VrManagerInternal.class);
+ boolean enable = msg.arg1 == 1;
+ vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
+ r.info.getComponentName());
+ }
+ } break;
}
}
};
@@ -3021,6 +3033,11 @@
mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
}
+ private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
+ }
+
final void showAskCompatModeDialogLocked(ActivityRecord r) {
Message msg = Message.obtain();
msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
@@ -6537,6 +6554,7 @@
// Some stack visibility might change (e.g. docked stack)
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ applyVrModeIfNeededLocked(mFocusedActivity, true);
}
}
} finally {
@@ -20925,6 +20943,7 @@
SleepTokenImpl token = new SleepTokenImpl(tag);
mSleepTokens.add(token);
updateSleepIfNeededLocked();
+ applyVrModeIfNeededLocked(mFocusedActivity, false);
return token;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index ab3a0b3..cd465d6 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2270,7 +2270,7 @@
final ActivityRecord r = task.getTopActivity();
final ActivityStack prevStack = task.stack;
final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r);
- final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r);
+ final boolean wasResumed = prevStack.mResumedActivity == r;
// In some cases the focused stack isn't the front stack. E.g. pinned stack.
// Whenever we are moving the top activity from the front stack we want to make sure to move
// the stack to the front.
diff --git a/services/core/java/com/android/server/connectivity/MetricsLoggerService.java b/services/core/java/com/android/server/connectivity/MetricsLoggerService.java
index 0c259ae..ac5c4ae 100644
--- a/services/core/java/com/android/server/connectivity/MetricsLoggerService.java
+++ b/services/core/java/com/android/server/connectivity/MetricsLoggerService.java
@@ -300,14 +300,14 @@
*/
public ConnectivityMetricsEvent[] getEvents(ConnectivityMetricsEvent.Reference reference) {
enforceDumpPermission();
- long ref = reference.value;
+ long ref = reference.getValue();
if (VDBG) Log.v(TAG, "getEvents(" + ref + ")");
ConnectivityMetricsEvent[] result;
synchronized (mEvents) {
if (ref > mLastEventReference) {
Log.e(TAG, "Invalid reference");
- reference.value = mLastEventReference;
+ reference.setValue(mLastEventReference);
return null;
}
if (ref < mLastEventReference - mEvents.size()) {
@@ -329,7 +329,7 @@
}
}
- reference.value = mLastEventReference;
+ reference.setValue(mLastEventReference);
return result;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index fed7e4b..e07d72f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1189,7 +1189,9 @@
@Override
public void binderDied() {
synchronized (mLock) {
- mRecordListenerRecord = null;
+ if (mRecordListenerRecord == this) {
+ mRecordListenerRecord = null;
+ }
}
}
}
@@ -1813,7 +1815,9 @@
@Override
public void binderDied() {
synchronized (mLock) {
- mInputChangeListenerRecord = null;
+ if (mInputChangeListenerRecord == this) {
+ mInputChangeListenerRecord = null;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c248608..3fb786b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -260,6 +260,8 @@
private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
private static final int MSG_SCREEN_ON_CHANGED = 8;
private static final int MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED = 9;
+ private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
+ private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
private final Context mContext;
private final IActivityManager mActivityManager;
@@ -1275,8 +1277,10 @@
}
for (String iface : ifaces) {
- removeInterfaceQuota(iface);
- setInterfaceQuota(iface, quotaBytes);
+ // long quotaBytes split up into two ints to fit in message
+ mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
+ (int) (quotaBytes >> 32), (int) (quotaBytes & 0xFFFFFFFF), iface)
+ .sendToTarget();
newMeteredIfaces.add(iface);
}
}
@@ -1292,8 +1296,10 @@
for (int i = connIfaces.size()-1; i >= 0; i--) {
String iface = connIfaces.valueAt(i);
- removeInterfaceQuota(iface);
- setInterfaceQuota(iface, Long.MAX_VALUE);
+ // long quotaBytes split up into two ints to fit in message
+ mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
+ (int) (Long.MAX_VALUE >> 32), (int) (Long.MAX_VALUE & 0xFFFFFFFF), iface)
+ .sendToTarget();
newMeteredIfaces.add(iface);
}
@@ -1303,7 +1309,8 @@
for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
final String iface = mMeteredIfaces.valueAt(i);
if (!newMeteredIfaces.contains(iface)) {
- removeInterfaceQuota(iface);
+ mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface)
+ .sendToTarget();
}
}
mMeteredIfaces = newMeteredIfaces;
@@ -2950,6 +2957,17 @@
updateScreenOn();
return true;
}
+ case MSG_UPDATE_INTERFACE_QUOTA: {
+ removeInterfaceQuota((String) msg.obj);
+ // int params need to be stitched back into a long
+ setInterfaceQuota((String) msg.obj,
+ ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL));
+ return true;
+ }
+ case MSG_REMOVE_INTERFACE_QUOTA: {
+ removeInterfaceQuota((String) msg.obj);
+ return true;
+ }
default: {
return false;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1fb260d..dc81c65 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2315,24 +2315,29 @@
// For security and version matching reason, only consider
// overlay packages if they reside in VENDOR_OVERLAY_DIR.
File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
- scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
- | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
+ scanDirTracedLI(vendorOverlayDir, mDefParseFlags
+ | PackageParser.PARSE_IS_SYSTEM
+ | PackageParser.PARSE_IS_SYSTEM_DIR
+ | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
// Find base frameworks (resource packages without code).
- scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
+ scanDirTracedLI(frameworkDir, mDefParseFlags
+ | PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED,
scanFlags | SCAN_NO_DEX, 0);
// Collected privileged system packages.
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
- scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
+ scanDirTracedLI(privilegedAppDir, mDefParseFlags
+ | PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
// Collect ordinary system packages.
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
- scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
+ scanDirTracedLI(systemAppDir, mDefParseFlags
+ | PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Collect all vendor packages.
@@ -2342,12 +2347,14 @@
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
- scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
+ scanDirTracedLI(vendorAppDir, mDefParseFlags
+ | PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Collect all OEM packages.
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
- scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
+ scanDirTracedLI(oemAppDir, mDefParseFlags
+ | PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Prune any system packages that no longer exist.
@@ -2428,10 +2435,12 @@
SystemClock.uptimeMillis());
scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
- scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
+ scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
+ | PackageParser.PARSE_FORWARD_LOCK,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
- scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL,
+ scanDirLI(mEphemeralInstallDir, mDefParseFlags
+ | PackageParser.PARSE_IS_EPHEMERAL,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
/**
@@ -2476,7 +2485,7 @@
logCriticalInfo(Log.WARN, "Expected better " + packageName
+ " but never showed up; reverting to system");
- final int reparseFlags;
+ int reparseFlags = mDefParseFlags;
if (FileUtils.contains(privilegedAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
@@ -6501,7 +6510,7 @@
return true;
}
- private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) {
+ private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
try {
scanDirLI(dir, parseFlags, scanFlags, currentTime);
@@ -6510,7 +6519,7 @@
}
}
- private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
+ private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
final File[] files = dir.listFiles();
if (ArrayUtils.isEmpty(files)) {
Log.d(TAG, "No files in app dir " + dir);
@@ -6576,7 +6585,7 @@
}
private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
- int parseFlags) throws PackageManagerException {
+ final int policyFlags) throws PackageManagerException {
if (ps != null
&& ps.codePath.equals(srcFile)
&& ps.timeStamp == srcFile.lastModified()
@@ -6605,7 +6614,7 @@
}
try {
- PackageParser.collectCertificates(pkg, parseFlags);
+ PackageParser.collectCertificates(pkg, policyFlags);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
}
@@ -6615,8 +6624,8 @@
* Traces a package scan.
* @see #scanPackageLI(File, int, int, long, UserHandle)
*/
- private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags,
- long currentTime, UserHandle user) throws PackageManagerException {
+ private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
+ int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
try {
return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
@@ -6632,7 +6641,6 @@
private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
long currentTime, UserHandle user) throws PackageManagerException {
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
- parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setOnlyCoreApps(mOnlyCore);
@@ -6642,11 +6650,14 @@
parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
}
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
final PackageParser.Package pkg;
try {
pkg = pp.parsePackage(scanFile, parseFlags);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
@@ -6657,7 +6668,7 @@
* @throws PackageManagerException on a parse error.
*/
private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
- int parseFlags, int scanFlags, long currentTime, UserHandle user)
+ final int policyFlags, int scanFlags, long currentTime, UserHandle user)
throws PackageManagerException {
// If the package has children and this is the first dive in the function
// we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
@@ -6673,20 +6684,20 @@
}
// Scan the parent
- PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags,
+ PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
scanFlags, currentTime, user);
// Scan the children
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageParser.Package childPackage = pkg.childPackages.get(i);
- scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags,
+ scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
currentTime, user);
}
if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
- return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
+ return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
}
return scannedPkg;
@@ -6697,7 +6708,7 @@
* @throws PackageManagerException on a parse error.
*/
private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
- int parseFlags, int scanFlags, long currentTime, UserHandle user)
+ int policyFlags, int scanFlags, long currentTime, UserHandle user)
throws PackageManagerException {
PackageSetting ps = null;
PackageSetting updatedPkg;
@@ -6724,7 +6735,7 @@
// may need to remove disabled child packages on the system partition
// or may need to not add child packages if the parent apk is updated
// on the data partition and no longer defines this child package.
- if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
+ if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
// If this is a parent package for an updated system app and this system
// app got an OTA update which no longer defines some of the child packages
// we have to prune them from the disabled system packages.
@@ -6754,7 +6765,7 @@
boolean updatedPkgBetter = false;
// First check if this is a system package that may involve an update
- if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
+ if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
// If new package is not located in "/system/priv-app" (e.g. due to an OTA),
// it needs to drop FLAG_PRIVILEGED.
if (locationIsPrivileged(scanFile)) {
@@ -6836,17 +6847,17 @@
if (updatedPkg != null) {
// An updated system app will not have the PARSE_IS_SYSTEM flag set
// initially
- parseFlags |= PackageParser.PARSE_IS_SYSTEM;
+ policyFlags |= PackageParser.PARSE_IS_SYSTEM;
// An updated privileged app will not have the PARSE_IS_PRIVILEGED
// flag set initially
if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
- parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
+ policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
}
}
// Verify certificates against what was last scanned
- collectCertificatesLI(ps, pkg, scanFile, parseFlags);
+ collectCertificatesLI(ps, pkg, scanFile, policyFlags);
/*
* A new system app appeared, but we already had a non-system one of the
@@ -6854,7 +6865,7 @@
*/
boolean shouldHideSystemApp = false;
if (updatedPkg == null && ps != null
- && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
+ && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
/*
* Check to make sure the signatures match first. If they don't,
* wipe the installed application and its data.
@@ -6902,16 +6913,16 @@
// are kept in different files. (except for app in either system or
// vendor path).
// TODO grab this value from PackageSettings
- if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
+ if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
- parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
+ policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
}
}
// TODO: extend to support forward-locked splits
String resourcePath = null;
String baseResourcePath = null;
- if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
+ if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
if (ps != null && ps.resourcePathString != null) {
resourcePath = ps.resourcePathString;
baseResourcePath = ps.resourcePathString;
@@ -6934,7 +6945,7 @@
pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
// Note that we invoke the following method only if we are about to unpack an application
- PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
+ PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
| SCAN_UPDATE_SIGNATURE, currentTime, user);
/*
@@ -7576,8 +7587,9 @@
return cpuAbiOverride;
}
- private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags,
- int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
+ private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
+ final int policyFlags, int scanFlags, long currentTime, UserHandle user)
+ throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
// If the package has children and this is the first dive in the function
// we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
@@ -7595,12 +7607,12 @@
final PackageParser.Package scannedPkg;
try {
// Scan the parent
- scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
+ scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
// Scan the children
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
PackageParser.Package childPkg = pkg.childPackages.get(i);
- scanPackageLI(childPkg, parseFlags,
+ scanPackageLI(childPkg, policyFlags,
scanFlags, currentTime, user);
}
} finally {
@@ -7608,17 +7620,17 @@
}
if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
- return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
+ return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
}
return scannedPkg;
}
- private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
+ private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
boolean success = false;
try {
- final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
+ final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
currentTime, user);
success = true;
return res;
@@ -7632,8 +7644,8 @@
}
}
- private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
- int scanFlags, long currentTime, UserHandle user)
+ private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
+ final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
throws PackageManagerException {
final File scanFile = new File(pkg.codePath);
if (pkg.applicationInfo.getCodePath() == null ||
@@ -7643,14 +7655,36 @@
"Code and resource paths haven't been set correctly");
}
- if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
+ // Apply policy
+ if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ if (pkg.applicationInfo.isDirectBootAware()) {
+ // we're direct boot aware; set for all components
+ for (PackageParser.Service s : pkg.services) {
+ s.info.encryptionAware = s.info.directBootAware = true;
+ }
+ for (PackageParser.Provider p : pkg.providers) {
+ p.info.encryptionAware = p.info.directBootAware = true;
+ }
+ for (PackageParser.Activity a : pkg.activities) {
+ a.info.encryptionAware = a.info.directBootAware = true;
+ }
+ for (PackageParser.Activity r : pkg.receivers) {
+ r.info.encryptionAware = r.info.directBootAware = true;
+ }
+ }
} else {
// Only allow system apps to be flagged as core apps.
pkg.coreApp = false;
+ // clear flags not applicable to regular apps
+ pkg.applicationInfo.privateFlags &=
+ ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
+ pkg.applicationInfo.privateFlags &=
+ ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
}
+ pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
- if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
+ if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
}
@@ -7699,7 +7733,7 @@
}
if (DEBUG_PACKAGE_SCANNING) {
- if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
+ if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Scanning package " + pkg.packageName);
}
@@ -7774,7 +7808,7 @@
+ " for shared user failed");
}
if (DEBUG_PACKAGE_SCANNING) {
- if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
+ if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
+ "): packages=" + suid.packages);
}
@@ -7820,6 +7854,7 @@
origPackage = null;
continue;
}
+ // TODO: Add case when shared user id is added [b/28144775]
} else {
if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
+ pkg.packageName + " to old name " + origPackage.name);
@@ -7886,7 +7921,7 @@
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
- if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
+ if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
// Check all shared libraries and map to their actual file path.
// We only do this here for apps not on a system dir, because those
// are the only ones that can fail an install due to this. We
@@ -7907,7 +7942,7 @@
// over the latest parsed certs.
pkgSetting.signatures.mSignatures = pkg.mSignatures;
} else {
- if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
+ if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"Package " + pkg.packageName + " upgrade keys do not match the "
+ "previously installed version");
@@ -7925,7 +7960,7 @@
// over the latest parsed certs.
pkgSetting.signatures.mSignatures = pkg.mSignatures;
} catch (PackageManagerException e) {
- if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
+ if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw e;
}
// The signature has changed, but this package is in the system
@@ -8114,7 +8149,7 @@
// Only privileged apps and updated privileged apps can add child packages.
if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
- if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) {
+ if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
throw new PackageManagerException("Only privileged apps and updated "
+ "privileged apps can add child packages. Ignoring package "
+ pkg.packageName);
@@ -8240,7 +8275,7 @@
} else if (pkgSetting.firstInstallTime == 0) {
// We need *something*. Take time time stamp of the file.
pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
- } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
+ } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
if (scanFileTime != pkgSetting.timeStamp) {
// A package on the system image has changed; consider this
// to be an update.
@@ -8283,7 +8318,7 @@
p.info.authority = p.info.authority + ";" + names[j];
}
if (DEBUG_PACKAGE_SCANNING) {
- if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
+ if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Registered content provider: " + names[j]
+ ", className = " + p.info.name + ", isSyncable = "
+ p.info.isSyncable);
@@ -8298,7 +8333,7 @@
}
}
}
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8318,7 +8353,7 @@
s.info.processName = fixProcessName(pkg.applicationInfo.processName,
s.info.processName, pkg.applicationInfo.uid);
mServices.addService(s);
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8338,7 +8373,7 @@
a.info.processName = fixProcessName(pkg.applicationInfo.processName,
a.info.processName, pkg.applicationInfo.uid);
mReceivers.addActivity(a, "receiver");
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8358,7 +8393,7 @@
a.info.processName = fixProcessName(pkg.applicationInfo.processName,
a.info.processName, pkg.applicationInfo.uid);
mActivities.addActivity(a, "activity");
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8378,7 +8413,7 @@
PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
if (cur == null) {
mPermissionGroups.put(pg.info.name, pg);
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8390,7 +8425,7 @@
Slog.w(TAG, "Permission group " + pg.info.name + " from package "
+ pg.info.packageName + " ignored: original from "
+ cur.info.packageName);
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8469,7 +8504,7 @@
bp.uid = pkg.applicationInfo.uid;
bp.sourcePackage = p.info.packageName;
p.info.flags |= PermissionInfo.FLAG_INSTALLED;
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8488,7 +8523,7 @@
+ p.info.packageName + " ignored: original from "
+ bp.sourcePackage);
}
- } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -8523,7 +8558,7 @@
// need other information about the application, like the ABI and what not ?
a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
mInstrumentation.put(a.getComponentName(), a);
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
@@ -13538,8 +13573,8 @@
/*
* Install a non-existing package.
*/
- private void installNewPackageLIF(PackageParser.Package pkg, int parseFlags, int scanFlags,
- UserHandle user, String installerPackageName, String volumeUuid,
+ private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
+ int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
PackageInstalledInfo res) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
@@ -13568,7 +13603,7 @@
}
try {
- PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
+ PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
System.currentTimeMillis(), user);
updateSettingsLI(newPackage, installerPackageName, null, res, user);
@@ -13625,9 +13660,9 @@
return false;
}
- private void replacePackageLIF(PackageParser.Package pkg, int parseFlags, int scanFlags,
+ private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
UserHandle user, String installerPackageName, PackageInstalledInfo res) {
- final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
+ final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
final PackageParser.Package oldPackage;
final String pkgName = pkg.packageName;
@@ -13715,10 +13750,18 @@
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
- replaceSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
+ // Set the system/privileged flags as needed
+ final boolean privileged =
+ (oldPackage.applicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
+ final int systemPolicyFlags = policyFlags
+ | PackageParser.PARSE_IS_SYSTEM
+ | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
+
+ replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
user, allUsers, installerPackageName, res);
} else {
- replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
+ replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
user, allUsers, installerPackageName, res);
}
}
@@ -13733,7 +13776,7 @@
}
private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
- PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
+ PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
+ deletedPackage);
@@ -13775,7 +13818,7 @@
clearAppProfilesLIF(pkg);
try {
- final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
+ final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
@@ -13872,20 +13915,13 @@
}
private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
- PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
+ PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
+ ", old=" + deletedPackage);
final boolean disabledSystem;
- // Set the system/privileged flags as needed
- parseFlags |= PackageParser.PARSE_IS_SYSTEM;
- if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
- != 0) {
- parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
- }
-
// Remove existing system package
removePackageLI(deletedPackage, true);
@@ -13914,7 +13950,7 @@
PackageParser.Package newPackage = null;
try {
// Add the package to the internal data structures
- newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
+ newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
// Set the update and install times
PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
@@ -13967,7 +14003,7 @@
}
// Add back the old system package
try {
- scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
+ scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
}
@@ -15296,7 +15332,10 @@
// Install the system package
if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
- int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
+ int parseFlags = mDefParseFlags
+ | PackageParser.PARSE_MUST_BE_APK
+ | PackageParser.PARSE_IS_SYSTEM
+ | PackageParser.PARSE_IS_SYSTEM_DIR;
if (locationIsPrivileged(disabledPs.codePath)) {
parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index ac6510a..0ac5c1f 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -907,6 +907,16 @@
}
}
+ public void cleanupBitmapsForPackage(@UserIdInt int userId, String packageName) {
+ final File packagePath = new File(getUserBitmapFilePath(userId), packageName);
+ if (!packagePath.isDirectory()) {
+ return;
+ }
+ if (!(FileUtils.deleteContents(packagePath) && packagePath.delete())) {
+ Slog.w(TAG, "Unable to remove directory " + packagePath);
+ }
+ }
+
@VisibleForTesting
static class FileOutputStreamWithPath extends FileOutputStream {
private final File mFile;
@@ -1572,7 +1582,7 @@
// First, remove the package from the package list (if the package is a publisher).
if (packageUserId == owningUserId) {
- if (mUser.removePackage(packageName) != null) {
+ if (mUser.removePackage(this, packageName) != null) {
doNotify = true;
}
}
@@ -2084,11 +2094,11 @@
pw.println(mIconPersistFormat);
pw.print(" Icon quality: ");
pw.println(mIconPersistQuality);
- pw.print(" saveDelayMillis:");
+ pw.print(" saveDelayMillis: ");
pw.println(mSaveDelayMillis);
- pw.print(" resetInterval:");
+ pw.print(" resetInterval: ");
pw.println(mResetInterval);
- pw.print(" maxUpdatesPerInterval:");
+ pw.print(" maxUpdatesPerInterval: ");
pw.println(mMaxUpdatesPerInterval);
pw.print(" maxDynamicShortcuts:");
pw.println(mMaxDynamicShortcuts);
@@ -2416,7 +2426,6 @@
return mPackageManagerInternal;
}
- @VisibleForTesting
File getUserBitmapFilePath(@UserIdInt int userId) {
return new File(injectUserDataPath(userId), DIRECTORY_BITMAPS);
}
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 593f607..0b8c3a2 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.ComponentName;
+import android.text.format.Formatter;
import android.util.ArrayMap;
import android.util.Slog;
@@ -29,6 +30,7 @@
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -103,8 +105,12 @@
return mPackages;
}
- public ShortcutPackage removePackage(@NonNull String packageName) {
- return mPackages.remove(packageName);
+ public ShortcutPackage removePackage(@NonNull ShortcutService s, @NonNull String packageName) {
+ final ShortcutPackage removed = mPackages.remove(packageName);
+
+ s.cleanupBitmapsForPackage(mUserId, packageName);
+
+ return removed;
}
public ArrayMap<PackageWithUser, ShortcutLauncher> getAllLaunchers() {
@@ -279,18 +285,51 @@
pw.print(mUserId);
pw.println();
+ prefix += prefix + " ";
+
pw.print(prefix);
- pw.print(" ");
pw.print("Default launcher: ");
pw.print(mLauncherComponent);
pw.println();
for (int i = 0; i < mLaunchers.size(); i++) {
- mLaunchers.valueAt(i).dump(s, pw, prefix + " ");
+ mLaunchers.valueAt(i).dump(s, pw, prefix);
}
for (int i = 0; i < mPackages.size(); i++) {
- mPackages.valueAt(i).dump(s, pw, prefix + " ");
+ mPackages.valueAt(i).dump(s, pw, prefix);
}
+
+ pw.println();
+ pw.print(prefix);
+ pw.println("Bitmap directories: ");
+ dumpDirectorySize(s, pw, prefix + " ", s.getUserBitmapFilePath(mUserId));
+ }
+
+ private void dumpDirectorySize(@NonNull ShortcutService s, @NonNull PrintWriter pw,
+ @NonNull String prefix, File path) {
+ int numFiles = 0;
+ long size = 0;
+ final File[] children = path.listFiles();
+ if (children != null) {
+ for (File child : path.listFiles()) {
+ if (child.isFile()) {
+ numFiles++;
+ size += child.length();
+ } else if (child.isDirectory()) {
+ dumpDirectorySize(s, pw, prefix + " ", child);
+ }
+ }
+ }
+ pw.print(prefix);
+ pw.print("Path: ");
+ pw.print(path.getName());
+ pw.print("/ has ");
+ pw.print(numFiles);
+ pw.print(" files, size=");
+ pw.print(size);
+ pw.print(" (");
+ pw.print(Formatter.formatFileSize(s.mContext, size));
+ pw.println(")");
}
}
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index 6bdcd42..0217c09 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -218,7 +218,7 @@
}
private int assignAndIncreaseLayerIfNeeded(WindowState win, int layer) {
- if (win != null && layer > win.mLayer) {
+ if (win != null) {
assignAnimLayer(win, layer);
// Make sure we leave space inbetween normal windows for dims and such.
layer += WINDOW_LAYER_MULTIPLIER;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 6fcc8f9..1f76f31 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1774,6 +1774,10 @@
}
if (mWin.mAttrs.type == TYPE_INPUT_METHOD) {
mService.adjustForImeIfNeeded(mWin.mDisplayContent);
+ if (isEntrance) {
+ mWin.setDisplayLayoutNeeded();
+ mService.mWindowPlacerLocked.requestTraversal();
+ }
}
return mAnimation != null;
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
index ce02a79..d20d5fa 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
@@ -15,9 +15,36 @@
*/
package com.android.server.pm;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamic;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamicOrPinned;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIcon;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIconFile;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIconResId;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveIntents;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllHaveTitle;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllKeyFieldsOnly;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotHaveIntents;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotHaveTitle;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllNotKeyFieldsOnly;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllPinned;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllUnique;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBitmapSize;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBundleEmpty;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackNotReceived;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCallbackReceived;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicAndPinned;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicOnly;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertShortcutIds;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makeBundle;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.pfdToBitmap;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.resetAll;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyList;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
@@ -27,7 +54,6 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.*;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -57,13 +83,11 @@
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.net.Uri;
-import android.os.BaseBundle;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.UserHandle;
@@ -71,7 +95,6 @@
import android.test.InstrumentationTestCase;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
@@ -84,9 +107,6 @@
import com.android.server.pm.ShortcutService.ConfigConstants;
import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
import com.android.server.pm.ShortcutUser.PackageWithUser;
-import com.android.server.testutis.TestUtils;
-
-import libcore.io.IoUtils;
import org.junit.Assert;
import org.mockito.ArgumentCaptor;
@@ -98,8 +118,6 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -4018,24 +4036,33 @@
checkCanRestoreTo(false, spi2, 11, "x", "sig2x", "sig1", "y");
}
+ private boolean bitmapDirectoryExists(String packageName, int userId) {
+ final File path = new File(mService.getUserBitmapFilePath(userId), packageName);
+ return path.isDirectory();
+ }
+
public void testHandlePackageDelete() {
+ final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+ getTestContext().getResources(), R.drawable.black_32x32));
setCaller(CALLING_PACKAGE_1, USER_0);
- assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
+ assertTrue(mManager.addDynamicShortcuts(list(
+ makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
+ )));
setCaller(CALLING_PACKAGE_2, USER_0);
- assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
setCaller(CALLING_PACKAGE_3, USER_0);
- assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
setCaller(CALLING_PACKAGE_1, USER_10);
- assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
setCaller(CALLING_PACKAGE_2, USER_10);
- assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
setCaller(CALLING_PACKAGE_3, USER_10);
- assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
+ assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
@@ -4044,6 +4071,13 @@
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+
uninstallPackage(USER_0, CALLING_PACKAGE_1);
mService.mPackageMonitor.onReceive(getTestContext(),
genPackageDeleteIntent(CALLING_PACKAGE_1, USER_0));
@@ -4055,6 +4089,13 @@
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+
uninstallPackage(USER_10, CALLING_PACKAGE_2);
mService.mPackageMonitor.onReceive(getTestContext(),
genPackageDeleteIntent(CALLING_PACKAGE_2, USER_10));
@@ -4066,6 +4107,13 @@
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+
mInjectedPackages.remove(CALLING_PACKAGE_1);
mInjectedPackages.remove(CALLING_PACKAGE_3);
@@ -4078,6 +4126,13 @@
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+
mService.handleUnlockUser(USER_10);
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
@@ -4086,6 +4141,13 @@
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
}
private void backupAndRestore() {
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 87fc7fa..2579d9f 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -199,6 +199,12 @@
// Whether STA responder role is supported.
public boolean responderSupported;
+ /** Whether the secure RTT protocol is supported. */
+ public boolean secureRttSupported;
+
+ /** Draft 11mc version supported, including major and minor version. e.g, draft 4.3 is 43 */
+ public int mcVersion;
+
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -223,7 +229,7 @@
sb.append("VHT ");
}
- sb.append("is supported. \n");
+ sb.append("is supported. ");
if ((bwSupported & RTT_BW_5_SUPPORT) != 0) {
sb.append("5 MHz ");
@@ -252,7 +258,10 @@
sb.append("is supported.");
sb.append(" STA responder role is ")
- .append(responderSupported ? "supported" : "not supported.");
+ .append(responderSupported ? "supported" : "not supported");
+ sb.append(" Secure RTT protocol is ")
+ .append(secureRttSupported ? "supported" : "not supported");
+ sb.append(" 11mc version is " + mcVersion);
return sb.toString();
}
@@ -272,6 +281,8 @@
dest.writeInt(preambleSupported);
dest.writeInt(bwSupported);
dest.writeInt(responderSupported ? 1 : 0);
+ dest.writeInt(secureRttSupported ? 1 : 0);
+ dest.writeInt(mcVersion);
}
/** Implement the Parcelable interface {@hide} */
@@ -279,16 +290,18 @@
new Creator<RttCapabilities>() {
@Override
public RttCapabilities createFromParcel(Parcel in) {
- RttCapabilities capabilities = new RttCapabilities();
- capabilities.oneSidedRttSupported = (in.readInt() == 1);
- capabilities.twoSided11McRttSupported = (in.readInt() == 1);
- capabilities.lciSupported = (in.readInt() == 1);
- capabilities.lcrSupported = (in.readInt() == 1);
- capabilities.preambleSupported = in.readInt();
- capabilities.bwSupported = in.readInt();
- capabilities.responderSupported = (in.readInt() == 1);
- return capabilities;
- }
+ RttCapabilities capabilities = new RttCapabilities();
+ capabilities.oneSidedRttSupported = (in.readInt() == 1);
+ capabilities.twoSided11McRttSupported = (in.readInt() == 1);
+ capabilities.lciSupported = (in.readInt() == 1);
+ capabilities.lcrSupported = (in.readInt() == 1);
+ capabilities.preambleSupported = in.readInt();
+ capabilities.bwSupported = in.readInt();
+ capabilities.responderSupported = (in.readInt() == 1);
+ capabilities.secureRttSupported = (in.readInt() == 1);
+ capabilities.mcVersion = in.readInt();
+ return capabilities;
+ }
/** Implement the Parcelable interface {@hide} */
@Override
public RttCapabilities[] newArray(int size) {
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 1a8197c..2ee1aef 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -20,7 +20,6 @@
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
@@ -31,13 +30,11 @@
import android.util.Log;
import android.util.SparseArray;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
/**
@@ -1143,7 +1140,6 @@
private final Object mListenerMapLock = new Object();
private AsyncChannel mAsyncChannel;
- private final CountDownLatch mConnected;
private final Handler mInternalHandler;
/**
@@ -1157,22 +1153,6 @@
* @hide
*/
public WifiScanner(Context context, IWifiScanner service, Looper looper) {
- this(context, service, looper, true);
- }
-
- /**
- * Create a new WifiScanner instance.
- *
- * @param context The application context.
- * @param service The IWifiScanner Binder interface
- * @param looper the Looper used to deliver callbacks
- * @param waitForConnection If true, this will not return until a connection to Wifi Scanner
- * service is established.
- * @hide
- */
- @VisibleForTesting
- public WifiScanner(Context context, IWifiScanner service, Looper looper,
- boolean waitForConnection) {
mContext = context;
mService = service;
@@ -1188,17 +1168,12 @@
}
mAsyncChannel = new AsyncChannel();
- mConnected = new CountDownLatch(1);
mInternalHandler = new ServiceHandler(looper);
- mAsyncChannel.connect(mContext, mInternalHandler, messenger);
- if (waitForConnection) {
- try {
- mConnected.await();
- } catch (InterruptedException e) {
- Log.e(TAG, "interrupted wait at init");
- }
- }
+ mAsyncChannel.connectSync(mContext, mInternalHandler, messenger);
+ // We cannot use fullyConnectSync because it sends the FULL_CONNECTION message
+ // synchronously, which causes WifiScanningService to receive the wrong replyTo value.
+ mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
}
private void validateChannel() {
@@ -1326,17 +1301,6 @@
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
- } else {
- Log.e(TAG, "Failed to set up channel connection");
- // This will cause all further async API calls on the WifiManager
- // to fail and throw an exception
- mAsyncChannel = null;
- }
- mConnected.countDown();
- return;
case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
return;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: