Merge "Fix NotificaitonPanelView x-axis shift with IME" into pi-dev
diff --git a/Android.mk b/Android.mk
index a984a0f..3553f92 100644
--- a/Android.mk
+++ b/Android.mk
@@ -257,6 +257,15 @@
-federate AndroidX https://developer.android.com \
-federationapi AndroidX prebuilts/sdk/current/androidx-api.txt
+framework_metalava_docs_LOCAL_DROIDDOC_OPTIONS := \
+ --manifest ./frameworks/base/core/res/AndroidManifest.xml \
+ --hide-package com.android.okhttp \
+ --hide-package com.android.org.conscrypt --hide-package com.android.server \
+ --hide RequiresPermission \
+ --hide MissingPermission --hide BroadcastBehavior \
+ --hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol \
+ --hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo
+
# ==== Public API diff ===========================
include $(CLEAR_VARS)
@@ -351,6 +360,43 @@
$(INTERNAL_PLATFORM_REMOVED_API_FILE)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE))
+# ==== the metalava api stubs and current.xml ===========================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
+LOCAL_GENERATED_SOURCES:=$(framework_docs_LOCAL_GENERATED_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
+LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
+LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
+LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
+LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
+
+LOCAL_MODULE := metalava-api-stubs
+LOCAL_DROIDDOC_USE_METALAVA := true
+LOCAL_DROIDDOC_METALAVA_PREVIOUS_API := prebuilts/sdk/api/27.txt
+LOCAL_DROIDDOC_METALAVA_ANNOTATIONS_ENABLED := true
+LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR := tools/metalava/manual
+
+LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/metalava_android_stubs_current_intermediates/src
+
+INTERNAL_PLATFORM_METALAVA_PUBLIC_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava_public_api.txt
+INTERNAL_PLATFORM_METALAVA_PUBLIC_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava_removed.txt
+
+LOCAL_DROIDDOC_OPTIONS:=\
+ $(framework_metalava_docs_LOCAL_DROIDDOC_OPTIONS) \
+ --api $(INTERNAL_PLATFORM_METALAVA_PUBLIC_API_FILE) \
+ --removed-api $(INTERNAL_PLATFORM_METALAVA_PUBLIC_REMOVED_API_FILE) \
+ -nodocs
+
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_DROIDDOC)
+
+$(full_target): .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_METALAVA_PUBLIC_API_FILE) \
+ $(INTERNAL_PLATFORM_METALAVA_PUBLIC_REMOVED_API_FILE)
+$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_METALAVA_PUBLIC_API_FILE))
+
# ==== the system api stubs ===================================
include $(CLEAR_VARS)
@@ -388,6 +434,44 @@
$(INTERNAL_PLATFORM_SYSTEM_EXACT_API_FILE)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE))
+# ==== the metalava system api stubs ===================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
+LOCAL_GENERATED_SOURCES:=$(framework_docs_LOCAL_GENERATED_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
+LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
+LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
+LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
+LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
+
+LOCAL_MODULE := metalava-system-api-stubs
+LOCAL_DROIDDOC_USE_METALAVA := true
+LOCAL_DROIDDOC_METALAVA_PREVIOUS_API := prebuilts/sdk/api/27.txt
+LOCAL_DROIDDOC_METALAVA_ANNOTATIONS_ENABLED := true
+LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR := tools/metalava/manual
+
+LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/metalava_android_system_stubs_current_intermediates/src
+
+INTERNAL_PLATFORM_METALAVA_SYSTEM_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava-system-api.txt
+INTERNAL_PLATFORM_METALAVA_SYSTEM_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava-system-removed.txt
+
+LOCAL_DROIDDOC_OPTIONS:=\
+ $(framework_metalava_docs_LOCAL_DROIDDOC_OPTIONS) \
+ --show-annotation android.annotation.SystemApi \
+ --api $(INTERNAL_PLATFORM_METALAVA_SYSTEM_API_FILE) \
+ --removed-api $(INTERNAL_PLATFORM_METALAVA_SYSTEM_REMOVED_API_FILE) \
+ -nodocs
+
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_DROIDDOC)
+
+$(full_target): .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_METALAVA_SYSTEM_API_FILE) \
+ $(INTERNAL_PLATFORM_METALAVA_SYSTEM_REMOVED_API_FILE) \
+$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_METALAVA_SYSTEM_API_FILE))
+
# ==== the test api stubs ===================================
include $(CLEAR_VARS)
@@ -426,6 +510,44 @@
$(INTERNAL_PLATFORM_TEST_EXACT_API_FILE)
$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE))
+# ==== the metalava test api stubs ===================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
+LOCAL_GENERATED_SOURCES:=$(framework_docs_LOCAL_GENERATED_SOURCES)
+LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
+LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
+LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
+LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
+LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
+
+LOCAL_MODULE := metalava-test-api-stubs
+LOCAL_DROIDDOC_USE_METALAVA := true
+LOCAL_DROIDDOC_METALAVA_PREVIOUS_API := prebuilts/sdk/api/27.txt
+LOCAL_DROIDDOC_METALAVA_ANNOTATIONS_ENABLED := true
+LOCAL_DROIDDOC_METALAVA_MERGE_ANNOTATIONS_DIR := tools/metalava/manual
+
+LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/metalava_android_test_stubs_current_intermediates/src
+
+INTERNAL_PLATFORM_METALAVA_TEST_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava-test-api.txt
+INTERNAL_PLATFORM_METALAVA_TEST_REMOVED_API_FILE := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/metalava-test-removed.txt
+
+LOCAL_DROIDDOC_OPTIONS:=\
+ $(framework_metalava_docs_LOCAL_DROIDDOC_OPTIONS) \
+ --show-annotation android.annotation.TestApi \
+ --api $(INTERNAL_PLATFORM_METALAVA_TEST_API_FILE) \
+ --removed-api $(INTERNAL_PLATFORM_METALAVA_TEST_REMOVED_API_FILE) \
+ -nodocs
+
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_DROIDDOC)
+
+$(full_target): .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_METALAVA_TEST_API_FILE) \
+ $(INTERNAL_PLATFORM_METALAVA_TEST_REMOVED_API_FILE) \
+$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_METALAVA_TEST_API_FILE))
+
# ==== the complete hidden api list ===================================
include $(CLEAR_VARS)
diff --git a/cmds/statsd/statsd.rc b/cmds/statsd/statsd.rc
index f349292..cbf2a8d 100644
--- a/cmds/statsd/statsd.rc
+++ b/cmds/statsd/statsd.rc
@@ -19,6 +19,9 @@
group statsd log
writepid /dev/cpuset/system-background/tasks
+on property:ro.statsd.enable=false
+ stop statsd
+
on post-fs-data
# Create directory for statsd
mkdir /data/misc/stats-data/ 0770 statsd system
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index cee71b2..f75fb9c 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -171,6 +171,7 @@
Landroid/app/ActivityManagerNative;->isSystemReady()Z
Landroid/app/ActivityOptions;->makeCustomAnimation(Landroid/content/Context;IILandroid/os/Handler;Landroid/app/ActivityOptions$OnAnimationStartedListener;)Landroid/app/ActivityOptions;
Landroid/app/ActivityOptions;->makeMultiThumbFutureAspectScaleAnimation(Landroid/content/Context;Landroid/os/Handler;Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/app/ActivityOptions$OnAnimationStartedListener;Z)Landroid/app/ActivityOptions;
+Landroid/app/ActivityThread$ActivityClientRecord;-><init>()V
Landroid/app/ActivityThread$ActivityClientRecord;->activity:Landroid/app/Activity;
Landroid/app/ActivityThread$ActivityClientRecord;->activityInfo:Landroid/content/pm/ActivityInfo;
Landroid/app/ActivityThread$ActivityClientRecord;->compatInfo:Landroid/content/res/CompatibilityInfo;
@@ -180,6 +181,7 @@
Landroid/app/ActivityThread$ActivityClientRecord;->paused:Z
Landroid/app/ActivityThread$ActivityClientRecord;->stopped:Z
Landroid/app/ActivityThread$ActivityClientRecord;->token:Landroid/os/IBinder;
+Landroid/app/ActivityThread$AppBindData;-><init>()V
Landroid/app/ActivityThread$AppBindData;->appInfo:Landroid/content/pm/ApplicationInfo;
Landroid/app/ActivityThread$AppBindData;->compatInfo:Landroid/content/res/CompatibilityInfo;
Landroid/app/ActivityThread$AppBindData;->info:Landroid/app/LoadedApk;
@@ -504,6 +506,7 @@
Landroid/app/ContentProviderHolder;->info:Landroid/content/pm/ProviderInfo;
Landroid/app/ContentProviderHolder;->noReleaseNeeded:Z
Landroid/app/ContentProviderHolder;->provider:Landroid/content/IContentProvider;
+Landroid/app/ContextImpl$ApplicationContentResolver;->acquireProvider(Landroid/content/Context;Ljava/lang/String;)Landroid/content/IContentProvider;
Landroid/app/ContextImpl$ApplicationContentResolver;->mMainThread:Landroid/app/ActivityThread;
Landroid/app/ContextImpl;->createActivityContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/pm/ActivityInfo;Landroid/os/IBinder;ILandroid/content/res/Configuration;)Landroid/app/ContextImpl;
Landroid/app/ContextImpl;->createAppContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;)Landroid/app/ContextImpl;
@@ -587,6 +590,7 @@
Landroid/app/IActivityManager$Stub$Proxy;->isAppForeground(I)Z
Landroid/app/IActivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/app/IActivityManager$Stub$Proxy;->setActivityController(Landroid/app/IActivityController;Z)V
+Landroid/app/IActivityManager$Stub$Proxy;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V
Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
Landroid/app/IActivityManager;->bindService(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;ILjava/lang/String;I)I
Landroid/app/IActivityManager;->broadcastIntent(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
@@ -880,8 +884,10 @@
Landroid/app/ProgressDialog;->mProgressNumber:Landroid/widget/TextView;
Landroid/app/QueuedWork;->addFinisher(Ljava/lang/Runnable;)V
Landroid/app/QueuedWork;->getHandler()Landroid/os/Handler;
+Landroid/app/QueuedWork;->queue(Ljava/lang/Runnable;Z)V
Landroid/app/QueuedWork;->removeFinisher(Ljava/lang/Runnable;)V
Landroid/app/QueuedWork;->sFinishers:Ljava/util/LinkedList;
+Landroid/app/ResourcesManager$ActivityResources;-><init>()V
Landroid/app/ResourcesManager;-><init>()V
Landroid/app/ResourcesManager;->appendLibAssetForMainAssetPath(Ljava/lang/String;Ljava/lang/String;)V
Landroid/app/ResourcesManager;->createAssetManager(Landroid/content/res/ResourcesKey;)Landroid/content/res/AssetManager;
@@ -898,6 +904,7 @@
Landroid/app/SearchableInfo$ActionKeyInfo;->getQueryActionMsg()Ljava/lang/String;
Landroid/app/SearchableInfo$ActionKeyInfo;->getSuggestActionMsg()Ljava/lang/String;
Landroid/app/SearchableInfo$ActionKeyInfo;->getSuggestActionMsgColumn()Ljava/lang/String;
+Landroid/app/SearchableInfo;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;Landroid/content/ComponentName;)V
Landroid/app/SearchableInfo;->findActionKey(I)Landroid/app/SearchableInfo$ActionKeyInfo;
Landroid/app/SearchableInfo;->getActivityContext(Landroid/content/Context;)Landroid/content/Context;
Landroid/app/SearchableInfo;->getIconId()I
@@ -1356,8 +1363,10 @@
Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/Bundle;Landroid/os/UserHandle;)V
Landroid/content/Context;->startActivityForResult(Ljava/lang/String;Landroid/content/Intent;ILandroid/os/Bundle;)V
Landroid/content/Context;->STATUS_BAR_SERVICE:Ljava/lang/String;
+Landroid/content/ContextWrapper;->createApplicationContext(Landroid/content/pm/ApplicationInfo;I)Landroid/content/Context;
Landroid/content/ContextWrapper;->getBasePackageName()Ljava/lang/String;
Landroid/content/ContextWrapper;->getDisplay()Landroid/view/Display;
+Landroid/content/ContextWrapper;->getOpPackageName()Ljava/lang/String;
Landroid/content/ContextWrapper;->mBase:Landroid/content/Context;
Landroid/content/ContextWrapper;->registerReceiverAsUser(Landroid/content/BroadcastReceiver;Landroid/os/UserHandle;Landroid/content/IntentFilter;Ljava/lang/String;Landroid/os/Handler;)Landroid/content/Intent;
Landroid/content/ContextWrapper;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V
@@ -1506,6 +1515,8 @@
Landroid/content/pm/IPackageInstallObserver2;->onPackageInstalled(Ljava/lang/String;ILjava/lang/String;Landroid/os/Bundle;)V
Landroid/content/pm/IPackageInstallObserver2;->onUserActionRequired(Landroid/content/Intent;)V
Landroid/content/pm/IPackageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageManager$Stub$Proxy;->checkUidPermission(Ljava/lang/String;I)I
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstallLocation()I
Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
@@ -1526,6 +1537,7 @@
Landroid/content/pm/IPackageManager;->deleteApplicationCacheFiles(Ljava/lang/String;Landroid/content/pm/IPackageDataObserver;)V
Landroid/content/pm/IPackageManager;->enterSafeMode()V
Landroid/content/pm/IPackageManager;->getApplicationEnabledSetting(Ljava/lang/String;I)I
+Landroid/content/pm/IPackageManager;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
Landroid/content/pm/IPackageManager;->getBlockUninstallForUser(Ljava/lang/String;I)Z
Landroid/content/pm/IPackageManager;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
Landroid/content/pm/IPackageManager;->getFlagsForUid(I)I
@@ -1795,6 +1807,7 @@
Landroid/content/pm/VerifierInfo;-><init>(Ljava/lang/String;Ljava/security/PublicKey;)V
Landroid/content/pm/XmlSerializerAndParser;->createFromXml(Lorg/xmlpull/v1/XmlPullParser;)Ljava/lang/Object;
Landroid/content/pm/XmlSerializerAndParser;->writeAsXml(Ljava/lang/Object;Lorg/xmlpull/v1/XmlSerializer;)V
+Landroid/content/res/ApkAssets;->getAssetPath()Ljava/lang/String;
Landroid/content/res/AssetFileDescriptor;->mFd:Landroid/os/ParcelFileDescriptor;
Landroid/content/res/AssetFileDescriptor;->mLength:J
Landroid/content/res/AssetFileDescriptor;->mStartOffset:J
@@ -1806,6 +1819,7 @@
Landroid/content/res/AssetManager;->addOverlayPath(Ljava/lang/String;)I
Landroid/content/res/AssetManager;->applyStyle(JIILandroid/content/res/XmlBlock$Parser;[IJJ)V
Landroid/content/res/AssetManager;->createTheme()J
+Landroid/content/res/AssetManager;->getApkAssets()[Landroid/content/res/ApkAssets;
Landroid/content/res/AssetManager;->getAssignedPackageIdentifiers()Landroid/util/SparseArray;
Landroid/content/res/AssetManager;->getGlobalAssetCount()I
Landroid/content/res/AssetManager;->getGlobalAssetManagerCount()I
@@ -1848,6 +1862,7 @@
Landroid/content/res/CompatibilityInfo$Translator;->translateRectInScreenToAppWinFrame(Landroid/graphics/Rect;)V
Landroid/content/res/CompatibilityInfo$Translator;->translateRegionInWindowToScreen(Landroid/graphics/Region;)V
Landroid/content/res/CompatibilityInfo$Translator;->translateWindowLayout(Landroid/view/WindowManager$LayoutParams;)V
+Landroid/content/res/CompatibilityInfo;-><init>()V
Landroid/content/res/CompatibilityInfo;-><init>(Landroid/content/pm/ApplicationInfo;IIZ)V
Landroid/content/res/CompatibilityInfo;->applicationScale:F
Landroid/content/res/CompatibilityInfo;->computeCompatibleScaling(Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;)F
@@ -1861,6 +1876,7 @@
Landroid/content/res/Configuration;->resourceQualifierString(Landroid/content/res/Configuration;)Ljava/lang/String;
Landroid/content/res/Configuration;->seq:I
Landroid/content/res/Configuration;->userSetLocale:Z
+Landroid/content/res/ConfigurationBoundResourceCache;-><init>()V
Landroid/content/res/DrawableCache;-><init>()V
Landroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
Landroid/content/res/ObbInfo;->salt:[B
@@ -2765,6 +2781,7 @@
Landroid/media/AudioGainConfig;->mValues:[I
Landroid/media/AudioHandle;-><init>(I)V
Landroid/media/AudioHandle;->mId:I
+Landroid/media/AudioManager;-><init>()V
Landroid/media/AudioManager;-><init>(Landroid/content/Context;)V
Landroid/media/AudioManager;->abandonAudioFocusForCall()V
Landroid/media/AudioManager;->createAudioPatch([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)I
@@ -3024,6 +3041,8 @@
Landroid/media/MediaPlayer;->getMediaTimeProvider()Landroid/media/MediaTimeProvider;
Landroid/media/MediaPlayer;->getMetadata(ZZ)Landroid/media/Metadata;
Landroid/media/MediaPlayer;->invoke(Landroid/os/Parcel;Landroid/os/Parcel;)V
+Landroid/media/MediaPlayer;->MEDIA_INFO_EXTERNAL_METADATA_UPDATE:I
+Landroid/media/MediaPlayer;->MEDIA_INFO_TIMED_TEXT_ERROR:I
Landroid/media/MediaPlayer;->METADATA_ALL:Z
Landroid/media/MediaPlayer;->mEventHandler:Landroid/media/MediaPlayer$EventHandler;
Landroid/media/MediaPlayer;->mOnCompletionListener:Landroid/media/MediaPlayer$OnCompletionListener;
@@ -3393,6 +3412,7 @@
Landroid/net/LinkProperties;->getAddresses()Ljava/util/List;
Landroid/net/LinkProperties;->getAllAddresses()Ljava/util/List;
Landroid/net/LinkProperties;->getAllLinkAddresses()Ljava/util/List;
+Landroid/net/LinkProperties;->getTcpBufferSizes()Ljava/lang/String;
Landroid/net/LinkProperties;->isIdenticalHttpProxy(Landroid/net/LinkProperties;)Z
Landroid/net/LinkProperties;->isIdenticalInterfaceName(Landroid/net/LinkProperties;)Z
Landroid/net/LinkProperties;->mIfaceName:Ljava/lang/String;
@@ -6935,6 +6955,7 @@
Landroid/widget/Gallery;->mSpacing:I
Landroid/widget/Gallery;->trackMotionScroll(I)V
Landroid/widget/GridLayout;->UNDEFINED_ALIGNMENT:Landroid/widget/GridLayout$Alignment;
+Landroid/widget/GridView;->determineColumns(I)Z
Landroid/widget/GridView;->fillDown(II)Landroid/view/View;
Landroid/widget/GridView;->fillUp(II)Landroid/view/View;
Landroid/widget/GridView;->mColumnWidth:I
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 2971ef8..0014793 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2771,10 +2771,8 @@
android.security.net.config.RootTrustManager
android.security.net.config.RootTrustManagerFactorySpi
android.security.net.config.SystemCertificateSource
-android.security.net.config.SystemCertificateSource$NoPreloadHolder
android.security.net.config.TrustedCertificateStoreAdapter
android.security.net.config.UserCertificateSource
-android.security.net.config.UserCertificateSource$NoPreloadHolder
android.security.net.config.XmlConfigSource
android.security.net.config.XmlConfigSource$ParserException
android.service.media.IMediaBrowserService
@@ -4556,7 +4554,6 @@
com.android.org.conscrypt.PeerInfoProvider
com.android.org.conscrypt.PeerInfoProvider$1
com.android.org.conscrypt.Platform
-com.android.org.conscrypt.Platform$NoPreloadHolder
com.android.org.conscrypt.Preconditions
com.android.org.conscrypt.SSLClientSessionCache
com.android.org.conscrypt.SSLParametersImpl
@@ -6072,7 +6069,6 @@
javax.net.ssl.HandshakeCompletedListener
javax.net.ssl.HostnameVerifier
javax.net.ssl.HttpsURLConnection
-javax.net.ssl.HttpsURLConnection$NoPreloadHolder
javax.net.ssl.KeyManager
javax.net.ssl.KeyManagerFactory
javax.net.ssl.KeyManagerFactory$1
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 3c7541f..83630f4 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2177,7 +2177,8 @@
}
/**
- * @return Whether or not the snapshot is of a translucent app window.
+ * @return Whether or not the snapshot is of a translucent app window (non-fullscreen or has
+ * a non-opaque pixel format).
*/
public boolean isTranslucent() {
return mIsTranslucent;
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index e4a0583..8bed105 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -291,10 +291,7 @@
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
- if (mDecor.getVisibility() != View.VISIBLE) {
- mDecor.setVisibility(View.VISIBLE);
- sendShowMessage();
- }
+ mDecor.setVisibility(View.VISIBLE);
}
return;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1ea93a4..c22a43e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2767,7 +2767,6 @@
*/
private void fixDuplicateExtras() {
if (extras != null) {
- fixDuplicateExtra(mSmallIcon, EXTRA_SMALL_ICON);
fixDuplicateExtra(mLargeIcon, EXTRA_LARGE_ICON);
}
}
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 30f340c..43f69e1 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -253,20 +253,27 @@
}
/**
- * @deprecated Since Android P app can no longer request restoring of its backup.
+ * @deprecated Applications shouldn't request a restore operation using this method. In Android
+ * P and later, this method is a no-op.
*
- * Restore the calling application from backup. The data will be restored from the
+ * <p>Restore the calling application from backup. The data will be restored from the
* current backup dataset if the application has stored data there, or from
* the dataset used during the last full device setup operation if the current
* backup dataset has no matching data. If no backup data exists for this application
- * in either source, a nonzero value will be returned.
+ * in either source, a non-zero value is returned.
*
- * <p>If this method returns zero (meaning success), the OS will attempt to retrieve
- * a backed-up dataset from the remote transport, instantiate the application's
- * backup agent, and pass the dataset to the agent's
+ * <p>If this method returns zero (meaning success), the OS attempts to retrieve a backed-up
+ * dataset from the remote transport, instantiate the application's backup agent, and pass the
+ * dataset to the agent's
* {@link android.app.backup.BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) onRestore()}
* method.
*
+ * <p class="caution">Unlike other restore operations, this method doesn't terminate the
+ * application after the restore. The application continues running to receive the
+ * {@link RestoreObserver} callbacks on the {@code observer} argument. Full backups use an
+ * {@link android.app.Application Application} base class while key-value backups use the
+ * application subclass declared in the AndroidManifest.xml {@code <application>} tag.
+ *
* @param observer The {@link RestoreObserver} to receive callbacks during the restore
* operation. This must not be null.
*
@@ -282,7 +289,7 @@
/**
* @deprecated Since Android P app can no longer request restoring of its backup.
*
- * Restore the calling application from backup. The data will be restored from the
+ * <p>Restore the calling application from backup. The data will be restored from the
* current backup dataset if the application has stored data there, or from
* the dataset used during the last full device setup operation if the current
* backup dataset has no matching data. If no backup data exists for this application
@@ -635,7 +642,7 @@
}
return false;
}
-
+
/**
* Request an immediate backup, providing an observer to which results of the backup operation
* will be published. The Android backup system will decide for each package whether it will
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1bc3bc9..3dfabdd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6994,6 +6994,7 @@
"<INTENT> specifications include these flags and arguments:",
" [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]",
" [-c <CATEGORY> [-c <CATEGORY>] ...]",
+ " [-n <COMPONENT_NAME>]",
" [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]",
" [--esn <EXTRA_KEY> ...]",
" [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]",
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 03e600e..c988fa9 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -598,8 +598,6 @@
boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId);
boolean getApplicationHiddenSettingAsUser(String packageName, int userId);
- boolean setSystemAppInstallState(String packageName, boolean installed, int userId);
-
IPackageInstaller getPackageInstaller();
boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b677b5e..7253e77 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -147,7 +147,6 @@
GET_DISABLED_COMPONENTS,
GET_DISABLED_UNTIL_USED_COMPONENTS,
GET_UNINSTALLED_PACKAGES,
- MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PackageInfoFlags {}
@@ -165,7 +164,6 @@
MATCH_STATIC_SHARED_LIBRARIES,
GET_DISABLED_UNTIL_USED_COMPONENTS,
GET_UNINSTALLED_PACKAGES,
- MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ApplicationInfoFlags {}
@@ -524,12 +522,6 @@
public static final int MATCH_DEBUG_TRIAGED_MISSING = 0x10000000;
/**
- * Internal flag used to indicate that a package is a hidden system app.
- * @hide
- */
- public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 0x20000000;
-
- /**
* Flag for {@link #addCrossProfileIntentFilter}: if this flag is set: when
* resolving an intent that matches the {@code CrossProfileIntentFilter},
* the current profile will be skipped. Only activities in the target user
@@ -1965,8 +1957,6 @@
* </ul>
* A version of 1.1.0 or higher also indicates:
* <ul>
- * <li>The {@code VK_ANDROID_external_memory_android_hardware_buffer} extension is
- * supported.</li>
* <li>{@code SYNC_FD} external semaphore and fence handles are supported.</li>
* <li>{@code VkPhysicalDeviceSamplerYcbcrConversionFeatures::samplerYcbcrConversion} is
* supported.</li>
@@ -4851,8 +4841,7 @@
* on the system for other users, also install it for the specified user.
* @hide
*/
- @RequiresPermission(anyOf = {
- Manifest.permission.INSTALL_EXISTING_PACKAGES,
+ @RequiresPermission(anyOf = {
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.INTERACT_ACROSS_USERS_FULL})
public abstract int installExistingPackageAsUser(String packageName, @UserIdInt int userId)
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b8eb074..2da2cb4 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -639,19 +639,11 @@
*/
private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state,
ApplicationInfo appInfo) {
- // Returns false if the package is hidden system app until installed.
- if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
- && !state.installed
- && appInfo != null && appInfo.isSystemApp()) {
- return false;
- }
-
// If available for the target user, or trying to match uninstalled packages and it's
// a system app.
return state.isAvailable(flags)
|| (appInfo != null && appInfo.isSystemApp()
- && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
- || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
+ && (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0);
}
public static boolean isAvailable(PackageUserState state) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0510418..68c3111 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7529,9 +7529,6 @@
*/
public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity";
- private static final Validator ASSIST_GESTURE_SENSITIVITY_VALIDATOR =
- new SettingsValidators.InclusiveFloatRangeValidator(0.0f, 1.0f);
-
/**
* Whether the assist gesture should silence alerts.
*
@@ -7561,8 +7558,6 @@
*/
public static final String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
- private static final Validator ASSIST_GESTURE_SETUP_COMPLETE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Control whether Night display is currently activated.
* @hide
@@ -8018,8 +8013,6 @@
NFC_PAYMENT_DEFAULT_COMPONENT,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
ASSIST_GESTURE_ENABLED,
- ASSIST_GESTURE_SENSITIVITY,
- ASSIST_GESTURE_SETUP_COMPLETE,
ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
ASSIST_GESTURE_WAKE_ENABLED,
VR_DISPLAY_MODE,
@@ -8158,8 +8151,6 @@
VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
VALIDATORS.put(ASSIST_GESTURE_ENABLED, ASSIST_GESTURE_ENABLED_VALIDATOR);
- VALIDATORS.put(ASSIST_GESTURE_SENSITIVITY, ASSIST_GESTURE_SENSITIVITY_VALIDATOR);
- VALIDATORS.put(ASSIST_GESTURE_SETUP_COMPLETE, ASSIST_GESTURE_SETUP_COMPLETE_VALIDATOR);
VALIDATORS.put(ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
ASSIST_GESTURE_SILENCE_ALERTS_ENABLED_VALIDATOR);
VALIDATORS.put(ASSIST_GESTURE_WAKE_ENABLED, ASSIST_GESTURE_WAKE_ENABLED_VALIDATOR);
diff --git a/core/java/android/service/autofill/TextValueSanitizer.java b/core/java/android/service/autofill/TextValueSanitizer.java
index e5ad77a..a8c080a 100644
--- a/core/java/android/service/autofill/TextValueSanitizer.java
+++ b/core/java/android/service/autofill/TextValueSanitizer.java
@@ -37,7 +37,7 @@
* <p>For example, to remove spaces from groups of 4-digits in a credit card:
*
* <pre class="prettyprint">
- * new TextValueSanitizer(Pattern.compile("^(\\d{4})\\s?(\\d{4})\\s?(\\d{4})\\s?(\\d{4})$",
+ * new TextValueSanitizer(Pattern.compile("^(\\d{4})\\s?(\\d{4})\\s?(\\d{4})\\s?(\\d{4})$"),
* "$1$2$3$4")
* </pre>
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 172e248..2c9e543 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -26933,10 +26933,10 @@
* version supported by the application. For example, the method
* {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} is not available
* in API version 4 when the accessibility APIs were first introduced. If a
- * developer would like his application to run on API version 4 devices (assuming
+ * developer would like their application to run on API version 4 devices (assuming
* all other APIs used by the application are version 4 or lower) and take advantage
* of this method, instead of overriding the method which would break the application's
- * backwards compatibility, he can override the corresponding method in this
+ * backwards compatibility, they can override the corresponding method in this
* delegate and register the delegate in the target View if the API version of
* the system is high enough, i.e. the API version is the same as or higher than the API
* version that introduced
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0506f30..b2e53ed7 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3305,8 +3305,11 @@
}
useAsyncReport = true;
- mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this, mNextRtFrameCallback);
+
+ // draw(...) might invoke post-draw, which might register the next callback already.
+ final FrameDrawingCallback callback = mNextRtFrameCallback;
mNextRtFrameCallback = null;
+ mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this, callback);
} else {
// If we get here with a disabled & requested hardware renderer, something went
// wrong (an invalidate posted right before we destroyed the hardware surface
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 6df76fa..e6f948f 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -21,6 +21,7 @@
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionGroupInfo;
@@ -590,7 +591,8 @@
private void addPermToList(List<MyPermissionInfo> permList,
MyPermissionInfo pInfo) {
if (pInfo.mLabel == null) {
- pInfo.mLabel = pInfo.loadLabel(mPm);
+ pInfo.mLabel = pInfo.loadSafeLabel(mPm, 20000, PackageItemInfo.SAFE_LABEL_FLAG_TRIM
+ | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
}
int idx = Collections.binarySearch(permList, pInfo, mPermComparator);
if(localLOGV) Log.i(TAG, "idx="+idx+", list.size="+permList.size());
@@ -611,7 +613,9 @@
}
MyPermissionGroupInfo group = mPermGroups.get(pInfo.group);
if (group != null) {
- pInfo.mLabel = pInfo.loadLabel(mPm);
+ pInfo.mLabel = pInfo.loadSafeLabel(mPm, 20000,
+ PackageItemInfo.SAFE_LABEL_FLAG_TRIM
+ | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
addPermToList(group.mAllPermissions, pInfo);
if (pInfo.mNew) {
addPermToList(group.mNewPermissions, pInfo);
@@ -622,14 +626,18 @@
for (MyPermissionGroupInfo pgrp : mPermGroups.values()) {
if (pgrp.labelRes != 0 || pgrp.nonLocalizedLabel != null) {
- pgrp.mLabel = pgrp.loadLabel(mPm);
+ pgrp.mLabel = pgrp.loadSafeLabel(mPm, 20000, PackageItemInfo.SAFE_LABEL_FLAG_TRIM
+ | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
} else {
ApplicationInfo app;
try {
app = mPm.getApplicationInfo(pgrp.packageName, 0);
- pgrp.mLabel = app.loadLabel(mPm);
+ pgrp.mLabel = app.loadSafeLabel(mPm, 20000, PackageItemInfo.SAFE_LABEL_FLAG_TRIM
+ | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
} catch (NameNotFoundException e) {
- pgrp.mLabel = pgrp.loadLabel(mPm);
+ pgrp.mLabel = pgrp.loadSafeLabel(mPm, 20000,
+ PackageItemInfo.SAFE_LABEL_FLAG_TRIM
+ | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
}
}
mPermGroupsList.add(pgrp);
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index 26fb6b64..07bb453 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -27,9 +27,11 @@
public class AmbientDisplayConfiguration {
private final Context mContext;
+ private final boolean mAlwaysOnByDefault;
public AmbientDisplayConfiguration(Context context) {
mContext = context;
+ mAlwaysOnByDefault = mContext.getResources().getBoolean(R.bool.config_dozeAlwaysOnEnabled);
}
public boolean enabled(int user) {
@@ -101,8 +103,8 @@
}
public boolean alwaysOnEnabled(int user) {
- return boolSettingDefaultOn(Settings.Secure.DOZE_ALWAYS_ON, user) && alwaysOnAvailable()
- && !accessibilityInversionEnabled(user);
+ return boolSetting(Settings.Secure.DOZE_ALWAYS_ON, user, mAlwaysOnByDefault ? 1 : 0)
+ && alwaysOnAvailable() && !accessibilityInversionEnabled(user);
}
public boolean alwaysOnAvailable() {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 3fe8f85..daea9a8 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2032,7 +2032,7 @@
* Do this in onKeyUp since the Search key is also used for
* chording quick launch shortcuts.
*/
- if (getKeyguardManager().inKeyguardRestrictedInputMode()) {
+ if (isNotInstantAppAndKeyguardRestricted()) {
break;
}
if ((getContext().getResources().getConfiguration().uiMode
@@ -2056,6 +2056,11 @@
return false;
}
+ private boolean isNotInstantAppAndKeyguardRestricted() {
+ return !getContext().getPackageManager().isInstantApp()
+ && getKeyguardManager().inKeyguardRestrictedInputMode();
+ }
+
@Override
protected void onActive() {
}
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 0fd6109..4ba93bc 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -60,6 +60,13 @@
public class MessagingLayout extends FrameLayout {
private static final float COLOR_SHIFT_AMOUNT = 60;
+ /**
+ * Pattren for filter some ingonable characters.
+ * p{Z} for any kind of whitespace or invisible separator.
+ * p{C} for any kind of punctuation character.
+ */
+ private static final Pattern IGNORABLE_CHAR_PATTERN
+ = Pattern.compile("[\\p{C}\\p{Z}]");
private static final Pattern SPECIAL_CHAR_PATTERN
= Pattern.compile ("[!@#$%&*()_+=|<>?{}\\[\\]~-]");
private static final Consumer<MessagingMessage> REMOVE_MESSAGE
@@ -233,7 +240,10 @@
continue;
}
if (!uniqueNames.containsKey(senderName)) {
- char c = senderName.charAt(0);
+ // Only use visible characters to get uniqueNames
+ String pureSenderName = IGNORABLE_CHAR_PATTERN
+ .matcher(senderName).replaceAll("" /* replacement */);
+ char c = pureSenderName.charAt(0);
if (uniqueCharacters.containsKey(c)) {
// this character was already used, lets make it more unique. We first need to
// resolve the existing character if it exists
@@ -245,7 +255,7 @@
uniqueNames.put(senderName, findNameSplit((String) senderName));
} else {
uniqueNames.put(senderName, Character.toString(c));
- uniqueCharacters.put(c, senderName);
+ uniqueCharacters.put(c, pureSenderName);
}
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index dced0ad..66c497e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3024,15 +3024,6 @@
<permission android:name="android.permission.INSTALL_PACKAGE_UPDATES"
android:protectionLevel="signature|privileged" />
- <!-- Allows an application to install existing system packages. This is a limited
- version of {@link android.Manifest.permission#INSTALL_PACKAGES}.
- <p>Not for use by third-party applications.
- TODO(b/80204953): remove this permission once we have a long-term solution.
- @hide
- -->
- <permission android:name="com.android.permission.INSTALL_EXISTING_PACKAGES"
- android:protectionLevel="signature|privileged" />
-
<!-- @SystemApi Allows an application to clear user data.
<p>Not for use by third-party applications
@hide
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0b5dd7e..94c8a8b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -659,9 +659,27 @@
<!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
<bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
- <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements
- during voice calls -->
- <bool translatable="false" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit">false</bool>
+ <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements -->
+ <bool translatable="false" name="config_wifi_framework_enable_sar_tx_power_limit">false</bool>
+
+ <!-- Boolean indicating whether framework needs to use body proximity to set the tx power limit
+ for meeting SAR requirements -->
+ <bool translatable="false" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit">false</bool>
+
+ <!-- String for the sensor type for body/head proximity for SAR -->
+ <string translatable="false" name="config_wifi_sar_sensor_type"></string>
+
+ <!-- Integer indicating event id by sar sensor for free space -->
+ <integer translatable="false" name="config_wifi_framework_sar_free_space_event_id">1</integer>
+
+ <!-- Integer indicating event id by sar sensor for near hand -->
+ <integer translatable="false" name="config_wifi_framework_sar_near_hand_event_id">2</integer>
+
+ <!-- Integer indicating event id by sar sensor for near head -->
+ <integer translatable="false" name="config_wifi_framework_sar_near_head_event_id">3</integer>
+
+ <!-- Integer indicating event id by sar sensor for near body -->
+ <integer translatable="false" name="config_wifi_framework_sar_near_body_event_id">4</integer>
<!-- Wifi driver supports batched scan -->
<bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
@@ -2085,6 +2103,10 @@
states. -->
<bool name="config_dozeAlwaysOnDisplayAvailable">false</bool>
+ <!-- Control whether the always on display mode is enabled by default. This value will be used
+ during initialization when the setting is still null. -->
+ <bool name="config_dozeAlwaysOnEnabled">true</bool>
+
<!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
<bool name="config_displayBlanksAfterDoze">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f80abc1..a9b2722 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -336,7 +336,13 @@
<java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
<java-symbol type="bool" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection" />
<java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
- <java-symbol type="bool" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit" />
+ <java-symbol type="bool" name="config_wifi_framework_enable_sar_tx_power_limit" />
+ <java-symbol type="bool" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit" />
+ <java-symbol type="string" name="config_wifi_sar_sensor_type" />
+ <java-symbol type="integer" name="config_wifi_framework_sar_free_space_event_id" />
+ <java-symbol type="integer" name="config_wifi_framework_sar_near_hand_event_id" />
+ <java-symbol type="integer" name="config_wifi_framework_sar_near_head_event_id" />
+ <java-symbol type="integer" name="config_wifi_framework_sar_near_body_event_id" />
<java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
<java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
<java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
@@ -3231,6 +3237,7 @@
<java-symbol type="dimen" name="config_inCallNotificationVolume" />
<java-symbol type="string" name="config_inCallNotificationSound" />
<java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
+ <java-symbol type="bool" name="config_dozeAlwaysOnEnabled" />
<java-symbol type="bool" name="config_displayBlanksAfterDoze" />
<java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
<java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index fc00f1b..cad0b85 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -507,6 +507,8 @@
Settings.Secure.ANR_SHOW_BACKGROUND,
Settings.Secure.ASSISTANT,
Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
+ Settings.Secure.ASSIST_GESTURE_SENSITIVITY,
+ Settings.Secure.ASSIST_GESTURE_SETUP_COMPLETE,
Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
Settings.Secure.ASSIST_STRUCTURE_ENABLED,
Settings.Secure.AUTOFILL_FEATURE_FIELD_CLASSIFICATION,
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index bde4943..ab90e1b 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -168,6 +168,7 @@
<assign-permission name="android.permission.DUMP" uid="incidentd" />
<assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="incidentd" />
+ <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="incidentd" />
<assign-permission name="android.permission.ACCESS_LOWPAN_STATE" uid="lowpan" />
<assign-permission name="android.permission.MANAGE_LOWPAN_INTERFACES" uid="lowpan" />
diff --git a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
index a02fd89..f739fa2 100644
--- a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
+++ b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
Binary files differ
diff --git a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
index c309ac5..4b45e3a 100644
--- a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
+++ b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
Binary files differ
diff --git a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
index 414fad4..748d1a2 100644
--- a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
+++ b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
Binary files differ
diff --git a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png
index c147a87..6e436ba 100644
--- a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png
+++ b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png
Binary files differ
diff --git a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
index 4ce2125..9776874 100644
--- a/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
+++ b/docs/html/reference/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
Binary files differ
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 54358e3..e397ed9 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -57,6 +57,8 @@
import com.android.internal.R;
import com.android.internal.util.VirtualRefBasePtr;
+import dalvik.annotation.optimization.FastNative;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -64,7 +66,6 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import dalvik.annotation.optimization.FastNative;
/**
* This class animates properties of a {@link android.graphics.drawable.VectorDrawable} with
@@ -167,7 +168,7 @@
* </p>
* Below is an example of a VectorDrawable defined in vectordrawable.xml. This VectorDrawable is
* referred to by its file name (not including file suffix) in the
- * <a href="AVDExample">AnimatedVectorDrawable XML example</a>.
+ * <a href="#AVDExample">AnimatedVectorDrawable XML example</a>.
* <pre>
* <vector xmlns:android="http://schemas.android.com/apk/res/android"
* android:height="64dp"
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index b644cc3..861dc0f 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -6824,8 +6824,16 @@
}
} else if (ctype == RES_TABLE_LIBRARY_TYPE) {
+
if (group->dynamicRefTable.entries().size() == 0) {
- status_t err = group->dynamicRefTable.load((const ResTable_lib_header*) chunk);
+ const ResTable_lib_header* lib = (const ResTable_lib_header*) chunk;
+ status_t err = validate_chunk(&lib->header, sizeof(*lib),
+ endPos, "ResTable_lib_header");
+ if (err != NO_ERROR) {
+ return (mError=err);
+ }
+
+ err = group->dynamicRefTable.load(lib);
if (err != NO_ERROR) {
return (mError=err);
}
diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml
index abafb68..48094c4 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2017 The Android Open Source Project
+Copyright (C) 2018 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.
@@ -13,28 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:pathData="M25.0,25.0m-20.5,0.0a20.5,20.5,0,1,1,41.0,0.0a20.5,20.5,0,1,1,-41.0,0.0"
- android:fillAlpha="0.066"
- android:fillColor="#000000"/>
- <path
- android:pathData="M24.0,24.0m-20.0,0.0a20.0,20.0,0,1,1,40.0,0.0a20.0,20.0,0,1,1,-40.0,0.0"
- android:fillColor="#FFC107"/>
- <path
- android:pathData="M44,24.2010101 L33.9004889,14.101499 L14.101499,33.9004889 L24.2010101,44 C29.2525804,43.9497929 34.2887564,41.9975027 38.1431296,38.1431296 C41.9975027,34.2887564 43.9497929,29.2525804 44,24.2010101 Z"
- android:fillColor="#FE9F00"/>
- <path
- android:pathData="M24.0,24.0m-14.0,0.0a14.0,14.0,0,1,1,28.0,0.0a14.0,14.0,0,1,1,-28.0,0.0"
- android:fillColor="#FED44F"/>
- <path
- android:pathData="M37.7829445,26.469236 L29.6578482,18.3441397 L18.3441397,29.6578482 L26.469236,37.7829445 C29.1911841,37.2979273 31.7972024,36.0037754 33.9004889,33.9004889 C36.0037754,31.7972024 37.2979273,29.1911841 37.7829445,26.469236 Z"
- android:fillColor="#FFC107"/>
- <path
- android:pathData="M24.0,24.0m-8.0,0.0a8.0,8.0,0,1,1,16.0,0.0a8.0,8.0,0,1,1,-16.0,0.0"
- android:fillColor="#FFFFFF"/>
-</vector>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@drawable/icon_bg"/>
+ <foreground android:drawable="@drawable/p"/>
+</adaptive-icon>
diff --git a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
new file mode 100644
index 0000000..31ecf7e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
@@ -0,0 +1,18 @@
+<!--
+Copyright (C) 2018 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.
+-->
+<color xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="#C5E1A5" />
+
diff --git a/packages/SystemUI/res/drawable-nodpi/p.xml b/packages/SystemUI/res/drawable-nodpi/p.xml
new file mode 100644
index 0000000..596b782
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/p.xml
@@ -0,0 +1,33 @@
+<!--
+Copyright (C) 2018 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M49,65L54,65C60.075,65 65,60.075 65,54C65,47.925 60.075,43 54,43C47.925,43 43,47.925 43,54L43,108"
+ android:strokeWidth="16"
+ android:fillColor="#00000000"
+ android:strokeColor="#7CB342"
+ android:fillType="evenOdd"/>
+ <path
+ android:pathData="M51,65L54,65C60.075,65 65,60.075 65,54C65,47.925 60.075,43 54,43C47.925,43 43,47.925 43,54L43,108"
+ android:strokeWidth="8"
+ android:fillColor="#00000000"
+ android:strokeColor="#FFFFFF"
+ android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml
index 9c24c2c..47e1059 100644
--- a/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml
@@ -22,5 +22,5 @@
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M12.72,23H11C5.49,23 1,18.51 1,13h2c0,3.78 2.63,6.95 6.15,7.79L8.13,19L9.87,18L12.72,23zM13,1h-1.72l2.85,5L15.87,5l-1.02,-1.79C18.37,4.05 21,7.22 21,11h2C23,5.49 18.51,1 13,1zM10.23,6L18,13.76L13.77,18L6,10.24L10.23,6C10.23,6 10.23,6 10.23,6M10.23,4C9.72,4 9.21,4.2 8.82,4.59L4.59,8.82c-0.78,0.78 -0.78,2.04 0,2.82l7.77,7.77c0.39,0.39 0.9,0.59 1.41,0.59c0.51,0 1.02,-0.2 1.41,-0.59l4.24,-4.24c0.78,-0.78 0.78,-2.04 0,-2.82l-7.77,-7.77C11.26,4.2 10.75,4 10.23,4L10.23,4z"/>
+ android:pathData="M7.4,10.94H2.45V5.99l2,0.01v1.53l4.61,-4.61c0.64,-0.64 1.67,-0.66 2.29,-0.04l8.18,8.18h-2.83l-6.48,-6.48L5.86,8.95H7.4V10.94zM16.6,13.06l0.01,2h1.53l-4.36,4.36l-6.48,-6.48H4.46l8.19,8.19c0.62,0.62 1.65,0.6 2.29,-0.04l4.61,-4.61l0.01,0.01v1.53h1.99v-4.95H16.6z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
index 2cd7883..3304c19 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
@@ -17,16 +17,16 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector android:name="root"
- android:width="21dp"
- android:height="21dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28.0"
+ android:viewportHeight="28.0">
<!-- Use scaleX to flip icon so arrows always point in the direction of motion -->
- <group android:name="icon" android:pivotX="12" android:pivotY="12"
+ <group android:name="icon" android:pivotX="14" android:pivotY="14"
android:scaleX="?attr/rotateButtonScaleX">
<!-- Tint color to be set directly -->
<path android:fillColor="#FFFFFFFF"
- android:pathData="M19,12c0,1.72 -0.63,3.3 -1.66,4.52l-1.44,-1.44C16.58,14.23 17,13.17 17,12c0,-2.76 -2.24,-5 -5,-5c-0.06,0 -0.11,0.01 -0.17,0.01l1.08,1.08L11.5,9.5L8,6l3.5,-3.5l1.41,1.42l-1.09,1.09C11.88,5.01 11.94,5 12,5C15.87,5 19,8.13 19,12zM12.5,14.51l-1.41,1.41l1.06,1.06C12.1,16.99 12.05,17 12,17c-2.76,0 -5,-2.24 -5,-5c0,-1.17 0.42,-2.23 1.09,-3.08L6.66,7.48C5.62,8.7 5,10.28 5,12c0,3.87 3.13,7 7,7c0.06,0 0.13,-0.01 0.19,-0.01v0l-1.1,1.1l1.41,1.41L16,18L12.5,14.51z"/>
+ android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/>
</group>
</vector>
</aapt:attr>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
index 2e1487c..37e2b53 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -39,7 +39,7 @@
android:layout_height="match_parent"
android:layout_marginTop="@dimen/car_user_switcher_margin_top"
app:verticallyCenterListContent="true"
- app:dayNightStyle="force_night"
+ app:dayNightStyle="always_light"
app:showPagedListViewDivider="false"
app:gutter="both"
app:itemSpacing="@dimen/car_user_switcher_vertical_spacing_between_users"/>
diff --git a/packages/SystemUI/res/layout/car_qs_panel.xml b/packages/SystemUI/res/layout/car_qs_panel.xml
index 0e8db77..c43afc9 100644
--- a/packages/SystemUI/res/layout/car_qs_panel.xml
+++ b/packages/SystemUI/res/layout/car_qs_panel.xml
@@ -39,7 +39,7 @@
android:id="@+id/user_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:dayNightStyle="force_night"
+ app:dayNightStyle="always_light"
app:showPagedListViewDivider="false"
app:gutter="both"
app:itemSpacing="@dimen/car_user_switcher_vertical_spacing_between_users"/>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index b81d363..c59dbdc 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -22,7 +22,7 @@
<dimen name="docked_divider_handle_width">2dp</dimen>
<dimen name="docked_divider_handle_height">16dp</dimen>
- <dimen name="brightness_mirror_height">96dp</dimen>
+ <dimen name="brightness_mirror_height">40dp</dimen>
<!-- Width for the spacer, used between QS tiles. -->
<dimen name="qs_quick_tile_space_width">38dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4433532..3b58b72 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -287,7 +287,7 @@
<dimen name="notification_panel_width">@dimen/match_parent</dimen>
- <dimen name="brightness_mirror_height">108dp</dimen>
+ <dimen name="brightness_mirror_height">48dp</dimen>
<!-- The width of the panel that holds the quick settings. -->
<dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
@@ -1012,4 +1012,7 @@
<!-- How much into a DisplayCutout's bounds we can go, on each side -->
<dimen name="display_cutout_margin_consumption">0px</dimen>
+ <!-- How much we expand the touchable region of the status bar below the notch to catch touches
+ that just start below the notch. -->
+ <dimen name="display_cutout_touchable_region_size">12dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index 5b0f1c3..66475e2 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -334,8 +334,10 @@
break;
case SimPermDisabled:
- carrierText = getContext().getText(
- R.string.keyguard_permanent_disabled_sim_message_short);
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ getContext().getText(
+ R.string.keyguard_permanent_disabled_sim_message_short),
+ text);
break;
case SimMissingLocked:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 49dba68..225f7fc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -73,6 +73,7 @@
private ArraySet<View> mVisibleInDoze;
private boolean mPulsing;
+ private boolean mWasPulsing;
private float mDarkAmount = 0;
private int mTextColor;
private float mWidgetPadding;
@@ -224,7 +225,8 @@
boolean hasHeader = mKeyguardSlice.hasHeader();
boolean smallClock = hasHeader || mPulsing;
long duration = KeyguardSliceView.DEFAULT_ANIM_DURATION;
- long delay = smallClock ? 0 : duration / 4;
+ long delay = smallClock || mWasPulsing ? 0 : duration / 4;
+ mWasPulsing = false;
boolean shouldAnimate = mKeyguardSlice.getLayoutTransition() != null
&& mKeyguardSlice.getLayoutTransition().isRunning();
@@ -282,6 +284,7 @@
mClockView.setPivotX(mClockView.getWidth() / 2);
mClockView.setPivotY(0);
mLastLayoutHeight = getHeight();
+ layoutOwnerInfo();
}
@Override
@@ -418,9 +421,11 @@
if (mLogoutView != null) {
mLogoutView.setAlpha(dark ? 0 : 1);
}
+
if (mOwnerInfo != null) {
boolean hasText = !TextUtils.isEmpty(mOwnerInfo.getText());
- mOwnerInfo.setVisibility(hasText && mDarkAmount != 1 ? VISIBLE : GONE);
+ mOwnerInfo.setVisibility(hasText ? VISIBLE : GONE);
+ layoutOwnerInfo();
}
final int blendedTextColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
@@ -430,7 +435,27 @@
mClockSeparator.setBackgroundColor(blendedTextColor);
}
+ private void layoutOwnerInfo() {
+ if (mOwnerInfo != null && mOwnerInfo.getVisibility() != GONE) {
+ // Animate owner info during wake-up transition
+ mOwnerInfo.setAlpha(1f - mDarkAmount);
+
+ float ratio = mDarkAmount;
+ // Calculate how much of it we should crop in order to have a smooth transition
+ int collapsed = mOwnerInfo.getTop() - mOwnerInfo.getPaddingTop();
+ int expanded = mOwnerInfo.getBottom() + mOwnerInfo.getPaddingBottom();
+ int toRemove = (int) ((expanded - collapsed) * ratio);
+ setBottom(getMeasuredHeight() - toRemove);
+ }
+ }
+
public void setPulsing(boolean pulsing, boolean animate) {
+ if (mPulsing == pulsing) {
+ return;
+ }
+ if (mPulsing) {
+ mWasPulsing = true;
+ }
mPulsing = pulsing;
mKeyguardSlice.setPulsing(pulsing, animate);
updateDozeVisibleViews();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 62cd13b..ef3aa42 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1589,6 +1589,10 @@
}
}
+ public boolean isKeyguardVisible() {
+ return mKeyguardIsVisible;
+ }
+
/**
* Notifies that the visibility state of Keyguard has changed.
*
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index efaf557..194679c 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -52,6 +52,7 @@
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -89,6 +90,9 @@
private float mDensity;
private WindowManager mWindowManager;
private int mRotation;
+ private DisplayCutoutView mCutoutTop;
+ private DisplayCutoutView mCutoutBottom;
+ private boolean mPendingRotationChange;
@Override
public void start() {
@@ -122,6 +126,22 @@
@Override
public void onDisplayChanged(int displayId) {
+ if (mOverlay != null && mBottomOverlay != null
+ && mRotation != RotationUtils.getExactRotation(mContext)) {
+ // We cannot immediately update the orientation. Otherwise
+ // WindowManager is still deferring layout until it has finished dispatching
+ // the config changes, which may cause divergence between what we draw
+ // (new orientation), and where we are placed on the screen (old orientation).
+ // Instead we wait until either:
+ // - we are trying to redraw. This because WM resized our window and told us to.
+ // - the config change has been dispatched, so WM is no longer deferring layout.
+ mPendingRotationChange = true;
+ mOverlay.getViewTreeObserver().addOnPreDrawListener(
+ new RestartingPreDrawListener(mOverlay));
+ mBottomOverlay.getViewTreeObserver().addOnPreDrawListener(
+ new RestartingPreDrawListener(mBottomOverlay));
+
+ }
updateOrientation();
}
};
@@ -135,14 +155,14 @@
private void setupDecorations() {
mOverlay = LayoutInflater.from(mContext)
.inflate(R.layout.rounded_corners, null);
- DisplayCutoutView cutoutTop = new DisplayCutoutView(mContext, true,
- this::updateWindowVisibilities);
- ((ViewGroup)mOverlay).addView(cutoutTop);
+ mCutoutTop = new DisplayCutoutView(mContext, true,
+ this::updateWindowVisibilities, this);
+ ((ViewGroup)mOverlay).addView(mCutoutTop);
mBottomOverlay = LayoutInflater.from(mContext)
.inflate(R.layout.rounded_corners, null);
- DisplayCutoutView cutoutBottom = new DisplayCutoutView(mContext, false,
- this::updateWindowVisibilities);
- ((ViewGroup)mBottomOverlay).addView(cutoutBottom);
+ mCutoutBottom = new DisplayCutoutView(mContext, false,
+ this::updateWindowVisibilities, this);
+ ((ViewGroup)mBottomOverlay).addView(mCutoutBottom);
mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
mOverlay.setAlpha(0);
@@ -172,8 +192,8 @@
((ImageView) mOverlay.findViewById(R.id.right)).setImageTintList(tintList);
((ImageView) mBottomOverlay.findViewById(R.id.left)).setImageTintList(tintList);
((ImageView) mBottomOverlay.findViewById(R.id.right)).setImageTintList(tintList);
- cutoutTop.setColor(tint);
- cutoutBottom.setColor(tint);
+ mCutoutTop.setColor(tint);
+ mCutoutBottom.setColor(tint);
}
};
setting.setListening(true);
@@ -199,6 +219,7 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
+ mPendingRotationChange = false;
updateOrientation();
if (shouldDrawCutout() && mOverlay == null) {
setupDecorations();
@@ -206,6 +227,9 @@
}
protected void updateOrientation() {
+ if (mPendingRotationChange) {
+ return;
+ }
int newRotation = RotationUtils.getExactRotation(mContext);
if (newRotation != mRotation) {
mRotation = newRotation;
@@ -245,6 +269,9 @@
updateView(bottomRight, Gravity.TOP | Gravity.LEFT, 0);
}
+ mCutoutTop.setRotation(mRotation);
+ mCutoutBottom.setRotation(mRotation);
+
updateWindowVisibilities();
}
@@ -416,15 +443,19 @@
private final Rect mBoundingRect = new Rect();
private final Path mBoundingPath = new Path();
private final int[] mLocation = new int[2];
- private final boolean mStart;
+ private final boolean mInitialStart;
private final Runnable mVisibilityChangedListener;
+ private final ScreenDecorations mDecorations;
private int mColor = Color.BLACK;
+ private boolean mStart;
+ private int mRotation;
public DisplayCutoutView(Context context, boolean start,
- Runnable visibilityChangedListener) {
+ Runnable visibilityChangedListener, ScreenDecorations decorations) {
super(context);
- mStart = start;
+ mInitialStart = start;
mVisibilityChangedListener = visibilityChangedListener;
+ mDecorations = decorations;
setId(R.id.display_cutout);
}
@@ -475,7 +506,22 @@
}
}
+ public void setRotation(int rotation) {
+ mRotation = rotation;
+ update();
+ }
+
+ private boolean isStart() {
+ final boolean flipped = (mRotation == RotationUtils.ROTATION_SEASCAPE
+ || mRotation == RotationUtils.ROTATION_UPSIDE_DOWN);
+ return flipped ? !mInitialStart : mInitialStart;
+ }
+
private void update() {
+ if (!isAttachedToWindow() || mDecorations.mPendingRotationChange) {
+ return;
+ }
+ mStart = isStart();
requestLayout();
getDisplay().getDisplayInfo(mInfo);
mBounds.setEmpty();
@@ -560,31 +606,34 @@
resolveSizeAndState(mBoundingRect.height(), heightMeasureSpec, 0));
}
- public static void boundsFromDirection(DisplayCutout displayCutout, int gravity, Rect out) {
+ public static void boundsFromDirection(DisplayCutout displayCutout, int gravity,
+ Rect out) {
+ Region bounds = boundsFromDirection(displayCutout, gravity);
+ out.set(bounds.getBounds());
+ bounds.recycle();
+ }
+
+ public static Region boundsFromDirection(DisplayCutout displayCutout, int gravity) {
Region bounds = displayCutout.getBounds();
switch (gravity) {
case Gravity.TOP:
bounds.op(0, 0, Integer.MAX_VALUE, displayCutout.getSafeInsetTop(),
Region.Op.INTERSECT);
- out.set(bounds.getBounds());
break;
case Gravity.LEFT:
bounds.op(0, 0, displayCutout.getSafeInsetLeft(), Integer.MAX_VALUE,
Region.Op.INTERSECT);
- out.set(bounds.getBounds());
break;
case Gravity.BOTTOM:
bounds.op(0, displayCutout.getSafeInsetTop() + 1, Integer.MAX_VALUE,
Integer.MAX_VALUE, Region.Op.INTERSECT);
- out.set(bounds.getBounds());
break;
case Gravity.RIGHT:
bounds.op(displayCutout.getSafeInsetLeft() + 1, 0, Integer.MAX_VALUE,
Integer.MAX_VALUE, Region.Op.INTERSECT);
- out.set(bounds.getBounds());
break;
}
- bounds.recycle();
+ return bounds;
}
private void localBounds(Rect out) {
@@ -635,4 +684,28 @@
return rotation == RotationUtils.ROTATION_LANDSCAPE || rotation ==
RotationUtils.ROTATION_SEASCAPE;
}
+
+ /**
+ * A pre-draw listener, that cancels the draw and restarts the traversal with the updated
+ * window attributes.
+ */
+ private class RestartingPreDrawListener implements ViewTreeObserver.OnPreDrawListener {
+
+ private final View mView;
+
+ private RestartingPreDrawListener(View view) {
+ mView = view;
+ }
+
+ @Override
+ public boolean onPreDraw() {
+ mPendingRotationChange = false;
+ mView.getViewTreeObserver().removeOnPreDrawListener(this);
+ // This changes the window attributes - we need to restart the traversal for them to
+ // take effect.
+ updateOrientation();
+ mView.invalidate();
+ return false;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 9a43d9e..3c8a461 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.os.Handler;
import android.os.RemoteException;
-import android.os.Trace;
import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
@@ -46,7 +45,7 @@
public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
private static final String TAG = "SysuiColorExtractor";
private boolean mWallpaperVisible;
- private boolean mMediaBackdropVisible;
+ private boolean mHasBackdrop;
// Colors to return when the wallpaper isn't visible
private final GradientColors mWpHiddenColors;
@@ -165,7 +164,7 @@
return mWpHiddenColors;
}
} else {
- if (mMediaBackdropVisible) {
+ if (mHasBackdrop) {
return mWpHiddenColors;
} else {
return super.getColors(which, type);
@@ -181,9 +180,9 @@
}
}
- public void setMediaBackdropVisible(boolean visible) {
- if (mMediaBackdropVisible != visible) {
- mMediaBackdropVisible = visible;
+ public void setHasBackdrop(boolean hasBackdrop) {
+ if (mHasBackdrop != hasBackdrop) {
+ mHasBackdrop = hasBackdrop;
triggerColorsChanged(WallpaperManager.FLAG_LOCK);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index a4927b7..615b29f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -342,7 +342,7 @@
mHandler.post(() -> {
event.getAnimationTrigger().decrement();
});
- }, true /* notifyMenuVisibility */);
+ }, true /* notifyMenuVisibility */, false /* isDismissing */);
}
}
@@ -396,10 +396,12 @@
}
private void hideMenu() {
- hideMenu(null /* animationFinishedRunnable */, true /* notifyMenuVisibility */);
+ hideMenu(null /* animationFinishedRunnable */, true /* notifyMenuVisibility */,
+ false /* isDismissing */);
}
- private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility) {
+ private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
+ boolean isDismissing) {
if (mMenuState != MENU_STATE_NONE) {
cancelDelayedFinish();
if (notifyMenuVisibility) {
@@ -422,7 +424,12 @@
if (animationFinishedRunnable != null) {
animationFinishedRunnable.run();
}
- finish();
+
+ if (!isDismissing) {
+ // If we are dismissing the PiP, then don't try to pre-emptively finish the
+ // menu activity
+ finish();
+ }
}
});
mMenuContainerAnimator.start();
@@ -583,7 +590,7 @@
hideMenu(() -> {
sendEmptyMessage(PipMenuActivityController.MESSAGE_EXPAND_PIP,
"Could not notify controller to expand PIP");
- }, false /* notifyMenuVisibility */);
+ }, false /* notifyMenuVisibility */, false /* isDismissing */);
}
private void minimizePip() {
@@ -597,7 +604,7 @@
hideMenu(() -> {
sendEmptyMessage(PipMenuActivityController.MESSAGE_DISMISS_PIP,
"Could not notify controller to dismiss PIP");
- }, false /* notifyMenuVisibility */);
+ }, false /* notifyMenuVisibility */, true /* isDismissing */);
}
private void showPipMenu() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index a48bcbd..6418c80 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -153,9 +153,14 @@
hasCACerts, hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName,
vpnNameWorkProfile, organizationName, workProfileName);
// Update the icon
- int footerIconId = vpnName != null || vpnNameWorkProfile != null
- ? R.drawable.ic_qs_vpn
- : R.drawable.ic_info_outline;
+ int footerIconId = R.drawable.ic_info_outline;
+ if (vpnName != null || vpnNameWorkProfile != null) {
+ if (mSecurityController.isVpnBranded()) {
+ footerIconId = R.drawable.ic_qs_branded_vpn;
+ } else {
+ footerIconId = R.drawable.ic_qs_vpn;
+ }
+ }
if (mFooterIconId != footerIconId) {
mFooterIconId = footerIconId;
mMainHandler.post(mUpdateIcon);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 8d8e206..ce9d7e1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -479,7 +479,7 @@
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
x, -mNavBarHeight / 2,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
flags,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index fac7768..3063199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -482,8 +482,8 @@
iconTransformDistance = Math.min(iconTransformDistance, fullHeight);
if (isLastChild) {
fullHeight = Math.min(fullHeight, row.getMinHeight() - getIntrinsicHeight());
- iconTransformDistance = Math.min(iconTransformDistance,
- row.getMinHeight() - getIntrinsicHeight() * icon.getIconScale());
+ iconTransformDistance = Math.min(iconTransformDistance, row.getMinHeight()
+ - getIntrinsicHeight());
}
float viewEnd = viewStart + fullHeight;
if (expandingAnimated && mAmbientState.getScrollY() == 0
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 27cb077..c0e7ac4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -197,6 +197,7 @@
mDarkAmount);
final int outerBounds = mStatusBarIconSize;
mIconScale = (float)imageBounds / (float)outerBounds;
+ updatePivot();
}
private void updateIconScaleForSystemIcons() {
@@ -859,6 +860,12 @@
mLayoutRunnable.run();
mLayoutRunnable = null;
}
+ updatePivot();
+ }
+
+ private void updatePivot() {
+ setPivotX((1 - mIconScale) / 2.0f * getWidth());
+ setPivotY((getHeight() - mIconScale * getWidth()) / 2.0f);
}
public void executeOnLayout(Runnable runnable) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index ba265d8..f78e391 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -19,6 +19,8 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
+import android.content.pm.UserInfo;
+import android.util.Log;
import android.view.View;
import android.view.ViewStub;
@@ -60,6 +62,11 @@
}
public void show() {
+ // On a switch from the system user, don't show the user switcher
+ if (mUserManagerHelper.isHeadlessSystemUser() && mUserManagerHelper
+ .userIsSystemUser(mUserManagerHelper.getForegroundUserInfo())) {
+ return;
+ }
if (mShowing) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 76860e6..f0b1a82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -403,10 +403,19 @@
pw.print(" mWakeLock="); pw.println(mWakeLock);
}
+ /**
+ * Successful authentication with fingerprint that wakes up the device.
+ */
public boolean isWakeAndUnlock() {
- return mMode == MODE_UNLOCK
- || mMode == MODE_WAKE_AND_UNLOCK
+ return mMode == MODE_WAKE_AND_UNLOCK
|| mMode == MODE_WAKE_AND_UNLOCK_PULSING
|| mMode == MODE_WAKE_AND_UNLOCK_FROM_DREAM;
}
+
+ /**
+ * Successful authentication with fingerprint when the screen was either on or off.
+ */
+ public boolean isFingerprintUnlock() {
+ return isWakeAndUnlock() || mMode == MODE_UNLOCK;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index fa0a774..0aad438 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -21,15 +21,22 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.graphics.Region.Op;
import android.support.v4.util.ArraySet;
import android.util.Log;
import android.util.Pools;
+import android.view.DisplayCutout;
+import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.InternalInsetsInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import com.android.systemui.ScreenDecorations;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.StatusBarState;
@@ -41,6 +48,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashSet;
+import java.util.List;
import java.util.Stack;
/**
@@ -60,6 +68,7 @@
private int mStatusBarHeight;
private int mHeadsUpInset;
+ private int mDisplayCutoutTouchableRegionSize;
private boolean mTrackingHeadsUp;
private HashSet<String> mSwipedOutKeys = new HashSet<>();
private HashSet<NotificationData.Entry> mEntriesToRemoveAfterExpand = new HashSet<>();
@@ -120,6 +129,8 @@
com.android.internal.R.dimen.status_bar_height);
mHeadsUpInset = mStatusBarHeight + resources.getDimensionPixelSize(
R.dimen.heads_up_status_bar_padding);
+ mDisplayCutoutTouchableRegionSize = resources.getDimensionPixelSize(
+ R.dimen.display_cutout_touchable_region_size);
}
@Override
@@ -128,6 +139,11 @@
initResources();
}
+ @Override
+ public void onOverlayChanged() {
+ initResources();
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////
// Public methods:
@@ -301,12 +317,32 @@
info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
info.touchableRegion.set(minX, 0, maxX, mHeadsUpInset + height);
- } else if (mHeadsUpGoingAway || mWaitingOnCollapseWhenGoingAway) {
- info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- info.touchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
+ } else {
+ setCollapsedTouchableInsets(info);
}
}
+ private void setCollapsedTouchableInsets(ViewTreeObserver.InternalInsetsInfo info) {
+ info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ info.touchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
+ updateRegionForNotch(info.touchableRegion);
+ }
+
+ private void updateRegionForNotch(Region region) {
+ DisplayCutout cutout = mStatusBarWindowView.getRootWindowInsets().getDisplayCutout();
+ if (cutout == null) {
+ return;
+ }
+
+ // Expand touchable region such that we also catch touches that just start below the notch
+ // area.
+ Region bounds = ScreenDecorations.DisplayCutoutView.boundsFromDirection(
+ cutout, Gravity.TOP);
+ bounds.translate(0, mDisplayCutoutTouchableRegionSize);
+ region.op(bounds, Op.UNION);
+ bounds.recycle();
+ }
+
@Override
public void onConfigChanged(Configuration newConfig) {
Resources resources = mContext.getResources();
@@ -403,7 +439,8 @@
private void updateTouchableRegionListener() {
boolean shouldObserve = hasPinnedHeadsUp() || mHeadsUpGoingAway
- || mWaitingOnCollapseWhenGoingAway;
+ || mWaitingOnCollapseWhenGoingAway
+ || mStatusBarWindowView.getRootWindowInsets().getDisplayCutout() != null;
if (shouldObserve == mIsObserving) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 44d666e..2bfdfeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -47,6 +47,8 @@
private final Rect mTintArea = new Rect();
private NotificationStackScrollLayout mNotificationScrollLayout;
private Context mContext;
+ private boolean mFullyDark;
+ private boolean mHasShelfIconsWhenFullyDark;
public NotificationIconAreaController(Context context, StatusBar statusBar) {
mStatusBar = statusBar;
@@ -173,13 +175,40 @@
public void updateNotificationIcons() {
updateStatusBarIcons();
- updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons,
- NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */,
- false /* hideRepliedMessages */);
+ updateShelfIcons();
+ updateHasShelfIconsWhenFullyDark();
applyNotificationIconsTint();
}
+ private void updateHasShelfIconsWhenFullyDark() {
+ boolean hasIconsWhenFullyDark = false;
+ for (int i = 0; i < mNotificationScrollLayout.getChildCount(); i++) {
+ View view = mNotificationScrollLayout.getChildAt(i);
+ if (view instanceof ExpandableNotificationRow) {
+ NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry();
+ if (shouldShowNotificationIcon(ent,
+ NotificationShelf.SHOW_AMBIENT_ICONS /* showAmbient */,
+ false /* hideDismissed */,
+ true /* hideReplied */)) {
+ hasIconsWhenFullyDark = true;
+ break;
+ }
+ }
+ }
+ mHasShelfIconsWhenFullyDark = hasIconsWhenFullyDark;
+ }
+
+ public boolean hasShelfIconsWhenFullyDark() {
+ return mHasShelfIconsWhenFullyDark;
+ }
+
+ private void updateShelfIcons() {
+ updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons,
+ NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */,
+ mFullyDark /* hideRepliedMessages */);
+ }
+
public void updateStatusBarIcons() {
updateIconsForLayout(entry -> entry.icon, mNotificationIcons,
false /* showAmbient */, true /* hideDismissed */, true /* hideRepliedMessages */);
@@ -320,6 +349,11 @@
v.setDecorColor(mIconTint);
}
+ public void setFullyDark(boolean fullyDark) {
+ mFullyDark = fullyDark;
+ updateShelfIcons();
+ }
+
public void setDark(boolean dark) {
mNotificationIcons.setDark(dark, false, 0);
mShelfIcons.setDark(dark, false, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 2f18aad9..95ae2c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2736,13 +2736,14 @@
public void setPulsing(boolean pulsing) {
mPulsing = pulsing;
- final boolean canAnimatePulse =
- !DozeParameters.getInstance(mContext).getDisplayNeedsBlanking();
- if (canAnimatePulse) {
+ DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
+ final boolean animatePulse = !dozeParameters.getDisplayNeedsBlanking()
+ && dozeParameters.getAlwaysOn();
+ if (animatePulse) {
mAnimateNextPositionUpdate = true;
}
- mNotificationStackScroller.setPulsing(pulsing, canAnimatePulse);
- mKeyguardStatusView.setPulsing(pulsing, canAnimatePulse);
+ mNotificationStackScroller.setPulsing(pulsing, animatePulse);
+ mKeyguardStatusView.setPulsing(pulsing, animatePulse);
}
public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 9ba0880..482cffa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -29,9 +29,7 @@
import android.os.Trace;
import android.util.Log;
import android.util.MathUtils;
-import android.view.Choreographer;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
@@ -43,12 +41,11 @@
import com.android.internal.graphics.ColorUtils;
import com.android.internal.util.function.TriConsumer;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.statusbar.ExpandableNotificationRow;
-import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.stack.ViewState;
import com.android.systemui.util.AlarmTimeout;
@@ -482,21 +479,13 @@
// Make sure we have the right gradients and their opacities will satisfy GAR.
if (mNeedsDrawableColorUpdate) {
mNeedsDrawableColorUpdate = false;
- final GradientColors currentScrimColors;
- if (mState == ScrimState.KEYGUARD || mState == ScrimState.BOUNCER_SCRIMMED
- || mState == ScrimState.BOUNCER) {
- // Always animate color changes if we're seeing the keyguard
- mScrimInFront.setColors(mLockColors, true /* animated */);
- mScrimBehind.setColors(mLockColors, true /* animated */);
- currentScrimColors = mLockColors;
- } else {
- // Only animate scrim color if the scrim view is actually visible
- boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
- boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0;
- mScrimInFront.setColors(mSystemColors, animateScrimInFront);
- mScrimBehind.setColors(mSystemColors, animateScrimBehind);
- currentScrimColors = mSystemColors;
- }
+ boolean isKeyguard = mKeyguardUpdateMonitor.isKeyguardVisible() && !mKeyguardOccluded;
+ GradientColors currentScrimColors = isKeyguard ? mLockColors : mSystemColors;
+ // Only animate scrim color if the scrim view is actually visible
+ boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0 && !mBlankScreen;
+ boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0 && !mBlankScreen;
+ mScrimInFront.setColors(currentScrimColors, animateScrimInFront);
+ mScrimBehind.setColors(currentScrimColors, animateScrimBehind);
// Calculate minimum scrim opacity for white or black text.
int textColor = currentScrimColors.supportsDarkText() ? Color.BLACK : Color.WHITE;
@@ -896,6 +885,14 @@
public void setKeyguardOccluded(boolean keyguardOccluded) {
mKeyguardOccluded = keyguardOccluded;
+ updateScrims();
+ }
+
+ public void setHasBackdrop(boolean hasBackdrop) {
+ ScrimState[] states = ScrimState.values();
+ for (int i = 0; i < states.length; i++) {
+ states[i].setHasBackdrop(hasBackdrop);
+ }
}
public interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 713356b..ec6ada4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -20,7 +20,6 @@
import android.os.Trace;
import android.util.MathUtils;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -106,8 +105,7 @@
public void prepare(ScrimState previousState) {
final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
mBlankScreen = mDisplayRequiresBlanking;
- mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
- && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
+ mCurrentBehindAlpha = mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f;
mCurrentInFrontAlpha = alwaysOnEnabled ? mAodFrontScrimAlpha : 1f;
mCurrentInFrontTint = Color.BLACK;
mCurrentBehindTint = Color.BLACK;
@@ -131,8 +129,7 @@
public void prepare(ScrimState previousState) {
mCurrentInFrontAlpha = 0;
mCurrentInFrontTint = Color.BLACK;
- mCurrentBehindAlpha = mWallpaperSupportsAmbientMode
- && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
+ mCurrentBehindAlpha = mWallpaperSupportsAmbientMode && !mHasBackdrop ? 0f : 1f;
mCurrentBehindTint = Color.BLACK;
mBlankScreen = mDisplayRequiresBlanking;
}
@@ -178,8 +175,8 @@
DozeParameters mDozeParameters;
boolean mDisplayRequiresBlanking;
boolean mWallpaperSupportsAmbientMode;
- KeyguardUpdateMonitor mKeyguardUpdateMonitor;
int mIndex;
+ boolean mHasBackdrop;
ScrimState(int index) {
mIndex = index;
@@ -190,7 +187,6 @@
mScrimBehind = scrimBehind;
mDozeParameters = dozeParameters;
mDisplayRequiresBlanking = dozeParameters.getDisplayNeedsBlanking();
- mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(scrimInFront.getContext());
}
public void prepare(ScrimState previousState) {
@@ -256,4 +252,8 @@
public boolean isLowPowerState() {
return false;
}
+
+ public void setHasBackdrop(boolean hasBackdrop) {
+ mHasBackdrop = hasBackdrop;
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index c70f034..e02cec3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -607,6 +607,12 @@
maybeEscalateHeadsUp();
}
}
+
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ super.onStrongAuthStateChanged(userId);
+ mEntryManager.updateNotifications();
+ }
};
private NavigationBarFragment mNavigationBar;
@@ -823,6 +829,7 @@
.createNotificationIconAreaController(context, this);
inflateShelf();
mNotificationIconAreaController.setupShelf(mNotificationShelf);
+ mStackScroller.setIconAreaController(mNotificationIconAreaController);
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
FragmentHostManager.get(mStatusBarWindow)
.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
@@ -1599,7 +1606,9 @@
return; // called too early
}
- if (mLaunchTransitionFadingAway) {
+ boolean wakeAndUnlock = mFingerprintUnlockController != null
+ && mFingerprintUnlockController.isWakeAndUnlock();
+ if (mLaunchTransitionFadingAway || wakeAndUnlock) {
mBackdrop.setVisibility(View.INVISIBLE);
Trace.endSection();
return;
@@ -1643,8 +1652,12 @@
&& mStatusBarKeyguardViewManager.isOccluded();
final boolean hasArtwork = artworkDrawable != null;
+ mColorExtractor.setHasBackdrop(hasArtwork);
+ if (mScrimController != null) {
+ mScrimController.setHasBackdrop(hasArtwork);
+ }
- if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) && !mDozing
+ if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
&& (mState != StatusBarState.SHADE || allowWhenShade)
&& mFingerprintUnlockController.getMode()
!= FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
@@ -1660,7 +1673,6 @@
mBackdrop.setAlpha(1f);
}
mStatusBarWindowManager.setBackdropShowing(true);
- mColorExtractor.setMediaBackdropVisible(true);
metaDataChanged = true;
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
@@ -1712,7 +1724,6 @@
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
}
- mColorExtractor.setMediaBackdropVisible(false);
boolean cannotAnimateDoze = mDozing && !ScrimState.AOD.getAnimateChange();
if (mFingerprintUnlockController.getMode()
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
@@ -3844,7 +3855,7 @@
* Switches theme from light to dark and vice-versa.
*/
protected void updateTheme() {
- final boolean inflated = mStackScroller != null;
+ final boolean inflated = mStackScroller != null && mStatusBarWindowManager != null;
// The system wallpaper defines if QS should be light or dark.
WallpaperColors systemColors = mColorExtractor
@@ -4712,11 +4723,11 @@
// We don't want to end up in KEYGUARD state when we're unlocking with
// fingerprint from doze. We should cross fade directly from black.
- final boolean wakeAndUnlocking = mFingerprintUnlockController.getMode()
- == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+ boolean wakeAndUnlocking = mFingerprintUnlockController.isWakeAndUnlock();
// Do not animate the scrim expansion when triggered by the fingerprint sensor.
- mScrimController.setExpansionAffectsAlpha(!mFingerprintUnlockController.isWakeAndUnlock());
+ mScrimController.setExpansionAffectsAlpha(
+ !mFingerprintUnlockController.isFingerprintUnlock());
if (mBouncerShowing) {
// Bouncer needs the front scrim when it's on top of an activity,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 5001d4f..b49ad46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -173,7 +173,7 @@
|| mStatusBar.isFullScreenUserSwitcherState()) {
mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
} else if (mShowing && !mDozing) {
- if (!isWakeAndUnlocking()) {
+ if (!isWakeAndUnlocking() && !mStatusBar.isInLaunchTransition()) {
mBouncer.setExpansion(expansion);
}
if (expansion != KeyguardBouncer.EXPANSION_HIDDEN && tracking
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 43958db..237ca25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -95,6 +95,12 @@
private boolean mExpandAnimationRunning;
private boolean mExpandAnimationPending;
+ /**
+ * If set to true, the current gesture started below the notch and we need to dispatch touch
+ * events manually as it's outside of the regular view bounds.
+ */
+ private boolean mExpandingBelowNotch;
+
public StatusBarWindowView(Context context, AttributeSet attrs) {
super(context, attrs);
setMotionEventSplittingEnabled(false);
@@ -270,7 +276,16 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
+ boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
+
+ // Reset manual touch dispatch state here but make sure the UP/CANCEL event still gets
+ // delivered.
+ boolean expandingBelowNotch = mExpandingBelowNotch;
+ if (isUp || isCancel) {
+ mExpandingBelowNotch = false;
+ }
+
if (!isCancel && mService.shouldIgnoreTouch()) {
return false;
}
@@ -303,6 +318,17 @@
mService.mDozeScrimController.extendPulse();
}
+ // In case we start outside of the view bounds (below the status bar), we need to dispatch
+ // the touch manually as the view system can't accomodate for touches outside of the
+ // regular view bounds.
+ if (isDown && ev.getY() >= mBottom) {
+ mExpandingBelowNotch = true;
+ expandingBelowNotch = true;
+ }
+ if (expandingBelowNotch) {
+ return mNotificationPanel.dispatchTouchEvent(ev);
+ }
+
return super.dispatchTouchEvent(ev);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 2031b27..59b376f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -113,10 +113,6 @@
@Override
public void addCallback(Callback callback) {
- if (callback == null) {
- Slog.e(TAG, "Attempted to add a null callback.");
- return;
- }
mCallbacks.add(callback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index c26568e..e80f483 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -137,6 +137,10 @@
// to look nice
customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP_CLICKED
+ StackStateAnimator.ANIMATION_DELAY_HEADS_UP;
+ } else if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
+ .ANIMATION_TYPE_PULSE_APPEAR || ev.animationType ==
+ NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_PULSE_DISAPPEAR) {
+ customDelay = StackStateAnimator.ANIMATION_DURATION_PULSE_APPEAR / 2;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 9c26c69..01ee7f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -101,6 +101,7 @@
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
@@ -140,7 +141,6 @@
private boolean mSwipingInProgress;
private int mCurrentStackHeight = Integer.MAX_VALUE;
private final Paint mBackgroundPaint = new Paint();
- private final Path mBackgroundPath = new Path();
private final boolean mShouldDrawNotificationBackground;
private float mExpandedHeight;
@@ -376,6 +376,11 @@
private View mForcedScroll;
private View mNeedingPulseAnimation;
private float mDarkAmount = 0f;
+
+ /**
+ * How fast the background scales in the X direction as a factor of the Y expansion.
+ */
+ private float mBackgroundXFactor = 1f;
private static final Property<NotificationStackScrollLayout, Float> DARK_AMOUNT =
new FloatProperty<NotificationStackScrollLayout>("darkAmount") {
@Override
@@ -416,6 +421,7 @@
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
private int mHeadsUpInset;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
+ private NotificationIconAreaController mIconAreaController;
public NotificationStackScrollLayout(Context context) {
this(context, null);
@@ -532,10 +538,16 @@
final int lockScreenRight = getWidth() - mSidePaddings;
final int lockScreenTop = mCurrentBounds.top;
final int lockScreenBottom = mCurrentBounds.bottom;
- final int darkLeft = getWidth() / 2 - mSeparatorWidth / 2;
- final int darkRight = darkLeft + mSeparatorWidth;
- final int darkTop = (int) (mRegularTopPadding + mSeparatorThickness / 2f);
- final int darkBottom = darkTop + mSeparatorThickness;
+ int separatorWidth = 0;
+ int separatorThickness = 0;
+ if (mIconAreaController.hasShelfIconsWhenFullyDark()) {
+ separatorThickness = mSeparatorThickness;
+ separatorWidth = mSeparatorWidth;
+ }
+ final int darkLeft = getWidth() / 2 - separatorWidth / 2;
+ final int darkRight = darkLeft + separatorWidth;
+ final int darkTop = (int) (mRegularTopPadding + separatorThickness / 2f);
+ final int darkBottom = darkTop + separatorThickness;
if (mAmbientState.hasPulsingNotifications()) {
// No divider, we have a notification icon instead
@@ -548,7 +560,7 @@
float inverseDark = 1 - mDarkAmount;
float yProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(inverseDark);
float xProgress = Interpolators.FAST_OUT_SLOW_IN
- .getInterpolation(inverseDark * 2f);
+ .getInterpolation(inverseDark * mBackgroundXFactor);
mBackgroundAnimationRect.set(
(int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress),
@@ -2041,11 +2053,9 @@
}
private int getScrollRange() {
- int contentHeight = getContentHeight();
- int scrollRange = Math.max(0, contentHeight - mMaxLayoutHeight);
+ int scrollRange = Math.max(0, mContentHeight - mMaxLayoutHeight);
int imeInset = getImeInset();
- scrollRange += Math.min(imeInset, Math.max(0,
- getContentHeight() - (getHeight() - imeInset)));
+ scrollRange += Math.min(imeInset, Math.max(0, mContentHeight - (getHeight() - imeInset)));
return scrollRange;
}
@@ -2146,10 +2156,6 @@
return count;
}
- public int getContentHeight() {
- return mContentHeight;
- }
-
private void updateContentHeight() {
int height = 0;
float previousPaddingRequest = mPaddingBetweenElements;
@@ -2213,7 +2219,11 @@
}
}
mIntrinsicContentHeight = height;
- mContentHeight = height + mTopPadding + mBottomMargin;
+
+ // We don't want to use the toppadding since that might be interpolated and we want
+ // to take the final value of the animation.
+ int topPadding = mAmbientState.isFullyDark() ? mDarkTopPadding : mRegularTopPadding;
+ mContentHeight = height + topPadding + mBottomMargin;
updateScrollability();
clampScrollPosition();
mAmbientState.setLayoutMaxHeight(mContentHeight);
@@ -4011,12 +4021,16 @@
mDarkAmount = darkAmount;
boolean wasFullyDark = mAmbientState.isFullyDark();
mAmbientState.setDarkAmount(darkAmount);
- if (mAmbientState.isFullyDark() != wasFullyDark) {
+ boolean nowFullyDark = mAmbientState.isFullyDark();
+ if (nowFullyDark != wasFullyDark) {
updateContentHeight();
DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
- if (mAmbientState.isFullyDark() && dozeParameters.shouldControlScreenOff()) {
+ if (nowFullyDark && dozeParameters.shouldControlScreenOff()) {
mShelf.fadeInTranslating();
}
+ if (mIconAreaController != null) {
+ mIconAreaController.setFullyDark(nowFullyDark);
+ }
}
updateAlgorithmHeightAndPadding();
updateBackgroundDimming();
@@ -4028,21 +4042,37 @@
return mDarkAmount;
}
+ /**
+ * Cancel any previous dark animations - to avoid race conditions - and creates a new one.
+ * This function also sets {@code mBackgroundXFactor} based on the current {@code mDarkAmount}.
+ */
private void startDarkAmountAnimation() {
- ObjectAnimator darkAnimator = ObjectAnimator.ofFloat(this, DARK_AMOUNT, mDarkAmount,
- mAmbientState.isDark() ? 1f : 0);
- darkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
- darkAnimator.setInterpolator(Interpolators.ALPHA_IN);
- darkAnimator.addListener(new AnimatorListenerAdapter() {
+ boolean dark = mAmbientState.isDark();
+ if (mDarkAmountAnimator != null) {
+ mDarkAmountAnimator.cancel();
+ }
+
+ long duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
+ // Longer animation when sleeping with more than 1 notification
+ if (dark && getNotGoneChildCount() > 2) {
+ duration *= 1.2f;
+ }
+
+ mDarkAmountAnimator = ObjectAnimator.ofFloat(this, DARK_AMOUNT, mDarkAmount,
+ dark ? 1f : 0);
+ // We only swap the scaling factor if we're fully dark or fully awake to avoid
+ // interpolation issues when playing with the power button.
+ if (mDarkAmount == 0 || mDarkAmount == 1) {
+ mBackgroundXFactor = dark ? 2.5f : 1.5f;
+ }
+ mDarkAmountAnimator.setDuration(duration);
+ mDarkAmountAnimator.setInterpolator(Interpolators.LINEAR);
+ mDarkAmountAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mDarkAmountAnimator = null;
}
});
- if (mDarkAmountAnimator != null) {
- mDarkAmountAnimator.cancel();
- }
- mDarkAmountAnimator = darkAnimator;
mDarkAmountAnimator.start();
}
@@ -4618,6 +4648,10 @@
mHeadsUpAppearanceController = headsUpAppearanceController;
}
+ public void setIconAreaController(NotificationIconAreaController controller) {
+ mIconAreaController = controller;
+ }
+
/**
* A listener that is notified when the empty space below the notifications is clicked on
*/
@@ -5031,11 +5065,13 @@
// ANIMATION_TYPE_PULSE_APPEAR
new AnimationFilter()
.animateAlpha()
+ .hasDelays()
.animateY(),
// ANIMATION_TYPE_PULSE_DISAPPEAR
new AnimationFilter()
.animateAlpha()
+ .hasDelays()
.animateY(),
};
@@ -5099,10 +5135,10 @@
StackStateAnimator.ANIMATION_DURATION_STANDARD,
// ANIMATION_TYPE_PULSE_APPEAR
- KeyguardSliceView.DEFAULT_ANIM_DURATION,
+ StackStateAnimator.ANIMATION_DURATION_PULSE_APPEAR,
// ANIMATION_TYPE_PULSE_DISAPPEAR
- KeyguardSliceView.DEFAULT_ANIM_DURATION / 2,
+ StackStateAnimator.ANIMATION_DURATION_PULSE_APPEAR / 2,
};
static final int ANIMATION_TYPE_ADD = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index a75d40f..b83a09d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -24,6 +24,7 @@
import android.view.ViewGroup;
import android.view.animation.Interpolator;
+import com.android.keyguard.KeyguardSliceView;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -51,6 +52,8 @@
= (int) (ANIMATION_DURATION_HEADS_UP_APPEAR
* HeadsUpAppearInterpolator.getFractionUntilOvershoot());
public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 300;
+ public static final int ANIMATION_DURATION_PULSE_APPEAR =
+ KeyguardSliceView.DEFAULT_ANIM_DURATION;
public static final int ANIMATION_DURATION_BLOCKING_HELPER_FADE = 240;
public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
@@ -430,15 +433,26 @@
} else if (event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_PULSE_APPEAR) {
ExpandableViewState viewState = finalState.getViewStateForView(changingView);
- mTmpState.copyFrom(viewState);
- mTmpState.yTranslation += mPulsingAppearingTranslation;
- mTmpState.alpha = 0;
- mTmpState.applyToView(changingView);
+ if (viewState != null) {
+ mTmpState.copyFrom(viewState);
+ mTmpState.yTranslation += mPulsingAppearingTranslation;
+ mTmpState.alpha = 0;
+ mTmpState.applyToView(changingView);
+ }
} else if (event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_PULSE_DISAPPEAR) {
ExpandableViewState viewState = finalState.getViewStateForView(changingView);
- viewState.yTranslation += mPulsingAppearingTranslation;
- viewState.alpha = 0;
+ if (viewState != null) {
+ viewState.alpha = 0;
+ // We want to animate the alpha away before the view starts translating,
+ // otherwise everything will overlap and look xtra ugly.
+ float originalYTranslation = viewState.yTranslation;
+ viewState.yTranslation = changingView.getTranslationY();
+ mAnimationFilter.animateAlpha = true;
+ mAnimationProperties.duration = ANIMATION_DURATION_PULSE_APPEAR / 2;
+ viewState.animateTo(changingView, mAnimationProperties);
+ viewState.yTranslation = originalYTranslation;
+ }
} else if (event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR) {
// This item is added, initialize it's properties.
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index eca6127..6812410 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -26,11 +26,14 @@
/**
* Allows lambda iteration over a list. It is done in reverse order so it is safe
- * to add or remove items during the iteration.
+ * to add or remove items during the iteration. Skips over null items.
*/
public static <T> void safeForeach(List<T> list, Consumer<T> c) {
for (int i = list.size() - 1; i >= 0; i--) {
- c.accept(list.get(i));
+ T item = list.get(i);
+ if (item != null) {
+ c.accept(item);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index bf962b8..d7fad67 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -38,6 +38,7 @@
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
+import android.media.AudioManager;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
@@ -527,7 +528,7 @@
private final ICarVolumeCallback mVolumeChangeCallback = new ICarVolumeCallback.Stub() {
@Override
- public void onGroupVolumeChanged(int groupId) {
+ public void onGroupVolumeChanged(int groupId, int flags) {
VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
int value = getSeekbarValue(mCarAudioManager, groupId);
// Do not update the progress if it is the same as before. When car audio manager sets its
@@ -536,12 +537,14 @@
if (value != volumeItem.progress) {
volumeItem.listItem.setProgress(value);
volumeItem.progress = value;
- show(Events.SHOW_REASON_VOLUME_CHANGED);
+ if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
+ show(Events.SHOW_REASON_VOLUME_CHANGED);
+ }
}
}
@Override
- public void onMasterMuteChanged() {
+ public void onMasterMuteChanged(int flags) {
// ignored
}
};
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
index 8153953..13dc36d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -93,7 +93,7 @@
SysuiColorExtractor extractor = getTestableExtractor(colors);
simulateEvent(extractor);
extractor.setWallpaperVisible(true);
- extractor.setMediaBackdropVisible(true);
+ extractor.setHasBackdrop(true);
ColorExtractor.GradientColors fallbackColors = extractor.getFallbackColors();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
index 64507be..bb67d6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
@@ -16,7 +16,7 @@
package com.android.systemui.doze;
-import static org.junit.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
import android.os.UserHandle;
import android.provider.Settings;
@@ -42,14 +42,15 @@
}
@Test
- public void alwaysOn_onByDefault() throws Exception {
+ public void alwaysOn_followsConfigByDefault() throws Exception {
if (!mDozeConfig.alwaysOnAvailable()) {
return;
}
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON,
null);
-
- assertTrue(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
+ boolean defaultValue = mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_dozeAlwaysOnEnabled);
+ assertEquals(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT), defaultValue);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 40337b8..89d562a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -44,7 +44,6 @@
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.util.function.TriConsumer;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.util.wakelock.WakeLock;
@@ -94,6 +93,7 @@
mScrimInFrontColor = scrimInFrontColor;
},
visible -> mScrimVisibility = visible, mDozeParamenters, mAlarmManager);
+ mScrimController.setHasBackdrop(false);
}
@Test
@@ -140,12 +140,7 @@
@Test
public void transitionToAod_withAodWallpaperAndLockScreenWallpaper() {
- ScrimState.AOD.mKeyguardUpdateMonitor = new KeyguardUpdateMonitor(getContext()) {
- @Override
- public boolean hasLockscreenWallpaper() {
- return true;
- }
- };
+ mScrimController.setHasBackdrop(true);
mScrimController.setWallpaperSupportsAmbientMode(true);
mScrimController.transitionTo(ScrimState.AOD);
mScrimController.finishAnimationsImmediately();
@@ -542,6 +537,18 @@
}
@Test
+ public void testHidesShowWhenLockedActivity_whenAlreadyInAod() {
+ mScrimController.setWallpaperSupportsAmbientMode(true);
+ mScrimController.transitionTo(ScrimState.AOD);
+ mScrimController.finishAnimationsImmediately();
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
+
+ mScrimController.setKeyguardOccluded(true);
+ mScrimController.finishAnimationsImmediately();
+ assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
+ }
+
+ @Test
public void testEatsTouchEvent() {
HashSet<ScrimState> eatsTouches =
new HashSet<>(Arrays.asList(ScrimState.AOD, ScrimState.PULSING));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 85135ac..94ab9d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -177,6 +177,14 @@
verify(mBouncer, never()).setExpansion(anyFloat());
}
+ @Test
+ public void onPanelExpansionChanged_neverTranslatesBouncerWhenLaunchingApp() {
+ when(mStatusBar.isInLaunchTransition()).thenReturn(true);
+ mStatusBarKeyguardViewManager.onPanelExpansionChanged(KeyguardBouncer.EXPANSION_VISIBLE,
+ false /* tracking */);
+ verify(mBouncer, never()).setExpansion(anyFloat());
+ }
+
private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
public TestableStatusBarKeyguardViewManager(Context context,
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index fbbb76c..52c3f64 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -100,7 +100,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
@@ -2538,13 +2537,14 @@
}
}
pw.print(prefix); pw.print("mCurrentViewId: "); pw.println(mCurrentViewId);
- pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
pw.print(prefix); pw.print("mIsSaving: "); pw.println(mIsSaving);
pw.print(prefix); pw.print("mPendingSaveUi: "); pw.println(mPendingSaveUi);
- for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
- pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
- entry.getValue().dump(prefix2, pw);
+ final int numberViews = mViewStates.size();
+ pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
+ for (int i = 0; i < numberViews; i++) {
+ pw.print(prefix); pw.print("ViewState at #"); pw.println(i);
+ mViewStates.valueAt(i).dump(prefix2, pw);
}
pw.print(prefix); pw.print("mContexts: " );
@@ -2555,7 +2555,7 @@
pw.print(prefix2); pw.print(context);
if (sVerbose) {
- pw.println(context.getStructure() + " (look at logcat)");
+ pw.println("AssistStructure dumped at logcat)");
// TODO: add method on AssistStructure to dump on pw
context.getStructure().dump(false);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2458234..692d606 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15311,6 +15311,7 @@
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
+ BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
BinderInternal.nSetBinderProxyCountEnabled(true);
BinderInternal.setBinderProxyCountCallback(
new BinderInternal.BinderProxyLimitListener() {
@@ -21035,15 +21036,9 @@
}
private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
- int callingUid, boolean callerInstantApp, int[] users) {
+ int callingUid, int[] users) {
// TODO: come back and remove this assumption to triage all broadcasts
int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
- // Instant apps should be able to send broadcasts to themselves, so we would
- // match instant receivers and later the broadcast queue would enforce that
- // the broadcast cannot be sent to a receiver outside the instant UID.
- if (callerInstantApp) {
- pmFlags |= PackageManager.MATCH_INSTANT;
- }
List<ResolveInfo> receivers = null;
try {
@@ -21672,8 +21667,7 @@
// Need to resolve the intent to interested receivers...
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
- receivers = collectReceiverComponents(intent, resolvedType, callingUid,
- callerInstantApp, users);
+ receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if (intent.getComponent() == null) {
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index cc7a230..aea29ac 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1654,13 +1654,6 @@
void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
mStackSupervisor.mStoppingActivities.add(r);
-
- // Some activity is waiting for another activity to become visible before it's being
- // stopped, which means that we also want to wait with stopping this one to avoid
- // flickers.
- if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.isEmpty()) {
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r);
- }
}
// If we already have a few activities waiting to stop, then give up
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 3fd69ee..13de652 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -236,7 +236,6 @@
private static final int MSG_PERSIST_RINGER_MODE = 3;
private static final int MSG_AUDIO_SERVER_DIED = 4;
private static final int MSG_PLAY_SOUND_EFFECT = 5;
- private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6;
private static final int MSG_LOAD_SOUND_EFFECTS = 7;
private static final int MSG_SET_FORCE_USE = 8;
private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
@@ -268,6 +267,7 @@
private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103;
private static final int MSG_DISABLE_AUDIO_FOR_UID = 104;
private static final int MSG_SET_HEARING_AID_CONNECTION_STATE = 105;
+ private static final int MSG_BTA2DP_DOCK_TIMEOUT = 106;
// end of messages handled under wakelock
private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -2623,6 +2623,7 @@
broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
}
+ @GuardedBy("mSettingsLock")
private void muteRingerModeStreams() {
// Mute stream if not previously muted by ringer mode and (ringer mode
// is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
@@ -2710,10 +2711,9 @@
synchronized(mSettingsLock) {
change = mRingerMode != ringerMode;
mRingerMode = ringerMode;
+ muteRingerModeStreams();
}
- muteRingerModeStreams();
-
// Post a persist ringer mode msg
if (persist) {
sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
@@ -4512,13 +4512,21 @@
}
synchronized (mLastDeviceConnectMsgTime) {
long time = SystemClock.uptimeMillis() + delay;
- handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
- if (msg == MSG_SET_WIRED_DEVICE_CONNECTION_STATE ||
- msg == MSG_SET_A2DP_SRC_CONNECTION_STATE ||
- msg == MSG_SET_A2DP_SINK_CONNECTION_STATE ||
- msg == MSG_SET_HEARING_AID_CONNECTION_STATE) {
+
+ if (msg == MSG_SET_A2DP_SRC_CONNECTION_STATE ||
+ msg == MSG_SET_A2DP_SINK_CONNECTION_STATE ||
+ msg == MSG_SET_HEARING_AID_CONNECTION_STATE ||
+ msg == MSG_SET_WIRED_DEVICE_CONNECTION_STATE ||
+ msg == MSG_A2DP_DEVICE_CONFIG_CHANGE ||
+ msg == MSG_BTA2DP_DOCK_TIMEOUT) {
+ if (mLastDeviceConnectMsgTime >= time) {
+ // add a little delay to make sure messages are ordered as expected
+ time = mLastDeviceConnectMsgTime + 30;
+ }
mLastDeviceConnectMsgTime = time;
}
+
+ handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
}
}
@@ -4680,6 +4688,13 @@
} else {
delay = 0;
}
+
+ if (DEBUG_DEVICES) {
+ Log.d(TAG, "setBluetoothA2dpDeviceConnectionStateInt device: " + device
+ + " state: " + state + " delay(ms): " + delay
+ + " suppressNoisyIntent: " + suppressNoisyIntent);
+ }
+
queueMsgUnderWakeLock(mAudioHandler,
(profile == BluetoothProfile.A2DP ?
MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
@@ -5588,6 +5603,7 @@
synchronized (mConnectedDevices) {
makeA2dpDeviceUnavailableNow( (String) msg.obj );
}
+ mAudioEventWakeLock.release();
break;
case MSG_SET_FORCE_USE:
@@ -5818,6 +5834,9 @@
// must be called synchronized on mConnectedDevices
private void makeA2dpDeviceUnavailableNow(String address) {
+ if (address == null) {
+ return;
+ }
synchronized (mA2dpAvrcpLock) {
mAvrcpAbsVolSupported = false;
}
@@ -5827,6 +5846,9 @@
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
// Remove A2DP routes as well
setCurrentAudioRouteName(null);
+ if (mDockAddress == address) {
+ mDockAddress = null;
+ }
}
// must be called synchronized on mConnectedDevices
@@ -5838,9 +5860,12 @@
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
// send the delayed message to make the device unavailable later
- Message msg = mAudioHandler.obtainMessage(MSG_BTA2DP_DOCK_TIMEOUT, address);
- mAudioHandler.sendMessageDelayed(msg, delayMs);
-
+ queueMsgUnderWakeLock(mAudioHandler,
+ MSG_BTA2DP_DOCK_TIMEOUT,
+ 0,
+ 0,
+ address,
+ delayMs);
}
// must be called synchronized on mConnectedDevices
@@ -5912,7 +5937,8 @@
private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state, int a2dpVolume)
{
if (DEBUG_DEVICES) {
- Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice+"state=" + state);
+ Log.d(TAG, "onSetA2dpSinkConnectionState btDevice= " + btDevice+" state= " + state
+ + " is dock: "+btDevice.isBluetoothDock());
}
if (btDevice == null) {
return;
@@ -5949,7 +5975,7 @@
} else {
// this could be a connection of another A2DP device before the timeout of
// a dock: cancel the dock timeout, and make the dock unavailable now
- if(hasScheduledA2dpDockTimeout()) {
+ if (hasScheduledA2dpDockTimeout() && mDockAddress != null) {
cancelA2dpDeviceTimeout();
makeA2dpDeviceUnavailableNow(mDockAddress);
}
@@ -6168,17 +6194,6 @@
}
}
- if (mAudioHandler.hasMessages(MSG_SET_A2DP_SRC_CONNECTION_STATE) ||
- mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE) ||
- mAudioHandler.hasMessages(MSG_SET_HEARING_AID_CONNECTION_STATE) ||
- mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
- synchronized (mLastDeviceConnectMsgTime) {
- long time = SystemClock.uptimeMillis();
- if (mLastDeviceConnectMsgTime > time) {
- delay = (int)(mLastDeviceConnectMsgTime - time) + 30;
- }
- }
- }
return delay;
}
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index 4f53ed4..33525fd 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -46,6 +46,7 @@
import libcore.io.Streams;
import com.android.server.LocalServices;
+import com.android.server.policy.WindowManagerPolicy;
/**
* <p>
@@ -63,7 +64,7 @@
// The layer for the electron beam surface.
// This is currently hardcoded to be one layer above the boot animation.
- private static final int COLOR_FADE_LAYER = 0x40000001;
+ private static final int COLOR_FADE_LAYER = WindowManagerPolicy.COLOR_FADE_LAYER;
// The number of frames to draw when preparing the animation so that it will
// be ready to run smoothly. We use 3 frames because we are triple-buffered.
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 0f8c526..8d730b4 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -253,8 +253,8 @@
// 1 second, or 1 Hz frequency.
private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
- // 30 seconds.
- private static final long LOCATION_UPDATE_DURATION_MILLIS = 30 * 1000;
+ // Default update duration in milliseconds for REQUEST_LOCATION.
+ private static final long LOCATION_UPDATE_DURATION_MILLIS = 0;
/** simpler wrapper for ProviderRequest + Worksource */
private static class GpsRequest {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 6fff367..68b2a58 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -781,6 +781,9 @@
}
private void dispatchVolumeKeyLongPressLocked(KeyEvent keyEvent) {
+ if (mCurrentFullUserRecord.mOnVolumeKeyLongPressListener == null) {
+ return;
+ }
try {
mCurrentFullUserRecord.mOnVolumeKeyLongPressListener.onVolumeKeyLongPress(keyEvent);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1010ce1..9ed2b9c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13967,43 +13967,6 @@
return false;
}
- @Override
- public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
- enforceSystemOrPhoneCaller("setSystemAppInstallState");
- PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
- // The target app should always be in system
- if (pkgSetting == null || !pkgSetting.isSystem()) {
- return false;
- }
- // Check if the install state is the same
- if (pkgSetting.getInstalled(userId) == installed) {
- return false;
- }
-
- long callingId = Binder.clearCallingIdentity();
- try {
- if (installed) {
- // install the app from uninstalled state
- installExistingPackageAsUser(
- packageName,
- userId,
- 0 /*installFlags*/,
- PackageManager.INSTALL_REASON_DEVICE_SETUP);
- return true;
- }
-
- // uninstall the app from installed state
- deletePackageVersioned(
- new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
- new LegacyPackageDeleteObserver(null).getBinder(),
- userId,
- PackageManager.DELETE_SYSTEM_APP);
- return true;
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
- }
-
private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
int userId) {
final PackageRemovedInfo info = new PackageRemovedInfo(this);
@@ -14068,16 +14031,10 @@
@Override
public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
int installReason) {
- final int callingUid = Binder.getCallingUid();
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
- != PackageManager.PERMISSION_GRANTED
- && mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Neither user " + callingUid + " nor current process has "
- + android.Manifest.permission.INSTALL_PACKAGES + ".");
- }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
+ null);
PackageSetting pkgSetting;
+ final int callingUid = Binder.getCallingUid();
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"installExistingPackage for user " + userId);
@@ -14221,7 +14178,7 @@
unactionedPackages.add(packageName);
continue;
}
- if (!canSuspendPackageForUserLocked(packageName, userId)) {
+ if (suspended && !canSuspendPackageForUserLocked(packageName, userId)) {
unactionedPackages.add(packageName);
continue;
}
@@ -14376,44 +14333,44 @@
@GuardedBy("mPackages")
private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
if (isPackageDeviceAdmin(packageName, userId)) {
- Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ Slog.w(TAG, "Cannot suspend package \"" + packageName
+ "\": has an active device admin");
return false;
}
String activeLauncherPackageName = getActiveLauncherPackageName(userId);
if (packageName.equals(activeLauncherPackageName)) {
- Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ Slog.w(TAG, "Cannot suspend package \"" + packageName
+ "\": contains the active launcher");
return false;
}
if (packageName.equals(mRequiredInstallerPackage)) {
- Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ Slog.w(TAG, "Cannot suspend package \"" + packageName
+ "\": required for package installation");
return false;
}
if (packageName.equals(mRequiredUninstallerPackage)) {
- Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ Slog.w(TAG, "Cannot suspend package \"" + packageName
+ "\": required for package uninstallation");
return false;
}
if (packageName.equals(mRequiredVerifierPackage)) {
- Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ Slog.w(TAG, "Cannot suspend package \"" + packageName
+ "\": required for package verification");
return false;
}
if (packageName.equals(getDefaultDialerPackageName(userId))) {
- Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ Slog.w(TAG, "Cannot suspend package \"" + packageName
+ "\": is the default dialer");
return false;
}
if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
- Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
+ Slog.w(TAG, "Cannot suspend package \"" + packageName
+ "\": protected package");
return false;
}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index c9aa1ef..1ae59cb 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -833,11 +833,11 @@
getSystemPackage(textClassifierPackageName);
if (textClassifierPackage != null
&& doesPackageSupportRuntimePermissions(textClassifierPackage)) {
- grantRuntimePermissions(textClassifierPackage, PHONE_PERMISSIONS, true, userId);
- grantRuntimePermissions(textClassifierPackage, SMS_PERMISSIONS, true, userId);
- grantRuntimePermissions(textClassifierPackage, CALENDAR_PERMISSIONS, true, userId);
- grantRuntimePermissions(textClassifierPackage, LOCATION_PERMISSIONS, true, userId);
- grantRuntimePermissions(textClassifierPackage, CONTACTS_PERMISSIONS, true, userId);
+ grantRuntimePermissions(textClassifierPackage, PHONE_PERMISSIONS, false, userId);
+ grantRuntimePermissions(textClassifierPackage, SMS_PERMISSIONS, false, userId);
+ grantRuntimePermissions(textClassifierPackage, CALENDAR_PERMISSIONS, false, userId);
+ grantRuntimePermissions(textClassifierPackage, LOCATION_PERMISSIONS, false, userId);
+ grantRuntimePermissions(textClassifierPackage, CONTACTS_PERMISSIONS, false, userId);
}
}
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index a02ee22..e11b642 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -157,6 +157,8 @@
int FINISH_LAYOUT_REDO_WALLPAPER = 0x0004;
/** Need to recompute animations */
int FINISH_LAYOUT_REDO_ANIM = 0x0008;
+ /** Layer for the screen off animation */
+ int COLOR_FADE_LAYER = 0x40000001;
/**
* Register shortcuts for window manager to dispatch.
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index e45de45..fa6079c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
@@ -1334,8 +1335,20 @@
// for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
if (pinnedStack != null) {
+ final Rect stackBounds;
+ if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
+ // We are animating the bounds, use the pre-animation bounds to save the snap
+ // fraction
+ stackBounds = pinnedStack.mPreAnimationBounds;
+ } else {
+ // We skip the animation if the fullscreen configuration is not compatible, so
+ // use the current bounds to calculate the saved snap fraction instead
+ // (see PinnedActivityStack.skipResizeAnimation())
+ stackBounds = mTmpRect;
+ pinnedStack.getBounds(stackBounds);
+ }
mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
- pinnedStack.mPreAnimationBounds);
+ stackBounds);
}
}
}
@@ -1365,7 +1378,7 @@
setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
// We can now show all of the drawn windows!
- if (!mService.mOpeningApps.contains(this)) {
+ if (!mService.mOpeningApps.contains(this) && canShowWindows()) {
showAllWindowsLocked();
}
}
@@ -2258,4 +2271,21 @@
boolean isClosingOrEnteringPip() {
return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
}
+
+ /**
+ * @return Whether we are allowed to show non-starting windows at the moment. We disallow
+ * showing windows during transitions in case we have windows that have wide-color-gamut
+ * color mode set to avoid jank in the middle of the transition.
+ */
+ boolean canShowWindows() {
+ return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
+ }
+
+ /**
+ * @return true if we have a window that has a non-default color mode set; false otherwise.
+ */
+ private boolean hasNonDefaultColorWindow() {
+ return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
+ true /* topToBottom */);
+ }
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b0e6208..47dbccb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -404,7 +404,7 @@
WindowStateAnimator winAnimator = w.mWinAnimator;
final AppWindowToken atoken = w.mAppToken;
if (winAnimator.mDrawState == READY_TO_SHOW) {
- if (atoken == null || atoken.allDrawn) {
+ if (atoken == null || atoken.canShowWindows()) {
if (w.performShowLocked()) {
pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
if (DEBUG_LAYOUT_REPEATS) {
@@ -1106,11 +1106,12 @@
}
}
+ forAllWindows(w -> {
+ w.forceSeamlesslyRotateIfAllowed(oldRotation, rotation);
+ }, true /* traverseTopToBottom */);
+
if (rotateSeamlessly) {
- forAllWindows(w -> {
- w.mWinAnimator.seamlesslyRotateWindow(getPendingTransaction(),
- oldRotation, rotation);
- }, true /* traverseTopToBottom */);
+ seamlesslyRotate(getPendingTransaction(), oldRotation, rotation);
}
mService.mDisplayManagerInternal.performTraversal(getPendingTransaction());
@@ -3538,7 +3539,14 @@
// docked or freeform stack is visible...except for the home stack/task if the
// docked stack is minimized and it actually set something.
if (mHomeStack != null && mHomeStack.isVisible()
- && mDividerControllerLocked.isMinimizedDock()) {
+ && mDividerControllerLocked.isMinimizedDock()
+ // TODO(b/110159357): Work around to unblock the release for failing test
+ // ActivityManagerAppConfigurationTests#testSplitscreenPortraitAppOrientationRequests
+ // which shouldn't be failing since home stack shouldn't be visible. We need
+ // to dig deeper to see why it is failing. NOTE: Not failing on current
+ // master...
+ && !(mDividerControllerLocked.isHomeStackResizable()
+ && mHomeStack.matchParentBounds())) {
final int orientation = mHomeStack.getOrientation();
if (orientation != SCREEN_ORIENTATION_UNSET) {
return orientation;
@@ -3694,6 +3702,19 @@
}
@Override
+ SurfaceControl.Builder makeChildSurface(WindowContainer child) {
+ final SurfaceControl.Builder builder = super.makeChildSurface(child);
+ if (child instanceof WindowToken && ((WindowToken) child).mRoundedCornerOverlay) {
+ // To draw above the ColorFade layer during the screen off transition, the
+ // rounded corner overlays need to be at the root of the surface hierarchy.
+ // TODO: move the ColorLayer into the display overlay layer such that this is not
+ // necessary anymore.
+ builder.setParent(null);
+ }
+ return builder;
+ }
+
+ @Override
void assignChildLayers(SurfaceControl.Transaction t) {
assignChildLayers(t, null /* imeContainer */);
}
@@ -3709,6 +3730,10 @@
wt.assignRelativeLayer(t, mTaskStackContainers.getSplitScreenDividerAnchor(), 1);
continue;
}
+ if (wt.mRoundedCornerOverlay) {
+ wt.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
+ continue;
+ }
wt.assignLayer(t, j);
wt.assignChildLayers(t);
diff --git a/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java b/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java
new file mode 100644
index 0000000..3218e83
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import android.graphics.Matrix;
+import android.view.DisplayInfo;
+
+import com.android.server.wm.utils.CoordinateTransforms;
+
+/**
+ * Helper class for forced seamless rotation.
+ *
+ * Works by transforming the window token back into the old display rotation.
+ *
+ * Uses deferTransactionUntil instead of latching on the buffer size to allow for seamless 180
+ * degree rotations.
+ */
+public class ForcedSeamlessRotator {
+
+ private final Matrix mTransform = new Matrix();
+ private final float[] mFloat9 = new float[9];
+
+ public ForcedSeamlessRotator(int oldRotation, int newRotation, DisplayInfo info) {
+ final boolean flipped = info.rotation == ROTATION_90 || info.rotation == ROTATION_270;
+ final int h = flipped ? info.logicalWidth : info.logicalHeight;
+ final int w = flipped ? info.logicalHeight : info.logicalWidth;
+
+ final Matrix tmp = new Matrix();
+ CoordinateTransforms.transformLogicalToPhysicalCoordinates(oldRotation, w, h, mTransform);
+ CoordinateTransforms.transformPhysicalToLogicalCoordinates(newRotation, w, h, tmp);
+ mTransform.postConcat(tmp);
+ }
+
+ /**
+ * Applies a transform to the window token's surface that undoes the effect of the global
+ * display rotation.
+ */
+ public void unrotate(WindowToken token) {
+ token.getPendingTransaction().setMatrix(token.getSurfaceControl(), mTransform, mFloat9);
+ }
+
+ /**
+ * Removes the transform to the window token's surface that undoes the effect of the global
+ * display rotation.
+ *
+ * Removing the transform and the result of the WindowState's layout are both tied to the
+ * WindowState's next frame, such that they apply at the same time the client draws the
+ * window in the new orientation.
+ */
+ public void finish(WindowToken token, WindowState win) {
+ mTransform.reset();
+ token.getPendingTransaction().setMatrix(token.mSurfaceControl, mTransform, mFloat9);
+ token.getPendingTransaction().deferTransactionUntil(token.mSurfaceControl,
+ win.mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
+ win.getFrameNumber());
+ win.getPendingTransaction().deferTransactionUntil(win.mSurfaceControl,
+ win.mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
+ win.getFrameNumber());
+ }
+}
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 5f1916d..278d2b8 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -589,6 +589,7 @@
pw.println(prefix + " mImeHeight=" + mImeHeight);
pw.println(prefix + " mIsShelfShowing=" + mIsShelfShowing);
pw.println(prefix + " mShelfHeight=" + mShelfHeight);
+ pw.println(prefix + " mReentrySnapFraction=" + mReentrySnapFraction);
pw.println(prefix + " mIsMinimized=" + mIsMinimized);
if (mActions.isEmpty()) {
pw.println(prefix + " mActions=[]");
@@ -601,6 +602,7 @@
}
pw.println(prefix + " ]");
}
+ pw.println(prefix + " mDisplayInfo=" + mDisplayInfo);
}
void writeToProto(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index f17bbb9..733a248 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -28,6 +28,7 @@
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.GraphicBuffer;
+import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Environment;
import android.os.Handler;
@@ -266,7 +267,7 @@
final GraphicBuffer buffer = SurfaceControl.captureLayers(
task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
-
+ final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
if (DEBUG_SCREENSHOT) {
Slog.w(TAG_WM, "Failed to take screenshot for " + task);
@@ -276,7 +277,7 @@
return new TaskSnapshot(buffer, top.getConfiguration().orientation,
getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */,
true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
- !top.fillsParent());
+ !top.fillsParent() || isWindowTranslucent);
}
private boolean shouldDisableSnapshots() {
@@ -363,11 +364,13 @@
if (hwBitmap == null) {
return null;
}
+ // Note, the app theme snapshot is never translucent because we enforce a non-translucent
+ // color above
return new TaskSnapshot(hwBitmap.createGraphicBufferHandle(),
topChild.getConfiguration().orientation, mainWindow.mStableInsets,
ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */,
false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
- !topChild.fillsParent());
+ false);
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 19c5a3d..8fe7063 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -736,6 +736,20 @@
}
/**
+ * Seamlessly rotates the container, by recomputing the location in the new
+ * rotation, and rotating buffers until they are updated for the new rotation.
+ *
+ * @param t the transaction to perform the seamless rotation in
+ * @param oldRotation the rotation we are rotating from
+ * @param newRotation the rotation we are rotating to
+ */
+ void seamlesslyRotate(Transaction t, int oldRotation, int newRotation) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ mChildren.get(i).seamlesslyRotate(t, oldRotation, newRotation);
+ }
+ }
+
+ /**
* Returns true if this container is opaque and fills all the space made available by its parent
* container.
*
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7a2c28b..ef74586 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1883,6 +1883,12 @@
}
win.setFrameNumber(frameNumber);
+
+ if (win.mPendingForcedSeamlessRotate != null && !mWaitingForConfig) {
+ win.mPendingForcedSeamlessRotate.finish(win.mToken, win);
+ win.mPendingForcedSeamlessRotate = null;
+ }
+
int attrChanges = 0;
int flagChanges = 0;
if (attrs != null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index bee70a0..a7f432d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -150,6 +150,8 @@
import static com.android.server.wm.WindowStateProto.VISIBLE_FRAME;
import static com.android.server.wm.WindowStateProto.VISIBLE_INSETS;
import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER;
+import static com.android.server.wm.utils.CoordinateTransforms.transformRect;
+import static com.android.server.wm.utils.CoordinateTransforms.transformToRotation;
import android.annotation.CallSuper;
import android.app.AppOpsManager;
@@ -278,6 +280,13 @@
private boolean mDragResizing;
private boolean mDragResizingChangeReported = true;
private int mResizeMode;
+ /**
+ * Special mode that is intended only for the rounded corner overlay: during rotation
+ * transition, we un-rotate the window token such that the window appears as it did before the
+ * rotation.
+ */
+ final boolean mForceSeamlesslyRotate;
+ ForcedSeamlessRotator mPendingForcedSeamlessRotate;
private RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
@@ -667,6 +676,14 @@
private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f;
+ void forceSeamlesslyRotateIfAllowed(int oldRotation, int rotation) {
+ if (mForceSeamlesslyRotate) {
+ mPendingForcedSeamlessRotate = new ForcedSeamlessRotator(
+ oldRotation, rotation, getDisplayInfo());
+ mPendingForcedSeamlessRotate.unrotate(this.mToken);
+ }
+ }
+
interface PowerManagerWrapper {
void wakeUp(long time, String reason);
@@ -713,6 +730,7 @@
mSeq = seq;
mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
mPowerManagerWrapper = powerManagerWrapper;
+ mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
if (localLOGV) Slog.v(
TAG, "Window " + this + " client=" + c.asBinder()
+ " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
@@ -1811,7 +1829,8 @@
&& (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
&& !isDragResizing() && !adjustedForMinimizedDockOrIme
&& getWindowConfiguration().hasMovementAnimations()
- && !mWinAnimator.mLastHidden) {
+ && !mWinAnimator.mLastHidden
+ && !mSeamlesslyRotated) {
startMoveAnimation(left, top);
}
@@ -4697,7 +4716,10 @@
transformFrameToSurfacePosition(mFrame.left, mFrame.top, mSurfacePosition);
- if (!mSurfaceAnimator.hasLeash() && !mLastSurfacePosition.equals(mSurfacePosition)) {
+ // Freeze position while we're unrotated, so the surface remains at the position it was
+ // prior to the rotation.
+ if (!mSurfaceAnimator.hasLeash() && mPendingForcedSeamlessRotate == null &&
+ !mLastSurfacePosition.equals(mSurfacePosition)) {
t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y);
mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) {
@@ -4850,6 +4872,31 @@
mFrameNumber = frameNumber;
}
+ @Override
+ void seamlesslyRotate(Transaction t, int oldRotation, int newRotation) {
+ // Invisible windows, the wallpaper, and force seamlessly rotated windows do not participate
+ // in the regular seamless rotation animation.
+ if (!isVisibleNow() || mIsWallpaper || mForceSeamlesslyRotate) {
+ return;
+ }
+ final Matrix transform = mTmpMatrix;
+
+ mService.markForSeamlessRotation(this, true);
+
+ // We rotated the screen, but have not performed a new layout pass yet. In the mean time,
+ // we recompute the coordinates of mFrame in the new orientation, so the surface can be
+ // properly placed.
+ transformToRotation(oldRotation, newRotation, getDisplayInfo(), transform);
+ transformRect(transform, mFrame, null /* tmpRectF */);
+
+ updateSurfacePosition(t);
+ mWinAnimator.seamlesslyRotate(t, oldRotation, newRotation);
+
+ // Dispatch to children only after mFrame has been updated, as it's needed in the
+ // child's updateSurfacePosition.
+ super.seamlesslyRotate(t, oldRotation, newRotation);
+ }
+
private final class MoveAnimationSpec implements AnimationSpec {
private final long mDuration;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3eef125..a05e04d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -41,18 +41,18 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
import static com.android.server.wm.WindowManagerService.logWithStack;
-import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE;
import static com.android.server.wm.WindowStateAnimatorProto.LAST_CLIP_RECT;
import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
+import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.utils.CoordinateTransforms.transformToRotation;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.Region;
import android.os.Debug;
import android.os.Trace;
@@ -366,7 +366,8 @@
mDrawState = READY_TO_SHOW;
boolean result = false;
final AppWindowToken atoken = mWin.mAppToken;
- if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
+ if (atoken == null || atoken.canShowWindows()
+ || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
result = mWin.performShowLocked();
}
return result;
@@ -685,8 +686,11 @@
final int displayId = mWin.getDisplayId();
final ScreenRotationAnimation screenRotationAnimation =
mAnimator.getScreenRotationAnimationLocked(displayId);
- final boolean screenAnimation =
- screenRotationAnimation != null && screenRotationAnimation.isAnimating();
+ final boolean windowParticipatesInScreenRotationAnimation =
+ !mWin.mForceSeamlesslyRotate;
+ final boolean screenAnimation = screenRotationAnimation != null
+ && screenRotationAnimation.isAnimating()
+ && windowParticipatesInScreenRotationAnimation;
if (screenAnimation) {
// cache often used attributes locally
@@ -798,6 +802,13 @@
return false;
}
+ // During forced seamless rotation, the surface bounds get updated with the crop in the
+ // new rotation, which is not compatible with showing the surface in the old rotation.
+ // To work around that we disable cropping for such windows, as it is not necessary anyways.
+ if (w.mForceSeamlesslyRotate) {
+ return false;
+ }
+
// If we're animating, the wallpaper should only
// be updated at the end of the animation.
if (w.mAttrs.type == TYPE_WALLPAPER) {
@@ -1492,40 +1503,14 @@
}
}
- void seamlesslyRotateWindow(SurfaceControl.Transaction t,
- int oldRotation, int newRotation) {
+ void seamlesslyRotate(SurfaceControl.Transaction t, int oldRotation, int newRotation) {
final WindowState w = mWin;
- if (!w.isVisibleNow() || w.mIsWallpaper) {
- return;
- }
- final Rect cropRect = mService.mTmpRect;
- final Rect displayRect = mService.mTmpRect2;
- final RectF frameRect = mService.mTmpRectF;
+ // We rotated the screen, but have not received a new buffer with the correct size yet. In
+ // the mean time, we rotate the buffer we have to the new orientation.
final Matrix transform = mService.mTmpTransform;
-
- final float x = w.mFrame.left;
- final float y = w.mFrame.top;
- final float width = w.mFrame.width();
- final float height = w.mFrame.height();
-
- mService.getDefaultDisplayContentLocked().getBounds(displayRect);
- final float displayWidth = displayRect.width();
- final float displayHeight = displayRect.height();
-
- // Compute a transform matrix to undo the coordinate space transformation,
- // and present the window at the same physical position it previously occupied.
- final int deltaRotation = DisplayContent.deltaRotation(newRotation, oldRotation);
- DisplayContent.createRotationMatrix(deltaRotation, x, y, displayWidth, displayHeight,
+ transformToRotation(oldRotation, newRotation, w.mFrame.width(), w.mFrame.height(),
transform);
-
- // We just need to apply a rotation matrix to the window. For example
- // if we have a portrait window and rotate to landscape, the window is still portrait
- // and now extends off the bottom of the screen (and only halfway across). Essentially we
- // apply a transform to display the current buffer at it's old position
- // (in the new coordinate space). We then freeze layer updates until the resize
- // occurs, at which point we undo, them.
- mService.markForSeamlessRotation(w, true);
transform.getValues(mService.mTmpFloats);
float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index b97460a..e411c0a 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -270,12 +270,6 @@
dc.reParentWindowToken(this);
mDisplayContent = dc;
- // The rounded corner overlay should not be rotated. We ensure that by moving it outside
- // the windowing layer.
- if (mRoundedCornerOverlay) {
- mDisplayContent.reparentToOverlay(mPendingTransaction, mSurfaceControl);
- }
-
// TODO(b/36740756): One day this should perhaps be hooked
// up with goodToGo, so we don't move a window
// to another display before the window behind
diff --git a/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java b/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java
index 09d7b5d..a2f37a5 100644
--- a/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java
+++ b/services/core/java/com/android/server/wm/utils/CoordinateTransforms.java
@@ -22,7 +22,11 @@
import static android.view.Surface.ROTATION_90;
import android.annotation.Dimension;
+import android.annotation.Nullable;
import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.view.DisplayInfo;
import android.view.Surface.Rotation;
public class CoordinateTransforms {
@@ -59,4 +63,93 @@
throw new IllegalArgumentException("Unknown rotation: " + rotation);
}
}
+
+ /**
+ * Sets a matrix such that given a rotation, it transforms that rotation's logical coordinates
+ * to physical coordinates.
+ *
+ * @param rotation the rotation to which the matrix should transform
+ * @param out the matrix to be set
+ */
+ public static void transformLogicalToPhysicalCoordinates(@Rotation int rotation,
+ @Dimension int physicalWidth, @Dimension int physicalHeight, Matrix out) {
+ switch (rotation) {
+ case ROTATION_0:
+ out.reset();
+ break;
+ case ROTATION_90:
+ out.setRotate(90);
+ out.preTranslate(0, -physicalWidth);
+ break;
+ case ROTATION_180:
+ out.setRotate(180);
+ out.preTranslate(-physicalWidth, -physicalHeight);
+ break;
+ case ROTATION_270:
+ out.setRotate(270);
+ out.preTranslate(-physicalHeight, 0);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown rotation: " + rotation);
+ }
+ }
+
+ /**
+ * Sets a matrix such that given a two rotations, that it transforms coordinates given in the
+ * old rotation to coordinates that refer to the same physical location in the new rotation.
+ *
+ * @param oldRotation the rotation to transform from
+ * @param newRotation the rotation to transform to
+ * @param info the display info
+ * @param out a matrix that will be set to the transform
+ */
+ public static void transformToRotation(@Rotation int oldRotation,
+ @Rotation int newRotation, DisplayInfo info, Matrix out) {
+ final boolean flipped = info.rotation == ROTATION_90 || info.rotation == ROTATION_270;
+ final int h = flipped ? info.logicalWidth : info.logicalHeight;
+ final int w = flipped ? info.logicalHeight : info.logicalWidth;
+
+ final Matrix tmp = new Matrix();
+ transformLogicalToPhysicalCoordinates(oldRotation, w, h, out);
+ transformPhysicalToLogicalCoordinates(newRotation, w, h, tmp);
+ out.postConcat(tmp);
+ }
+
+ /**
+ * Sets a matrix such that given a two rotations, that it transforms coordinates given in the
+ * old rotation to coordinates that refer to the same physical location in the new rotation.
+ *
+ * @param oldRotation the rotation to transform from
+ * @param newRotation the rotation to transform to
+ * @param newWidth the width of the area to transform, in the new rotation
+ * @param newHeight the height of the area to transform, in the new rotation
+ * @param out a matrix that will be set to the transform
+ */
+ public static void transformToRotation(@Rotation int oldRotation,
+ @Rotation int newRotation, int newWidth, int newHeight, Matrix out) {
+ final boolean flipped = newRotation == ROTATION_90 || newRotation == ROTATION_270;
+ final int h = flipped ? newWidth : newHeight;
+ final int w = flipped ? newHeight : newWidth;
+
+ final Matrix tmp = new Matrix();
+ transformLogicalToPhysicalCoordinates(oldRotation, w, h, out);
+ transformPhysicalToLogicalCoordinates(newRotation, w, h, tmp);
+ out.postConcat(tmp);
+ }
+
+ /**
+ * Transforms a rect using a transformation matrix
+ *
+ * @param transform the transformation to apply to the rect
+ * @param inOutRect the rect to transform
+ * @param tmp a temporary value, if null the function will allocate its own.
+ */
+ public static void transformRect(Matrix transform, Rect inOutRect, @Nullable RectF tmp) {
+ if (tmp == null) {
+ tmp = new RectF();
+ }
+ tmp.set(inOutRect);
+ transform.mapRect(tmp);
+ inOutRect.set((int) tmp.left, (int) tmp.top, (int) tmp.right, (int) tmp.bottom);
+ }
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c370a00..b74a582 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2353,8 +2353,12 @@
final String value = Boolean.toString(hasDeviceOwner);
mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, value);
Slog.i(LOG_TAG, "Set ro.device_owner property to " + value);
+ }
+ }
- if (hasDeviceOwner && mInjector.securityLogGetLoggingEnabledProperty()) {
+ private void maybeStartSecurityLogMonitorOnActivityManagerReady() {
+ synchronized (getLockObject()) {
+ if (mInjector.securityLogIsLoggingEnabled()) {
mSecurityLogMonitor.start();
mInjector.runCryptoSelfTest();
maybePauseDeviceWideLoggingLocked();
@@ -3353,6 +3357,9 @@
loadAdminDataAsync();
mOwners.systemReady();
break;
+ case SystemService.PHASE_ACTIVITY_MANAGER_READY:
+ maybeStartSecurityLogMonitorOnActivityManagerReady();
+ break;
case SystemService.PHASE_BOOT_COMPLETED:
ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this.
break;
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 85e846d..9f113ad 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
import android.view.WindowManager;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -29,6 +31,8 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
+import static android.view.Surface.ROTATION_0;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -48,8 +52,10 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
@@ -349,6 +355,32 @@
assertThat(app.getDisplayId(), is(mDisplayContent.getDisplayId()));
}
+ @Test
+ public void testSeamlesslyRotateWindow() {
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+ final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
+
+ app.mHasSurface = true;
+ app.mSurfaceControl = mock(SurfaceControl.class);
+ app.mWinAnimator.mSurfaceController = mock(WindowSurfaceController.class);
+ try {
+ app.mFrame.set(10, 20, 60, 80);
+
+ app.seamlesslyRotate(t, ROTATION_0, ROTATION_90);
+
+ assertTrue(app.mSeamlesslyRotated);
+ assertEquals(new Rect(20, mDisplayInfo.logicalWidth - 60,
+ 80, mDisplayInfo.logicalWidth - 10), app.mFrame);
+
+ verify(t).setPosition(app.mSurfaceControl, app.mFrame.left, app.mFrame.top);
+ verify(app.mWinAnimator.mSurfaceController).setPosition(t, 0, 50, false);
+ verify(app.mWinAnimator.mSurfaceController).setMatrix(t, 0, -1, 1, 0, false);
+ } finally {
+ app.mSurfaceControl = null;
+ app.mHasSurface = false;
+ }
+ }
+
private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
reset(mPowerManagerWrapper);
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
index 40a10e0..f82b012 100644
--- a/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
@@ -21,14 +21,19 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
+import static com.android.server.wm.utils.CoordinateTransforms.transformLogicalToPhysicalCoordinates;
import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;
+
+import static com.android.server.wm.utils.CoordinateTransforms.transformToRotation;
+
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
+import android.view.DisplayInfo;
import org.junit.Before;
import org.junit.Rule;
@@ -41,6 +46,7 @@
private static final int H = 400;
private final Matrix mMatrix = new Matrix();
+ private final Matrix mMatrix2 = new Matrix();
@Rule
public final ErrorCollector mErrorCollector = new ErrorCollector();
@@ -48,39 +54,140 @@
@Before
public void setUp() throws Exception {
mMatrix.setTranslate(0xdeadbeef, 0xdeadbeef);
+ mMatrix2.setTranslate(0xbeefdead, 0xbeefdead);
}
@Test
- public void transformPhysicalToLogicalCoordinates_rot0() throws Exception {
+ public void transformPhysicalToLogicalCoordinates_rot0() {
transformPhysicalToLogicalCoordinates(ROTATION_0, W, H, mMatrix);
assertThat(mMatrix, is(Matrix.IDENTITY_MATRIX));
}
@Test
- public void transformPhysicalToLogicalCoordinates_rot90() throws Exception {
+ public void transformPhysicalToLogicalCoordinates_rot90() {
transformPhysicalToLogicalCoordinates(ROTATION_90, W, H, mMatrix);
- checkDevicePoint(0, 0).mapsToLogicalPoint(0, W);
- checkDevicePoint(W, H).mapsToLogicalPoint(H, 0);
+ checkPoint(0, 0).transformsTo(0, W);
+ checkPoint(W, H).transformsTo(H, 0);
}
@Test
- public void transformPhysicalToLogicalCoordinates_rot180() throws Exception {
+ public void transformPhysicalToLogicalCoordinates_rot180() {
transformPhysicalToLogicalCoordinates(ROTATION_180, W, H, mMatrix);
- checkDevicePoint(0, 0).mapsToLogicalPoint(W, H);
- checkDevicePoint(W, H).mapsToLogicalPoint(0, 0);
+ checkPoint(0, 0).transformsTo(W, H);
+ checkPoint(W, H).transformsTo(0, 0);
}
@Test
- public void transformPhysicalToLogicalCoordinates_rot270() throws Exception {
+ public void transformPhysicalToLogicalCoordinates_rot270() {
transformPhysicalToLogicalCoordinates(ROTATION_270, W, H, mMatrix);
- checkDevicePoint(0, 0).mapsToLogicalPoint(H, 0);
- checkDevicePoint(W, H).mapsToLogicalPoint(0, W);
+ checkPoint(0, 0).transformsTo(H, 0);
+ checkPoint(W, H).transformsTo(0, W);
}
- private DevicePointAssertable checkDevicePoint(int x, int y) {
+ @Test
+ public void transformLogicalToPhysicalCoordinates_rot0() {
+ transformLogicalToPhysicalCoordinates(ROTATION_0, W, H, mMatrix);
+ assertThat(mMatrix, is(Matrix.IDENTITY_MATRIX));
+ }
+
+ @Test
+ public void transformLogicalToPhysicalCoordinates_rot90() {
+ transformLogicalToPhysicalCoordinates(ROTATION_90, W, H, mMatrix);
+
+ checkPoint(0, W).transformsTo(0, 0);
+ checkPoint(H, 0).transformsTo(W, H);
+ }
+
+ @Test
+ public void transformLogicalToPhysicalCoordinates_rot180() {
+ transformLogicalToPhysicalCoordinates(ROTATION_180, W, H, mMatrix);
+
+ checkPoint(W, H).transformsTo(0, 0);
+ checkPoint(0, 0).transformsTo(W, H);
+ }
+
+ @Test
+ public void transformLogicalToPhysicalCoordinates_rot270() {
+ transformLogicalToPhysicalCoordinates(ROTATION_270, W, H, mMatrix);
+
+ checkPoint(H, 0).transformsTo(0, 0);
+ checkPoint(0, W).transformsTo(W, H);
+ }
+
+ @Test
+ public void transformLogicalToPhysicalCoordinatesIsInverse_rot0() {
+ transformLogicalToPhysicalCoordinates(ROTATION_0, W, H, mMatrix);
+ transformPhysicalToLogicalCoordinates(ROTATION_0, W, H, mMatrix2);
+
+ assertMatricesAreInverses(mMatrix, mMatrix2);
+ }
+
+ @Test
+ public void transformLogicalToPhysicalCoordinatesIsInverse_rot90() {
+ transformLogicalToPhysicalCoordinates(ROTATION_90, W, H, mMatrix);
+ transformPhysicalToLogicalCoordinates(ROTATION_90, W, H, mMatrix2);
+
+ assertMatricesAreInverses(mMatrix, mMatrix2);
+ }
+
+ @Test
+ public void transformLogicalToPhysicalCoordinatesIsInverse_rot180() {
+ transformLogicalToPhysicalCoordinates(ROTATION_180, W, H, mMatrix);
+ transformPhysicalToLogicalCoordinates(ROTATION_180, W, H, mMatrix2);
+
+ assertMatricesAreInverses(mMatrix, mMatrix2);
+ }
+
+ @Test
+ public void transformLogicalToPhysicalCoordinatesIsInverse_rot270() {
+ transformLogicalToPhysicalCoordinates(ROTATION_270, W, H, mMatrix);
+ transformPhysicalToLogicalCoordinates(ROTATION_270, W, H, mMatrix2);
+
+ assertMatricesAreInverses(mMatrix, mMatrix2);
+ }
+
+ @Test
+ public void transformBetweenRotations_rot180_rot270() {
+ // W,H are flipped, because they need to be given in the new orientation, i.e. ROT_270.
+ transformToRotation(ROTATION_180, ROTATION_270, H, W, mMatrix);
+
+ checkPoint(0, 0).transformsTo(0, W);
+ checkPoint(W, H).transformsTo(H, 0);
+ }
+
+ @Test
+ public void transformBetweenRotations_rot90_rot0() {
+ transformToRotation(ROTATION_180, ROTATION_270, W, H, mMatrix);
+
+ checkPoint(0, 0).transformsTo(0, H);
+ // H,W is bottom right in ROT_90
+ checkPoint(H, W).transformsTo(W, 0);
+ }
+
+ @Test
+ public void transformBetweenRotations_displayInfo() {
+ final DisplayInfo di = new DisplayInfo();
+ di.rotation = ROTATION_90;
+ di.logicalWidth = H; // dimensions are flipped in ROT_90
+ di.logicalHeight = W;
+ transformToRotation(ROTATION_180, ROTATION_270, di, mMatrix);
+
+ // W,H are flipped, because they need to be given in the new orientation, i.e. ROT_270.
+ transformToRotation(ROTATION_180, ROTATION_270, H, W, mMatrix2);
+
+ assertEquals(mMatrix2, mMatrix);
+ }
+
+ private void assertMatricesAreInverses(Matrix matrix, Matrix matrix2) {
+ final Matrix concat = new Matrix();
+ concat.setConcat(matrix, matrix2);
+ assertTrue("expected identity, but was: " + concat, concat.isIdentity());
+ }
+
+ private TransformPointAssertable checkPoint(int x, int y) {
final Point devicePoint = new Point(x, y);
final float[] fs = new float[] {x, y};
mMatrix.mapPoints(fs);
@@ -92,7 +199,7 @@
};
}
- public interface DevicePointAssertable {
- void mapsToLogicalPoint(int x, int y);
+ public interface TransformPointAssertable {
+ void transformsTo(int x, int y);
}
}
\ No newline at end of file
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a7d3f78..e6584c5 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -710,7 +710,7 @@
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- if (mPackageManagerInternal.getPackageUid(pkg, PackageManager.MATCH_ANY_USER,
+ if (mPackageManagerInternal.getPackageUid(pkg, /*flags=*/ 0,
callingUserId) != callingUid) {
throw new SecurityException("Calling uid " + pkg + " cannot query events"
+ "for package " + pkg);
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 145ed7e..c68a780 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -40,7 +40,14 @@
import java.util.Objects;
/**
- * A class representing an APN configuration.
+ * An Access Point Name (APN) configuration for a carrier data connection.
+ *
+ * <p>The APN provides configuration to connect a cellular network device to an IP data network. A
+ * carrier uses the name, type and other configuration in an {@code APNSetting} to decide which IP
+ * address to assign, any security methods to apply, and how the device might be connected to
+ * private networks.
+ *
+ * <p>Use {@link ApnSetting.Builder} to create new instances.
*/
public class ApnSetting implements Parcelable {
@@ -336,7 +343,7 @@
}
/**
- * Returns the entry name of the APN.
+ * Gets the human-readable name that describes the APN.
*
* @return the entry name for the APN
*/
@@ -354,18 +361,21 @@
}
/**
- * Returns the proxy address of the APN.
+ * Gets the HTTP proxy address configured for the APN. The proxy address might be an IP address
+ * or hostname. This method returns {@code null} if system networking (typically DNS) isn’t
+ * available to resolve a hostname value—values set as IP addresses don’t have this restriction.
+ * This is a known problem and will be addressed in a future release.
*
- * @return proxy address.
+ * @return the HTTP proxy address or {@code null} if DNS isn’t available to resolve a hostname
*/
public InetAddress getProxyAddress() {
return mProxyAddress;
}
/**
- * Returns the proxy port of the APN.
+ * Returns the proxy address of the APN.
*
- * @return proxy port
+ * @return proxy address.
*/
public int getProxyPort() {
return mProxyPort;
@@ -380,9 +390,12 @@
}
/**
- * Returns the MMS proxy address of the APN.
+ * Gets the MMS proxy address configured for the APN. The MMS proxy address might be an IP
+ * address or hostname. This method returns {@code null} if system networking (typically DNS)
+ * isn’t available to resolve a hostname value—values set as IP addresses don’t have this
+ * restriction. This is a known problem and will be addressed in a future release.
*
- * @return MMS proxy address.
+ * @return the MMS proxy address or {@code null} if DNS isn’t available to resolve a hostname
*/
public InetAddress getMmsProxyAddress() {
return mMmsProxyAddress;
@@ -1040,6 +1053,39 @@
return value == null ? NOT_IN_MAP_INT : value;
}
+ /**
+ * Provides a convenient way to set the fields of a {@link ApnSetting} when creating a new
+ * instance. The following settings are required to build an {@code ApnSetting}:
+ *
+ * <ul><li>apnTypeBitmask</li>
+ * <li>apnName</li>
+ * <li>entryName</li></ul>
+ *
+ * <p>The example below shows how you might create a new {@code ApnSetting}:
+ *
+ * <pre><code>
+ * // Create an MMS proxy address with a hostname. A network might not be
+ * // available, so supply a dummy (0.0.0.0) IPv4 address to avoid DNS lookup.
+ * String host = "mms.example.com";
+ * byte[] ipAddress = new byte[4];
+ * InetAddress mmsProxy;
+ * try {
+ * mmsProxy = InetAddress.getByAddress(host, ipAddress);
+ * } catch (UnknownHostException e) {
+ * e.printStackTrace();
+ * return;
+ * }
+ *
+ * ApnSetting apn = new ApnSetting.Builder()
+ * .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ * .setApnName("apn.example.com")
+ * .setEntryName("Example Carrier APN")
+ * .setMmsc(Uri.parse("http://mms.example.com:8002"))
+ * .setMmsProxyAddress(mmsProxy)
+ * .setMmsProxyPort(8799)
+ * .build();
+ * </code></pre>
+ */
public static class Builder{
private String mEntryName;
private String mApnName;
@@ -1160,7 +1206,7 @@
}
/**
- * Sets the entry name of the APN.
+ * Sets a human-readable name that describes the APN.
*
* @param entryName the entry name to set for the APN
*/
@@ -1180,7 +1226,15 @@
}
/**
- * Sets the proxy address of the APN.
+ * Sets the address of an HTTP proxy for the APN. The proxy address can be an IP address or
+ * hostname. If {@code proxy} contains both an IP address and hostname, this method ignores
+ * the IP address.
+ *
+ * <p>The {@link java.net.InetAddress} methods
+ * {@link java.net.InetAddress#getAllByName getAllByName()} require DNS for hostname
+ * resolution. To avoid this requirement when setting a hostname, call
+ * {@link java.net.InetAddress#getByAddress(java.lang.String, byte[])} with both the
+ * hostname and a dummy IP address. See {@link ApnSetting.Builder above} for an example.
*
* @param proxy the proxy address to set for the APN
*/
@@ -1210,7 +1264,16 @@
}
/**
- * Sets the MMS proxy address of the APN.
+ * Sets the address of an MMS proxy for the APN. The MMS proxy address can be an IP address
+ * or hostname. If {@code mmsProxy} contains both an IP address and hostname, this method
+ * ignores the IP address.
+ *
+ * <p>The {@link java.net.InetAddress} methods
+ * {@link java.net.InetAddress#getByName getByName()} and
+ * {@link java.net.InetAddress#getAllByName getAllByName()} require DNS for hostname
+ * resolution. To avoid this requirement when setting a hostname, call
+ * {@link java.net.InetAddress#getByAddress(java.lang.String, byte[])} with both the
+ * hostname and a dummy IP address. See {@link ApnSetting.Builder above} for an example.
*
* @param mmsProxy the MMS proxy address to set for the APN
*/
@@ -1358,4 +1421,3 @@
}
}
}
-
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index 676684c..bcad554 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -152,14 +152,9 @@
&& (ai.enabledSetting ==
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| ai.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
- || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0)) {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
Slog.i(TAG, "Update state(" + packageName + "): ENABLED for user "
+ userId);
- packageManager.setSystemAppInstallState(
- packageName,
- true /*installed*/,
- userId);
packageManager.setApplicationEnabledSetting(
packageName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -175,14 +170,9 @@
if (associatedApp.enabledSetting ==
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| associatedApp.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
- || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
Slog.i(TAG, "Update associated state(" + associatedApp.packageName
+ "): ENABLED for user " + userId);
- packageManager.setSystemAppInstallState(
- associatedApp.packageName,
- true /*installed*/,
- userId);
packageManager.setApplicationEnabledSetting(
associatedApp.packageName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -200,14 +190,15 @@
// updated we shouldn't touch it.
if (!ai.isUpdatedSystemApp()
&& ai.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
- && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
+ PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
Slog.i(TAG, "Update state(" + packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setSystemAppInstallState(
+ packageManager.setApplicationEnabledSetting(
packageName,
- false /*installed*/,
- userId);
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
+ 0,
+ userId,
+ callingPackage);
}
// Also disable any associated apps for this carrier app if this is the first
@@ -222,10 +213,13 @@
Slog.i(TAG,
"Update associated state(" + associatedApp.packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setSystemAppInstallState(
+ packageManager.setApplicationEnabledSetting(
associatedApp.packageName,
- false /*installed*/,
- userId);
+ PackageManager
+ .COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
+ 0,
+ userId,
+ callingPackage);
}
}
}
@@ -363,8 +357,7 @@
String packageName) {
try {
ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
- PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
- | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, userId);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId);
if (ai != null && ai.isSystemApp()) {
return ai;
}
diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
index c095438..4790b75 100644
--- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
@@ -105,7 +105,7 @@
/**
* PLMN (MCC/MNC) is encoded as per 24.008 10.5.1.3
* Returns a concatenated string of MCC+MNC, stripping
- * all invalid character 'f'
+ * all invalid character 'F'
*/
public static String bcdPlmnToString(byte[] data, int offset) {
if (offset + 3 > data.length) {
@@ -117,9 +117,9 @@
trans[2] = (byte) ((data[2 + offset] & 0xF0) | ((data[1 + offset] >> 4) & 0xF));
String ret = bytesToHexString(trans);
- // For a valid plmn we trim all character 'f'
- if (ret.contains("f")) {
- ret = ret.replaceAll("f", "");
+ // For a valid plmn we trim all character 'F'
+ if (ret.contains("F")) {
+ ret = ret.replaceAll("F", "");
}
return ret;
}
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 280afade..703a67b 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -106,6 +106,7 @@
shared_libs: [
"liblog",
"libutils",
+ "libcutils",
],
static_libs: ["libstatssocket"],
}
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 638549d..140653a 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -104,6 +104,7 @@
fprintf(out, "#include <mutex>\n");
fprintf(out, "#include <chrono>\n");
fprintf(out, "#include <thread>\n");
+ fprintf(out, "#include <cutils/properties.h>\n");
fprintf(out, "#include <stats_event_list.h>\n");
fprintf(out, "#include <log/log.h>\n");
fprintf(out, "#include <statslog.h>\n");
@@ -114,6 +115,7 @@
fprintf(out, "namespace util {\n");
fprintf(out, "// the single event tag id for all stats logs\n");
fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
+ fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed",
"audio_state_changed",
@@ -242,6 +244,7 @@
fprintf(out, "{\n");
argIndex = 1;
+ fprintf(out, " if (kStatsdEnabled) {\n");
fprintf(out, " stats_event_list event(kStatsEventTag);\n");
fprintf(out, " event << android::elapsedRealtimeNano();\n\n");
fprintf(out, " event << code;\n\n");
@@ -286,6 +289,9 @@
}
fprintf(out, " return event.write(LOG_ID_STATS);\n");
+ fprintf(out, " } else {\n");
+ fprintf(out, " return 1;\n");
+ fprintf(out, " }\n");
fprintf(out, "}\n");
fprintf(out, "\n");
}
@@ -375,6 +381,7 @@
fprintf(out, "{\n");
argIndex = 1;
+ fprintf(out, " if (kStatsdEnabled) {\n");
fprintf(out, " stats_event_list event(kStatsEventTag);\n");
fprintf(out, " event << android::elapsedRealtimeNano();\n\n");
fprintf(out, " event << code;\n\n");
@@ -398,6 +405,9 @@
}
fprintf(out, " return event.write(LOG_ID_STATS);\n");
+ fprintf(out, " } else {\n");
+ fprintf(out, " return 1;\n");
+ fprintf(out, " }\n");
fprintf(out, "}\n");
fprintf(out, "\n");
}
@@ -1193,4 +1203,4 @@
GOOGLE_PROTOBUF_VERIFY_VERSION;
return android::stats_log_api_gen::run(argc, argv);
-}
\ No newline at end of file
+}