diff options
28 files changed, 385 insertions, 61 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index adb06c79eaf5..e34614e966c4 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -249,6 +249,7 @@ package android.content.pm { method public abstract java.lang.String getDefaultBrowserPackageNameAsUser(int); method public abstract int getInstallReason(java.lang.String, android.os.UserHandle); method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); + method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); method public abstract java.lang.String[] getNamesForUids(int[]); method public abstract java.lang.String getPermissionControllerPackageName(); method public abstract java.lang.String getServicesSystemSharedLibraryPackageName(); diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 7176a5d2d26a..f3091b113985 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -697,6 +697,7 @@ Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z Landroid/app/INotificationManager$Stub;-><init>()V Landroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager; +Landroid/app/INotificationManager$Stub;->TRANSACTION_enqueueNotificationWithTag:I Landroid/app/INotificationManager;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z Landroid/app/INotificationManager;->cancelAllNotifications(Ljava/lang/String;I)V Landroid/app/INotificationManager;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;II)V @@ -1234,6 +1235,7 @@ Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAddress()Ljava/lang/String; Landroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I Landroid/bluetooth/IBluetooth$Stub;-><init>()V Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth; +Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_enable:I Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String; Landroid/bluetooth/IBluetooth;->getRemoteAlias(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String; Landroid/bluetooth/IBluetooth;->isEnabled()Z @@ -1260,6 +1262,7 @@ Landroid/bluetooth/IBluetoothHeadset;->setPriority(Landroid/bluetooth/BluetoothD Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;-><init>()V Landroid/bluetooth/IBluetoothManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/bluetooth/IBluetoothManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothManager; +Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_enable:I Landroid/bluetooth/IBluetoothManager;->getBluetoothGatt()Landroid/bluetooth/IBluetoothGatt; Landroid/bluetooth/IBluetoothManager;->registerStateChangeCallback(Landroid/bluetooth/IBluetoothStateChangeCallback;)V Landroid/bluetooth/IBluetoothManager;->unregisterStateChangeCallback(Landroid/bluetooth/IBluetoothStateChangeCallback;)V @@ -1371,6 +1374,7 @@ Landroid/content/IContentProvider;->call(Ljava/lang/String;Ljava/lang/String;Lja Landroid/content/IContentProvider;->delete(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I Landroid/content/IContentProvider;->descriptor:Ljava/lang/String; Landroid/content/IContentProvider;->insert(Ljava/lang/String;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri; +Landroid/content/IContentProvider;->QUERY_TRANSACTION:I Landroid/content/IContentProvider;->update(Ljava/lang/String;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I Landroid/content/IContentService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/content/IContentService$Stub;-><init>()V @@ -1478,6 +1482,7 @@ Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBind Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver; Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder; +Landroid/content/pm/IPackageDeleteObserver2$Stub;-><init>()V Landroid/content/pm/IPackageDeleteObserver2$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver2; Landroid/content/pm/IPackageDeleteObserver2;->onPackageDeleted(Ljava/lang/String;ILjava/lang/String;)V Landroid/content/pm/IPackageInstaller;->uninstall(Landroid/content/pm/VersionedPackage;Ljava/lang/String;ILandroid/content/IntentSender;I)V @@ -1507,6 +1512,7 @@ Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String; Landroid/content/pm/IPackageManager$Stub;-><init>()V Landroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager; +Landroid/content/pm/IPackageManager$Stub;->TRANSACTION_getApplicationInfo:I Landroid/content/pm/IPackageManager;->addPermission(Landroid/content/pm/PermissionInfo;)Z Landroid/content/pm/IPackageManager;->addPermissionAsync(Landroid/content/pm/PermissionInfo;)Z Landroid/content/pm/IPackageManager;->canonicalToCurrentPackageNames([Ljava/lang/String;)[Ljava/lang/String; @@ -1991,6 +1997,7 @@ Landroid/database/CursorWindow;->sWindowToPidMap:Landroid/util/LongSparseArray; Landroid/database/CursorWrapper;->mCursor:Landroid/database/Cursor; Landroid/database/DatabaseUtils;->cursorPickFillWindowStartPosition(II)I Landroid/database/DatabaseUtils;->getTypeOfObject(Ljava/lang/Object;)I +Landroid/database/IContentObserver$Stub;-><init>()V Landroid/database/IContentObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/database/IContentObserver; Landroid/database/IContentObserver;->onChange(ZLandroid/net/Uri;I)V Landroid/database/MatrixCursor;->data:[Ljava/lang/Object; @@ -2699,6 +2706,7 @@ Landroid/location/ILocationListener;->onStatusChanged(Ljava/lang/String;ILandroi Landroid/location/ILocationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/location/ILocationManager$Stub;-><init>()V Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager; +Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I Landroid/location/ILocationManager;->getAllProviders()Ljava/util/List; Landroid/location/Location;->mElapsedRealtimeNanos:J Landroid/location/Location;->mProvider:Ljava/lang/String; @@ -3564,6 +3572,7 @@ Landroid/net/WebAddress;->setPath(Ljava/lang/String;)V Landroid/net/wifi/IWifiManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/net/wifi/IWifiManager$Stub;-><init>()V Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager; +Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getScanResults:I Landroid/net/wifi/IWifiManager;->getCurrentNetwork()Landroid/net/Network; Landroid/net/wifi/IWifiManager;->getWifiApConfiguration()Landroid/net/wifi/WifiConfiguration; Landroid/net/wifi/IWifiManager;->getWifiApEnabledState()I @@ -3751,6 +3760,7 @@ Landroid/nfc/cardemulation/ApduServiceInfo;->mService:Landroid/content/pm/Resolv Landroid/nfc/cardemulation/ApduServiceInfo;->mStaticAidGroups:Ljava/util/HashMap; Landroid/nfc/cardemulation/ApduServiceInfo;->requiresUnlock()Z Landroid/nfc/ErrorCodes;->isError(I)Z +Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I Landroid/nfc/INfcAdapterExtras;->authenticate(Ljava/lang/String;[B)V Landroid/nfc/INfcAdapterExtras;->close(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle; Landroid/nfc/INfcAdapterExtras;->getCardEmulationRoute(Ljava/lang/String;)I @@ -4010,6 +4020,7 @@ Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/os/IPowerManager$Stub$Proxy;->isLightDeviceIdleMode()Z Landroid/os/IPowerManager$Stub;-><init>()V Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager; +Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I Landroid/os/IPowerManager;->isInteractive()Z Landroid/os/IPowerManager;->nap(J)V @@ -8234,6 +8245,7 @@ Lcom/android/internal/telephony/IPhoneStateListener;->onSignalStrengthsChanged(L Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Lcom/android/internal/telephony/IPhoneSubInfo$Stub;-><init>()V Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneSubInfo; +Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->TRANSACTION_getDeviceId:I Lcom/android/internal/telephony/IPhoneSubInfo;->getIccSerialNumber(Ljava/lang/String;)Ljava/lang/String; Lcom/android/internal/telephony/IPhoneSubInfo;->getSubscriberId(Ljava/lang/String;)Ljava/lang/String; Lcom/android/internal/telephony/ISms$Stub;-><init>()V @@ -8253,6 +8265,7 @@ Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinde Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String; Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_answerRingingCall:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I +Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I Lcom/android/internal/telephony/ITelephony;->answerRingingCall()V diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 37bf21a898b1..87b334992d2d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -347,6 +347,13 @@ public final class ActivityThread extends ClientTransactionHandler { final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<ComponentName, ProviderClientRecord>(); + // Mitigation for b/74523247: Used to serialize calls to AM.getContentProvider(). + // Note we never removes items from this map but that's okay because there are only so many + // users and so many authorities. + // TODO Remove it once we move CPR.wait() from AMS to the client side. + @GuardedBy("mGetProviderLocks") + final ArrayMap<ProviderKey, Object> mGetProviderLocks = new ArrayMap<>(); + final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); @@ -5959,8 +5966,10 @@ public final class ActivityThread extends ClientTransactionHandler { // be re-entrant in the case where the provider is in the same process. ContentProviderHolder holder = null; try { - holder = ActivityManager.getService().getContentProvider( - getApplicationThread(), auth, userId, stable); + synchronized (getGetProviderLock(auth, userId)) { + holder = ActivityManager.getService().getContentProvider( + getApplicationThread(), auth, userId, stable); + } } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } @@ -5976,6 +5985,18 @@ public final class ActivityThread extends ClientTransactionHandler { return holder.provider; } + private Object getGetProviderLock(String auth, int userId) { + final ProviderKey key = new ProviderKey(auth, userId); + synchronized (mGetProviderLocks) { + Object lock = mGetProviderLocks.get(key); + if (lock == null) { + lock = key; + mGetProviderLocks.put(key, lock); + } + return lock; + } + } + private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { if (stable) { prc.stableCount += 1; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 3f9798b7d6c9..b677b5e2c947 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3798,6 +3798,7 @@ public abstract class PackageManager { * deleted with {@code DONT_DELETE_DATA} flag set). * @hide */ + @TestApi public abstract List<ApplicationInfo> getInstalledApplicationsAsUser( @ApplicationInfoFlags int flags, @UserIdInt int userId); diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index d19cc9c8fa92..5b61015e9d42 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -329,6 +329,7 @@ public final class ThreadedRenderer { // in response, so it really just exists to differentiate from LOST_SURFACE // but possibly both can just be deleted. private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2; + private static final int SYNC_FRAME_DROPPED = 1 << 3; private static final String[] VISUALIZERS = { PROFILE_PROPERTY_VISUALIZE_BARS, @@ -832,6 +833,10 @@ public final class ThreadedRenderer { } } + void setFrameCompleteCallback(FrameCompleteCallback callback) { + nSetFrameCompleteCallback(mNativeProxy, callback); + } + static void invokeFunctor(long functor, boolean waitForCompletion) { nInvokeFunctor(functor, waitForCompletion); } @@ -1067,6 +1072,18 @@ public final class ThreadedRenderer { void onFrameDraw(long frame); } + /** + * Interface used to be notified when a frame has finished rendering + */ + public interface FrameCompleteCallback { + /** + * Invoked after a frame draw + * + * @param frameNr The id of the frame that was drawn. + */ + void onFrameComplete(long frameNr); + } + private static class ProcessInitializer { static ProcessInitializer sInstance = new ProcessInitializer(); @@ -1218,6 +1235,8 @@ public final class ThreadedRenderer { private static native void nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom); private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback); + private static native void nSetFrameCompleteCallback(long nativeProxy, + FrameCompleteCallback callback); private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer); private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 48f380d87dcc..0506f30d04b8 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3096,13 +3096,28 @@ public final class ViewRootImpl implements ViewParent, return; } - final boolean fullRedrawNeeded = mFullRedrawNeeded; + final boolean fullRedrawNeeded = mFullRedrawNeeded || mReportNextDraw; mFullRedrawNeeded = false; mIsDrawing = true; Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw"); + + boolean usingAsyncReport = false; + if (mReportNextDraw && mAttachInfo.mThreadedRenderer != null + && mAttachInfo.mThreadedRenderer.isEnabled()) { + usingAsyncReport = true; + mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> { + // TODO: Use the frame number + pendingDrawFinished(); + }); + } + try { - draw(fullRedrawNeeded); + boolean canUseAsync = draw(fullRedrawNeeded); + if (usingAsyncReport && !canUseAsync) { + mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(null); + usingAsyncReport = false; + } } finally { mIsDrawing = false; Trace.traceEnd(Trace.TRACE_TAG_VIEW); @@ -3132,7 +3147,6 @@ public final class ViewRootImpl implements ViewParent, } if (mAttachInfo.mThreadedRenderer != null) { - mAttachInfo.mThreadedRenderer.fence(); mAttachInfo.mThreadedRenderer.setStopped(mStopped); } @@ -3145,16 +3159,19 @@ public final class ViewRootImpl implements ViewParent, SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks); - } else { + } else if (!usingAsyncReport) { + if (mAttachInfo.mThreadedRenderer != null) { + mAttachInfo.mThreadedRenderer.fence(); + } pendingDrawFinished(); } } } - private void draw(boolean fullRedrawNeeded) { + private boolean draw(boolean fullRedrawNeeded) { Surface surface = mSurface; if (!surface.isValid()) { - return; + return false; } if (DEBUG_FPS) { @@ -3203,7 +3220,7 @@ public final class ViewRootImpl implements ViewParent, if (animating && mScroller != null) { mScroller.abortAnimation(); } - return; + return false; } if (fullRedrawNeeded) { @@ -3250,6 +3267,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mDrawingTime = mChoreographer.getFrameTimeNanos() / TimeUtils.NANOS_PER_MS; + boolean useAsyncReport = false; if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) { if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) { // If accessibility focus moved, always invalidate the root. @@ -3286,6 +3304,7 @@ public final class ViewRootImpl implements ViewParent, requestDrawWindow(); } + useAsyncReport = true; mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this, mNextRtFrameCallback); mNextRtFrameCallback = null; } else { @@ -3307,17 +3326,17 @@ public final class ViewRootImpl implements ViewParent, mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets); } catch (OutOfResourcesException e) { handleOutOfResourcesException(e); - return; + return false; } mFullRedrawNeeded = true; scheduleTraversals(); - return; + return false; } if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty, surfaceInsets)) { - return; + return false; } } } @@ -3326,6 +3345,7 @@ public final class ViewRootImpl implements ViewParent, mFullRedrawNeeded = true; scheduleTraversals(); } + return useAsyncReport; } /** diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 7481f1c1fe53..ee9a123ab674 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -15,9 +15,11 @@ */ #define LOG_TAG "ThreadedRenderer" +#define ATRACE_TAG ATRACE_TAG_VIEW #include <algorithm> #include <atomic> +#include <inttypes.h> #include "jni.h" #include <nativehelper/JNIHelp.h> @@ -37,6 +39,7 @@ #include <utils/RefBase.h> #include <utils/StrongPointer.h> #include <utils/Timers.h> +#include <utils/TraceUtils.h> #include <android_runtime/android_view_Surface.h> #include <system/window.h> @@ -72,6 +75,10 @@ struct { jmethodID onFrameDraw; } gFrameDrawingCallback; +struct { + jmethodID onFrameComplete; +} gFrameCompleteCallback; + static JNIEnv* getenv(JavaVM* vm) { JNIEnv* env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { @@ -153,6 +160,49 @@ private: std::string mMessage; }; +class FrameCompleteWrapper : public MessageHandler { +public: + FrameCompleteWrapper(JNIEnv* env, jobject jobject) { + mLooper = Looper::getForThread(); + LOG_ALWAYS_FATAL_IF(!mLooper.get(), "Must create runnable on a Looper thread!"); + env->GetJavaVM(&mVm); + mObject = env->NewGlobalRef(jobject); + LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref"); + } + + virtual ~FrameCompleteWrapper() { + releaseObject(); + } + + void postFrameComplete(int64_t frameNr) { + if (mObject) { + mFrameNr = frameNr; + mLooper->sendMessage(this, 0); + } + } + + virtual void handleMessage(const Message&) { + if (mObject) { + ATRACE_FORMAT("frameComplete %" PRId64, mFrameNr); + getenv(mVm)->CallVoidMethod(mObject, gFrameCompleteCallback.onFrameComplete, mFrameNr); + releaseObject(); + } + } + +private: + JavaVM* mVm; + jobject mObject; + sp<Looper> mLooper; + int64_t mFrameNr = -1; + + void releaseObject() { + if (mObject) { + getenv(mVm)->DeleteGlobalRef(mObject); + mObject = nullptr; + } + } +}; + class RootRenderNode : public RenderNode, ErrorHandler { public: explicit RootRenderNode(JNIEnv* env) : RenderNode() { @@ -891,6 +941,19 @@ static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env, } } +static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env, + jobject clazz, jlong proxyPtr, jobject callback) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); + if (!callback) { + proxy->setFrameCompleteCallback(nullptr); + } else { + sp<FrameCompleteWrapper> wrapper = new FrameCompleteWrapper{env, callback}; + proxy->setFrameCompleteCallback([wrapper](int64_t frameNr) { + wrapper->postFrameComplete(frameNr); + }); + } +} + static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env, jobject clazz, jobject jsurface, jint left, jint top, jint right, jint bottom, jobject jbitmap) { @@ -1091,6 +1154,8 @@ static const JNINativeMethod gMethods[] = { { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds}, { "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V", (void*)android_view_ThreadedRenderer_setFrameCallback}, + { "nSetFrameCompleteCallback", "(JLandroid/view/ThreadedRenderer$FrameCompleteCallback;)V", + (void*)android_view_ThreadedRenderer_setFrameCompleteCallback }, { "nAddFrameMetricsObserver", "(JLandroid/view/FrameMetricsObserver;)J", (void*)android_view_ThreadedRenderer_addFrameMetricsObserver }, @@ -1143,6 +1208,11 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) { gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass, "onFrameDraw", "(J)V"); + jclass frameCompleteClass = FindClassOrDie(env, + "android/view/ThreadedRenderer$FrameCompleteCallback"); + gFrameCompleteCallback.onFrameComplete = GetMethodIDOrDie(env, frameCompleteClass, + "onFrameComplete", "(J)V"); + return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 0f04b5d16454..cb260b5b4b91 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -41,6 +41,7 @@ cc_defaults { "external/skia/src/image", "external/skia/src/utils", "external/skia/src/gpu", + "external/skia/src/shaders", ], product_variables: { diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp index 9c80ff86df53..3684bc1e6a1f 100644 --- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp @@ -21,6 +21,11 @@ #include "RenderNode.h" #include "SkAndroidFrameworkUtils.h" #include "SkClipStack.h" +#include "SkRect.h" +#include "GrBackendSurface.h" +#include "GrRenderTarget.h" +#include "GrRenderTargetContext.h" +#include "GrGLTypes.h" namespace android { namespace uirenderer { @@ -44,6 +49,33 @@ static void setScissor(int viewportHeight, const SkIRect& clip) { glScissor(clip.fLeft, y, clip.width(), height); } +static bool GetFboDetails(SkCanvas* canvas, GLuint* outFboID, SkISize* outFboSize) { + GrRenderTargetContext *renderTargetContext = + canvas->internal_private_accessTopLayerRenderTargetContext(); + if (!renderTargetContext) { + ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw"); + return false; + } + + GrRenderTarget *renderTarget = renderTargetContext->accessRenderTarget(); + if (!renderTarget) { + ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw"); + return false; + } + + GrBackendRenderTarget backendTarget = renderTarget->getBackendRenderTarget(); + const GrGLFramebufferInfo* fboInfo = backendTarget.getGLFramebufferInfo(); + + if (!fboInfo) { + ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw"); + return false; + } + + *outFboID = fboInfo->fFBOID; + *outFboSize = SkISize::Make(renderTargetContext->width(), renderTargetContext->height()); + return true; +} + void GLFunctorDrawable::onDraw(SkCanvas* canvas) { if (canvas->getGrContext() == nullptr) { SkDEBUGF(("Attempting to draw GLFunctor into an unsupported surface")); @@ -55,41 +87,96 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { return; } - SkImageInfo canvasInfo = canvas->imageInfo(); + GLuint fboID = 0; + SkISize fboSize; + if (!GetFboDetails(canvas, &fboID, &fboSize)) { + return; + } + + SkIRect surfaceBounds = canvas->internal_private_getTopLayerBounds(); + SkIRect clipBounds = canvas->getDeviceClipBounds(); SkMatrix44 mat4(canvas->getTotalMatrix()); + SkRegion clipRegion; + canvas->temporary_internal_getRgnClip(&clipRegion); + + sk_sp<SkSurface> tmpSurface; + // we are in a state where there is an unclipped saveLayer + if (fboID != 0 && !surfaceBounds.contains(clipBounds)) { - SkIRect ibounds = canvas->getDeviceClipBounds(); + // create an offscreen layer and clear it + SkImageInfo surfaceInfo = canvas->imageInfo().makeWH(clipBounds.width(), clipBounds.height()); + tmpSurface = SkSurface::MakeRenderTarget(canvas->getGrContext(), SkBudgeted::kYes, + surfaceInfo); + tmpSurface->getCanvas()->clear(SK_ColorTRANSPARENT); + + GrBackendObject backendObject; + if (!tmpSurface->getRenderTargetHandle(&backendObject, SkSurface::kFlushWrite_BackendHandleAccess)) { + ALOGW("Unable to extract renderTarget info from offscreen canvas; aborting GLFunctor"); + return; + } + + fboSize = SkISize::Make(surfaceInfo.width(), surfaceInfo.height()); + fboID = (GLuint)backendObject; + + // update the matrix and clip that we pass to the WebView to match the coordinates of + // the offscreen layer + mat4.preTranslate(-clipBounds.fLeft, -clipBounds.fTop, 0); + clipBounds.offsetTo(0, 0); + clipRegion.translate(-surfaceBounds.fLeft, -surfaceBounds.fTop); + + } else if (fboID != 0) { + // we are drawing into a (clipped) offscreen layer so we must update the clip and matrix + // from device coordinates to the layer's coordinates + clipBounds.offset(-surfaceBounds.fLeft, -surfaceBounds.fTop); + mat4.preTranslate(-surfaceBounds.fLeft, -surfaceBounds.fTop, 0); + } DrawGlInfo info; - info.clipLeft = ibounds.fLeft; - info.clipTop = ibounds.fTop; - info.clipRight = ibounds.fRight; - info.clipBottom = ibounds.fBottom; - // info.isLayer = hasLayer(); - info.isLayer = false; - info.width = canvasInfo.width(); - info.height = canvasInfo.height(); + info.clipLeft = clipBounds.fLeft; + info.clipTop = clipBounds.fTop; + info.clipRight = clipBounds.fRight; + info.clipBottom = clipBounds.fBottom; + info.isLayer = fboID != 0; + info.width = fboSize.width(); + info.height = fboSize.height(); mat4.asColMajorf(&info.transform[0]); - bool clearStencilAfterFunctor = false; - - // apply a simple clip with a scissor or a complex clip with a stencil - SkRegion clipRegion; - canvas->temporary_internal_getRgnClip(&clipRegion); + // ensure that the framebuffer that the webview will render into is bound before we clear + // the stencil and/or draw the functor. canvas->flush(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, info.width, info.height); + glBindFramebuffer(GL_FRAMEBUFFER, fboID); + + // apply a simple clip with a scissor or a complex clip with a stencil + bool clearStencilAfterFunctor = false; if (CC_UNLIKELY(clipRegion.isComplex())) { + // clear the stencil //TODO: move stencil clear and canvas flush to SkAndroidFrameworkUtils::clipWithStencil glDisable(GL_SCISSOR_TEST); glStencilMask(0x1); glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); + + // notify Skia that we just updated the FBO and stencil + const uint32_t grState = kStencil_GrGLBackendState | kRenderTarget_GrGLBackendState; + canvas->getGrContext()->resetContext(grState); + + SkCanvas* tmpCanvas = canvas; + if (tmpSurface) { + tmpCanvas = tmpSurface->getCanvas(); + // set the clip on the new canvas + tmpCanvas->clipRegion(clipRegion); + } + // GL ops get inserted here if previous flush is missing, which could dirty the stencil - bool stencilWritten = SkAndroidFrameworkUtils::clipWithStencil(canvas); - canvas->flush(); //need this flush for the single op that draws into the stencil - glBindFramebuffer(GL_FRAMEBUFFER, 0); + bool stencilWritten = SkAndroidFrameworkUtils::clipWithStencil(tmpCanvas); + tmpCanvas->flush(); //need this flush for the single op that draws into the stencil + + // ensure that the framebuffer that the webview will render into is bound before after we + // draw into the stencil glViewport(0, 0, info.width, info.height); + glBindFramebuffer(GL_FRAMEBUFFER, fboID); + if (stencilWritten) { glStencilMask(0x1); glStencilFunc(GL_EQUAL, 0x1, 0x1); @@ -120,6 +207,20 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { } canvas->getGrContext()->resetContext(); + + // if there were unclipped save layers involved we draw our offscreen surface to the canvas + if (tmpSurface) { + SkAutoCanvasRestore acr(canvas, true); + SkMatrix invertedMatrix; + if (!canvas->getTotalMatrix().invert(&invertedMatrix)) { + ALOGW("Unable to extract invert canvas matrix; aborting GLFunctor draw"); + return; + } + canvas->concat(invertedMatrix); + + const SkIRect deviceBounds = canvas->getDeviceClipBounds(); + tmpSurface->draw(canvas, deviceBounds.fLeft, deviceBounds.fTop, nullptr); + } } }; // namespace skiapipeline diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 2ddf55be7574..aed0620166dd 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -46,6 +46,7 @@ #include <algorithm> #include <cstdlib> +#include <functional> #define TRIM_MEMORY_COMPLETE 80 #define TRIM_MEMORY_UI_HIDDEN 20 @@ -383,6 +384,12 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy info.out.canDrawThisFrame = true; } + // TODO: Do we need to abort out if the backdrop is added but not ready? Should that even + // be an allowable combination? + if (mRenderNodes.size() > 2 && !mRenderNodes[1]->isRenderable()) { + info.out.canDrawThisFrame = false; + } + if (!info.out.canDrawThisFrame) { mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); } @@ -449,6 +456,8 @@ void CanvasContext::draw() { mContentDrawBounds, mOpaque, mWideColorGamut, mLightInfo, mRenderNodes, &(profiler())); + int64_t frameCompleteNr = mFrameCompleteCallbacks.size() ? getFrameNumber() : -1; + waitOnFences(); bool requireSwap = false; @@ -509,6 +518,13 @@ void CanvasContext::draw() { } #endif + if (didSwap) { + for (auto& func : mFrameCompleteCallbacks) { + std::invoke(func, frameCompleteNr); + } + mFrameCompleteCallbacks.clear(); + } + mJankTracker.finishFrame(*mCurrentFrameInfo); if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) { mFrameMetricsReporter->reportFrameMetrics(mCurrentFrameInfo->data()); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index e52b6447a611..1c4e02d7df70 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -190,6 +190,10 @@ public: IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); } + void addFrameCompleteListener(std::function<void(int64_t)>&& func) { + mFrameCompleteCallbacks.push_back(std::move(func)); + } + private: CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline); @@ -267,6 +271,8 @@ private: std::vector<sp<FuncTask>> mFrameFences; sp<TaskProcessor<bool>> mFrameWorkProcessor; std::unique_ptr<IRenderPipeline> mRenderPipeline; + + std::vector<std::function<void(int64_t)>> mFrameCompleteCallbacks; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 60df514ecc2b..51eeab7e46ce 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -90,6 +90,11 @@ void DrawFrameTask::run() { TreeInfo info(TreeInfo::MODE_FULL, *mContext); canUnblockUiThread = syncFrameState(info); canDrawThisFrame = info.out.canDrawThisFrame; + + if (mFrameCompleteCallback) { + mContext->addFrameCompleteListener(std::move(mFrameCompleteCallback)); + mFrameCompleteCallback = nullptr; + } } // Grab a copy of everything we need @@ -152,6 +157,9 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) { mSyncResult |= SyncResult::UIRedrawRequired; } } + if (!info.out.canDrawThisFrame) { + mSyncResult |= SyncResult::FrameDropped; + } // If prepareTextures is false, we ran out of texture cache space return info.prepareTextures; } diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index d8c43e0d8ca8..2c46762fee5c 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -46,6 +46,7 @@ enum { UIRedrawRequired = 1 << 0, LostSurfaceRewardIfFound = 1 << 1, ContextIsStopped = 1 << 2, + FrameDropped = 1 << 3, }; } @@ -78,6 +79,10 @@ public: mFrameCallback = std::move(callback); } + void setFrameCompleteCallback(std::function<void(int64_t)>&& callback) { + mFrameCompleteCallback = std::move(callback); + } + private: void postAndWait(); bool syncFrameState(TreeInfo& info); @@ -102,6 +107,7 @@ private: int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; std::function<void(int64_t)> mFrameCallback; + std::function<void(int64_t)> mFrameCompleteCallback; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index c6a9b55f8ac1..59048be768e9 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -274,6 +274,10 @@ void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) { mDrawFrameTask.setFrameCallback(std::move(callback)); } +void RenderProxy::setFrameCompleteCallback(std::function<void(int64_t)>&& callback) { + mDrawFrameTask.setFrameCompleteCallback(std::move(callback)); +} + void RenderProxy::serializeDisplayListTree() { mRenderThread.queue().post([=]() { mContext->serializeDisplayListTree(); }); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 3425c5c68a72..ad534f0d96b5 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -116,6 +116,7 @@ public: ANDROID_API void drawRenderNode(RenderNode* node); ANDROID_API void setContentDrawBounds(int left, int top, int right, int bottom); ANDROID_API void setFrameCallback(std::function<void(int64_t)>&& callback); + ANDROID_API void setFrameCompleteCallback(std::function<void(int64_t)>&& callback); ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer); ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer); diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml index 03afdb659f21..4a55a99d0d93 100644 --- a/packages/SettingsLib/res/values-pl/arrays.xml +++ b/packages/SettingsLib/res/values-pl/arrays.xml @@ -25,7 +25,7 @@ <item msgid="8934131797783724664">"Trwa skanowanie..."</item> <item msgid="8513729475867537913">"Trwa łączenie..."</item> <item msgid="515055375277271756">"Trwa uwierzytelnianie..."</item> - <item msgid="1943354004029184381">"Uzyskiwanie adresu IP..."</item> + <item msgid="1943354004029184381">"Uzyskuję adres IP..."</item> <item msgid="4221763391123233270">"Połączono"</item> <item msgid="624838831631122137">"Zawieszona"</item> <item msgid="7979680559596111948">"Trwa rozłączanie..."</item> @@ -39,7 +39,7 @@ <item msgid="8878186979715711006">"Trwa skanowanie..."</item> <item msgid="355508996603873860">"Trwa łączenie z siecią <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> <item msgid="554971459996405634">"Trwa uwierzytelnianie w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> - <item msgid="7928343808033020343">"Uzyskiwanie adresu IP z sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> + <item msgid="7928343808033020343">"Uzyskuję adres IP z sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> <item msgid="8937994881315223448">"Połączono z siecią <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> <item msgid="1330262655415760617">"Zawieszona"</item> <item msgid="7698638434317271902">"Trwa rozłączanie z siecią <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 92ce28c30b74..f157cc4bffd3 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1405,6 +1405,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo newIntents.add(intent); } + final boolean isSleeping() { + final ActivityStack stack = getStack(); + return stack != null ? stack.shouldSleepActivities() : service.isSleepingLocked(); + } + /** * Deliver a new Intent to an existing activity, so that its onNewIntent() * method will be called at the proper time. @@ -1415,9 +1420,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo intent, getUriPermissionsLocked(), userId); final ReferrerIntent rintent = new ReferrerIntent(intent, referrer); boolean unsent = true; - final ActivityStack stack = getStack(); - final boolean isTopActivityWhileSleeping = isTopRunningActivity() - && (stack != null ? stack.shouldSleepActivities() : service.isSleepingLocked()); + final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping(); // We want to immediately deliver the intent to the activity if: // - It is currently resumed or paused. i.e. it is currently visible to the user and we want @@ -1645,7 +1648,10 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo parent.onActivityStateChanged(this, state, reason); } - if (state == STOPPING) { + // The WindowManager interprets the app stopping signal as + // an indication that the Surface will eventually be destroyed. + // This however isn't necessarily true if we are going to sleep. + if (state == STOPPING && !isSleeping()) { mWindowContainerController.notifyAppStopping(); } } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 3ad461f9b1b0..748eae951379 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -134,7 +134,6 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; -import android.os.Trace; import android.os.UserHandle; import android.service.voice.IVoiceInteractionSession; import android.util.ArraySet; @@ -4789,6 +4788,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } + void onPipAnimationEndResize() { + mWindowContainerController.onPipAnimationEndResize(); + } + /** * Adjust bounds to stay within stack bounds. diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 257d79d2c153..76cc3425d060 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2968,6 +2968,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D insetBounds.right = tempPinnedTaskBounds.width(); insetBounds.bottom = tempPinnedTaskBounds.height(); } + if (pinnedBounds != null && tempPinnedTaskBounds == null) { + // We have finished the animation into PiP, and are resizing the tasks to match the + // stack bounds, while layouts are deferred, update any task state as a part of + // transitioning it from fullscreen into a floating state. + stack.onPipAnimationEndResize(); + } stack.resize(pinnedBounds, tempPinnedTaskBounds, insetBounds); stack.ensureVisibleActivitiesConfigurationLocked(r, false); } finally { diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 9a5b1a60219e..d3ac7cb15824 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1606,6 +1606,9 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi boolean topActivity = true; for (--activityNdx; activityNdx >= 0; --activityNdx) { final ActivityRecord r = mActivities.get(activityNdx); + if (r.mTaskOverlay) { + continue; + } if (r.taskDescription != null) { if (label == null) { label = r.taskDescription.getLabel(); diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java index 5ed14a07cb6c..6371d777aeb7 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java @@ -185,7 +185,12 @@ public class TetherInterfaceStateMachine extends StateMachine { private boolean startIPv4() { return configureIPv4(true); } - private void stopIPv4() { configureIPv4(false); } + private void stopIPv4() { + configureIPv4(false); + // NOTE: All of configureIPv4() will be refactored out of existence + // into calls to InterfaceController, shared with startIPv4(). + mInterfaceCtrl.clearIPv4Address(); + } // TODO: Refactor this in terms of calls to InterfaceController. private boolean configureIPv4(boolean enabled) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7b7bc41e4bbb..605644eb4d39 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -7997,6 +7997,13 @@ public class PackageManagerService extends IPackageManager.Stub flags = updateFlagsForApplication(flags, userId, null); final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; + mPermissionManager.enforceCrossUserPermission( + callingUid, + userId, + false /* requireFullPermission */, + false /* checkShell */, + "get installed application info"); + // writer synchronized (mPackages) { ArrayList<ApplicationInfo> list; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 7ffd5ed07a31..03e34d3070ab 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -549,7 +549,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { volatile boolean mGoingToSleep; volatile boolean mRequestedOrGoingToSleep; volatile boolean mRecentsVisible; - volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled; + volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled = true; volatile boolean mPictureInPictureVisible; // Written by vr manager thread, only read in this class. volatile private boolean mPersistentVrModeEnabled; @@ -5761,11 +5761,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStatusBarController.updateVisibilityLw(false /*transientAllowed*/, mLastSystemUiFlags, mLastSystemUiFlags); } - if (statusBarExpanded && mNavigationBar != null) { - if (mNavigationBarController.setBarShowingLw(true)) { - changes |= FINISH_LAYOUT_REDO_LAYOUT; - } - } } else if (mTopFullscreenOpaqueWindowState != null) { topIsFullscreen = topAppHidesStatusBar; // The subtle difference between the window for mTopFullscreenOpaqueWindowState diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java index 653850aa288f..1fd2c0fd19c5 100644 --- a/services/core/java/com/android/server/wm/StackWindowController.java +++ b/services/core/java/com/android/server/wm/StackWindowController.java @@ -192,6 +192,12 @@ public class StackWindowController } } + public void onPipAnimationEndResize() { + synchronized (mService.mWindowMap) { + mContainer.onPipAnimationEndResize(); + } + } + /** * @see TaskStack.getStackDockedModeBoundsLocked(Rect, Rect, Rect, boolean) */ diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 2fbb84604598..c59540b3d088 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -1667,16 +1667,6 @@ public class TaskStack extends WindowContainer<Task> implements @Override // AnimatesBounds public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize, boolean moveToFullscreen) { - // Hold the lock since this is called from the BoundsAnimator running on the UiThread - synchronized (mService.mWindowMap) { - mBoundsAnimating = false; - for (int i = 0; i < mChildren.size(); i++) { - final Task t = mChildren.get(i); - t.clearPreserveNonFloatingState(); - } - mService.requestTraversal(); - } - if (inPinnedWindowingMode()) { // Update to the final bounds if requested. This is done here instead of in the bounds // animator to allow us to coordinate this after we notify the PiP mode changed @@ -1706,6 +1696,18 @@ public class TaskStack extends WindowContainer<Task> implements } } + /** + * Called immediately prior to resizing the tasks at the end of the pinned stack animation. + */ + public void onPipAnimationEndResize() { + mBoundsAnimating = false; + for (int i = 0; i < mChildren.size(); i++) { + final Task t = mChildren.get(i); + t.clearPreserveNonFloatingState(); + } + mService.requestTraversal(); + } + @Override public boolean shouldDeferStartOnMoveToFullscreen() { // Workaround for the recents animation -- normally we need to wait for the new activity to diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java index b5c018a452a4..da4da79a39df 100644 --- a/telephony/java/android/telephony/MbmsDownloadSession.java +++ b/telephony/java/android/telephony/MbmsDownloadSession.java @@ -664,9 +664,6 @@ public class MbmsDownloadSession implements AutoCloseable { * If the operation encountered an error, the error code will be delivered via * {@link MbmsDownloadSessionCallback#onError}. * - * Repeated calls to this method for the same {@link DownloadRequest} will replace the - * previously registered listener. - * * @param request The {@link DownloadRequest} provided during registration * @param listener The listener provided during registration. */ @@ -726,6 +723,9 @@ public class MbmsDownloadSession implements AutoCloseable { * If the operation encountered an error, the error code will be delivered via * {@link MbmsDownloadSessionCallback#onError}. * + * Repeated calls to this method for the same {@link DownloadRequest} will replace the + * previously registered listener. + * * @param request The {@link DownloadRequest} that you want updates on. * @param executor The {@link Executor} on which calls to {@code listener} should be executed. * @param listener The listener that should be called when the middleware has information to diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index d643c69c0e44..f0f3f2c748a0 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -775,11 +775,12 @@ public class TetheringTest { sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); - // We verify get/set called twice here: once for setup and once during + // We verify get/set called thrice here: once for setup and twice during // teardown because all events happen over the course of the single - // dispatchAll() above. + // dispatchAll() above. Note that once the TISM IPv4 address config + // code is refactored the two calls during shutdown will revert to one. verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME); - verify(mNMService, times(2)) + verify(mNMService, times(3)) .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME); verify(mWifiManager).updateInterfaceIpState( diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java index 7c77cf59524d..19d3a2e11904 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java @@ -173,6 +173,7 @@ public class TetherInterfaceStateMachineTest { dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper); inOrder.verify(mNMService).untetherInterface(IFACE_NAME); + inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any()); inOrder.verify(mTetherHelper).updateInterfaceState( mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); inOrder.verify(mTetherHelper).updateLinkProperties( @@ -270,6 +271,7 @@ public class TetherInterfaceStateMachineTest { inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).untetherInterface(IFACE_NAME); + inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any()); inOrder.verify(mTetherHelper).updateInterfaceState( mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); inOrder.verify(mTetherHelper).updateLinkProperties( |