Merge "Move FlickerTests to frameworks/base/tests 2/2"
diff --git a/Android.bp b/Android.bp
index 21b8404..6815a0d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -94,6 +94,7 @@
"core/java/android/app/trust/IStrongAuthTracker.aidl",
"core/java/android/app/trust/ITrustManager.aidl",
"core/java/android/app/trust/ITrustListener.aidl",
+ "core/java/android/app/backup/IBackupCallback.aidl",
"core/java/android/app/backup/IBackupManager.aidl",
"core/java/android/app/backup/IBackupObserver.aidl",
"core/java/android/app/backup/IBackupManagerMonitor.aidl",
diff --git a/Android.mk b/Android.mk
index f81f756..edbb94d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -171,15 +171,17 @@
-hidePackage com.android.server
# Convert an sdk level to a "since" argument.
-since-arg = -since $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(1)/public/api/android.*) $(1)
+since-arg = -since $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(1)/public/api/android.$(2)) $(1)
-finalized_sdks := $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.xml,%,\
- $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.xml))
-finalized_sdks += $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.txt,%,\
- $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.txt))
-finalized_sdks := $(call numerically_sort,$(finalized_sdks))
+finalized_xml_sdks := $(call numerically_sort,\
+ $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.xml,%,\
+ $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.xml)))
+finalized_txt_sdks := $(call numerically_sort,\
+ $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.txt,%,\
+ $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.txt)))
-framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_sdks),$(call since-arg,$(sdk)))
+framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_xml_sdks),$(call since-arg,$(sdk),xml))
+framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_txt_sdks),$(call since-arg,$(sdk),txt))
ifneq ($(PLATFORM_VERSION_CODENAME),REL)
framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-since ./frameworks/base/api/current.txt $(PLATFORM_VERSION_CODENAME)
@@ -361,8 +363,8 @@
LOCAL_SRC_GREYLIST := frameworks/base/config/hiddenapi-light-greylist.txt
LOCAL_SRC_VENDOR_LIST := frameworks/base/config/hiddenapi-vendor-list.txt
LOCAL_SRC_FORCE_BLACKLIST := frameworks/base/config/hiddenapi-force-blacklist.txt
-LOCAL_SRC_PUBLIC_API := $(INTERNAL_PLATFORM_DEX_API_FILE)
-LOCAL_SRC_PRIVATE_API := $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
+LOCAL_SRC_PUBLIC_API := $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
+LOCAL_SRC_PRIVATE_API := $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)
LOCAL_SRC_REMOVED_API := $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)
LOCAL_SRC_ALL := \
diff --git a/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java b/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
index 05293a2..66a2600d 100644
--- a/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
@@ -48,7 +48,7 @@
@Before
public void setUp() {
- mBinderCallsStats = new BinderCallsStats(new Random());
+ mBinderCallsStats = new BinderCallsStats(new BinderCallsStats.Injector());
}
@After
diff --git a/api/system-current.txt b/api/system-current.txt
index 924d3af..01f4709 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4524,9 +4524,11 @@
public abstract class AutofillFieldClassificationService extends android.app.Service {
method public android.os.IBinder onBind(android.content.Intent);
method public float[][] onGetScores(java.lang.String, android.os.Bundle, java.util.List<android.view.autofill.AutofillValue>, java.util.List<java.lang.String>);
+ field public static final java.lang.String RESOURCE_AVAILABLE_ALGORITHMS = "autofill_field_classification_available_algorithms";
+ field public static final java.lang.String RESOURCE_DEFAULT_ALGORITHM = "autofill_field_classification_default_algorithm";
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
- field public static final java.lang.String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = "android.autofill.field_classification.available_algorithms";
- field public static final java.lang.String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM = "android.autofill.field_classification.default_algorithm";
+ field public static final deprecated java.lang.String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = "android.autofill.field_classification.available_algorithms";
+ field public static final deprecated java.lang.String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM = "android.autofill.field_classification.default_algorithm";
}
}
@@ -4665,6 +4667,7 @@
field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
field public static final java.lang.String KEY_PEOPLE = "key_people";
field public static final java.lang.String KEY_SMART_ACTIONS = "key_smart_actions";
+ field public static final java.lang.String KEY_SMART_REPLIES = "key_smart_replies";
field public static final java.lang.String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
field public static final java.lang.String KEY_USER_SENTIMENT = "key_user_sentiment";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 462d22e..1d08da5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1044,6 +1044,7 @@
field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
field public static final java.lang.String KEY_PEOPLE = "key_people";
field public static final java.lang.String KEY_SMART_ACTIONS = "key_smart_actions";
+ field public static final java.lang.String KEY_SMART_REPLIES = "key_smart_replies";
field public static final java.lang.String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
field public static final java.lang.String KEY_USER_SENTIMENT = "key_user_sentiment";
}
diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blacklist.txt
index 3a9e2d1..dca3b52 100644
--- a/config/hiddenapi-force-blacklist.txt
+++ b/config/hiddenapi-force-blacklist.txt
@@ -1,38 +1,38 @@
Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V
Ljava/lang/invoke/MethodHandles$Lookup;->IMPL_LOOKUP:Ljava/lang/invoke/MethodHandles$Lookup;
Ljava/lang/invoke/VarHandle;->acquireFence()V
-Ljava/lang/invoke/VarHandle;->compareAndExchange([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->compareAndExchangeAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->compareAndExchangeRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->compareAndSet([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->compareAndExchange([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndExchangeAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndExchangeRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndSet([Ljava/lang/Object;)Z
Ljava/lang/invoke/VarHandle;->fullFence()V
-Ljava/lang/invoke/VarHandle;->get([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndAdd([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndAddAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndAddRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseAnd([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseAndAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseAndRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseOr([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseOrAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseOrRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseXor([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseXorAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseXorRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndSet([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndSetAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndSetRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getOpaque([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getVolatile([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->get([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAdd([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAddAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAddRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAnd([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAndAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAndRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOr([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOrAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOrRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXor([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXorAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXorRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSet([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSetAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSetRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getOpaque([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getVolatile([Ljava/lang/Object;)Ljava/lang/Object;
Ljava/lang/invoke/VarHandle;->loadLoadFence()V
Ljava/lang/invoke/VarHandle;->releaseFence()V
-Ljava/lang/invoke/VarHandle;->set([[Ljava/lang/Object;)V
-Ljava/lang/invoke/VarHandle;->setOpaque([[Ljava/lang/Object;)V
-Ljava/lang/invoke/VarHandle;->setRelease([[Ljava/lang/Object;)V
-Ljava/lang/invoke/VarHandle;->setVolatile([[Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->set([Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setOpaque([Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setRelease([Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setVolatile([Ljava/lang/Object;)V
Ljava/lang/invoke/VarHandle;->storeStoreFence()V
-Ljava/lang/invoke/VarHandle;->weakCompareAndSet([[Ljava/lang/Object;)Z
-Ljava/lang/invoke/VarHandle;->weakCompareAndSetAcquire([[Ljava/lang/Object;)Z
-Ljava/lang/invoke/VarHandle;->weakCompareAndSetPlain([[Ljava/lang/Object;)Z
-Ljava/lang/invoke/VarHandle;->weakCompareAndSetRelease([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSet([Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetAcquire([Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetPlain([Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetRelease([Ljava/lang/Object;)Z
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index b936fe7..0b94c27 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,6 +1,3 @@
-Landroid/accessibilityservice/AccessibilityService;->mInfo:Landroid/accessibilityservice/AccessibilityServiceInfo;
-Landroid/accessibilityservice/AccessibilityService;->mWindowToken:Landroid/os/IBinder;
-Landroid/accessibilityservice/AccessibilityServiceInfo;->setCapabilities(I)V
Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;-><init>()V
Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accessibilityservice/IAccessibilityServiceConnection;
Landroid/accounts/Account;->accessId:Ljava/lang/String;
@@ -51,13 +48,6 @@
Landroid/accounts/IAccountManagerResponse$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManagerResponse;
Landroid/accounts/IAccountManagerResponse;->onError(ILjava/lang/String;)V
Landroid/accounts/IAccountManagerResponse;->onResult(Landroid/os/Bundle;)V
-Landroid/animation/Animator;->reverse()V
-Landroid/animation/ArgbEvaluator;->getInstance()Landroid/animation/ArgbEvaluator;
-Landroid/animation/LayoutTransition;->cancel()V
-Landroid/animation/LayoutTransition;->cancel(I)V
-Landroid/animation/ValueAnimator;->animateValue(F)V
-Landroid/animation/ValueAnimator;->mDuration:J
-Landroid/animation/ValueAnimator;->sDurationScale:F
Landroid/app/ActionBar;->collapseActionView()Z
Landroid/app/ActionBar;->DISPLAY_TITLE_MULTIPLE_LINES:I
Landroid/app/ActionBar;->setShowHideAnimationEnabled(Z)V
@@ -533,7 +523,7 @@
Landroid/app/DownloadManager$Request;->mUri:Landroid/net/Uri;
Landroid/app/DownloadManager;->getWhereArgsForIds([J)[Ljava/lang/String;
Landroid/app/DownloadManager;->getWhereClauseForIds([J)Ljava/lang/String;
-Landroid/app/DownloadManager;->restartDownload([[J)V
+Landroid/app/DownloadManager;->restartDownload([J)V
Landroid/app/DownloadManager;->setAccessAllDownloads(Z)V
Landroid/app/DownloadManager;->setAccessFilename(Z)V
Landroid/app/DownloadManager;->UNDERLYING_COLUMNS:[Ljava/lang/String;
@@ -1049,7 +1039,6 @@
Landroid/bluetooth/BluetoothClass;->doesClassMatch(I)Z
Landroid/bluetooth/BluetoothClass;->PROFILE_A2DP:I
Landroid/bluetooth/BluetoothClass;->PROFILE_HEADSET:I
-Landroid/bluetooth/BluetoothCodecConfig;
Landroid/bluetooth/BluetoothCodecConfig;-><init>(IIIIIJJJJ)V
Landroid/bluetooth/BluetoothCodecConfig;->BITS_PER_SAMPLE_16:I
Landroid/bluetooth/BluetoothCodecConfig;->BITS_PER_SAMPLE_24:I
@@ -1085,7 +1074,6 @@
Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_LDAC:I
Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_MAX:I
Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_SBC:I
-Landroid/bluetooth/BluetoothCodecStatus;
Landroid/bluetooth/BluetoothCodecStatus;->EXTRA_CODEC_STATUS:Ljava/lang/String;
Landroid/bluetooth/BluetoothCodecStatus;->getCodecConfig()Landroid/bluetooth/BluetoothCodecConfig;
Landroid/bluetooth/BluetoothCodecStatus;->getCodecsLocalCapabilities()[Landroid/bluetooth/BluetoothCodecConfig;
@@ -1453,10 +1441,15 @@
Landroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName;
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->onRemoveCompleted(Ljava/lang/String;Z)V
Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
+Landroid/content/pm/IPackageDataObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/content/pm/IPackageDataObserver$Stub;->TRANSACTION_onRemoveCompleted:I
Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
+Landroid/content/pm/IPackageDeleteObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/content/pm/IPackageDeleteObserver$Stub;->TRANSACTION_packageDeleted:I
Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/pm/IPackageDeleteObserver2$Stub;-><init>()V
@@ -1555,6 +1548,8 @@
Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/pm/IPackageStatsObserver$Stub;-><init>()V
Landroid/content/pm/IPackageStatsObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageStatsObserver;
+Landroid/content/pm/IPackageStatsObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/content/pm/IPackageStatsObserver$Stub;->TRANSACTION_onGetStatsCompleted:I
Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IShortcutService;
Landroid/content/pm/LauncherActivityInfo;->mActivityInfo:Landroid/content/pm/ActivityInfo;
@@ -2025,8 +2020,6 @@
Landroid/database/sqlite/SqliteWrapper;->checkSQLiteException(Landroid/content/Context;Landroid/database/sqlite/SQLiteException;)V
Landroid/database/sqlite/SqliteWrapper;->delete(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I
Landroid/database/sqlite/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-Landroid/ddm/DdmHandleAppName;->getAppName()Ljava/lang/String;
-Landroid/ddm/DdmHandleAppName;->setAppName(Ljava/lang/String;I)V
Landroid/filterfw/core/Filter;-><init>(Ljava/lang/String;)V
Landroid/filterfw/core/Filter;->isAvailable(Ljava/lang/String;)Z
Landroid/filterfw/core/Filter;->setInputValue(Ljava/lang/String;Ljava/lang/Object;)V
@@ -2093,268 +2086,7 @@
Landroid/filterfw/GraphEnvironment;-><init>()V
Landroid/filterfw/GraphEnvironment;->getRunner(II)Landroid/filterfw/core/GraphRunner;
Landroid/filterfw/GraphEnvironment;->loadGraph(Landroid/content/Context;I)I
-Landroid/graphics/BaseCanvas;->mNativeCanvasWrapper:J
-Landroid/graphics/Bitmap$Config;->nativeInt:I
-Landroid/graphics/Bitmap$Config;->nativeToConfig(I)Landroid/graphics/Bitmap$Config;
-Landroid/graphics/Bitmap;-><init>(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;)V
-Landroid/graphics/Bitmap;->createAshmemBitmap()Landroid/graphics/Bitmap;
-Landroid/graphics/Bitmap;->createAshmemBitmap(Landroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
-Landroid/graphics/Bitmap;->getDefaultDensity()I
-Landroid/graphics/Bitmap;->mHeight:I
-Landroid/graphics/Bitmap;->mNativePtr:J
-Landroid/graphics/Bitmap;->mNinePatchChunk:[B
-Landroid/graphics/Bitmap;->mNinePatchInsets:Landroid/graphics/NinePatch$InsetStruct;
-Landroid/graphics/Bitmap;->mWidth:I
-Landroid/graphics/Bitmap;->nativeReconfigure(JIIIZ)V
-Landroid/graphics/Bitmap;->reinit(IIZ)V
-Landroid/graphics/Bitmap;->scaleFromDensity(III)I
-Landroid/graphics/Bitmap;->setDefaultDensity(I)V
-Landroid/graphics/Bitmap;->setNinePatchChunk([B)V
-Landroid/graphics/BitmapFactory;->nativeDecodeAsset(JLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapFactory;->nativeDecodeByteArray([BIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapFactory;->nativeDecodeFileDescriptor(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapFactory;->nativeDecodeStream(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapRegionDecoder;-><init>(J)V
-Landroid/graphics/BitmapRegionDecoder;->nativeNewInstance([BIIZ)Landroid/graphics/BitmapRegionDecoder;
-Landroid/graphics/BitmapShader;->mBitmap:Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapShader;->mTileX:I
-Landroid/graphics/BitmapShader;->mTileY:I
-Landroid/graphics/Camera;->native_instance:J
-Landroid/graphics/Canvas;-><init>(J)V
-Landroid/graphics/Canvas;->freeCaches()V
-Landroid/graphics/Canvas;->freeTextLayoutCaches()V
-Landroid/graphics/Canvas;->getGL()Ljavax/microedition/khronos/opengles/GL;
-Landroid/graphics/Canvas;->getNativeCanvasWrapper()J
-Landroid/graphics/Canvas;->mBitmap:Landroid/graphics/Bitmap;
-Landroid/graphics/Canvas;->release()V
-Landroid/graphics/Canvas;->setScreenDensity(I)V
-Landroid/graphics/CanvasProperty;->createFloat(F)Landroid/graphics/CanvasProperty;
-Landroid/graphics/CanvasProperty;->createPaint(Landroid/graphics/Paint;)Landroid/graphics/CanvasProperty;
-Landroid/graphics/ColorMatrixColorFilter;->mMatrix:Landroid/graphics/ColorMatrix;
-Landroid/graphics/ColorMatrixColorFilter;->setColorMatrix(Landroid/graphics/ColorMatrix;)V
-Landroid/graphics/ColorMatrixColorFilter;->setColorMatrixArray([F)V
-Landroid/graphics/drawable/AnimatedImageDrawable;->onAnimationEnd()V
-Landroid/graphics/drawable/AnimatedRotateDrawable;->setFramesCount(I)V
-Landroid/graphics/drawable/AnimatedRotateDrawable;->setFramesDuration(I)V
-Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->mStateIds:Landroid/util/SparseIntArray;
-Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->mTransitions:Landroid/util/LongSparseLongArray;
-Landroid/graphics/drawable/AnimatedStateListDrawable;->mState:Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;
-Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->callOnFinished(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V
-Landroid/graphics/drawable/AnimatedVectorDrawable;->forceAnimationOnUI()V
-Landroid/graphics/drawable/AnimatedVectorDrawable;->mAnimatedVectorState:Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;
-Landroid/graphics/drawable/AnimatedVectorDrawable;->mAnimatorSet:Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;
-Landroid/graphics/drawable/AnimationDrawable;->mCurFrame:I
-Landroid/graphics/drawable/BitmapDrawable;->getTint()Landroid/content/res/ColorStateList;
-Landroid/graphics/drawable/BitmapDrawable;->getTintMode()Landroid/graphics/PorterDuff$Mode;
-Landroid/graphics/drawable/BitmapDrawable;->mBitmapState:Landroid/graphics/drawable/BitmapDrawable$BitmapState;
-Landroid/graphics/drawable/BitmapDrawable;->mTargetDensity:I
-Landroid/graphics/drawable/BitmapDrawable;->setBitmap(Landroid/graphics/Bitmap;)V
-Landroid/graphics/drawable/ClipDrawable;->mState:Landroid/graphics/drawable/ClipDrawable$ClipState;
-Landroid/graphics/drawable/ColorDrawable$ColorState;->mUseColor:I
-Landroid/graphics/drawable/ColorDrawable;->mPaint:Landroid/graphics/Paint;
-Landroid/graphics/drawable/Drawable;->inflateWithAttributes(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/TypedArray;I)V
-Landroid/graphics/drawable/Drawable;->mCallback:Ljava/lang/ref/WeakReference;
-Landroid/graphics/drawable/Drawable;->mSrcDensityOverride:I
-Landroid/graphics/drawable/Drawable;->parseTintMode(ILandroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuff$Mode;
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mConstantPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mDrawables:[Landroid/graphics/drawable/Drawable;
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mHasColorFilter:Z
-Landroid/graphics/drawable/DrawableContainer;->mDrawableContainerState:Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;
-Landroid/graphics/drawable/DrawableContainer;->mLastDrawable:Landroid/graphics/drawable/Drawable;
-Landroid/graphics/drawable/DrawableInflater;->mClassLoader:Ljava/lang/ClassLoader;
-Landroid/graphics/drawable/DrawableWrapper;->mState:Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mAngle:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradient:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradientColors:[I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mHeight:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mInnerRadius:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mInnerRadiusRatio:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mOrientation:Landroid/graphics/drawable/GradientDrawable$Orientation;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mPositions:[F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadius:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadiusArray:[F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mShape:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mSolidColors:Landroid/content/res/ColorStateList;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mStrokeDashGap:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mStrokeDashWidth:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mStrokeWidth:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mThickness:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mThicknessRatio:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mWidth:I
-Landroid/graphics/drawable/GradientDrawable;->mFillPaint:Landroid/graphics/Paint;
-Landroid/graphics/drawable/GradientDrawable;->mGradientState:Landroid/graphics/drawable/GradientDrawable$GradientState;
-Landroid/graphics/drawable/GradientDrawable;->mPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/GradientDrawable;->mStrokePaint:Landroid/graphics/Paint;
-Landroid/graphics/drawable/Icon;->createWithResource(Landroid/content/res/Resources;I)Landroid/graphics/drawable/Icon;
-Landroid/graphics/drawable/Icon;->getBitmap()Landroid/graphics/Bitmap;
-Landroid/graphics/drawable/Icon;->getDataBytes()[B
-Landroid/graphics/drawable/Icon;->getDataLength()I
-Landroid/graphics/drawable/Icon;->getDataOffset()I
-Landroid/graphics/drawable/Icon;->getResources()Landroid/content/res/Resources;
-Landroid/graphics/drawable/Icon;->hasTint()Z
-Landroid/graphics/drawable/Icon;->mString1:Ljava/lang/String;
-Landroid/graphics/drawable/Icon;->mType:I
-Landroid/graphics/drawable/InsetDrawable;->mState:Landroid/graphics/drawable/InsetDrawable$InsetState;
-Landroid/graphics/drawable/LayerDrawable$ChildDrawable;->mDrawable:Landroid/graphics/drawable/Drawable;
-Landroid/graphics/drawable/LayerDrawable$LayerState;->mChildren:[Landroid/graphics/drawable/LayerDrawable$ChildDrawable;
-Landroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I
-Landroid/graphics/drawable/LayerDrawable;->ensurePadding()V
-Landroid/graphics/drawable/LayerDrawable;->mLayerState:Landroid/graphics/drawable/LayerDrawable$LayerState;
-Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;->mNinePatch:Landroid/graphics/NinePatch;
-Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;
-Landroid/graphics/drawable/RippleDrawable$RippleState;->mColor:Landroid/content/res/ColorStateList;
-Landroid/graphics/drawable/RippleDrawable;->getRipplePaint()Landroid/graphics/Paint;
-Landroid/graphics/drawable/RippleDrawable;->mDensity:I
-Landroid/graphics/drawable/RippleDrawable;->mState:Landroid/graphics/drawable/RippleDrawable$RippleState;
-Landroid/graphics/drawable/RippleDrawable;->setForceSoftware(Z)V
-Landroid/graphics/drawable/RotateDrawable;->mState:Landroid/graphics/drawable/RotateDrawable$RotateState;
-Landroid/graphics/drawable/ScaleDrawable;->mState:Landroid/graphics/drawable/ScaleDrawable$ScaleState;
-Landroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
-Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I
-Landroid/graphics/drawable/StateListDrawable;->mStateListState:Landroid/graphics/drawable/StateListDrawable$StateListState;
-Landroid/graphics/drawable/StateListDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
-Landroid/graphics/drawable/TransitionDrawable;->mAlpha:I
-Landroid/graphics/drawable/TransitionDrawable;->mCrossFade:Z
-Landroid/graphics/drawable/TransitionDrawable;->mTo:I
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setPivotX(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setPivotY(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setRotation(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setTranslateX(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setTranslateY(F)V
-Landroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
-Landroid/graphics/drawable/VectorDrawable;->mTintFilter:Landroid/graphics/PorterDuffColorFilter;
-Landroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
-Landroid/graphics/FontFamily;-><init>()V
-Landroid/graphics/FontFamily;-><init>([Ljava/lang/String;I)V
-Landroid/graphics/FontFamily;->abortCreation()V
-Landroid/graphics/FontFamily;->addFontFromAssetManager(Landroid/content/res/AssetManager;Ljava/lang/String;IZIII[Landroid/graphics/fonts/FontVariationAxis;)Z
-Landroid/graphics/FontFamily;->addFontFromBuffer(Ljava/nio/ByteBuffer;I[Landroid/graphics/fonts/FontVariationAxis;II)Z
-Landroid/graphics/FontFamily;->freeze()Z
-Landroid/graphics/FontFamily;->mNativePtr:J
-Landroid/graphics/FontListParser;->parse(Ljava/io/InputStream;)Landroid/text/FontConfig;
-Landroid/graphics/fonts/FontVariationAxis;->mStyleValue:F
-Landroid/graphics/fonts/FontVariationAxis;->mTag:I
-Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
-Landroid/graphics/GraphicBuffer;->createFromExisting(IIIIJ)Landroid/graphics/GraphicBuffer;
-Landroid/graphics/GraphicBuffer;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/graphics/GraphicBuffer;->mNativeObject:J
-Landroid/graphics/ImageDecoder;->postProcessAndRelease(Landroid/graphics/Canvas;)I
-Landroid/graphics/ImageFormat;->Y8:I
-Landroid/graphics/LightingColorFilter;->setColorAdd(I)V
-Landroid/graphics/LightingColorFilter;->setColorMultiply(I)V
-Landroid/graphics/LinearGradient;->mColor0:I
-Landroid/graphics/LinearGradient;->mColor1:I
-Landroid/graphics/LinearGradient;->mColors:[I
-Landroid/graphics/LinearGradient;->mPositions:[F
-Landroid/graphics/LinearGradient;->mTileMode:Landroid/graphics/Shader$TileMode;
-Landroid/graphics/LinearGradient;->mX0:F
-Landroid/graphics/LinearGradient;->mX1:F
-Landroid/graphics/LinearGradient;->mY0:F
-Landroid/graphics/LinearGradient;->mY1:F
-Landroid/graphics/Matrix;->IDENTITY_MATRIX:Landroid/graphics/Matrix;
-Landroid/graphics/Matrix;->native_instance:J
-Landroid/graphics/Movie;-><init>(J)V
-Landroid/graphics/Movie;->mNativeMovie:J
-Landroid/graphics/NinePatch$InsetStruct;-><init>(IIIIIIIIFIF)V
-Landroid/graphics/NinePatch;->mBitmap:Landroid/graphics/Bitmap;
-Landroid/graphics/NinePatch;->mNativeChunk:J
-Landroid/graphics/Outline;->mRect:Landroid/graphics/Rect;
-Landroid/graphics/Paint;->getNativeInstance()J
-Landroid/graphics/Paint;->getTextRunAdvances([CIIIIZ[FI)F
-Landroid/graphics/Paint;->getTextRunCursor([CIIIII)I
-Landroid/graphics/Paint;->mNativePaint:J
-Landroid/graphics/Paint;->mTypeface:Landroid/graphics/Typeface;
-Landroid/graphics/Paint;->setCompatibilityScaling(F)V
-Landroid/graphics/Paint;->setHyphenEdit(I)V
-Landroid/graphics/Path;->isSimplePath:Z
-Landroid/graphics/Path;->rects:Landroid/graphics/Region;
-Landroid/graphics/pdf/PdfRenderer;->doClose()V
-Landroid/graphics/pdf/PdfRenderer;->mCurrentPage:Landroid/graphics/pdf/PdfRenderer$Page;
-Landroid/graphics/Picture;->mNativePicture:J
-Landroid/graphics/PorterDuff$Mode;->nativeInt:I
-Landroid/graphics/PorterDuffColorFilter;->getColor()I
-Landroid/graphics/PorterDuffColorFilter;->getMode()Landroid/graphics/PorterDuff$Mode;
-Landroid/graphics/RadialGradient;->mCenterColor:I
-Landroid/graphics/RadialGradient;->mColors:[I
-Landroid/graphics/RadialGradient;->mEdgeColor:I
-Landroid/graphics/RadialGradient;->mPositions:[F
-Landroid/graphics/RadialGradient;->mRadius:F
-Landroid/graphics/RadialGradient;->mTileMode:Landroid/graphics/Shader$TileMode;
-Landroid/graphics/RadialGradient;->mX:F
-Landroid/graphics/RadialGradient;->mY:F
-Landroid/graphics/Rect;->printShortString(Ljava/io/PrintWriter;)V
-Landroid/graphics/Rect;->scale(F)V
-Landroid/graphics/Region$Op;->nativeInt:I
-Landroid/graphics/Region;-><init>(JI)V
-Landroid/graphics/Region;->mNativeRegion:J
-Landroid/graphics/Region;->recycle()V
-Landroid/graphics/Region;->scale(F)V
-Landroid/graphics/Shader$TileMode;->nativeInt:I
-Landroid/graphics/SurfaceTexture;->mFrameAvailableListener:J
-Landroid/graphics/SurfaceTexture;->mOnFrameAvailableHandler:Landroid/os/Handler;
-Landroid/graphics/SurfaceTexture;->mProducer:J
-Landroid/graphics/SurfaceTexture;->mSurfaceTexture:J
-Landroid/graphics/SurfaceTexture;->nativeDetachFromGLContext()I
-Landroid/graphics/SurfaceTexture;->postEventFromNative(Ljava/lang/ref/WeakReference;)V
-Landroid/graphics/SweepGradient;->mColor0:I
-Landroid/graphics/SweepGradient;->mColor1:I
-Landroid/graphics/SweepGradient;->mColors:[I
-Landroid/graphics/SweepGradient;->mCx:F
-Landroid/graphics/SweepGradient;->mCy:F
-Landroid/graphics/SweepGradient;->mPositions:[F
-Landroid/graphics/TableMaskFilter;->CreateClipTable(II)Landroid/graphics/TableMaskFilter;
-Landroid/graphics/TemporaryBuffer;->obtain(I)[C
-Landroid/graphics/TemporaryBuffer;->recycle([C)V
-Landroid/graphics/Typeface;-><init>(J)V
-Landroid/graphics/Typeface;->createFromFamilies([Landroid/graphics/FontFamily;)Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->createFromFamiliesWithDefault([Landroid/graphics/FontFamily;II)Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->createFromFamiliesWithDefault([Landroid/graphics/FontFamily;Ljava/lang/String;II)Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->mStyle:I
-Landroid/graphics/Typeface;->nativeCreateFromArray([JII)J
-Landroid/graphics/Typeface;->nativeCreateWeightAlias(JI)J
-Landroid/graphics/Typeface;->native_instance:J
-Landroid/graphics/Typeface;->sDefaults:[Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->setDefault(Landroid/graphics/Typeface;)V
-Landroid/graphics/Typeface;->sSystemFallbackMap:Ljava/util/Map;
-Landroid/graphics/Typeface;->sSystemFontMap:Ljava/util/Map;
-Landroid/graphics/Xfermode;->porterDuffMode:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_GOOD:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_IMAGER_DIRTY:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_INSUFFICIENT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_PARTIAL:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_TOO_FAST:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_TOO_SLOW:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_CANCELED:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_HW_NOT_PRESENT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_HW_UNAVAILABLE:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_LOCKOUT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_LOCKOUT_PERMANENT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_NO_BIOMETRICS:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_NO_SPACE:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_TIMEOUT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_UNABLE_TO_PROCESS:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_USER_CANCELED:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_VENDOR:I
Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_VENDOR_BASE:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_GOOD:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_IMAGER_DIRTY:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_INSUFFICIENT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_PARTIAL:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_TOO_FAST:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_TOO_SLOW:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_CANCELED:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_HW_NOT_PRESENT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_HW_UNAVAILABLE:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_LOCKOUT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_LOCKOUT_PERMANENT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_NO_FINGERPRINTS:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_NO_SPACE:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_TIMEOUT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_UNABLE_TO_PROCESS:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_USER_CANCELED:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_VENDOR:I
Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_VENDOR_BASE:I
Landroid/hardware/Camera$Parameters;->copyFrom(Landroid/hardware/Camera$Parameters;)V
Landroid/hardware/Camera$Parameters;->dump()V
@@ -2615,7 +2347,6 @@
Landroid/icu/text/Transliterator;->transliterate(Landroid/icu/text/Replaceable;Landroid/icu/text/Transliterator$Position;Ljava/lang/String;)V
Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String;
Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/UForwardCharacterIterator;->DONE:I
Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
Landroid/icu/util/PersianCalendar;-><init>(Ljava/util/Locale;)V
Landroid/icu/util/UResourceBundle;->getBundleInstance(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/util/UResourceBundle;
@@ -2624,26 +2355,6 @@
Landroid/icu/util/UResourceBundle;->getType()I
Landroid/icu/util/UResourceBundleIterator;->hasNext()Z
Landroid/icu/util/UResourceBundleIterator;->next()Landroid/icu/util/UResourceBundle;
-Landroid/inputmethodservice/InputMethodService$SettingsObserver;->shouldShowImeWithHardKeyboard()Z
-Landroid/inputmethodservice/InputMethodService;->mExtractEditText:Landroid/inputmethodservice/ExtractEditText;
-Landroid/inputmethodservice/InputMethodService;->mExtractView:Landroid/view/View;
-Landroid/inputmethodservice/InputMethodService;->mRootView:Landroid/view/View;
-Landroid/inputmethodservice/InputMethodService;->mSettingsObserver:Landroid/inputmethodservice/InputMethodService$SettingsObserver;
-Landroid/inputmethodservice/InputMethodService;->mTheme:I
-Landroid/inputmethodservice/InputMethodService;->mTmpInsets:Landroid/inputmethodservice/InputMethodService$Insets;
-Landroid/inputmethodservice/InputMethodService;->onExtractedDeleteText(II)V
-Landroid/inputmethodservice/InputMethodService;->onExtractedReplaceText(IILjava/lang/CharSequence;)V
-Landroid/inputmethodservice/InputMethodService;->onExtractedSetSpan(Ljava/lang/Object;III)V
-Landroid/inputmethodservice/Keyboard;->mModifierKeys:Ljava/util/List;
-Landroid/inputmethodservice/Keyboard;->mTotalHeight:I
-Landroid/inputmethodservice/Keyboard;->mTotalWidth:I
-Landroid/inputmethodservice/Keyboard;->resize(II)V
-Landroid/inputmethodservice/KeyboardView;->mKeyBackground:Landroid/graphics/drawable/Drawable;
-Landroid/inputmethodservice/KeyboardView;->mLabelTextSize:I
-Landroid/inputmethodservice/KeyboardView;->mPreviewText:Landroid/widget/TextView;
-Landroid/inputmethodservice/KeyboardView;->openPopupIfRequired(Landroid/view/MotionEvent;)Z
-Landroid/inputmethodservice/KeyboardView;->repeatKey()Z
-Landroid/inputmethodservice/KeyboardView;->showKey(I)V
Landroid/location/Country;-><init>(Ljava/lang/String;I)V
Landroid/location/Country;->getCountryIso()Ljava/lang/String;
Landroid/location/Country;->getSource()I
@@ -3143,81 +2854,6 @@
Landroid/media/TimedText;->getObject(I)Ljava/lang/Object;
Landroid/media/ToneGenerator;->mNativeContext:J
Landroid/media/TtmlRenderer;-><init>(Landroid/content/Context;)V
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_16_9:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_1_1:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_2_3:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_3_2:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_4_3:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->AVAILABILITY_AVAILABLE:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->AVAILABILITY_FREE_WITH_SUBSCRIPTION:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->AVAILABILITY_PAID_CONTENT:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_AUTHOR:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_AVAILABILITY:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_BROWSABLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_CONTENT_ID:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_DURATION_MILLIS:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTENT_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTERACTION_COUNT:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTERACTION_TYPE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTERNAL_PROVIDER_ID:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_ITEM_COUNT:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_LAST_PLAYBACK_POSITION_MILLIS:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_LIVE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_LOGO_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_OFFER_PRICE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_POSTER_ART_ASPECT_RATIO:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_PREVIEW_VIDEO_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_RELEASE_DATE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_STARTING_PRICE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_THUMBNAIL_ASPECT_RATIO:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_TRANSIENT:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_TYPE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_FANS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_FOLLOWERS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_LIKES:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_LISTENS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_THUMBS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_VIEWERS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_VIEWS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_ALBUM:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_ARTIST:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_CHANNEL:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_CLIP:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_EVENT:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_MOVIE:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_PLAYLIST:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_STATION:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TRACK:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TV_EPISODE:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TV_SEASON:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TV_SERIES:I
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_AUDIO_LANGUAGE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_CANONICAL_GENRE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_CONTENT_RATING:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_EPISODE_DISPLAY_NUMBER:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_EPISODE_TITLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_DATA:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG1:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG2:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG3:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG4:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_LONG_DESCRIPTION:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_POSTER_ART_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_REVIEW_RATING:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_REVIEW_RATING_STYLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SEARCHABLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SEASON_DISPLAY_NUMBER:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SEASON_TITLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SERIES_ID:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SHORT_DESCRIPTION:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_THUMBNAIL_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_TITLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_VERSION_NUMBER:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_VIDEO_HEIGHT:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_VIDEO_WIDTH:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->REVIEW_RATING_STYLE_PERCENTAGE:I
-Landroid/media/tv/TvContract$ProgramColumns;->REVIEW_RATING_STYLE_STARS:I
-Landroid/media/tv/TvContract$ProgramColumns;->REVIEW_RATING_STYLE_THUMBS_UP_DOWN:I
Landroid/media/tv/TvInputInfo;->getComponent()Landroid/content/ComponentName;
Landroid/media/tv/TvInputService$Session;->mOverlayFrame:Landroid/graphics/Rect;
Landroid/media/VolumeShaper$Configuration;-><init>(IIIDI[F[F)V
@@ -3709,28 +3345,6 @@
Landroid/net/wifi/WifiSsid;->getOctets()[B
Landroid/net/wifi/WifiSsid;->NONE:Ljava/lang/String;
Landroid/net/wifi/WifiSsid;->octets:Ljava/io/ByteArrayOutputStream;
-Landroid/nfc/cardemulation/AidGroup;-><init>(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/nfc/cardemulation/AidGroup;->aids:Ljava/util/List;
-Landroid/nfc/cardemulation/AidGroup;->category:Ljava/lang/String;
-Landroid/nfc/cardemulation/AidGroup;->createFromXml(Lorg/xmlpull/v1/XmlPullParser;)Landroid/nfc/cardemulation/AidGroup;
-Landroid/nfc/cardemulation/AidGroup;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/nfc/cardemulation/AidGroup;->description:Ljava/lang/String;
-Landroid/nfc/cardemulation/AidGroup;->getAids()Ljava/util/List;
-Landroid/nfc/cardemulation/AidGroup;->getCategory()Ljava/lang/String;
-Landroid/nfc/cardemulation/AidGroup;->writeAsXml(Lorg/xmlpull/v1/XmlSerializer;)V
-Landroid/nfc/cardemulation/ApduServiceInfo;-><init>(Landroid/content/pm/PackageManager;Landroid/content/pm/ResolveInfo;Z)V
-Landroid/nfc/cardemulation/ApduServiceInfo;-><init>(Landroid/content/pm/ResolveInfo;ZLjava/lang/String;Ljava/util/ArrayList;Ljava/util/ArrayList;ZIILjava/lang/String;)V
-Landroid/nfc/cardemulation/ApduServiceInfo;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/nfc/cardemulation/ApduServiceInfo;->getDescription()Ljava/lang/String;
-Landroid/nfc/cardemulation/ApduServiceInfo;->getSettingsActivityName()Ljava/lang/String;
-Landroid/nfc/cardemulation/ApduServiceInfo;->getUid()I
-Landroid/nfc/cardemulation/ApduServiceInfo;->isOnHost()Z
-Landroid/nfc/cardemulation/ApduServiceInfo;->loadBanner(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
-Landroid/nfc/cardemulation/ApduServiceInfo;->mDynamicAidGroups:Ljava/util/HashMap;
-Landroid/nfc/cardemulation/ApduServiceInfo;->mService:Landroid/content/pm/ResolveInfo;
-Landroid/nfc/cardemulation/ApduServiceInfo;->mStaticAidGroups:Ljava/util/HashMap;
-Landroid/nfc/cardemulation/ApduServiceInfo;->requiresUnlock()Z
-Landroid/nfc/ErrorCodes;->isError(I)Z
Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I
Landroid/nfc/INfcAdapterExtras;->authenticate(Ljava/lang/String;[B)V
Landroid/nfc/INfcAdapterExtras;->close(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle;
@@ -3739,21 +3353,6 @@
Landroid/nfc/INfcAdapterExtras;->open(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle;
Landroid/nfc/INfcAdapterExtras;->setCardEmulationRoute(Ljava/lang/String;I)V
Landroid/nfc/INfcAdapterExtras;->transceive(Ljava/lang/String;[B)Landroid/os/Bundle;
-Landroid/nfc/NdefRecord;->mId:[B
-Landroid/nfc/NfcActivityManager;->mAdapter:Landroid/nfc/NfcAdapter;
-Landroid/nfc/NfcAdapter;->attemptDeadServiceRecovery(Ljava/lang/Exception;)V
-Landroid/nfc/NfcAdapter;->getAdapterState()I
-Landroid/nfc/NfcAdapter;->getContext()Landroid/content/Context;
-Landroid/nfc/NfcAdapter;->getDefaultAdapter()Landroid/nfc/NfcAdapter;
-Landroid/nfc/NfcAdapter;->getNfcAdapter(Landroid/content/Context;)Landroid/nfc/NfcAdapter;
-Landroid/nfc/NfcAdapter;->getNfcAdapterExtrasInterface()Landroid/nfc/INfcAdapterExtras;
-Landroid/nfc/NfcAdapter;->getService()Landroid/nfc/INfcAdapter;
-Landroid/nfc/NfcAdapter;->setNdefPushMessageCallback(Landroid/nfc/NfcAdapter$CreateNdefMessageCallback;Landroid/app/Activity;I)V
-Landroid/nfc/NfcAdapter;->sService:Landroid/nfc/INfcAdapter;
-Landroid/nfc/NfcManager;-><init>(Landroid/content/Context;)V
-Landroid/nfc/Tag;->getServiceHandle()I
-Landroid/nfc/Tag;->getTagService()Landroid/nfc/INfcTag;
-Landroid/nfc/Tag;->mId:[B
Landroid/opengl/EGL14;->eglGetDisplay(J)Landroid/opengl/EGLDisplay;
Landroid/opengl/GLES20;->glGetActiveAttrib(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;B)V
Landroid/opengl/GLES20;->glGetActiveUniform(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;B)V
@@ -4445,9 +4044,6 @@
Landroid/provider/CalendarContract$CalendarAlerts;->rescheduleMissedAlarms(Landroid/content/ContentResolver;Landroid/content/Context;Landroid/app/AlarmManager;)V
Landroid/provider/CalendarContract$CalendarAlerts;->scheduleAlarm(Landroid/content/Context;Landroid/app/AlarmManager;J)V
Landroid/provider/CallLog$Calls;->addCall(Lcom/android/internal/telephony/CallerInfo;Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILandroid/telecom/PhoneAccountHandle;JILjava/lang/Long;ZLandroid/os/UserHandle;Z)Landroid/net/Uri;
-Landroid/provider/ContactsContract$ContactCounts;->EXTRA_ADDRESS_BOOK_INDEX:Ljava/lang/String;
-Landroid/provider/ContactsContract$ContactCounts;->EXTRA_ADDRESS_BOOK_INDEX_COUNTS:Ljava/lang/String;
-Landroid/provider/ContactsContract$ContactCounts;->EXTRA_ADDRESS_BOOK_INDEX_TITLES:Ljava/lang/String;
Landroid/provider/ContactsContract$Contacts$AggregationSuggestions;->builder()Landroid/provider/ContactsContract$Contacts$AggregationSuggestions$Builder;
Landroid/provider/ContactsContract$Contacts;->CORP_CONTENT_URI:Landroid/net/Uri;
Landroid/provider/ContactsContract$QuickContact;->composeQuickContactsIntent(Landroid/content/Context;Landroid/graphics/Rect;Landroid/net/Uri;I[Ljava/lang/String;)Landroid/content/Intent;
@@ -4971,7 +4567,7 @@
Landroid/renderscript/RSSurfaceView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
Landroid/renderscript/Script$Builder;-><init>(Landroid/renderscript/RenderScript;)V
Landroid/renderscript/Script$Builder;->mRS:Landroid/renderscript/RenderScript;
-Landroid/security/Credentials;->convertToPem([[Ljava/security/cert/Certificate;)[B
+Landroid/security/Credentials;->convertToPem([Ljava/security/cert/Certificate;)[B
Landroid/security/Credentials;->getInstance()Landroid/security/Credentials;
Landroid/security/Credentials;->install(Landroid/content/Context;Ljava/lang/String;[B)V
Landroid/security/Credentials;->install(Landroid/content/Context;Ljava/security/KeyPair;)V
@@ -5838,21 +5434,6 @@
Landroid/view/AccessibilityIterators$AbstractTextSegmentIterator;->mText:Ljava/lang/String;
Landroid/view/ActionProvider;->reset()V
Landroid/view/ActionProvider;->setSubUiVisibilityListener(Landroid/view/ActionProvider$SubUiVisibilityListener;)V
-Landroid/view/animation/Animation;->detach()V
-Landroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V
-Landroid/view/animation/Animation;->initializeInvalidateRegion(IIII)V
-Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener;
-Landroid/view/animation/Animation;->mPreviousRegion:Landroid/graphics/RectF;
-Landroid/view/animation/Animation;->mPreviousTransformation:Landroid/view/animation/Transformation;
-Landroid/view/animation/Animation;->mRegion:Landroid/graphics/RectF;
-Landroid/view/animation/Animation;->mTransformation:Landroid/view/animation/Transformation;
-Landroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/view/animation/AnimationSet;Landroid/util/AttributeSet;)Landroid/view/animation/Animation;
-Landroid/view/animation/Transformation;->printShortString(Ljava/io/PrintWriter;)V
-Landroid/view/animation/TranslateAnimation;->mFromXValue:F
-Landroid/view/animation/TranslateAnimation;->mFromYValue:F
-Landroid/view/animation/TranslateAnimation;->mToXValue:F
-Landroid/view/animation/TranslateAnimation;->mToYValue:F
-Landroid/view/animation/TranslateYAnimation;-><init>(IFIF)V
Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager;
Landroid/view/Choreographer$CallbackQueue;->addCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)V
@@ -6649,7 +6230,6 @@
Landroid/webkit/WebResourceResponse;->mImmutable:Z
Landroid/webkit/WebResourceResponse;->mStatusCode:I
Landroid/webkit/WebSettings$TextSize;->value:I
-Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler;
Landroid/webkit/WebSyncManager;->syncFromRamToFlash()V
Landroid/webkit/WebView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;IILjava/util/Map;Z)V
Landroid/webkit/WebView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;ILjava/util/Map;Z)V
@@ -7322,73 +6902,6 @@
Lcom/android/ims/internal/IImsVideoCallCallback;->receiveSessionModifyResponse(ILandroid/telecom/VideoProfile;Landroid/telecom/VideoProfile;)V
Lcom/android/ims/internal/IImsVideoCallProvider$Stub;-><init>()V
Lcom/android/ims/internal/IImsVideoCallProvider;->setCallback(Lcom/android/ims/internal/IImsVideoCallCallback;)V
-Lcom/android/ims/internal/uce/common/CapInfo;-><init>()V
-Lcom/android/ims/internal/uce/common/CapInfo;->setCapTimestamp(J)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setCdViaPresenceSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setExts([Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtHttpSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtSnFSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtThumbSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFullSnFGroupChatSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setGeoPullFtSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setGeoPullSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setGeoPushSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setImSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setIpVideoSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setIpVoiceSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setIsSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setRcsIpVideoCallSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setRcsIpVideoOnlyCallSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setRcsIpVoiceCallSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setSmSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setSpSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setVsDuringCSSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setVsSupported(Z)V
-Lcom/android/ims/internal/uce/common/StatusCode;-><init>()V
-Lcom/android/ims/internal/uce/common/StatusCode;->setStatusCode(I)V
-Lcom/android/ims/internal/uce/common/UceLong;->getUceLong()J
-Lcom/android/ims/internal/uce/common/UceLong;->setUceLong(J)V
-Lcom/android/ims/internal/uce/presence/PresCmdId;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresCmdId;->setCmdId(I)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setCmdId(Lcom/android/ims/internal/uce/presence/PresCmdId;)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setRequestId(I)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setStatus(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setUserData(I)V
-Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;->setPublishTrigeerType(I)V
-Lcom/android/ims/internal/uce/presence/PresResInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresResInfo;->setDisplayName(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInfo;->setInstanceInfo(Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;)V
-Lcom/android/ims/internal/uce/presence/PresResInfo;->setResUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setPresentityUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setReason(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setResId(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setResInstanceState(I)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setTupleInfo([Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setFullState(Z)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setListName(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setPresSubscriptionState(Lcom/android/ims/internal/uce/presence/PresSubscriptionState;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setRequestId(I)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setSubscriptionExpireTime(I)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setSubscriptionTerminatedReason(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setVersion(I)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setCmdId(Lcom/android/ims/internal/uce/presence/PresCmdId;)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setReasonPhrase(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setRequestId(I)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setRetryAfter(I)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setSipResponseCode(I)V
-Lcom/android/ims/internal/uce/presence/PresSubscriptionState;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresSubscriptionState;->setPresSubscriptionState(I)V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setContactUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setFeatureTag(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setTimestamp(Ljava/lang/String;)V
Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
Lcom/android/internal/app/AlertController$AlertParams;-><init>(Landroid/content/Context;)V
Lcom/android/internal/app/AlertController$AlertParams;->apply(Lcom/android/internal/app/AlertController;)V
@@ -8351,6 +7864,7 @@
Lcom/android/internal/util/AsyncChannel;->sendMessageSynchronously(Landroid/os/Message;)Landroid/os/Message;
Lcom/android/internal/util/AsyncChannel;->STATUS_SUCCESSFUL:I
Lcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;)V
+Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String;
Lcom/android/internal/util/XmlUtils;->convertValueToBoolean(Ljava/lang/CharSequence;Z)Z
Lcom/android/internal/util/XmlUtils;->convertValueToInt(Ljava/lang/CharSequence;I)I
Lcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
@@ -8440,6 +7954,7 @@
Lcom/android/internal/widget/IRemoteViewsFactory;->hasStableIds()Z
Lcom/android/internal/widget/IRemoteViewsFactory;->isCreated()Z
Lcom/android/internal/widget/IRemoteViewsFactory;->onDataSetChanged()V
+Lcom/android/internal/widget/ScrollBarUtils;->getThumbLength(IIII)I
Lcom/android/internal/widget/ScrollingTabContainerView;-><init>(Landroid/content/Context;)V
Lcom/android/internal/widget/ScrollingTabContainerView;->addTab(Landroid/app/ActionBar$Tab;IZ)V
Lcom/android/internal/widget/ScrollingTabContainerView;->addTab(Landroid/app/ActionBar$Tab;Z)V
@@ -8511,6 +8026,8 @@
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setNpnProtocols([B)V
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setSoWriteTimeout(I)V
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V
+Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setHostname(Ljava/lang/String;)V
+Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setUseSessionTickets(Z)V
Lcom/android/org/conscrypt/ConscryptSocketBase;->getHostname()Ljava/lang/String;
Lcom/android/org/conscrypt/ConscryptSocketBase;->getHostnameOrIP()Ljava/lang/String;
Lcom/android/org/conscrypt/ConscryptSocketBase;->getSoWriteTimeout()I
@@ -8980,46 +8497,6 @@
Ljava/util/zip/Inflater;->len:I
Ljava/util/zip/Inflater;->needDict:Z
Ljava/util/zip/Inflater;->off:I
-Ljava/util/zip/ZipConstants;->CENATT:I
-Ljava/util/zip/ZipConstants;->CENATX:I
-Ljava/util/zip/ZipConstants;->CENCOM:I
-Ljava/util/zip/ZipConstants;->CENCRC:I
-Ljava/util/zip/ZipConstants;->CENDSK:I
-Ljava/util/zip/ZipConstants;->CENEXT:I
-Ljava/util/zip/ZipConstants;->CENFLG:I
-Ljava/util/zip/ZipConstants;->CENHDR:I
-Ljava/util/zip/ZipConstants;->CENHOW:I
-Ljava/util/zip/ZipConstants;->CENLEN:I
-Ljava/util/zip/ZipConstants;->CENNAM:I
-Ljava/util/zip/ZipConstants;->CENOFF:I
-Ljava/util/zip/ZipConstants;->CENSIG:J
-Ljava/util/zip/ZipConstants;->CENSIZ:I
-Ljava/util/zip/ZipConstants;->CENTIM:I
-Ljava/util/zip/ZipConstants;->CENVEM:I
-Ljava/util/zip/ZipConstants;->CENVER:I
-Ljava/util/zip/ZipConstants;->ENDCOM:I
-Ljava/util/zip/ZipConstants;->ENDHDR:I
-Ljava/util/zip/ZipConstants;->ENDOFF:I
-Ljava/util/zip/ZipConstants;->ENDSIG:J
-Ljava/util/zip/ZipConstants;->ENDSIZ:I
-Ljava/util/zip/ZipConstants;->ENDSUB:I
-Ljava/util/zip/ZipConstants;->ENDTOT:I
-Ljava/util/zip/ZipConstants;->EXTCRC:I
-Ljava/util/zip/ZipConstants;->EXTHDR:I
-Ljava/util/zip/ZipConstants;->EXTLEN:I
-Ljava/util/zip/ZipConstants;->EXTSIG:J
-Ljava/util/zip/ZipConstants;->EXTSIZ:I
-Ljava/util/zip/ZipConstants;->LOCCRC:I
-Ljava/util/zip/ZipConstants;->LOCEXT:I
-Ljava/util/zip/ZipConstants;->LOCFLG:I
-Ljava/util/zip/ZipConstants;->LOCHDR:I
-Ljava/util/zip/ZipConstants;->LOCHOW:I
-Ljava/util/zip/ZipConstants;->LOCLEN:I
-Ljava/util/zip/ZipConstants;->LOCNAM:I
-Ljava/util/zip/ZipConstants;->LOCSIG:J
-Ljava/util/zip/ZipConstants;->LOCSIZ:I
-Ljava/util/zip/ZipConstants;->LOCTIM:I
-Ljava/util/zip/ZipConstants;->LOCVER:I
Ljava/util/zip/ZipEntry;-><init>(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V
Ljava/util/zip/ZipEntry;->method:I
Ljava/util/zip/ZipFile;->close(J)V
@@ -9034,6 +8511,16 @@
Ljavax/net/ssl/SSLServerSocketFactory;->defaultServerSocketFactory:Ljavax/net/ssl/SSLServerSocketFactory;
Ljavax/net/ssl/SSLSocketFactory;->createSocket(Ljava/net/Socket;Ljava/io/InputStream;Z)Ljava/net/Socket;
Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
+Llibcore/icu/ICU;->addLikelySubtags(Ljava/util/Locale;)Ljava/util/Locale;
+Llibcore/io/Memory;->peekByte(J)B
+Llibcore/io/Memory;->peekByteArray(J[BII)V
+Llibcore/io/Memory;->peekInt(JZ)I
+Llibcore/io/Memory;->peekLong(JZ)J
+Llibcore/io/Memory;->pokeByte(JB)V
+Llibcore/io/Memory;->pokeByteArray(J[BII)V
+Llibcore/io/Memory;->pokeInt(JIZ)V
+Llibcore/io/Memory;->pokeLong(JJZ)V
+Llibcore/io/Streams;->copy(Ljava/io/InputStream;Ljava/io/OutputStream;)I
Llibcore/util/BasicLruCache;->map:Ljava/util/LinkedHashMap;
Llibcore/util/ZoneInfo;->mTransitions:[J
Lorg/apache/http/conn/ssl/AbstractVerifier;->BAD_COUNTRY_2LDS:[Ljava/lang/String;
@@ -9056,6 +8543,8 @@
Lorg/ccil/cowan/tagsoup/ElementType;->theNamespace:Ljava/lang/String;
Lorg/ccil/cowan/tagsoup/ElementType;->theParent:Lorg/ccil/cowan/tagsoup/ElementType;
Lorg/ccil/cowan/tagsoup/ElementType;->theSchema:Lorg/ccil/cowan/tagsoup/Schema;
+Lorg/ccil/cowan/tagsoup/HTMLSchema;-><init>()V
+Lorg/ccil/cowan/tagsoup/Parser;-><init>()V
Lorg/ccil/cowan/tagsoup/Schema;->theElementTypes:Ljava/util/HashMap;
Lorg/ccil/cowan/tagsoup/Schema;->theEntities:Ljava/util/HashMap;
Lorg/ccil/cowan/tagsoup/Schema;->thePrefix:Ljava/lang/String;
@@ -9155,10 +8644,84 @@
Lorg/xml/sax/SAXParseException;->lineNumber:I
Lorg/xml/sax/SAXParseException;->publicId:Ljava/lang/String;
Lorg/xml/sax/SAXParseException;->systemId:Ljava/lang/String;
+Lsun/misc/Cleaner;->clean()V
+Lsun/misc/Unsafe;->addressSize()I
+Lsun/misc/Unsafe;->allocateInstance(Ljava/lang/Class;)Ljava/lang/Object;
+Lsun/misc/Unsafe;->allocateMemory(J)J
+Lsun/misc/Unsafe;->arrayBaseOffset(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->arrayIndexScale(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->compareAndSwapInt(Ljava/lang/Object;JII)Z
+Lsun/misc/Unsafe;->compareAndSwapLong(Ljava/lang/Object;JJJ)Z
+Lsun/misc/Unsafe;->compareAndSwapObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
+Lsun/misc/Unsafe;->copyMemory(JJJ)V
+Lsun/misc/Unsafe;->copyMemoryFromPrimitiveArray(Ljava/lang/Object;JJJ)V
+Lsun/misc/Unsafe;->copyMemoryToPrimitiveArray(JLjava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->freeMemory(J)V
+Lsun/misc/Unsafe;->fullFence()V
+Lsun/misc/Unsafe;->getAndAddInt(Ljava/lang/Object;JI)I
+Lsun/misc/Unsafe;->getAndAddLong(Ljava/lang/Object;JJ)J
+Lsun/misc/Unsafe;->getAndSetInt(Ljava/lang/Object;JI)I
+Lsun/misc/Unsafe;->getAndSetLong(Ljava/lang/Object;JJ)J
+Lsun/misc/Unsafe;->getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;
+Lsun/misc/Unsafe;->getArrayBaseOffsetForComponentType(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->getArrayIndexScaleForComponentType(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->getBoolean(Ljava/lang/Object;J)Z
+Lsun/misc/Unsafe;->getByte(J)B
+Lsun/misc/Unsafe;->getByte(Ljava/lang/Object;J)B
+Lsun/misc/Unsafe;->getChar(J)C
+Lsun/misc/Unsafe;->getChar(Ljava/lang/Object;J)C
+Lsun/misc/Unsafe;->getDouble(J)D
+Lsun/misc/Unsafe;->getDouble(Ljava/lang/Object;J)D
+Lsun/misc/Unsafe;->getFloat(J)F
+Lsun/misc/Unsafe;->getFloat(Ljava/lang/Object;J)F
+Lsun/misc/Unsafe;->getInt(J)I
+Lsun/misc/Unsafe;->getInt(Ljava/lang/Object;J)I
+Lsun/misc/Unsafe;->getIntVolatile(Ljava/lang/Object;J)I
+Lsun/misc/Unsafe;->getLong(J)J
+Lsun/misc/Unsafe;->getLong(Ljava/lang/Object;J)J
+Lsun/misc/Unsafe;->getLongVolatile(Ljava/lang/Object;J)J
+Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object;
+Lsun/misc/Unsafe;->getObjectVolatile(Ljava/lang/Object;J)Ljava/lang/Object;
+Lsun/misc/Unsafe;->getShort(J)S
+Lsun/misc/Unsafe;->getShort(Ljava/lang/Object;J)S
+Lsun/misc/Unsafe;->getUnsafe()Lsun/misc/Unsafe;
+Lsun/misc/Unsafe;->INVALID_FIELD_OFFSET:I
+Lsun/misc/Unsafe;->loadFence()V
+Lsun/misc/Unsafe;->objectFieldOffset(Ljava/lang/reflect/Field;)J
+Lsun/misc/Unsafe;->pageSize()I
+Lsun/misc/Unsafe;->park(ZJ)V
+Lsun/misc/Unsafe;->putBoolean(Ljava/lang/Object;JZ)V
+Lsun/misc/Unsafe;->putByte(JB)V
+Lsun/misc/Unsafe;->putByte(Ljava/lang/Object;JB)V
+Lsun/misc/Unsafe;->putChar(JC)V
+Lsun/misc/Unsafe;->putChar(Ljava/lang/Object;JC)V
+Lsun/misc/Unsafe;->putDouble(JD)V
+Lsun/misc/Unsafe;->putDouble(Ljava/lang/Object;JD)V
+Lsun/misc/Unsafe;->putFloat(JF)V
+Lsun/misc/Unsafe;->putFloat(Ljava/lang/Object;JF)V
+Lsun/misc/Unsafe;->putInt(JI)V
+Lsun/misc/Unsafe;->putInt(Ljava/lang/Object;JI)V
+Lsun/misc/Unsafe;->putIntVolatile(Ljava/lang/Object;JI)V
+Lsun/misc/Unsafe;->putLong(JJ)V
+Lsun/misc/Unsafe;->putLong(Ljava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->putLongVolatile(Ljava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->putObject(Ljava/lang/Object;JLjava/lang/Object;)V
+Lsun/misc/Unsafe;->putObjectVolatile(Ljava/lang/Object;JLjava/lang/Object;)V
+Lsun/misc/Unsafe;->putOrderedInt(Ljava/lang/Object;JI)V
+Lsun/misc/Unsafe;->putOrderedLong(Ljava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->putOrderedObject(Ljava/lang/Object;JLjava/lang/Object;)V
+Lsun/misc/Unsafe;->putShort(JS)V
+Lsun/misc/Unsafe;->putShort(Ljava/lang/Object;JS)V
+Lsun/misc/Unsafe;->setMemory(JJB)V
+Lsun/misc/Unsafe;->storeFence()V
Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe;
Lsun/misc/Unsafe;->THE_ONE:Lsun/misc/Unsafe;
+Lsun/misc/Unsafe;->unpark(Ljava/lang/Object;)V
Lsun/misc/URLClassPath$JarLoader;->getJarFile()Ljava/util/jar/JarFile;
Lsun/misc/URLClassPath;->lmap:Ljava/util/HashMap;
Lsun/misc/URLClassPath;->loaders:Ljava/util/ArrayList;
Lsun/misc/URLClassPath;->urls:Ljava/util/Stack;
+Lsun/nio/ch/DirectBuffer;->cleaner()Lsun/misc/Cleaner;
+Lsun/security/x509/AlgorithmId;->get(Ljava/lang/String;)Lsun/security/x509/AlgorithmId;
+Lsun/security/x509/AlgorithmId;->getName()Ljava/lang/String;
Lsun/security/x509/AVA;->hasRFC2253Keyword()Z
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index f1e700b..b8c1468 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -93,10 +93,6 @@
Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
Landroid/database/sqlite/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
Landroid/database/sqlite/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-Landroid/graphics/Bitmap;->createGraphicBufferHandle()Landroid/graphics/GraphicBuffer;
-Landroid/graphics/Bitmap;->createHardwareBitmap(Landroid/graphics/GraphicBuffer;)Landroid/graphics/Bitmap;
-Landroid/graphics/drawable/Drawable;->isProjected()Z
-Landroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
Landroid/hardware/display/DisplayManagerGlobal;->getInstance()Landroid/hardware/display/DisplayManagerGlobal;
Landroid/hardware/display/DisplayManagerGlobal;->getRealDisplay(I)Landroid/view/Display;
@@ -609,31 +605,6 @@
Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueryFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdated(Lcom/android/ims/internal/IImsUt;I)V
Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdateFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/uce/common/CapInfo;->getCapTimestamp()J
-Lcom/android/ims/internal/uce/common/CapInfo;->isCdViaPresenceSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtHttpSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtSnFSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtThumbSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFullSnFGroupChatSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isGeoPullFtSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isGeoPullSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isGeoPushSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isImSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isIpVideoSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isIpVoiceSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isIsSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isRcsIpVideoCallSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isRcsIpVideoOnlyCallSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isRcsIpVoiceCallSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isSmSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isSpSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isVsDuringCSSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isVsSupported()Z
-Lcom/android/ims/internal/uce/common/StatusCode;->getStatusCode()I
-Lcom/android/ims/internal/uce/common/UceLong;-><init>()V
-Lcom/android/ims/internal/uce/common/UceLong;->getClientId()I
-Lcom/android/ims/internal/uce/common/UceLong;->setClientId(I)V
Lcom/android/ims/internal/uce/options/IOptionsListener;->cmdStatus(Lcom/android/ims/internal/uce/options/OptionsCmdStatus;)V
Lcom/android/ims/internal/uce/options/IOptionsListener;->getVersionCb(Ljava/lang/String;)V
Lcom/android/ims/internal/uce/options/IOptionsListener;->incomingOptions(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;I)V
@@ -649,24 +620,6 @@
Lcom/android/ims/internal/uce/options/IOptionsService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/options/IOptionsService;->responseIncomingOptions(IIILjava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;Z)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/options/IOptionsService;->setMyInfo(ILcom/android/ims/internal/uce/common/CapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->getCapInfo()Lcom/android/ims/internal/uce/common/CapInfo;
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->getSdp()Ljava/lang/String;
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->setCapInfo(Lcom/android/ims/internal/uce/common/CapInfo;)V
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->setSdp(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdId;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsCmdId;->setCmdId(I)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setCapInfo(Lcom/android/ims/internal/uce/common/CapInfo;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setCmdId(Lcom/android/ims/internal/uce/options/OptionsCmdId;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setStatus(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setUserData(I)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setCmdId(Lcom/android/ims/internal/uce/options/OptionsCmdId;)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setReasonPhrase(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setRequestId(I)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setRetryAfter(I)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setSipResponseCode(I)V
Lcom/android/ims/internal/uce/presence/IPresenceListener;->capInfoReceived(Ljava/lang/String;[Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
Lcom/android/ims/internal/uce/presence/IPresenceListener;->cmdStatus(Lcom/android/ims/internal/uce/presence/PresCmdStatus;)V
Lcom/android/ims/internal/uce/presence/IPresenceListener;->getVersionCb(Ljava/lang/String;)V
@@ -685,18 +638,6 @@
Lcom/android/ims/internal/uce/presence/IPresenceService;->reenableService(II)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/presence/IPresenceService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjava/lang/String;Lcom/android/ims/internal/uce/presence/PresServiceInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/PresCapInfo;->getCapInfo()Lcom/android/ims/internal/uce/common/CapInfo;
-Lcom/android/ims/internal/uce/presence/PresCapInfo;->getContactUri()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresCapInfo;->mContactUri:Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getMediaType()I
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceDesc()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceId()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceVer()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getCmdId()Lcom/android/ims/internal/uce/presence/PresCmdId;
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getReasonPhrase()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getRequestId()I
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getRetryAfter()I
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getSipResponseCode()I
Lcom/android/ims/internal/uce/uceservice/IUceListener;->setStatus(I)V
Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
Lcom/android/ims/internal/uce/uceservice/IUceService;->createOptionsService(Lcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)I
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 300a530..5b73eaa 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.UnsupportedAppUsage;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -442,8 +443,10 @@
private int mConnectionId = AccessibilityInteractionClient.NO_ID;
+ @UnsupportedAppUsage
private AccessibilityServiceInfo mInfo;
+ @UnsupportedAppUsage
private IBinder mWindowToken;
private WindowManager mWindowManager;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index ed684d7..be2e2fa 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -19,6 +19,7 @@
import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
import android.annotation.IntDef;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -695,6 +696,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setCapabilities(int capabilities) {
mCapabilities = capabilities;
}
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 4ebcc44..17d54d2 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -17,6 +17,7 @@
package android.animation;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ConstantState;
@@ -460,6 +461,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void reverse() {
throw new IllegalStateException("Reverse is not supported");
}
diff --git a/core/java/android/animation/ArgbEvaluator.java b/core/java/android/animation/ArgbEvaluator.java
index a96bee6..5b69d18 100644
--- a/core/java/android/animation/ArgbEvaluator.java
+++ b/core/java/android/animation/ArgbEvaluator.java
@@ -16,6 +16,8 @@
package android.animation;
+import android.annotation.UnsupportedAppUsage;
+
/**
* This evaluator can be used to perform type interpolation between integer
* values that represent ARGB colors.
@@ -31,6 +33,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static ArgbEvaluator getInstance() {
return sInstance;
}
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 5a23fdd..5b3813d 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -16,6 +16,7 @@
package android.animation;
+import android.annotation.UnsupportedAppUsage;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -1070,6 +1071,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void cancel() {
if (currentChangingAnimations.size() > 0) {
LinkedHashMap<View, Animator> currentAnimCopy =
@@ -1105,6 +1107,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void cancel(int transitionType) {
switch (transitionType) {
case CHANGE_APPEARING:
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index cc95eb6..a0464df 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -19,6 +19,7 @@
import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.os.Looper;
import android.os.Trace;
import android.util.AndroidRuntimeException;
@@ -75,6 +76,7 @@
/**
* Internal constants
*/
+ @UnsupportedAppUsage
private static float sDurationScale = 1.0f;
/**
@@ -200,6 +202,7 @@
//
// How long the animation should last in ms
+ @UnsupportedAppUsage
private long mDuration = 300;
// The amount of time in ms to delay starting the animation after start() is called. Note
@@ -1534,6 +1537,7 @@
* @param fraction The elapsed fraction of the animation.
*/
@CallSuper
+ @UnsupportedAppUsage
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction);
mCurrentFraction = fraction;
diff --git a/core/java/android/app/IBackupAgent.aidl b/core/java/android/app/IBackupAgent.aidl
index 3aeef14..4517446 100644
--- a/core/java/android/app/IBackupAgent.aidl
+++ b/core/java/android/app/IBackupAgent.aidl
@@ -16,6 +16,7 @@
package android.app;
+import android.app.backup.IBackupCallback;
import android.app.backup.IBackupManager;
import android.os.ParcelFileDescriptor;
@@ -55,7 +56,7 @@
void doBackup(in ParcelFileDescriptor oldState,
in ParcelFileDescriptor data,
in ParcelFileDescriptor newState,
- long quotaBytes, int token, IBackupManager callbackBinder, int transportFlags);
+ long quotaBytes, IBackupCallback callbackBinder, int transportFlags);
/**
* Restore an entire data snapshot to the application.
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index ec2cf0c..097dd9c 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -941,11 +941,13 @@
private static final String TAG = "BackupServiceBinder";
@Override
- public void doBackup(ParcelFileDescriptor oldState,
+ public void doBackup(
+ ParcelFileDescriptor oldState,
ParcelFileDescriptor data,
ParcelFileDescriptor newState,
- long quotaBytes, int token, IBackupManager callbackBinder, int transportFlags)
- throws RemoteException {
+ long quotaBytes,
+ IBackupCallback callbackBinder,
+ int transportFlags) throws RemoteException {
// Ensure that we're running with the app's normal permission level
long ident = Binder.clearCallingIdentity();
@@ -969,7 +971,7 @@
Binder.restoreCallingIdentity(ident);
try {
- callbackBinder.opComplete(token, 0);
+ callbackBinder.operationComplete(0);
} catch (RemoteException e) {
// we'll time out anyway, so we're safe
}
diff --git a/core/java/android/app/backup/IBackupCallback.aidl b/core/java/android/app/backup/IBackupCallback.aidl
new file mode 100644
index 0000000..9582a58
--- /dev/null
+++ b/core/java/android/app/backup/IBackupCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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 android.app.backup;
+
+import android.app.backup.IBackupManager;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Callback interface made for responding to one-way calls from the system.
+ *
+ * @hide
+ */
+oneway interface IBackupCallback {
+ void operationComplete(long result);
+}
diff --git a/core/java/android/ddm/DdmHandleAppName.java b/core/java/android/ddm/DdmHandleAppName.java
index 7e39e47..9560787 100644
--- a/core/java/android/ddm/DdmHandleAppName.java
+++ b/core/java/android/ddm/DdmHandleAppName.java
@@ -16,6 +16,7 @@
package android.ddm;
+import android.annotation.UnsupportedAppUsage;
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
@@ -69,6 +70,7 @@
* before or after DDMS connects. For the latter we need to send up
* an APNM message.
*/
+ @UnsupportedAppUsage
public static void setAppName(String name, int userId) {
if (name == null || name.length() == 0)
return;
@@ -79,6 +81,7 @@
sendAPNM(name, userId);
}
+ @UnsupportedAppUsage
public static String getAppName() {
return mAppName;
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 431c651..46671b2 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -28,6 +28,7 @@
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.Context;
@@ -343,10 +344,12 @@
InputMethodManager mImm;
+ @UnsupportedAppUsage
int mTheme = 0;
LayoutInflater mInflater;
TypedArray mThemeAttrs;
+ @UnsupportedAppUsage
View mRootView;
SoftInputWindow mWindow;
boolean mInitialized;
@@ -378,8 +381,10 @@
boolean mFullscreenApplied;
boolean mIsFullscreen;
+ @UnsupportedAppUsage
View mExtractView;
boolean mExtractViewHidden;
+ @UnsupportedAppUsage
ExtractEditText mExtractEditText;
ViewGroup mExtractAccessories;
View mExtractAction;
@@ -402,6 +407,7 @@
*/
boolean mShouldClearInsetOfPreviousIme;
+ @UnsupportedAppUsage
final Insets mTmpInsets = new Insets();
final int[] mTmpLocation = new int[2];
@@ -811,6 +817,7 @@
mService.getContentResolver().unregisterContentObserver(this);
}
+ @UnsupportedAppUsage
private boolean shouldShowImeWithHardKeyboard() {
// Lazily initialize as needed.
if (mShowImeWithHardKeyboard == ShowImeWithHardKeyboardType.UNKNOWN) {
@@ -850,6 +857,7 @@
return "SettingsObserver{mShowImeWithHardKeyboard=" + mShowImeWithHardKeyboard + "}";
}
}
+ @UnsupportedAppUsage
private SettingsObserver mSettingsObserver;
/**
@@ -2492,6 +2500,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void onExtractedDeleteText(int start, int end) {
InputConnection conn = getCurrentInputConnection();
if (conn != null) {
@@ -2504,6 +2513,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void onExtractedReplaceText(int start, int end, CharSequence text) {
InputConnection conn = getCurrentInputConnection();
if (conn != null) {
@@ -2515,6 +2525,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void onExtractedSetSpan(Object span, int start, int end, int flags) {
InputConnection conn = getCurrentInputConnection();
if (conn != null) {
diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java
index a5490ef..ec5f050 100644
--- a/core/java/android/inputmethodservice/Keyboard.java
+++ b/core/java/android/inputmethodservice/Keyboard.java
@@ -18,6 +18,7 @@
import org.xmlpull.v1.XmlPullParserException;
+import android.annotation.UnsupportedAppUsage;
import android.annotation.XmlRes;
import android.content.Context;
import android.content.res.Resources;
@@ -110,18 +111,21 @@
private int mKeyHeight;
/** Total height of the keyboard, including the padding and keys */
+ @UnsupportedAppUsage
private int mTotalHeight;
/**
* Total width of the keyboard, including left side gaps and keys, but not any gaps on the
* right side.
*/
+ @UnsupportedAppUsage
private int mTotalWidth;
/** List of keys in this keyboard */
private List<Key> mKeys;
/** List of modifier keys such as Shift & Alt, if any */
+ @UnsupportedAppUsage
private List<Key> mModifierKeys;
/** Width of the screen available to fit the keyboard */
@@ -623,6 +627,7 @@
rows.add(row);
}
+ @UnsupportedAppUsage
final void resize(int newWidth, int newHeight) {
int numRows = rows.size();
for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 16c1f6d..9ca8049 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -16,6 +16,7 @@
package android.inputmethodservice;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -133,6 +134,7 @@
private Keyboard mKeyboard;
private int mCurrentKeyIndex = NOT_A_KEY;
+ @UnsupportedAppUsage
private int mLabelTextSize;
private int mKeyTextSize;
private int mKeyTextColor;
@@ -140,6 +142,7 @@
private int mShadowColor;
private float mBackgroundDimAmount;
+ @UnsupportedAppUsage
private TextView mPreviewText;
private PopupWindow mPreviewPopup;
private int mPreviewTextSizeLarge;
@@ -217,6 +220,7 @@
private float mOldPointerX;
private float mOldPointerY;
+ @UnsupportedAppUsage
private Drawable mKeyBackground;
private static final int REPEAT_INTERVAL = 50; // ~20 keys per second
@@ -910,6 +914,7 @@
}
}
+ @UnsupportedAppUsage
private void showKey(final int keyIndex) {
final PopupWindow previewPopup = mPreviewPopup;
final Key[] keys = mKeys;
@@ -1052,6 +1057,7 @@
key.x + key.width + mPaddingLeft, key.y + key.height + mPaddingTop);
}
+ @UnsupportedAppUsage
private boolean openPopupIfRequired(MotionEvent me) {
// Check if we have a popup layout specified first.
if (mPopupLayout == 0) {
@@ -1357,6 +1363,7 @@
return true;
}
+ @UnsupportedAppUsage
private boolean repeatKey() {
Key key = mKeys[mRepeatKeyIndex];
detectAndSendKey(mCurrentKey, key.x, key.y, mLastTapTime);
diff --git a/core/java/android/nfc/ErrorCodes.java b/core/java/android/nfc/ErrorCodes.java
index 3adcdc3..98e31ad 100644
--- a/core/java/android/nfc/ErrorCodes.java
+++ b/core/java/android/nfc/ErrorCodes.java
@@ -16,6 +16,8 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
+
/**
* This class defines all the error codes that can be returned by the service
* and producing an exception on the application level. These are needed since
@@ -25,6 +27,7 @@
*/
public class ErrorCodes {
+ @UnsupportedAppUsage
public static boolean isError(int code) {
if (code < 0) {
return true;
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 093a9b4..b0090ca 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -16,6 +16,7 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
@@ -279,6 +280,7 @@
private final short mTnf;
private final byte[] mType;
+ @UnsupportedAppUsage
private final byte[] mId;
private final byte[] mPayload;
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 958063a..abfa133 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -16,6 +16,7 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.Application;
import android.content.ContentProvider;
@@ -45,6 +46,7 @@
static final String TAG = NfcAdapter.TAG;
static final Boolean DBG = false;
+ @UnsupportedAppUsage
final NfcAdapter mAdapter;
// All objects in the lists are protected by this
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index c3f23a1..21fed48 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -20,6 +20,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.OnActivityPausedListener;
@@ -325,6 +326,7 @@
// Final after first constructor, except for
// attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
// recovery
+ @UnsupportedAppUsage
static INfcAdapter sService;
static INfcTag sTagService;
static INfcCardEmulation sCardEmulationService;
@@ -490,6 +492,7 @@
* or throws if NFC is not available.
* @hide
*/
+ @UnsupportedAppUsage
public static synchronized NfcAdapter getNfcAdapter(Context context) {
if (!sIsInitialized) {
sHasNfcFeature = hasNfcFeature();
@@ -593,6 +596,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static NfcAdapter getDefaultAdapter() {
// introduced in API version 9 (GB 2.3)
// deprecated in API version 10 (GB 2.3.3)
@@ -615,6 +619,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public Context getContext() {
return mContext;
}
@@ -623,6 +628,7 @@
* Returns the binder interface to the service.
* @hide
*/
+ @UnsupportedAppUsage
public INfcAdapter getService() {
isEnabled(); // NOP call to recover sService if it is stale
return sService;
@@ -676,6 +682,7 @@
* NFC service dead - attempt best effort recovery
* @hide
*/
+ @UnsupportedAppUsage
public void attemptDeadServiceRecovery(Exception e) {
Log.e(TAG, "NFC service dead - attempting to recover", e);
INfcAdapter service = getServiceInterface();
@@ -746,6 +753,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public int getAdapterState() {
try {
return sService.getState();
@@ -1227,6 +1235,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
int flags) {
if (activity == null) {
@@ -1862,6 +1871,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public INfcAdapterExtras getNfcAdapterExtrasInterface() {
if (mContext == null) {
throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
diff --git a/core/java/android/nfc/NfcManager.java b/core/java/android/nfc/NfcManager.java
index 50d6745..71199c9 100644
--- a/core/java/android/nfc/NfcManager.java
+++ b/core/java/android/nfc/NfcManager.java
@@ -17,6 +17,7 @@
package android.nfc;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
/**
@@ -44,6 +45,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public NfcManager(Context context) {
NfcAdapter adapter;
context = context.getApplicationContext();
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 154d5a1..ce684cf 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -16,6 +16,7 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
@@ -110,6 +111,7 @@
* <p>
*/
public final class Tag implements Parcelable {
+ @UnsupportedAppUsage
final byte[] mId;
final int[] mTechList;
final String[] mTechStringList;
@@ -235,6 +237,7 @@
* For use by NfcService only.
* @hide
*/
+ @UnsupportedAppUsage
public int getServiceHandle() {
return mServiceHandle;
}
@@ -355,6 +358,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public INfcTag getTagService() {
return mTagService;
}
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
index 78a9401..63776c4 100644
--- a/core/java/android/nfc/cardemulation/AidGroup.java
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -24,6 +24,7 @@
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -45,8 +46,11 @@
static final String TAG = "AidGroup";
+ @UnsupportedAppUsage
final List<String> aids;
+ @UnsupportedAppUsage
final String category;
+ @UnsupportedAppUsage
final String description;
/**
@@ -79,6 +83,7 @@
this.description = null;
}
+ @UnsupportedAppUsage
AidGroup(String category, String description) {
this.aids = new ArrayList<String>();
this.category = category;
@@ -88,6 +93,7 @@
/**
* @return the category of this AID group
*/
+ @UnsupportedAppUsage
public String getCategory() {
return category;
}
@@ -95,6 +101,7 @@
/**
* @return the list of AIDs in this group
*/
+ @UnsupportedAppUsage
public List<String> getAids() {
return aids;
}
@@ -124,6 +131,7 @@
}
}
+ @UnsupportedAppUsage
public static final Parcelable.Creator<AidGroup> CREATOR =
new Parcelable.Creator<AidGroup>() {
@@ -144,6 +152,7 @@
}
};
+ @UnsupportedAppUsage
static public AidGroup createFromXml(XmlPullParser parser) throws XmlPullParserException, IOException {
String category = null;
ArrayList<String> aids = new ArrayList<String>();
@@ -185,6 +194,7 @@
return group;
}
+ @UnsupportedAppUsage
public void writeAsXml(XmlSerializer out) throws IOException {
out.startTag(null, "aid-group");
out.attribute(null, "category", category);
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 218e4f2..e8d801c 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -16,6 +16,7 @@
package android.nfc.cardemulation;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -54,6 +55,7 @@
/**
* The service that implements this
*/
+ @UnsupportedAppUsage
final ResolveInfo mService;
/**
@@ -69,11 +71,13 @@
/**
* Mapping from category to static AID group
*/
+ @UnsupportedAppUsage
final HashMap<String, AidGroup> mStaticAidGroups;
/**
* Mapping from category to dynamic AID group
*/
+ @UnsupportedAppUsage
final HashMap<String, AidGroup> mDynamicAidGroups;
/**
@@ -99,6 +103,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
boolean requiresUnlock, int bannerResource, int uid,
@@ -120,6 +125,7 @@
this.mSettingsActivityName = settingsActivityName;
}
+ @UnsupportedAppUsage
public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost) throws
XmlPullParserException, IOException {
ServiceInfo si = info.serviceInfo;
@@ -374,18 +380,22 @@
return (mStaticAidGroups.containsKey(category) || mDynamicAidGroups.containsKey(category));
}
+ @UnsupportedAppUsage
public boolean isOnHost() {
return mOnHost;
}
+ @UnsupportedAppUsage
public boolean requiresUnlock() {
return mRequiresDeviceUnlock;
}
+ @UnsupportedAppUsage
public String getDescription() {
return mDescription;
}
+ @UnsupportedAppUsage
public int getUid() {
return mUid;
}
@@ -411,6 +421,7 @@
return mService.loadIcon(pm);
}
+ @UnsupportedAppUsage
public Drawable loadBanner(PackageManager pm) {
Resources res;
try {
@@ -426,6 +437,7 @@
}
}
+ @UnsupportedAppUsage
public String getSettingsActivityName() { return mSettingsActivityName; }
@Override
@@ -483,6 +495,7 @@
dest.writeString(mSettingsActivityName);
};
+ @UnsupportedAppUsage
public static final Parcelable.Creator<ApduServiceInfo> CREATOR =
new Parcelable.Creator<ApduServiceInfo>() {
@Override
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f4f43e3..6cf67de 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9217,6 +9217,19 @@
/** {@hide} */
public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
+ /**
+ * Whether or not Settings should enable psd API.
+ * {@hide}
+ */
+ public static final String SETTINGS_USE_PSD_API = "settings_use_psd_api";
+
+ /**
+ * Whether or not Settings should enable external provider API.
+ * {@hide}
+ */
+ public static final String SETTINGS_USE_EXTERNAL_PROVIDER_API =
+ "settings_use_external_provider_api";
+
/**
* Sample validity in seconds to configure for the system DNS resolver.
* {@hide}
@@ -9824,6 +9837,18 @@
"recommended_network_evaluator_cache_expiry_ms";
/**
+ * Whether wifi scan throttle is enabled or not.
+ * This is intended to be used via adb commands or a menu in developer option to turn off
+ * the default wifi scan throttling mechanism for apps.
+ *
+ * Type: int (0 for false, 1 for true)
+ * @hide
+ */
+ public static final String WIFI_SCAN_THROTTLE_ENABLED = "wifi_scan_throttle_enabled";
+
+ private static final Validator WIFI_SCAN_THROTTLE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
* Settings to allow BLE scans to be enabled even when Bluetooth is turned off for
* connectivity.
* @hide
@@ -12315,6 +12340,7 @@
VALIDATORS.put(SOFT_AP_TIMEOUT_ENABLED, SOFT_AP_TIMEOUT_ENABLED_VALIDATOR);
VALIDATORS.put(WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON,
WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR);
+ VALIDATORS.put(WIFI_SCAN_THROTTLE_ENABLED, WIFI_SCAN_THROTTLE_ENABLED_VALIDATOR);
VALIDATORS.put(APP_AUTO_RESTRICTION_ENABLED, APP_AUTO_RESTRICTION_ENABLED_VALIDATOR);
VALIDATORS.put(ZEN_DURATION, ZEN_DURATION_VALIDATOR);
VALIDATORS.put(CHARGING_VIBRATION_ENABLED, CHARGING_VIBRATION_ENABLED_VALIDATOR);
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index 1cd76d2..e5e1c92 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -65,16 +65,36 @@
/**
* Manifest metadata key for the resource string containing the name of the default field
* classification algorithm.
+ *
+ * @deprecated Use {@link #RESOURCE_DEFAULT_ALGORITHM} instead.
*/
+ @Deprecated
public static final String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM =
"android.autofill.field_classification.default_algorithm";
+
/**
* Manifest metadata key for the resource string array containing the names of all field
* classification algorithms provided by the service.
+ *
+ * @deprecated Use {@link #RESOURCE_AVAILABLE_ALGORITHMS} instead.
*/
+ @Deprecated
public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
"android.autofill.field_classification.available_algorithms";
+ /**
+ * Name of the resource string containing the name of the default field
+ * classification algorithm.
+ */
+ public static final String RESOURCE_DEFAULT_ALGORITHM =
+ "autofill_field_classification_default_algorithm";
+
+ /**
+ * Name of the resource string array containing the names of all field
+ * classification algorithms provided by the service.
+ */
+ public static final String RESOURCE_AVAILABLE_ALGORITHMS =
+ "autofill_field_classification_available_algorithms";
/** {@hide} **/
public static final String EXTRA_SCORES = "scores";
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 0d94af4..e0c354a 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -71,6 +71,12 @@
public static final String KEY_SMART_ACTIONS = "key_smart_actions";
/**
+ * Data type: ArrayList of {@link CharSequence}.
+ * Used to suggest smart replies for a notification.
+ */
+ public static final String KEY_SMART_REPLIES = "key_smart_replies";
+
+ /**
* Create a notification adjustment.
*
* @param pkg The package of the notification.
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 09425a9..09eecd8 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1427,6 +1427,7 @@
private @UserSentiment int mUserSentiment = USER_SENTIMENT_NEUTRAL;
private boolean mHidden;
private ArrayList<Notification.Action> mSmartActions;
+ private ArrayList<CharSequence> mSmartReplies;
public Ranking() {}
@@ -1564,6 +1565,13 @@
}
/**
+ * @hide
+ */
+ public List<CharSequence> getSmartReplies() {
+ return mSmartReplies;
+ }
+
+ /**
* Returns whether this notification can be displayed as a badge.
*
* @return true if the notification can be displayed as a badge, false otherwise.
@@ -1591,7 +1599,8 @@
CharSequence explanation, String overrideGroupKey,
NotificationChannel channel, ArrayList<String> overridePeople,
ArrayList<SnoozeCriterion> snoozeCriteria, boolean showBadge,
- int userSentiment, boolean hidden, ArrayList<Notification.Action> smartActions) {
+ int userSentiment, boolean hidden, ArrayList<Notification.Action> smartActions,
+ ArrayList<CharSequence> smartReplies) {
mKey = key;
mRank = rank;
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -1608,6 +1617,7 @@
mUserSentiment = userSentiment;
mHidden = hidden;
mSmartActions = smartActions;
+ mSmartReplies = smartReplies;
}
/**
@@ -1658,6 +1668,7 @@
private ArrayMap<String, Integer> mUserSentiment;
private ArrayMap<String, Boolean> mHidden;
private ArrayMap<String, ArrayList<Notification.Action>> mSmartActions;
+ private ArrayMap<String, ArrayList<CharSequence>> mSmartReplies;
private RankingMap(NotificationRankingUpdate rankingUpdate) {
mRankingUpdate = rankingUpdate;
@@ -1686,7 +1697,8 @@
getVisibilityOverride(key), getSuppressedVisualEffects(key),
getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
- getShowBadge(key), getUserSentiment(key), getHidden(key), getSmartActions(key));
+ getShowBadge(key), getUserSentiment(key), getHidden(key), getSmartActions(key),
+ getSmartReplies(key));
return rank >= 0;
}
@@ -1833,6 +1845,15 @@
return mSmartActions.get(key);
}
+ private ArrayList<CharSequence> getSmartReplies(String key) {
+ synchronized (this) {
+ if (mSmartReplies == null) {
+ buildSmartReplies();
+ }
+ }
+ return mSmartReplies.get(key);
+ }
+
// Locked by 'this'
private void buildRanksLocked() {
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
@@ -1959,6 +1980,15 @@
}
}
+ // Locked by 'this'
+ private void buildSmartReplies() {
+ Bundle smartReplies = mRankingUpdate.getSmartReplies();
+ mSmartReplies = new ArrayMap<>(smartReplies.size());
+ for (String key : smartReplies.keySet()) {
+ mSmartReplies.put(key, smartReplies.getCharSequenceArrayList(key));
+ }
+ }
+
// ----------- Parcelable
@Override
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index bed22149..c67fad0 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -38,12 +38,14 @@
private final Bundle mUserSentiment;
private final Bundle mHidden;
private final Bundle mSmartActions;
+ private final Bundle mSmartReplies;
public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
Bundle visibilityOverrides, Bundle suppressedVisualEffects,
int[] importance, Bundle explanation, Bundle overrideGroupKeys,
Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
- Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions) {
+ Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions,
+ Bundle smartReplies) {
mKeys = keys;
mInterceptedKeys = interceptedKeys;
mVisibilityOverrides = visibilityOverrides;
@@ -58,6 +60,7 @@
mUserSentiment = userSentiment;
mHidden = hidden;
mSmartActions = smartActions;
+ mSmartReplies = smartReplies;
}
public NotificationRankingUpdate(Parcel in) {
@@ -76,6 +79,7 @@
mUserSentiment = in.readBundle();
mHidden = in.readBundle();
mSmartActions = in.readBundle();
+ mSmartReplies = in.readBundle();
}
@Override
@@ -99,6 +103,7 @@
out.writeBundle(mUserSentiment);
out.writeBundle(mHidden);
out.writeBundle(mSmartActions);
+ out.writeBundle(mSmartReplies);
}
public static final Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -167,4 +172,8 @@
public Bundle getSmartActions() {
return mSmartActions;
}
+
+ public Bundle getSmartReplies() {
+ return mSmartReplies;
+ }
}
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 2499afb..1b063e1 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -380,8 +380,8 @@
/** @hide */ public static final int LOG_ID_SYSTEM = 3;
/** @hide */ public static final int LOG_ID_CRASH = 4;
- /** @hide */ public static native int println_native(int bufID,
- int priority, String tag, String msg);
+ /** @hide */
+ public static native int println_native(int bufID, int priority, String tag, String msg);
/**
* Return the maximum payload the log daemon accepts without truncation.
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index b3400ef..af18caa 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -22,32 +22,34 @@
import libcore.util.EmptyArray;
/**
- * SparseArrays map integers to Objects. Unlike a normal array of Objects,
- * there can be gaps in the indices. It is intended to be more memory efficient
- * than using a HashMap to map Integers to Objects, both because it avoids
+ * <code>SparseArray</code> maps integers to Objects and, unlike a normal array of Objects,
+ * its indices can contain gaps. <code>SparseArray</code> is intended to be more memory-efficient
+ * than a
+ * <a href="/reference/java/util/HashMap"><code>HashMap</code></a>, because it avoids
* auto-boxing keys and its data structure doesn't rely on an extra entry object
* for each mapping.
*
* <p>Note that this container keeps its mappings in an array data structure,
- * using a binary search to find keys. The implementation is not intended to be appropriate for
+ * using a binary search to find keys. The implementation is not intended to be appropriate for
* data structures
- * that may contain large numbers of items. It is generally slower than a traditional
- * HashMap, since lookups require a binary search and adds and removes require inserting
- * and deleting entries in the array. For containers holding up to hundreds of items,
- * the performance difference is not significant, less than 50%.</p>
+ * that may contain large numbers of items. It is generally slower than a
+ * <code>HashMap</code> because lookups require a binary search,
+ * and adds and removes require inserting
+ * and deleting entries in the array. For containers holding up to hundreds of items,
+ * the performance difference is less than 50%.
*
* <p>To help with performance, the container includes an optimization when removing
* keys: instead of compacting its array immediately, it leaves the removed entry marked
- * as deleted. The entry can then be re-used for the same key, or compacted later in
- * a single garbage collection step of all removed entries. This garbage collection will
- * need to be performed at any time the array needs to be grown or the the map size or
- * entry values are retrieved.</p>
+ * as deleted. The entry can then be re-used for the same key or compacted later in
+ * a single garbage collection of all removed entries. This garbage collection
+ * must be performed whenever the array needs to be grown, or when the map size or
+ * entry values are retrieved.
*
* <p>It is possible to iterate over the items in this container using
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
- * <code>keyAt(int)</code> with ascending values of the index will return the
- * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)</code>.</p>
+ * <code>keyAt(int)</code> with ascending values of the index returns the
+ * keys in ascending order. In the case of <code>valueAt(int)</code>, the
+ * values corresponding to the keys are returned in ascending order.
*/
public class SparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
@@ -333,7 +335,7 @@
/**
* Returns an index for which {@link #valueAt} would return the
- * specified key, or a negative number if no keys map to the
+ * specified value, or a negative number if no keys map to the
* specified value.
* <p>Beware that this is a linear search, unlike lookups by key,
* and that multiple keys can map to the same value and this will
@@ -357,7 +359,7 @@
/**
* Returns an index for which {@link #valueAt} would return the
- * specified key, or a negative number if no keys map to the
+ * specified value, or a negative number if no keys map to the
* specified value.
* <p>Beware that this is a linear search, unlike lookups by key,
* and that multiple keys can map to the same value and this will
diff --git a/core/java/android/view/RecordingCanvas.java b/core/java/android/view/RecordingCanvas.java
index 74fa9e8..3364483 100644
--- a/core/java/android/view/RecordingCanvas.java
+++ b/core/java/android/view/RecordingCanvas.java
@@ -536,9 +536,6 @@
@Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset,
int indexCount, @NonNull Paint paint) {
checkRange(verts.length, vertOffset, vertexCount);
- if (isHardwareAccelerated()) {
- return;
- }
if (texs != null) {
checkRange(texs.length, texOffset, vertexCount);
}
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 64686dd..87b7b05 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -19,6 +19,7 @@
import android.annotation.AnimRes;
import android.annotation.ColorInt;
import android.annotation.InterpolatorRes;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.RectF;
@@ -183,6 +184,7 @@
/**
* The animation listener to be notified when the animation starts, ends or repeats.
*/
+ @UnsupportedAppUsage
AnimationListener mListener;
/**
@@ -211,9 +213,13 @@
private boolean mMore = true;
private boolean mOneMoreTime = true;
+ @UnsupportedAppUsage
RectF mPreviousRegion = new RectF();
+ @UnsupportedAppUsage
RectF mRegion = new RectF();
+ @UnsupportedAppUsage
Transformation mTransformation = new Transformation();
+ @UnsupportedAppUsage
Transformation mPreviousTransformation = new Transformation();
private final CloseGuard guard = CloseGuard.get();
@@ -322,6 +328,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void detach() {
if (mStarted && !mEnded) {
mEnded = true;
@@ -1046,6 +1053,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void getInvalidateRegion(int left, int top, int right, int bottom,
RectF invalidate, Transformation transformation) {
@@ -1077,6 +1085,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void initializeInvalidateRegion(int left, int top, int right, int bottom) {
final RectF region = mPreviousRegion;
region.set(left, top, right, bottom);
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java
index 29f8442..c877b9c 100644
--- a/core/java/android/view/animation/AnimationUtils.java
+++ b/core/java/android/view/animation/AnimationUtils.java
@@ -19,6 +19,7 @@
import android.annotation.AnimRes;
import android.annotation.InterpolatorRes;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
@@ -157,6 +158,7 @@
return createAnimationFromXml(c, parser, null, Xml.asAttributeSet(parser));
}
+ @UnsupportedAppUsage
private static Animation createAnimationFromXml(Context c, XmlPullParser parser,
AnimationSet parent, AttributeSet attrs) throws XmlPullParserException, IOException {
diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java
index 8eb5b5c..58da04d 100644
--- a/core/java/android/view/animation/Transformation.java
+++ b/core/java/android/view/animation/Transformation.java
@@ -17,6 +17,7 @@
package android.view.animation;
import android.annotation.FloatRange;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Matrix;
import android.graphics.Rect;
@@ -238,6 +239,7 @@
* Print short string, to optimize dumping.
* @hide
*/
+ @UnsupportedAppUsage
public void printShortString(PrintWriter pw) {
pw.print("{alpha="); pw.print(mAlpha);
pw.print(" matrix=");
diff --git a/core/java/android/view/animation/TranslateAnimation.java b/core/java/android/view/animation/TranslateAnimation.java
index 216022b..6c040d4 100644
--- a/core/java/android/view/animation/TranslateAnimation.java
+++ b/core/java/android/view/animation/TranslateAnimation.java
@@ -16,6 +16,7 @@
package android.view.animation;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
@@ -34,13 +35,17 @@
private int mToYType = ABSOLUTE;
/** @hide */
+ @UnsupportedAppUsage
protected float mFromXValue = 0.0f;
/** @hide */
+ @UnsupportedAppUsage
protected float mToXValue = 0.0f;
/** @hide */
+ @UnsupportedAppUsage
protected float mFromYValue = 0.0f;
/** @hide */
+ @UnsupportedAppUsage
protected float mToYValue = 0.0f;
/** @hide */
diff --git a/core/java/android/view/animation/TranslateYAnimation.java b/core/java/android/view/animation/TranslateYAnimation.java
index 714558d..a6e0ccb 100644
--- a/core/java/android/view/animation/TranslateYAnimation.java
+++ b/core/java/android/view/animation/TranslateYAnimation.java
@@ -16,6 +16,7 @@
package android.view.animation;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Matrix;
/**
@@ -38,6 +39,7 @@
/**
* Constructor. Passes in 0 for the x parameters of TranslateAnimation
*/
+ @UnsupportedAppUsage
public TranslateYAnimation(int fromYType, float fromYValue, int toYType, float toYValue) {
super(ABSOLUTE, 0, ABSOLUTE, 0, fromYType, fromYValue, toYType, toYValue);
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b5c7364..32b2f63 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1405,7 +1405,8 @@
final SyncResultReceiver receiver = new SyncResultReceiver();
try {
mService.getAvailableFieldClassificationAlgorithms(receiver);
- final String[] algorithms = receiver.getObjectResult(SyncResultReceiver.TYPE_STRING);
+ final String[] algorithms = receiver
+ .getObjectResult(SyncResultReceiver.TYPE_STRING_ARRAY);
return algorithms != null ? Arrays.asList(algorithms) : Collections.emptyList();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
@@ -2906,7 +2907,7 @@
case TYPE_STRING:
return (T) mBundle.getString(EXTRA);
case TYPE_STRING_ARRAY:
- return (T) mBundle.getString(EXTRA);
+ return (T) mBundle.getStringArray(EXTRA);
case TYPE_PARCELABLE:
return (T) mBundle.getParcelable(EXTRA);
default:
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index 9685f75..943c8bd 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -25,6 +25,7 @@
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Slog;
+import android.util.SparseLongArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;
@@ -62,8 +63,6 @@
import java.io.PrintWriter;
import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
public final class ProcessState {
private static final String TAG = "ProcessStats";
@@ -127,6 +126,7 @@
private final long mVersion;
private final DurationsTable mDurations;
private final PssTable mPssTable;
+ private final long[] mTotalRunningPss = new long[ProcessStats.PSS_COUNT];
private ProcessState mCommonProcess;
private int mCurCombinedState = STATE_NOTHING;
@@ -135,6 +135,9 @@
private int mLastPssState = STATE_NOTHING;
private long mLastPssTime;
+ private long mTotalRunningStartTime;
+ private long mTotalRunningDuration;
+
private boolean mActive;
private int mNumActiveServices;
private int mNumStartedServices;
@@ -182,6 +185,9 @@
mVersion = vers;
mCurCombinedState = commonProcess.mCurCombinedState;
mStartTime = now;
+ if (mCurCombinedState != STATE_NOTHING) {
+ mTotalRunningStartTime = now;
+ }
mDurations = new DurationsTable(commonProcess.mStats.mTableData);
mPssTable = new PssTable(commonProcess.mStats.mTableData);
}
@@ -190,6 +196,8 @@
ProcessState pnew = new ProcessState(this, mPackage, mUid, mVersion, mName, now);
pnew.mDurations.addDurations(mDurations);
pnew.mPssTable.copyFrom(mPssTable, PSS_COUNT);
+ System.arraycopy(mTotalRunningPss, 0, pnew.mTotalRunningPss, 0, ProcessStats.PSS_COUNT);
+ pnew.mTotalRunningDuration = getTotalRunningDuration(now);
pnew.mNumExcessiveCpu = mNumExcessiveCpu;
pnew.mNumCachedKill = mNumCachedKill;
pnew.mMinCachedKillPss = mMinCachedKillPss;
@@ -235,7 +243,7 @@
public void setMultiPackage(boolean val) {
mMultiPackage = val;
}
-
+
public int getDurationsBucketCount() {
return mDurations.getKeyCount();
}
@@ -243,6 +251,10 @@
public void add(ProcessState other) {
mDurations.addDurations(other.mDurations);
mPssTable.mergeStats(other.mPssTable);
+ // Note that we don't touch mTotalRunningPss, because in current use
+ // 'other' is older stats that are being added in to these newer ones.
+ // So the newer ones keep track of the total running time, which is always
+ // the right thing over whatever was in older stats.
mNumExcessiveCpu += other.mNumExcessiveCpu;
if (other.mNumCachedKill > 0) {
addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss,
@@ -277,6 +289,10 @@
out.writeInt(mMultiPackage ? 1 : 0);
mDurations.writeToParcel(out);
mPssTable.writeToParcel(out);
+ for (int i = 0; i < ProcessStats.PSS_COUNT; i++) {
+ out.writeLong(mTotalRunningPss[i]);
+ }
+ out.writeLong(getTotalRunningDuration(now));
out.writeInt(0); // was mNumExcessiveWake
out.writeInt(mNumExcessiveCpu);
out.writeInt(mNumCachedKill);
@@ -300,6 +316,10 @@
if (!mPssTable.readFromParcel(in)) {
return false;
}
+ for (int i = 0; i < ProcessStats.PSS_COUNT; i++) {
+ mTotalRunningPss[i] = in.readLong();
+ }
+ mTotalRunningDuration = in.readLong();
in.readInt(); // was mNumExcessiveWake
mNumExcessiveCpu = in.readInt();
mNumCachedKill = in.readInt();
@@ -334,7 +354,8 @@
public boolean hasAnyData() {
return !(mDurations.getKeyCount() == 0
&& mCurCombinedState == STATE_NOTHING
- && mPssTable.getKeyCount() == 0);
+ && mPssTable.getKeyCount() == 0
+ && mTotalRunningPss[PSS_SAMPLE_COUNT] == 0);
}
/**
@@ -374,6 +395,19 @@
if (!mDead && (mCurCombinedState != state)) {
//Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
commitStateTime(now);
+ if (state == STATE_NOTHING) {
+ // We are transitioning to a no longer running state... stop counting run time.
+ mTotalRunningDuration += now - mTotalRunningStartTime;
+ mTotalRunningStartTime = 0;
+ } else if (mCurCombinedState == STATE_NOTHING) {
+ // We previously weren't running... now starting again, clear out total
+ // running info.
+ mTotalRunningDuration = 0;
+ mTotalRunningStartTime = now;
+ for (int i = ProcessStats.PSS_COUNT - 1; i >= 0; i--) {
+ mTotalRunningPss[i] = 0;
+ }
+ }
mCurCombinedState = state;
}
}
@@ -388,6 +422,8 @@
if (dur > 0) {
mDurations.addDuration(mCurCombinedState, dur);
}
+ mTotalRunningDuration += now - mTotalRunningStartTime;
+ mTotalRunningStartTime = now;
}
mStartTime = now;
}
@@ -496,6 +532,8 @@
// First update the common process.
mCommonProcess.mPssTable.mergeStats(mCurCombinedState, 1, pss, pss, pss, uss, uss, uss,
rss, rss, rss);
+ PssTable.mergeStats(mCommonProcess.mTotalRunningPss, 0, 1, pss, pss, pss, uss, uss, uss,
+ rss, rss, rss);
// If the common process is not multi-package, there is nothing else to do.
if (!mCommonProcess.mMultiPackage) {
@@ -504,7 +542,10 @@
if (pkgList != null) {
for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).mPssTable.mergeStats(mCurCombinedState, 1,
+ ProcessState fixedProc = pullFixedProc(pkgList, ip);
+ fixedProc.mPssTable.mergeStats(mCurCombinedState, 1,
+ pss, pss, pss, uss, uss, uss, rss, rss, rss);
+ PssTable.mergeStats(fixedProc.mTotalRunningPss, 0, 1,
pss, pss, pss, uss, uss, uss, rss, rss, rss);
}
}
@@ -621,6 +662,11 @@
return proc;
}
+ public long getTotalRunningDuration(long now) {
+ return mTotalRunningDuration +
+ (mTotalRunningStartTime != 0 ? (now - mTotalRunningStartTime) : 0);
+ }
+
public long getDuration(int state, long now) {
long time = mDurations.getValueForId((byte)state);
if (mCurCombinedState == state) {
@@ -671,7 +717,7 @@
/**
* Sums up the PSS data and adds it to 'data'.
- *
+ *
* @param data The aggregate data is added here.
* @param now SystemClock.uptimeMillis()
*/
@@ -834,6 +880,7 @@
String running = "";
if (mCurCombinedState == bucket) {
running = " (running)";
+ time += now - mStartTime;
}
if (time != 0) {
pw.print(prefix);
@@ -870,7 +917,7 @@
}
public void dumpPss(PrintWriter pw, String prefix,
- int[] screenStates, int[] memStates, int[] procStates) {
+ int[] screenStates, int[] memStates, int[] procStates, long now) {
boolean printedHeader = false;
int printedScreen = -1;
for (int is=0; is<screenStates.length; is++) {
@@ -880,52 +927,51 @@
final int iscreen = screenStates[is];
final int imem = memStates[im];
final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
- long count = getPssSampleCount(bucket);
- if (count > 0) {
- if (!printedHeader) {
- pw.print(prefix);
- pw.print("PSS/USS (");
- pw.print(mPssTable.getKeyCount());
- pw.println(" entries):");
- printedHeader = true;
- }
- pw.print(prefix);
- pw.print(" ");
- if (screenStates.length > 1) {
- DumpUtils.printScreenLabel(pw,
- printedScreen != iscreen ? iscreen : STATE_NOTHING);
- printedScreen = iscreen;
- }
- if (memStates.length > 1) {
- DumpUtils.printMemLabel(pw,
- printedMem != imem ? imem : STATE_NOTHING, '/');
- printedMem = imem;
- }
- pw.print(DumpUtils.STATE_LABELS[procStates[ip]]); pw.print(": ");
- pw.print(count);
- pw.print(" samples ");
- DebugUtils.printSizeValue(pw, getPssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssMaximum(bucket) * 1024);
- pw.print(" / ");
- DebugUtils.printSizeValue(pw, getPssUssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssUssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssUssMaximum(bucket) * 1024);
- pw.print(" / ");
- DebugUtils.printSizeValue(pw, getPssRssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssRssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssRssMaximum(bucket) * 1024);
- pw.println();
+ final int key = mPssTable.getKey((byte)bucket);
+ if (key == SparseMappingTable.INVALID_KEY) {
+ continue;
}
+ final long[] table = mPssTable.getArrayForKey(key);
+ final int tableOffset = SparseMappingTable.getIndexFromKey(key);
+ if (!printedHeader) {
+ pw.print(prefix);
+ pw.print("PSS/USS (");
+ pw.print(mPssTable.getKeyCount());
+ pw.println(" entries):");
+ printedHeader = true;
+ }
+ pw.print(prefix);
+ pw.print(" ");
+ if (screenStates.length > 1) {
+ DumpUtils.printScreenLabel(pw,
+ printedScreen != iscreen ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ }
+ if (memStates.length > 1) {
+ DumpUtils.printMemLabel(pw,
+ printedMem != imem ? imem : STATE_NOTHING, '/');
+ printedMem = imem;
+ }
+ pw.print(DumpUtils.STATE_LABELS[procStates[ip]]); pw.print(": ");
+ dumpPssSamples(pw, table, tableOffset);
+ pw.println();
}
}
}
+ final long totalRunningDuration = getTotalRunningDuration(now);
+ if (totalRunningDuration != 0) {
+ pw.print(prefix);
+ pw.print("Cur time ");
+ TimeUtils.formatDuration(totalRunningDuration, pw);
+ if (mTotalRunningStartTime != 0) {
+ pw.print(" (running)");
+ }
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ pw.print(": ");
+ dumpPssSamples(pw, mTotalRunningPss, 0);
+ }
+ pw.println();
+ }
if (mNumExcessiveCpu != 0) {
pw.print(prefix); pw.print("Killed for excessive CPU use: ");
pw.print(mNumExcessiveCpu); pw.println(" times");
@@ -939,6 +985,28 @@
}
}
+ public static void dumpPssSamples(PrintWriter pw, long[] table, int offset) {
+ DebugUtils.printSizeValue(pw, table[offset + PSS_MINIMUM] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_AVERAGE] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_MAXIMUM] * 1024);
+ pw.print("/");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_USS_MINIMUM] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_USS_AVERAGE] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_USS_MAXIMUM] * 1024);
+ pw.print("/");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_RSS_MINIMUM] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_RSS_AVERAGE] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_RSS_MAXIMUM] * 1024);
+ pw.print(" over ");
+ pw.print(table[offset + PSS_SAMPLE_COUNT]);
+ }
+
private void dumpProcessSummaryDetails(PrintWriter pw, String prefix,
String label, int[] screenStates, int[] memStates, int[] procStates,
long now, long totalTime, boolean full) {
@@ -1116,6 +1184,21 @@
dumpAllPssCheckin(pw);
pw.println();
}
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ pw.print("pkgrun,");
+ pw.print(pkgName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(vers);
+ pw.print(",");
+ pw.print(DumpUtils.collapseString(pkgName, itemName));
+ pw.print(",");
+ pw.print(getTotalRunningDuration(now));
+ pw.print(",");
+ dumpPssSamplesCheckin(pw, mTotalRunningPss, 0);
+ pw.println();
+ }
if (mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
pw.print("pkgkills,");
pw.print(pkgName);
@@ -1158,6 +1241,17 @@
dumpAllPssCheckin(pw);
pw.println();
}
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ pw.print("procrun,");
+ pw.print(procName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(getTotalRunningDuration(now));
+ pw.print(",");
+ dumpPssSamplesCheckin(pw, mTotalRunningPss, 0);
+ pw.println();
+ }
if (mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
pw.print("kills,");
pw.print(procName);
@@ -1204,28 +1298,33 @@
pw.print(',');
DumpUtils.printProcStateTag(pw, type);
pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_SAMPLE_COUNT));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_MINIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_AVERAGE));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_MAXIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_USS_MINIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_USS_AVERAGE));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_USS_MAXIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_RSS_MINIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_RSS_AVERAGE));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_RSS_MAXIMUM));
+ dumpPssSamplesCheckin(pw, mPssTable.getArrayForKey(key),
+ SparseMappingTable.getIndexFromKey(key));
}
}
+ public static void dumpPssSamplesCheckin(PrintWriter pw, long[] table, int offset) {
+ pw.print(table[offset + PSS_SAMPLE_COUNT]);
+ pw.print(':');
+ pw.print(table[offset + PSS_MINIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_AVERAGE]);
+ pw.print(':');
+ pw.print(table[offset + PSS_MAXIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_USS_MINIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_USS_AVERAGE]);
+ pw.print(':');
+ pw.print(table[offset + PSS_USS_MAXIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_RSS_MINIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_RSS_AVERAGE]);
+ pw.print(':');
+ pw.print(table[offset + PSS_RSS_MAXIMUM]);
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder(128);
@@ -1253,7 +1352,7 @@
}
// Group proc stats by type (screen state + mem state + process state)
- Map<Integer, Long> durationByState = new HashMap<>();
+ SparseLongArray durationByState = new SparseLongArray();
boolean didCurState = false;
for (int i=0; i<mDurations.getKeyCount(); i++) {
final int key = mDurations.getKeyAt(i);
@@ -1272,7 +1371,7 @@
for (int i=0; i<mPssTable.getKeyCount(); i++) {
final int key = mPssTable.getKeyAt(i);
final int type = SparseMappingTable.getIdFromKey(key);
- if (!durationByState.containsKey(type)) {
+ if (durationByState.indexOfKey(type) < 0) {
// state without duration should not have stats!
continue;
}
@@ -1284,36 +1383,35 @@
type);
long duration = durationByState.get(type);
- durationByState.remove(type); // remove the key since it is already being dumped.
+ durationByState.delete(type); // remove the key since it is already being dumped.
proto.write(ProcessStatsProto.State.DURATION_MS, duration);
- proto.write(ProcessStatsProto.State.SAMPLE_SIZE, mPssTable.getValue(key, PSS_SAMPLE_COUNT));
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.PSS,
- mPssTable.getValue(key, PSS_MINIMUM),
- mPssTable.getValue(key, PSS_AVERAGE),
- mPssTable.getValue(key, PSS_MAXIMUM));
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.USS,
- mPssTable.getValue(key, PSS_USS_MINIMUM),
- mPssTable.getValue(key, PSS_USS_AVERAGE),
- mPssTable.getValue(key, PSS_USS_MAXIMUM));
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.RSS,
- mPssTable.getValue(key, PSS_RSS_MINIMUM),
- mPssTable.getValue(key, PSS_RSS_AVERAGE),
- mPssTable.getValue(key, PSS_RSS_MAXIMUM));
+ mPssTable.writeStatsToProtoForKey(proto, key);
proto.end(stateToken);
}
- for (Map.Entry<Integer, Long> entry : durationByState.entrySet()) {
+ for (int i = 0; i < durationByState.size(); i++) {
final long stateToken = proto.start(ProcessStatsProto.STATES);
DumpUtils.printProcStateTagProto(proto,
ProcessStatsProto.State.SCREEN_STATE,
ProcessStatsProto.State.MEMORY_STATE,
ProcessStatsProto.State.PROCESS_STATE,
- entry.getKey());
- proto.write(ProcessStatsProto.State.DURATION_MS, entry.getValue());
+ durationByState.keyAt(i));
+ proto.write(ProcessStatsProto.State.DURATION_MS, durationByState.valueAt(i));
proto.end(stateToken);
}
+
+ final long totalRunningDuration = getTotalRunningDuration(now);
+ if (totalRunningDuration > 0) {
+ final long stateToken = proto.start(ProcessStatsProto.TOTAL_RUNNING_STATE);
+ proto.write(ProcessStatsProto.State.DURATION_MS, totalRunningDuration);
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ PssTable.writeStatsToProto(proto, mTotalRunningPss, 0);
+ }
+ proto.end(stateToken);
+ }
+
proto.end(token);
}
}
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index 12b16d0..d088354 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -158,7 +158,7 @@
};
// Current version of the parcel format.
- private static final int PARCEL_VERSION = 33;
+ private static final int PARCEL_VERSION = 34;
// In-memory Parcel magic number, used to detect attempts to unmarshall bad data
private static final int MAGIC = 0x50535454;
@@ -1483,7 +1483,7 @@
proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
ALL_PROC_STATES, now);
proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES);
+ ALL_PROC_STATES, now);
proc.dumpInternalLocked(pw, " ", dumpAll);
}
} else {
@@ -1558,7 +1558,7 @@
int uid = uids.keyAt(iu);
numTotalProcs++;
final ProcessState proc = uids.valueAt(iu);
- if (proc.hasAnyData()) {
+ if (!proc.hasAnyData()) {
continue;
}
if (!proc.isMultiPackage()) {
@@ -1587,7 +1587,7 @@
pw.print(" entries)"); pw.println(":");
proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
ALL_PROC_STATES, now);
- proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES);
+ proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now);
proc.dumpInternalLocked(pw, " ", dumpAll);
}
}
diff --git a/core/java/com/android/internal/app/procstats/PssTable.java b/core/java/com/android/internal/app/procstats/PssTable.java
index 1e7c566..f858e55 100644
--- a/core/java/com/android/internal/app/procstats/PssTable.java
+++ b/core/java/com/android/internal/app/procstats/PssTable.java
@@ -28,6 +28,10 @@
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
+import android.service.procstats.ProcessStatsProto;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
+
/**
* Class to accumulate PSS data.
*/
@@ -46,18 +50,17 @@
public void mergeStats(PssTable that) {
final int N = that.getKeyCount();
for (int i=0; i<N; i++) {
- final int key = that.getKeyAt(i);
- final int state = SparseMappingTable.getIdFromKey(key);
- mergeStats(state, (int)that.getValue(key, PSS_SAMPLE_COUNT),
- that.getValue(key, PSS_MINIMUM),
- that.getValue(key, PSS_AVERAGE),
- that.getValue(key, PSS_MAXIMUM),
- that.getValue(key, PSS_USS_MINIMUM),
- that.getValue(key, PSS_USS_AVERAGE),
- that.getValue(key, PSS_USS_MAXIMUM),
- that.getValue(key, PSS_RSS_MINIMUM),
- that.getValue(key, PSS_RSS_AVERAGE),
- that.getValue(key, PSS_RSS_MAXIMUM));
+ final int thatKey = that.getKeyAt(i);
+ final int state = SparseMappingTable.getIdFromKey(thatKey);
+
+ final int key = getOrAddKey((byte)state, PSS_COUNT);
+ final long[] stats = getArrayForKey(key);
+ final int statsIndex = SparseMappingTable.getIndexFromKey(key);
+
+ final long[] thatStats = that.getArrayForKey(thatKey);
+ final int thatStatsIndex = SparseMappingTable.getIndexFromKey(thatKey);
+
+ mergeStats(stats, statsIndex, thatStats, thatStatsIndex);
}
}
@@ -68,64 +71,100 @@
public void mergeStats(int state, int inCount, long minPss, long avgPss, long maxPss,
long minUss, long avgUss, long maxUss, long minRss, long avgRss, long maxRss) {
final int key = getOrAddKey((byte)state, PSS_COUNT);
- final long count = getValue(key, PSS_SAMPLE_COUNT);
+ final long[] stats = getArrayForKey(key);
+ final int statsIndex = SparseMappingTable.getIndexFromKey(key);
+ mergeStats(stats, statsIndex, inCount, minPss, avgPss, maxPss, minUss, avgUss, maxUss,
+ minRss, avgRss, maxRss);
+ }
+
+ public static void mergeStats(final long[] stats, final int statsIndex,
+ final long[] thatStats, int thatStatsIndex) {
+ mergeStats(stats, statsIndex, (int)thatStats[thatStatsIndex + PSS_SAMPLE_COUNT],
+ thatStats[thatStatsIndex + PSS_MINIMUM],
+ thatStats[thatStatsIndex + PSS_AVERAGE],
+ thatStats[thatStatsIndex + PSS_MAXIMUM],
+ thatStats[thatStatsIndex + PSS_USS_MINIMUM],
+ thatStats[thatStatsIndex + PSS_USS_AVERAGE],
+ thatStats[thatStatsIndex + PSS_USS_MAXIMUM],
+ thatStats[thatStatsIndex + PSS_RSS_MINIMUM],
+ thatStats[thatStatsIndex + PSS_RSS_AVERAGE],
+ thatStats[thatStatsIndex + PSS_RSS_MAXIMUM]);
+ }
+
+ public static void mergeStats(final long[] stats, final int statsIndex, final int inCount,
+ final long minPss, final long avgPss, final long maxPss,
+ final long minUss, final long avgUss, final long maxUss,
+ final long minRss, final long avgRss, final long maxRss) {
+ final long count = stats[statsIndex + PSS_SAMPLE_COUNT];
if (count == 0) {
- setValue(key, PSS_SAMPLE_COUNT, inCount);
- setValue(key, PSS_MINIMUM, minPss);
- setValue(key, PSS_AVERAGE, avgPss);
- setValue(key, PSS_MAXIMUM, maxPss);
- setValue(key, PSS_USS_MINIMUM, minUss);
- setValue(key, PSS_USS_AVERAGE, avgUss);
- setValue(key, PSS_USS_MAXIMUM, maxUss);
- setValue(key, PSS_RSS_MINIMUM, minRss);
- setValue(key, PSS_RSS_AVERAGE, avgRss);
- setValue(key, PSS_RSS_MAXIMUM, maxRss);
+ stats[statsIndex + PSS_SAMPLE_COUNT] = inCount;
+ stats[statsIndex + PSS_MINIMUM] = minPss;
+ stats[statsIndex + PSS_AVERAGE] = avgPss;
+ stats[statsIndex + PSS_MAXIMUM] = maxPss;
+ stats[statsIndex + PSS_USS_MINIMUM] = minUss;
+ stats[statsIndex + PSS_USS_AVERAGE] = avgUss;
+ stats[statsIndex + PSS_USS_MAXIMUM] = maxUss;
+ stats[statsIndex + PSS_RSS_MINIMUM] = minRss;
+ stats[statsIndex + PSS_RSS_AVERAGE] = avgRss;
+ stats[statsIndex + PSS_RSS_MAXIMUM] = maxRss;
} else {
- setValue(key, PSS_SAMPLE_COUNT, count + inCount);
+ stats[statsIndex + PSS_SAMPLE_COUNT] = count + inCount;
- long val;
-
- val = getValue(key, PSS_MINIMUM);
- if (val > minPss) {
- setValue(key, PSS_MINIMUM, minPss);
+ if (stats[statsIndex + PSS_MINIMUM] > minPss) {
+ stats[statsIndex + PSS_MINIMUM] = minPss;
}
- val = getValue(key, PSS_AVERAGE);
- setValue(key, PSS_AVERAGE,
- (long)(((val*(double)count)+(avgPss*(double)inCount)) / (count+inCount)));
+ stats[statsIndex + PSS_AVERAGE] = (long)(((stats[statsIndex + PSS_AVERAGE]
+ * (double)count) + (avgPss * (double)inCount)) / (count + inCount));
- val = getValue(key, PSS_MAXIMUM);
- if (val < maxPss) {
- setValue(key, PSS_MAXIMUM, maxPss);
+ if (stats[statsIndex + PSS_MAXIMUM] < maxPss) {
+ stats[statsIndex + PSS_MAXIMUM] = maxPss;
}
- val = getValue(key, PSS_USS_MINIMUM);
- if (val > minUss) {
- setValue(key, PSS_USS_MINIMUM, minUss);
+ if (stats[statsIndex + PSS_USS_MINIMUM] > minUss) {
+ stats[statsIndex + PSS_USS_MINIMUM] = minUss;
}
- val = getValue(key, PSS_USS_AVERAGE);
- setValue(key, PSS_USS_AVERAGE,
- (long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount)));
+ stats[statsIndex + PSS_USS_AVERAGE] = (long)(((stats[statsIndex + PSS_USS_AVERAGE]
+ * (double)count) + (avgUss * (double)inCount)) / (count + inCount));
- val = getValue(key, PSS_USS_MAXIMUM);
- if (val < maxUss) {
- setValue(key, PSS_USS_MAXIMUM, maxUss);
+ if (stats[statsIndex + PSS_USS_MAXIMUM] < maxUss) {
+ stats[statsIndex + PSS_USS_MAXIMUM] = maxUss;
}
- val = getValue(key, PSS_RSS_MINIMUM);
- if (val > minUss) {
- setValue(key, PSS_RSS_MINIMUM, minUss);
+ if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) {
+ stats[statsIndex + PSS_RSS_MINIMUM] = minRss;
}
- val = getValue(key, PSS_RSS_AVERAGE);
- setValue(key, PSS_RSS_AVERAGE,
- (long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount)));
+ stats[statsIndex + PSS_RSS_AVERAGE] = (long)(((stats[statsIndex + PSS_RSS_AVERAGE]
+ * (double)count) + (avgRss * (double)inCount)) / (count + inCount));
- val = getValue(key, PSS_RSS_MAXIMUM);
- if (val < maxUss) {
- setValue(key, PSS_RSS_MAXIMUM, maxUss);
+ if (stats[statsIndex + PSS_RSS_MAXIMUM] < maxRss) {
+ stats[statsIndex + PSS_RSS_MAXIMUM] = maxRss;
}
}
}
+
+ public void writeStatsToProtoForKey(ProtoOutputStream proto, int key) {
+ final long[] stats = getArrayForKey(key);
+ final int statsIndex = SparseMappingTable.getIndexFromKey(key);
+ writeStatsToProto(proto, stats, statsIndex);
+ }
+
+ public static void writeStatsToProto(ProtoOutputStream proto, final long[] stats,
+ final int statsIndex) {
+ proto.write(ProcessStatsProto.State.SAMPLE_SIZE, stats[statsIndex + PSS_SAMPLE_COUNT]);
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.PSS,
+ stats[statsIndex + PSS_MINIMUM],
+ stats[statsIndex + PSS_AVERAGE],
+ stats[statsIndex + PSS_MAXIMUM]);
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.USS,
+ stats[statsIndex + PSS_USS_MINIMUM],
+ stats[statsIndex + PSS_USS_AVERAGE],
+ stats[statsIndex + PSS_USS_MAXIMUM]);
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.RSS,
+ stats[statsIndex + PSS_RSS_MINIMUM],
+ stats[statsIndex + PSS_RSS_AVERAGE],
+ stats[statsIndex + PSS_RSS_MAXIMUM]);
+ }
}
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 5a39915..eb369e1 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -17,12 +17,19 @@
package com.android.internal.os;
import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.BatteryManagerInternal;
import android.os.Binder;
+import android.os.OsProtoEnums;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.format.DateFormat;
import android.util.ArrayMap;
-import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -31,6 +38,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BinderInternal.CallSession;
import com.android.internal.util.Preconditions;
+import com.android.server.LocalServices;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
@@ -74,38 +82,117 @@
private final Random mRandom;
private long mStartTime = System.currentTimeMillis();
- public BinderCallsStats(Random random) {
- this.mRandom = random;
+ // State updated by the broadcast receiver below.
+ private boolean mScreenInteractive;
+ private boolean mCharging;
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case Intent.ACTION_BATTERY_CHANGED:
+ mCharging = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
+ break;
+ case Intent.ACTION_SCREEN_ON:
+ mScreenInteractive = true;
+ break;
+ case Intent.ACTION_SCREEN_OFF:
+ mScreenInteractive = false;
+ break;
+ }
+ }
+ };
+
+ /** Injector for {@link BinderCallsStats}. */
+ public static class Injector {
+ public Random getRandomGenerator() {
+ return new Random();
+ }
+ }
+
+ public BinderCallsStats(Injector injector) {
+ this.mRandom = injector.getRandomGenerator();
+ }
+
+ public void systemReady(Context context) {
+ registerBroadcastReceiver(context);
+ setInitialState(queryScreenInteractive(context), queryIsCharging());
+ }
+
+ /**
+ * Listens for screen/battery state changes.
+ */
+ @VisibleForTesting
+ public void registerBroadcastReceiver(Context context) {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+ context.registerReceiver(mBroadcastReceiver, filter);
+ }
+
+ /**
+ * Sets the battery/screen initial state.
+ *
+ * This has to be updated *after* the broadcast receiver is installed.
+ */
+ @VisibleForTesting
+ public void setInitialState(boolean isScreenInteractive, boolean isCharging) {
+ this.mScreenInteractive = isScreenInteractive;
+ this.mCharging = isCharging;
+ // Data collected previously was not accurate since the battery/screen state was not set.
+ reset();
+ }
+
+ private boolean queryIsCharging() {
+ final BatteryManagerInternal batteryManager =
+ LocalServices.getService(BatteryManagerInternal.class);
+ if (batteryManager == null) {
+ Slog.wtf(TAG, "BatteryManager null while starting BinderCallsStatsService");
+ // Default to true to not collect any data.
+ return true;
+ } else {
+ return batteryManager.getPlugType() != OsProtoEnums.BATTERY_PLUGGED_NONE;
+ }
+ }
+
+ private boolean queryScreenInteractive(Context context) {
+ final PowerManager powerManager = context.getSystemService(PowerManager.class);
+ final boolean screenInteractive;
+ if (powerManager == null) {
+ Slog.wtf(TAG, "PowerManager null while starting BinderCallsStatsService",
+ new Throwable());
+ return true;
+ } else {
+ return powerManager.isInteractive();
+ }
}
@Override
+ @Nullable
public CallSession callStarted(Binder binder, int code) {
- return callStarted(binder.getClass(), code);
- }
-
- private CallSession callStarted(Class<? extends Binder> binderClass, int code) {
- CallSession s = mCallSessionsPool.poll();
- if (s == null) {
- s = new CallSession();
+ if (mCharging) {
+ return null;
}
- s.binderClass = binderClass;
+ final CallSession s = obtainCallSession();
+ s.binderClass = binder.getClass();
s.transactionCode = code;
s.exceptionThrown = false;
s.cpuTimeStarted = -1;
s.timeStarted = -1;
-
- synchronized (mLock) {
- if (!mDetailedTracking && !shouldTrackCall()) {
- return s;
- }
-
+ if (mDetailedTracking || shouldRecordDetailedData()) {
s.cpuTimeStarted = getThreadTimeMicro();
s.timeStarted = getElapsedRealtimeMicro();
}
return s;
}
+ private CallSession obtainCallSession() {
+ CallSession s = mCallSessionsPool.poll();
+ return s == null ? new CallSession() : s;
+ }
+
@Override
public void callEnded(@Nullable CallSession s, int parcelRequestSize, int parcelReplySize) {
if (s == null) {
@@ -134,13 +221,15 @@
final int callingUid = getCallingUid();
synchronized (mLock) {
- UidEntry uidEntry = mUidEntries.get(callingUid);
- if (uidEntry == null) {
- uidEntry = new UidEntry(callingUid);
- mUidEntries.put(callingUid, uidEntry);
+ // This was already checked in #callStart but check again while synchronized.
+ if (mCharging) {
+ return;
}
+
+ final UidEntry uidEntry = getUidEntry(callingUid);
uidEntry.callCount++;
- CallStat callStat = uidEntry.getOrCreate(s.binderClass, s.transactionCode);
+ final CallStat callStat = uidEntry.getOrCreate(
+ s.binderClass, s.transactionCode, mScreenInteractive);
callStat.callCount++;
if (recordCall) {
@@ -164,6 +253,15 @@
}
}
+ private UidEntry getUidEntry(int uid) {
+ UidEntry uidEntry = mUidEntries.get(uid);
+ if (uidEntry == null) {
+ uidEntry = new UidEntry(uid);
+ mUidEntries.put(uid, uidEntry);
+ }
+ return uidEntry;
+ }
+
@Override
public void callThrewException(@Nullable CallSession s, Exception exception) {
if (s == null) {
@@ -176,12 +274,12 @@
if (mExceptionCounts.size() >= MAX_EXCEPTION_COUNT_SIZE) {
className = EXCEPTION_COUNT_OVERFLOW_NAME;
}
- Integer count = mExceptionCounts.get(className);
+ final Integer count = mExceptionCounts.get(className);
mExceptionCounts.put(className, count == null ? 1 : count + 1);
}
} catch (RuntimeException e) {
// Do not propagate the exception. We do not want to swallow original exception.
- Log.wtf(TAG, "Unexpected exception while updating mExceptionCounts", e);
+ Slog.wtf(TAG, "Unexpected exception while updating mExceptionCounts");
}
}
@@ -219,15 +317,16 @@
ArrayList<ExportedCallStat> resultCallStats = new ArrayList<>();
synchronized (mLock) {
- int uidEntriesSize = mUidEntries.size();
+ final int uidEntriesSize = mUidEntries.size();
for (int entryIdx = 0; entryIdx < uidEntriesSize; entryIdx++){
- UidEntry entry = mUidEntries.valueAt(entryIdx);
+ final UidEntry entry = mUidEntries.valueAt(entryIdx);
for (CallStat stat : entry.getCallStatsList()) {
ExportedCallStat exported = new ExportedCallStat();
exported.uid = entry.uid;
exported.className = stat.binderClass.getName();
exported.binderClass = stat.binderClass;
exported.transactionCode = stat.transactionCode;
+ exported.screenInteractive = stat.screenInteractive;
exported.cpuTimeMicros = stat.cpuTimeMicros;
exported.maxCpuTimeMicros = stat.maxCpuTimeMicros;
exported.latencyMicros = stat.latencyMicros;
@@ -294,9 +393,9 @@
pw.print("Start time: ");
pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStartTime));
pw.println("Sampling interval period: " + mPeriodicSamplingInterval);
- List<UidEntry> entries = new ArrayList<>();
+ final List<UidEntry> entries = new ArrayList<>();
- int uidEntriesSize = mUidEntries.size();
+ final int uidEntriesSize = mUidEntries.size();
for (int i = 0; i < uidEntriesSize; i++) {
UidEntry e = mUidEntries.valueAt(i);
entries.add(e);
@@ -306,16 +405,17 @@
}
entries.sort(Comparator.<UidEntry>comparingDouble(value -> value.cpuTimeMicros).reversed());
- String datasetSizeDesc = verbose ? "" : "(top 90% by cpu time) ";
- StringBuilder sb = new StringBuilder();
- List<UidEntry> topEntries = verbose ? entries
+ final String datasetSizeDesc = verbose ? "" : "(top 90% by cpu time) ";
+ final StringBuilder sb = new StringBuilder();
+ final List<UidEntry> topEntries = verbose ? entries
: getHighestValues(entries, value -> value.cpuTimeMicros, 0.9);
pw.println("Per-UID raw data " + datasetSizeDesc
- + "(package/uid, call_desc, cpu_time_micros, max_cpu_time_micros, "
+ + "(package/uid, call_desc, screen_interactive, "
+ + "cpu_time_micros, max_cpu_time_micros, "
+ "latency_time_micros, max_latency_time_micros, exception_count, "
+ "max_request_size_bytes, max_reply_size_bytes, recorded_call_count, "
+ "call_count):");
- List<ExportedCallStat> exportedCallStats = getExportedCallStats();
+ final List<ExportedCallStat> exportedCallStats = getExportedCallStats();
exportedCallStats.sort(BinderCallsStats::compareByCpuDesc);
for (ExportedCallStat e : exportedCallStats) {
sb.setLength(0);
@@ -323,6 +423,7 @@
.append(uidToString(e.uid, appIdToPkgNameMap))
.append(',').append(e.className)
.append('#').append(e.methodName)
+ .append(',').append(e.screenInteractive)
.append(',').append(e.cpuTimeMicros)
.append(',').append(e.maxCpuTimeMicros)
.append(',').append(e.latencyMicros)
@@ -337,7 +438,7 @@
pw.println();
pw.println("Per-UID Summary " + datasetSizeDesc
+ "(cpu_time, % of total cpu_time, recorded_call_count, call_count, package/uid):");
- List<UidEntry> summaryEntries = verbose ? entries
+ final List<UidEntry> summaryEntries = verbose ? entries
: getHighestValues(entries, value -> value.cpuTimeMicros, 0.9);
for (UidEntry entry : summaryEntries) {
String uidStr = uidToString(entry.uid, appIdToPkgNameMap);
@@ -352,7 +453,7 @@
pw.println();
pw.println("Exceptions thrown (exception_count, class_name):");
- List<Pair<String, Integer>> exceptionEntries = new ArrayList<>();
+ final List<Pair<String, Integer>> exceptionEntries = new ArrayList<>();
// We cannot use new ArrayList(Collection) constructor because MapCollections does not
// implement toArray method.
mExceptionCounts.entrySet().iterator().forEachRemaining(
@@ -369,9 +470,9 @@
}
private static String uidToString(int uid, Map<Integer, String> pkgNameMap) {
- int appId = UserHandle.getAppId(uid);
- String pkgName = pkgNameMap == null ? null : pkgNameMap.get(appId);
- String uidStr = UserHandle.formatUid(uid);
+ final int appId = UserHandle.getAppId(uid);
+ final String pkgName = pkgNameMap == null ? null : pkgNameMap.get(appId);
+ final String uidStr = UserHandle.formatUid(uid);
return pkgName == null ? uidStr : pkgName + '/' + uidStr;
}
@@ -387,7 +488,7 @@
return SystemClock.elapsedRealtimeNanos() / 1000;
}
- private boolean shouldTrackCall() {
+ private boolean shouldRecordDetailedData() {
return mRandom.nextInt() % mPeriodicSamplingInterval == 0;
}
@@ -444,6 +545,8 @@
public static class CallStat {
public Class<? extends Binder> binderClass;
public int transactionCode;
+ // True if the screen was interactive when the call ended.
+ public boolean screenInteractive;
// Number of calls for which we collected data for. We do not record data for all the calls
// when sampling is on.
public long recordedCallCount;
@@ -464,9 +567,11 @@
public long maxReplySizeBytes;
public long exceptionCount;
- CallStat(Class<? extends Binder> binderClass, int transactionCode) {
+ CallStat(Class<? extends Binder> binderClass, int transactionCode,
+ boolean screenInteractive) {
this.binderClass = binderClass;
this.transactionCode = transactionCode;
+ this.screenInteractive = screenInteractive;
}
}
@@ -474,6 +579,7 @@
public static class CallStatKey {
public Class<? extends Binder> binderClass;
public int transactionCode;
+ private boolean screenInteractive;
@Override
public boolean equals(Object o) {
@@ -481,8 +587,9 @@
return true;
}
- CallStatKey key = (CallStatKey) o;
+ final CallStatKey key = (CallStatKey) o;
return transactionCode == key.transactionCode
+ && screenInteractive == key.screenInteractive
&& (binderClass.equals(key.binderClass));
}
@@ -490,6 +597,7 @@
public int hashCode() {
int result = binderClass.hashCode();
result = 31 * result + transactionCode;
+ result = 31 * result + (screenInteractive ? 1231 : 1237);
return result;
}
}
@@ -516,17 +624,20 @@
private Map<CallStatKey, CallStat> mCallStats = new ArrayMap<>();
private CallStatKey mTempKey = new CallStatKey();
- CallStat getOrCreate(Class<? extends Binder> binderClass, int transactionCode) {
+ CallStat getOrCreate(Class<? extends Binder> binderClass, int transactionCode,
+ boolean screenInteractive) {
// Use a global temporary key to avoid creating new objects for every lookup.
mTempKey.binderClass = binderClass;
mTempKey.transactionCode = transactionCode;
+ mTempKey.screenInteractive = screenInteractive;
CallStat mapCallStat = mCallStats.get(mTempKey);
// Only create CallStat if it's a new entry, otherwise update existing instance
if (mapCallStat == null) {
- mapCallStat = new CallStat(binderClass, transactionCode);
+ mapCallStat = new CallStat(binderClass, transactionCode, screenInteractive);
CallStatKey key = new CallStatKey();
key.binderClass = binderClass;
key.transactionCode = transactionCode;
+ key.screenInteractive = screenInteractive;
mCallStats.put(key, mapCallStat);
}
return mapCallStat;
@@ -595,6 +706,11 @@
return result;
}
+ @VisibleForTesting
+ public BroadcastReceiver getBroadcastReceiver() {
+ return mBroadcastReceiver;
+ }
+
private static int compareByCpuDesc(
ExportedCallStat a, ExportedCallStat b) {
return Long.compare(b.cpuTimeMicros, a.cpuTimeMicros);
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 2790324..616520f 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -140,14 +140,14 @@
void showShutdownUi(boolean isReboot, String reason);
- // Used to show the dialog when FingerprintService starts authentication
- void showFingerprintDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
- // Used to hide the dialog when a finger is authenticated
- void onFingerprintAuthenticated();
+ // Used to show the dialog when BiometricService starts authentication
+ void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
+ // Used to hide the dialog when a biometric is authenticated
+ void onBiometricAuthenticated();
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
- void onFingerprintHelp(String message);
+ void onBiometricHelp(String message);
// Used to set a message - the dialog will dismiss after a certain amount of time
- void onFingerprintError(String error);
- // Used to hide the fingerprint dialog when the authenticationclient is stopped
- void hideFingerprintDialog();
+ void onBiometricError(String error);
+ // Used to hide the biometric dialog when the AuthenticationClient is stopped
+ void hideBiometricDialog();
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 159d49b..a79e15a 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -90,14 +90,14 @@
void showPinningEnterExitToast(boolean entering);
void showPinningEscapeToast();
- // Used to show the dialog when FingerprintService starts authentication
- void showFingerprintDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
- // Used to hide the dialog when a finger is authenticated
- void onFingerprintAuthenticated();
+ // Used to show the dialog when BiometricService starts authentication
+ void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
+ // Used to hide the dialog when a biometric is authenticated
+ void onBiometricAuthenticated();
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
- void onFingerprintHelp(String message);
+ void onBiometricHelp(String message);
// Used to set a message - the dialog will dismiss after a certain amount of time
- void onFingerprintError(String error);
- // Used to hide the fingerprint dialog when the authenticationclient is stopped
- void hideFingerprintDialog();
+ void onBiometricError(String error);
+ // Used to hide the biometric dialog when the AuthenticationClient is stopped
+ void hideBiometricDialog();
}
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 3b024b4..db3bfe6 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -320,9 +320,12 @@
jintArray jcolors, jint colorIndex,
jshortArray jindices, jint indexIndex,
jint indexCount, jlong paintHandle) {
+
+ const int vertexCount = floatCount >> 1; // 2 floats per SkPoint
+
AutoJavaFloatArray vertA(env, jverts, vertIndex + floatCount);
AutoJavaFloatArray texA(env, jtexs, texIndex + floatCount);
- AutoJavaIntArray colorA(env, jcolors, colorIndex + floatCount);
+ AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount);
AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount);
const float* verts = vertA.ptr() + vertIndex;
@@ -337,7 +340,6 @@
indices = (const uint16_t*)(indexA.ptr() + indexIndex);
}
- int vertexCount = floatCount >> 1; // 2 floats per SkPoint
SkVertices::VertexMode mode = static_cast<SkVertices::VertexMode>(modeHandle);
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawVertices(SkVertices::MakeCopy(mode, vertexCount,
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index 15ede0c..b2a88b7 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -174,4 +174,8 @@
optional android.util.AggStats rss = 8;
}
repeated State states = 5;
+
+ // Total time process has been running... screen_state, memory_state, and process_state
+ // will not be set.
+ optional State total_running_state = 6;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c2ff9c9..6a3487c1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -606,6 +606,14 @@
<protected-broadcast android:name="android.intent.action.DOCK_IDLE" />
<protected-broadcast android:name="android.intent.action.DOCK_ACTIVE" />
+ <!-- Added in Q -->
+
+ <!-- For CarIdlenessTracker -->
+ <protected-broadcast android:name="com.android.server.jobscheduler.GARAGE_MODE_ON" />
+ <protected-broadcast android:name="com.android.server.jobscheduler.GARAGE_MODE_OFF" />
+ <protected-broadcast android:name="com.android.server.jobscheduler.FORCE_IDLE" />
+ <protected-broadcast android:name="com.android.server.jobscheduler.UNFORCE_IDLE" />
+
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
<!-- ====================================================================== -->
@@ -3500,6 +3508,10 @@
<permission android:name="android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE"
android:protectionLevel="signature" />
+ <!-- @hide Internal permission to allows an application to access card content provider. -->
+ <permission android:name="android.permission.WRITE_SETTINGS_HOMEPAGE_DATA"
+ android:protectionLevel="signature|privileged" />
+
<!-- @SystemApi Allows applications to set a live wallpaper.
@hide XXX Change to signature once the picker is moved to its
own apk as Ghod Intended. -->
diff --git a/core/res/res/values-night/themes_package_installer.xml b/core/res/res/values-night/themes_package_installer.xml
new file mode 100644
index 0000000..0ad2bdc
--- /dev/null
+++ b/core/res/res/values-night/themes_package_installer.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<!-- themes for the permission grant dialog. -->
+<resources>
+ <style name="Theme.DeviceDefault.PermissionGrantApp"
+ parent="@style/Theme.DeviceDefault.Panel">
+ <item name="windowIsFloating">false</item>
+ <item name="windowTranslucentStatus">true</item>
+ <item name="backgroundDimEnabled">true</item>
+ <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
+ </style>
+
+ <style name="Theme.DeviceDefault.PermissionGrant"
+ parent="@style/Theme.DeviceDefault.Dialog">
+ <item name="titleTextStyle">@style/PermissionGrantTitleMessage</item>
+ <item name="radioButtonStyle">@style/PermissionGrantRadioButton</item>
+ <item name="checkboxStyle">@style/PermissionGrantCheckbox</item>
+ <item name="buttonBarStyle">@style/PermissionGrantButtonBar</item>
+ </style>
+</resources>
diff --git a/core/res/res/values/themes_package_installer.xml b/core/res/res/values/themes_package_installer.xml
index a6341dc..3bc93cd 100644
--- a/core/res/res/values/themes_package_installer.xml
+++ b/core/res/res/values/themes_package_installer.xml
@@ -17,7 +17,7 @@
<!-- themes for the permission grant dialog. -->
<resources>
- <style name="Theme.DeviceDefault.Light.Panel.PermissionGrantApp"
+ <style name="Theme.DeviceDefault.PermissionGrantApp"
parent="@style/Theme.DeviceDefault.Light.Panel">
<item name="windowIsFloating">false</item>
<item name="windowTranslucentStatus">true</item>
@@ -25,7 +25,7 @@
<item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
</style>
- <style name="Theme.DeviceDefault.Light.Dialog.PermissionGrant"
+ <style name="Theme.DeviceDefault.PermissionGrant"
parent="@style/Theme.DeviceDefault.Light.Dialog">
<item name="titleTextStyle">@style/PermissionGrantTitleMessage</item>
<item name="radioButtonStyle">@style/PermissionGrantRadioButton</item>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 1a87fa2..5542f00 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -383,6 +383,8 @@
Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL,
Settings.Global.SETUP_PREPAID_DETECTION_REDIR_HOST,
Settings.Global.SETUP_PREPAID_DETECTION_TARGET_URL,
+ Settings.Global.SETTINGS_USE_EXTERNAL_PROVIDER_API,
+ Settings.Global.SETTINGS_USE_PSD_API,
Settings.Global.SHORTCUT_MANAGER_CONSTANTS,
Settings.Global.SHOW_FIRST_CRASH_DIALOG,
Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG,
@@ -484,6 +486,7 @@
Settings.Global.WIFI_SAVED_STATE,
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED,
Settings.Global.WIFI_SCORE_PARAMS,
Settings.Global.WIFI_SLEEP_POLICY,
Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
@@ -704,3 +707,4 @@
}
}
+
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 5599ee6..2f83190 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -16,7 +16,11 @@
package com.android.internal.os;
+import android.content.Context;
+import android.content.Intent;
+import android.os.BatteryManager;
import android.os.Binder;
+import android.os.OsProtoEnums;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -392,6 +396,113 @@
}
@Test
+ public void testDataResetWhenInitialStateSet() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ bcs.setInitialState(true, true);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(0, uidEntries.size());
+ }
+
+ @Test
+ public void testScreenAndChargerInitialStates() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Binder binder = new Binder();
+ bcs.setInitialState(true /** screen iteractive */, false);
+
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ List<BinderCallsStats.CallStat> callStatsList =
+ new ArrayList(bcs.getUidEntries().get(TEST_UID).getCallStatsList());
+ assertEquals(true, callStatsList.get(0).screenInteractive);
+ }
+
+ @Test
+ public void testNoDataCollectedOnCharger() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED)
+ .putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_AC);
+ bcs.getBroadcastReceiver().onReceive(null, intent);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ assertEquals(0, bcs.getUidEntries().size());
+ }
+
+ @Test
+ public void testScreenOff() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ bcs.getBroadcastReceiver().onReceive(null, new Intent(Intent.ACTION_SCREEN_OFF));
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(1, uidEntries.size());
+ BinderCallsStats.UidEntry uidEntry = uidEntries.get(TEST_UID);
+ Assert.assertNotNull(uidEntry);
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
+ assertEquals(false, callStatsList.get(0).screenInteractive);
+ }
+
+ @Test
+ public void testScreenOn() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ bcs.getBroadcastReceiver().onReceive(null, new Intent(Intent.ACTION_SCREEN_ON));
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(1, uidEntries.size());
+ BinderCallsStats.UidEntry uidEntry = uidEntries.get(TEST_UID);
+ Assert.assertNotNull(uidEntry);
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
+ assertEquals(true, callStatsList.get(0).screenInteractive);
+ }
+
+ @Test
+ public void testOnCharger() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED)
+ .putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_AC);
+ bcs.getBroadcastReceiver().onReceive(null, intent);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ assertEquals(0, bcs.getExportedCallStats().size());
+ }
+
+ @Test
+ public void testOnBattery() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED)
+ .putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_NONE);
+ bcs.getBroadcastReceiver().onReceive(null, intent);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ assertEquals(1, bcs.getExportedCallStats().size());
+ }
+
+ @Test
public void testDumpDoesNotThrowException() {
TestBinderCallsStats bcs = new TestBinderCallsStats();
bcs.setDetailedTracking(true);
@@ -419,6 +530,8 @@
public void testGetExportedStatsWhenDetailedTrackingEnabled() {
TestBinderCallsStats bcs = new TestBinderCallsStats();
bcs.setDetailedTracking(true);
+ bcs.getBroadcastReceiver().onReceive(null, new Intent(Intent.ACTION_SCREEN_ON));
+
Binder binder = new Binder();
CallSession callSession = bcs.callStarted(binder, 1);
bcs.time += 10;
@@ -430,6 +543,7 @@
assertEquals(TEST_UID, stat.uid);
assertEquals("android.os.Binder", stat.className);
assertEquals("1", stat.methodName);
+ assertEquals(true, stat.screenInteractive);
assertEquals(10, stat.cpuTimeMicros);
assertEquals(10, stat.maxCpuTimeMicros);
assertEquals(20, stat.latencyMicros);
@@ -462,11 +576,15 @@
TestBinderCallsStats() {
// Make random generator not random.
- super(new Random() {
- int mCallCount = 0;
+ super(new Injector() {
+ public Random getRandomGenerator() {
+ return new Random() {
+ int mCallCount = 0;
- public int nextInt() {
- return mCallCount++;
+ public int nextInt() {
+ return mCallCount++;
+ }
+ };
}
});
}
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index ffe6abc1..53e9826 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Canvas.VertexMode;
import android.text.GraphicsOperations;
import android.text.MeasuredParagraph;
@@ -44,6 +45,7 @@
* freed by NativeAllocation.
* @hide
*/
+ @UnsupportedAppUsage
protected long mNativeCanvasWrapper;
/**
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index c6f8415..cea6c1c 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.annotation.WorkerThread;
import android.content.res.ResourcesImpl;
import android.os.Parcel;
@@ -59,6 +60,7 @@
private static final long NATIVE_ALLOCATION_SIZE = 32;
// Convenience for JNI access
+ @UnsupportedAppUsage
private final long mNativePtr;
/**
@@ -75,9 +77,13 @@
*/
private boolean mRequestPremultiplied;
+ @UnsupportedAppUsage
private byte[] mNinePatchChunk; // may be null
+ @UnsupportedAppUsage
private NinePatch.InsetStruct mNinePatchInsets; // may be null
+ @UnsupportedAppUsage
private int mWidth;
+ @UnsupportedAppUsage
private int mHeight;
private boolean mRecycled;
@@ -99,11 +105,13 @@
* density when running old apps.
* @hide
*/
+ @UnsupportedAppUsage
public static void setDefaultDensity(int density) {
sDefaultDensity = density;
}
@SuppressWarnings("deprecation")
+ @UnsupportedAppUsage
static int getDefaultDensity() {
if (sDefaultDensity >= 0) {
return sDefaultDensity;
@@ -117,6 +125,7 @@
* int (pointer).
*/
// called from JNI
+ @UnsupportedAppUsage
Bitmap(long nativeBitmap, int width, int height, int density, boolean requestPremultiplied,
byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets) {
if (nativeBitmap == 0) {
@@ -158,6 +167,7 @@
* width/height values
*/
@SuppressWarnings("unused") // called from JNI
+ @UnsupportedAppUsage
void reinit(int width, int height, boolean requestPremultiplied) {
mWidth = width;
mHeight = height;
@@ -328,6 +338,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setNinePatchChunk(byte[] chunk) {
mNinePatchChunk = chunk;
}
@@ -523,6 +534,7 @@
*/
HARDWARE (7);
+ @UnsupportedAppUsage
final int nativeInt;
private static Config sConfigs[] = {
@@ -533,6 +545,7 @@
this.nativeInt = ni;
}
+ @UnsupportedAppUsage
static Config nativeToConfig(int ni) {
return sConfigs[ni];
}
@@ -667,6 +680,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Bitmap createAshmemBitmap() {
checkRecycled("Can't copy a recycled bitmap");
noteHardwareBitmapSlowCall();
@@ -685,6 +699,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Bitmap createAshmemBitmap(Config config) {
checkRecycled("Can't copy a recycled bitmap");
noteHardwareBitmapSlowCall();
@@ -703,6 +718,7 @@
* currently PIXEL_FORMAT_RGBA_8888 is the only supported format
* @hide
*/
+ @UnsupportedAppUsage
public static Bitmap createHardwareBitmap(@NonNull GraphicBuffer graphicBuffer) {
return nativeCreateHardwareBitmap(graphicBuffer);
}
@@ -1500,6 +1516,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
static public int scaleFromDensity(int size, int sdensity, int tdensity) {
if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) {
return size;
@@ -2032,6 +2049,7 @@
* @return {@link GraphicBuffer} which is internally used by hardware bitmap
* @hide
*/
+ @UnsupportedAppUsage
public GraphicBuffer createGraphicBufferHandle() {
return nativeCreateGraphicBufferHandle(mNativePtr);
}
@@ -2049,6 +2067,7 @@
private static native Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig);
private static native long nativeGetNativeFinalizer();
private static native void nativeRecycle(long nativeBitmap);
+ @UnsupportedAppUsage
private static native void nativeReconfigure(long nativeBitmap, int width, int height,
int config, boolean isPremultiplied);
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 7ea35e7..adab1a9c 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Trace;
@@ -831,11 +832,15 @@
return decodeFileDescriptor(fd, null, null);
}
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
Rect padding, Options opts);
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
Rect padding, Options opts);
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeAsset(long nativeAsset, Rect padding, Options opts);
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts);
private static native boolean nativeIsSeekable(FileDescriptor fd);
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java
index 2da27c7..9b5027d 100644
--- a/graphics/java/android/graphics/BitmapRegionDecoder.java
+++ b/graphics/java/android/graphics/BitmapRegionDecoder.java
@@ -15,6 +15,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import java.io.FileDescriptor;
@@ -165,6 +166,7 @@
This can be called from JNI code.
*/
+ @UnsupportedAppUsage
private BitmapRegionDecoder(long decoder) {
mNativeBitmapRegionDecoder = decoder;
mRecycled = false;
@@ -267,6 +269,7 @@
private static native int nativeGetHeight(long lbm);
private static native void nativeClean(long lbm);
+ @UnsupportedAppUsage
private static native BitmapRegionDecoder nativeNewInstance(
byte[] data, int offset, int length, boolean isShareable);
private static native BitmapRegionDecoder nativeNewInstance(
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index 5577f53..bcf7229 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
/**
* Shader used to draw a bitmap as a texture. The bitmap can be repeated or
@@ -28,9 +29,12 @@
* @hide
*/
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+ @UnsupportedAppUsage
public Bitmap mBitmap;
+ @UnsupportedAppUsage
private int mTileX;
+ @UnsupportedAppUsage
private int mTileY;
/**
diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java
index 60588d0..3388941 100644
--- a/graphics/java/android/graphics/Camera.java
+++ b/graphics/java/android/graphics/Camera.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* A camera instance can be used to compute 3D transformations and
* generate a matrix that can be applied, for instance, on a
@@ -174,5 +176,6 @@
private native void nativeGetMatrix(long native_matrix);
private native void nativeApplyToCanvas(long native_canvas);
+ @UnsupportedAppUsage
long native_instance;
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index a465eea..ef58c8f 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.os.Build;
import dalvik.annotation.optimization.CriticalNative;
@@ -54,6 +55,7 @@
public static boolean sCompatibilitySetBitmap = false;
/** @hide */
+ @UnsupportedAppUsage
public long getNativeCanvasWrapper() {
return mNativeCanvasWrapper;
}
@@ -62,6 +64,7 @@
public boolean isRecordingFor(Object o) { return false; }
// may be null
+ @UnsupportedAppUsage
private Bitmap mBitmap;
// optional field set by the caller
@@ -123,6 +126,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public Canvas(long nativeCanvas) {
if (nativeCanvas == 0) {
throw new IllegalStateException();
@@ -141,6 +145,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
protected GL getGL() {
return null;
}
@@ -269,6 +274,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public void setScreenDensity(int density) {
mScreenDensity = density;
}
@@ -1263,6 +1269,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void release() {
mNativeCanvasWrapper = 0;
if (mFinalizer != null) {
@@ -1276,6 +1283,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static void freeCaches() {
nFreeCaches();
}
@@ -1285,6 +1293,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static void freeTextLayoutCaches() {
nFreeTextLayoutCaches();
}
@@ -1591,9 +1600,9 @@
* Draw the specified circle using the specified paint. If radius is <= 0, then nothing will be
* drawn. The circle will be filled or framed based on the Style in the paint.
*
- * @param cx The x-coordinate of the center of the cirle to be drawn
- * @param cy The y-coordinate of the center of the cirle to be drawn
- * @param radius The radius of the cirle to be drawn
+ * @param cx The x-coordinate of the center of the circle to be drawn
+ * @param cy The y-coordinate of the center of the circle to be drawn
+ * @param radius The radius of the circle to be drawn
* @param paint The paint used to draw the circle
*/
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
diff --git a/graphics/java/android/graphics/CanvasProperty.java b/graphics/java/android/graphics/CanvasProperty.java
index ea3886c..1275e08 100644
--- a/graphics/java/android/graphics/CanvasProperty.java
+++ b/graphics/java/android/graphics/CanvasProperty.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import com.android.internal.util.VirtualRefBasePtr;
/**
@@ -26,10 +27,12 @@
private VirtualRefBasePtr mProperty;
+ @UnsupportedAppUsage
public static CanvasProperty<Float> createFloat(float initialValue) {
return new CanvasProperty<Float>(nCreateFloat(initialValue));
}
+ @UnsupportedAppUsage
public static CanvasProperty<Paint> createPaint(Paint initialValue) {
return new CanvasProperty<Paint>(nCreatePaint(initialValue.getNativeInstance()));
}
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 9201a2e..0f7980c 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
/**
* A color filter that transforms colors through a 4x5 color matrix. This filter
@@ -26,6 +27,7 @@
* @see ColorMatrix
*/
public class ColorMatrixColorFilter extends ColorFilter {
+ @UnsupportedAppUsage
private final ColorMatrix mMatrix = new ColorMatrix();
/**
@@ -76,6 +78,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorMatrix(@Nullable ColorMatrix matrix) {
discardNativeInstance();
if (matrix == null) {
@@ -104,6 +107,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorMatrixArray(@Nullable float[] array) {
// called '...Array' so that passing null isn't ambiguous
discardNativeInstance();
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index c69eb32..229923c 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.graphics.fonts.FontVariationAxis;
import android.text.TextUtils;
@@ -51,16 +52,19 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public long mNativePtr;
// Points native font family builder. Must be zero after freezing this family.
private long mBuilderPtr;
+ @UnsupportedAppUsage
public FontFamily() {
mBuilderPtr = nInitBuilder(null, 0);
mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr);
}
+ @UnsupportedAppUsage
public FontFamily(@Nullable String[] langs, int variant) {
final String langsString;
if (langs == null || langs.length == 0) {
@@ -80,6 +84,7 @@
* @return boolean returns false if some error happens in native code, e.g. broken font file is
* passed, etc.
*/
+ @UnsupportedAppUsage
public boolean freeze() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen");
@@ -93,6 +98,7 @@
return mNativePtr != 0;
}
+ @UnsupportedAppUsage
public void abortCreation() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen or abandoned");
@@ -122,6 +128,7 @@
}
}
+ @UnsupportedAppUsage
public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes,
int weight, int italic) {
if (mBuilderPtr == 0) {
@@ -147,6 +154,7 @@
* using the OS/2 table in the font.
* @return
*/
+ @UnsupportedAppUsage
public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie,
boolean isAsset, int ttcIndex, int weight, int isItalic,
FontVariationAxis[] axes) {
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 431d0e0..e3e8380 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontVariationAxis;
import android.text.FontConfig;
import android.util.Xml;
@@ -37,6 +38,7 @@
public class FontListParser {
/* Parse fallback list (no names) */
+ @UnsupportedAppUsage
public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java
index 53d2177..7408683 100644
--- a/graphics/java/android/graphics/GraphicBuffer.java
+++ b/graphics/java/android/graphics/GraphicBuffer.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -53,6 +54,7 @@
private final int mFormat;
private final int mUsage;
// Note: do not rename, this field is used by native code
+ @UnsupportedAppUsage
private final long mNativeObject;
// These two fields are only used by lock/unlockCanvas()
@@ -84,6 +86,7 @@
/**
* Private use only. See {@link #create(int, int, int, int)}.
*/
+ @UnsupportedAppUsage
private GraphicBuffer(int width, int height, int format, int usage, long nativeObject) {
mWidth = width;
mHeight = height;
@@ -96,6 +99,7 @@
* For SurfaceControl JNI.
* @hide
*/
+ @UnsupportedAppUsage
public static GraphicBuffer createFromExisting(int width, int height,
int format, int usage, long unwrappedNativeObject) {
long nativeObject = nWrapGraphicBuffer(unwrappedNativeObject);
@@ -274,6 +278,7 @@
nWriteGraphicBufferToParcel(mNativeObject, dest);
}
+ @UnsupportedAppUsage
public static final Parcelable.Creator<GraphicBuffer> CREATOR =
new Parcelable.Creator<GraphicBuffer>() {
public GraphicBuffer createFromParcel(Parcel in) {
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 098f100..7bed1ac 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -28,6 +28,7 @@
import android.annotation.Nullable;
import android.annotation.Px;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.annotation.WorkerThread;
import android.content.ContentResolver;
import android.content.res.AssetFileDescriptor;
@@ -1856,6 +1857,7 @@
* Private method called by JNI.
*/
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
private int postProcessAndRelease(@NonNull Canvas canvas) {
try {
return mPostProcessor.onPostProcess(canvas);
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 43fd270..9546a4a 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
public class ImageFormat {
/*
* these constants are chosen to be binary compatible with their previous
@@ -103,6 +105,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int Y8 = 0x20203859;
/**
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index 1578ffb..62a890f 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -22,6 +22,7 @@
package android.graphics;
import android.annotation.ColorInt;
+import android.annotation.UnsupportedAppUsage;
/**
* A color filter that can be used to simulate simple lighting effects.
@@ -72,6 +73,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorMultiply(@ColorInt int mul) {
if (mMul != mul) {
mMul = mul;
@@ -97,6 +99,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorAdd(@ColorInt int add) {
if (mAdd != add) {
mAdd = add;
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 7139efe..7e6fc35 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -19,6 +19,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
public class LinearGradient extends Shader {
@@ -31,15 +32,24 @@
*/
private int mType;
+ @UnsupportedAppUsage
private float mX0;
+ @UnsupportedAppUsage
private float mY0;
+ @UnsupportedAppUsage
private float mX1;
+ @UnsupportedAppUsage
private float mY1;
+ @UnsupportedAppUsage
private int[] mColors;
+ @UnsupportedAppUsage
private float[] mPositions;
+ @UnsupportedAppUsage
private int mColor0;
+ @UnsupportedAppUsage
private int mColor1;
+ @UnsupportedAppUsage
private TileMode mTileMode;
/**
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index 486070c..f8cb366 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -21,6 +21,7 @@
import libcore.util.NativeAllocationRegistry;
+import android.annotation.UnsupportedAppUsage;
import java.io.PrintWriter;
/**
@@ -39,6 +40,7 @@
public static final int MPERSP_2 = 8; //!< use with getValues/setValues
/** @hide */
+ @UnsupportedAppUsage
public final static Matrix IDENTITY_MATRIX = new Matrix() {
void oops() {
throw new IllegalStateException("Matrix can not be modified");
@@ -231,6 +233,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public final long native_instance;
/**
diff --git a/graphics/java/android/graphics/Movie.java b/graphics/java/android/graphics/Movie.java
index 83857be..4c953b5 100644
--- a/graphics/java/android/graphics/Movie.java
+++ b/graphics/java/android/graphics/Movie.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import java.io.FileInputStream;
@@ -25,8 +26,10 @@
* @deprecated Prefer {@link android.graphics.drawable.AnimatedImageDrawable}.
*/
public class Movie {
+ @UnsupportedAppUsage
private long mNativeMovie;
+ @UnsupportedAppUsage
private Movie(long nativeMovie) {
if (nativeMovie == 0) {
throw new RuntimeException("native movie creation failed");
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index b6a209f..800247a 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* The NinePatch class permits drawing a bitmap in nine or more sections.
* Essentially, it allows the creation of custom graphics that will scale the
@@ -41,6 +43,7 @@
*/
public static class InsetStruct {
@SuppressWarnings({"UnusedDeclaration"}) // called from JNI
+ @UnsupportedAppUsage
InsetStruct(int opticalLeft, int opticalTop, int opticalRight, int opticalBottom,
int outlineLeft, int outlineTop, int outlineRight, int outlineBottom,
float outlineRadius, int outlineAlpha, float decodeScale) {
@@ -77,6 +80,7 @@
}
}
+ @UnsupportedAppUsage
private final Bitmap mBitmap;
/**
@@ -84,6 +88,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public long mNativeChunk;
private Paint mPaint;
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 1c85df0..98c990a 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -19,6 +19,7 @@
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.drawable.Drawable;
import java.lang.annotation.Retention;
@@ -66,6 +67,7 @@
public Path mPath;
/** @hide */
+ @UnsupportedAppUsage
public final Rect mRect = new Rect();
/** @hide */
public float mRadius = RADIUS_UNDEFINED;
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 42dac38..9dab536 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -19,6 +19,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontVariationAxis;
import android.os.LocaleList;
import android.text.GraphicsOperations;
@@ -44,6 +45,7 @@
*/
public class Paint {
+ @UnsupportedAppUsage
private long mNativePaint;
private long mNativeShader;
private long mNativeColorFilter;
@@ -61,6 +63,7 @@
private MaskFilter mMaskFilter;
private PathEffect mPathEffect;
private Shader mShader;
+ @UnsupportedAppUsage
private Typeface mTypeface;
private Xfermode mXfermode;
@@ -618,6 +621,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public void setCompatibilityScaling(float factor) {
if (factor == 1.0) {
mHasCompatScaling = false;
@@ -635,6 +639,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public long getNativeInstance() {
long newNativeShader = mShader == null ? 0 : mShader.getNativeInstance();
if (newNativeShader != mNativeShader) {
@@ -1718,6 +1723,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setHyphenEdit(int hyphen) {
nSetHyphenEdit(mNativePaint, hyphen);
}
@@ -2261,6 +2267,7 @@
* @see #getTextRunAdvances(String, int, int, int, int, boolean, float[], int)
* @hide
*/
+ @UnsupportedAppUsage
public float getTextRunAdvances(char[] chars, int index, int count,
int contextIndex, int contextCount, boolean isRtl, float[] advances,
int advancesIndex) {
@@ -2451,6 +2458,7 @@
* @return the offset of the next position, or -1
* @hide
*/
+ @UnsupportedAppUsage
public int getTextRunCursor(char[] text, int contextStart, int contextLength,
int dir, int offset, int cursorOpt) {
int contextEnd = contextStart + contextLength;
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 1652f64..405ab0b 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
@@ -46,10 +47,12 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public boolean isSimplePath = true;
/**
* @hide
*/
+ @UnsupportedAppUsage
public Region rects;
private Direction mLastDirection = null;
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index f2d0227..f7acb11 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import java.io.InputStream;
import java.io.OutputStream;
@@ -32,6 +33,7 @@
*/
public class Picture {
private PictureCanvas mRecordingCanvas;
+ @UnsupportedAppUsage
private long mNativePicture;
private boolean mRequiresHwAcceleration;
diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index d7d3049..fba5043 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* <p>This class contains the list of alpha compositing and blending modes
* that can be passed to {@link PorterDuffXfermode}, a specialized implementation
@@ -364,6 +366,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public final int nativeInt;
}
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index 88a6322..6665220 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -18,6 +18,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
/**
* A color filter that can be used to tint the source pixels using a single
@@ -50,6 +51,7 @@
* @hide
*/
@ColorInt
+ @UnsupportedAppUsage
public int getColor() {
return mColor;
}
@@ -62,6 +64,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public PorterDuff.Mode getMode() {
return mMode;
}
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index f4b1191..41d2628 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.ColorInt;
+import android.annotation.UnsupportedAppUsage;
public class RadialGradient extends Shader {
@@ -31,14 +32,22 @@
*/
private int mType;
+ @UnsupportedAppUsage
private float mX;
+ @UnsupportedAppUsage
private float mY;
+ @UnsupportedAppUsage
private float mRadius;
+ @UnsupportedAppUsage
private int[] mColors;
+ @UnsupportedAppUsage
private float[] mPositions;
+ @UnsupportedAppUsage
private int mCenterColor;
+ @UnsupportedAppUsage
private int mEdgeColor;
+ @UnsupportedAppUsage
private TileMode mTileMode;
/**
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 56a6820..4fec33f 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -19,6 +19,7 @@
import android.annotation.CheckResult;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -206,6 +207,7 @@
* Print short representation to given writer.
* @hide
*/
+ @UnsupportedAppUsage
public void printShortString(@NonNull PrintWriter pw) {
pw.print('['); pw.print(left); pw.print(',');
pw.print(top); pw.print("]["); pw.print(right);
@@ -694,6 +696,7 @@
* Scales up the rect by the given scale.
* @hide
*/
+ @UnsupportedAppUsage
public void scale(float scale) {
if (scale != 1.0f) {
left = (int) (left * scale + 0.5f);
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index b27fadd..29d9367 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pools.SynchronizedPool;
@@ -31,6 +32,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public long mNativeRegion;
// the native values for these must match up with the enum in SkRegion.h
@@ -49,6 +51,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public final int nativeInt;
}
@@ -239,6 +242,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void scale(float scale) {
scale(scale, null);
}
@@ -333,6 +337,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void recycle() {
setEmpty();
sPool.release(this);
@@ -406,6 +411,7 @@
/* add dummy parameter so constructor can be called from jni without
triggering 'not cloneable' exception */
+ @UnsupportedAppUsage
private Region(long ni, int dummy) {
this(ni);
}
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 40288f5..40bcc9e 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import libcore.util.NativeAllocationRegistry;
@@ -72,6 +73,7 @@
TileMode(int nativeInt) {
this.nativeInt = nativeInt;
}
+ @UnsupportedAppUsage
final int nativeInt;
}
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 1eebd26..99f440d 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -68,13 +69,17 @@
*/
public class SurfaceTexture {
private final Looper mCreatorLooper;
+ @UnsupportedAppUsage
private Handler mOnFrameAvailableHandler;
/**
* These fields are used by native code, do not access or modify.
*/
+ @UnsupportedAppUsage
private long mSurfaceTexture;
+ @UnsupportedAppUsage
private long mProducer;
+ @UnsupportedAppUsage
private long mFrameAvailableListener;
private boolean mIsSingleBuffered;
@@ -378,6 +383,7 @@
* This method is invoked from native code only.
*/
@SuppressWarnings({"UnusedDeclaration"})
+ @UnsupportedAppUsage
private static void postEventFromNative(WeakReference<SurfaceTexture> weakSelf) {
SurfaceTexture st = weakSelf.get();
if (st != null) {
@@ -405,6 +411,7 @@
private native void nativeSetDefaultBufferSize(int width, int height);
private native void nativeUpdateTexImage();
private native void nativeReleaseTexImage();
+ @UnsupportedAppUsage
private native int nativeDetachFromGLContext();
private native int nativeAttachToGLContext(int texName);
private native void nativeRelease();
diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index b6b80b4..f944d85 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -19,6 +19,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
public class SweepGradient extends Shader {
@@ -31,11 +32,17 @@
*/
private int mType;
+ @UnsupportedAppUsage
private float mCx;
+ @UnsupportedAppUsage
private float mCy;
+ @UnsupportedAppUsage
private int[] mColors;
+ @UnsupportedAppUsage
private float[] mPositions;
+ @UnsupportedAppUsage
private int mColor0;
+ @UnsupportedAppUsage
private int mColor1;
/**
diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java
index d0c1438..d81c491 100644
--- a/graphics/java/android/graphics/TableMaskFilter.java
+++ b/graphics/java/android/graphics/TableMaskFilter.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* @hide
*/
@@ -32,6 +34,7 @@
native_instance = ni;
}
+ @UnsupportedAppUsage
public static TableMaskFilter CreateClipTable(int min, int max) {
return new TableMaskFilter(nativeNewClip(min, max));
}
diff --git a/graphics/java/android/graphics/TemporaryBuffer.java b/graphics/java/android/graphics/TemporaryBuffer.java
index 36a2275..0ae2c70 100644
--- a/graphics/java/android/graphics/TemporaryBuffer.java
+++ b/graphics/java/android/graphics/TemporaryBuffer.java
@@ -16,12 +16,14 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import com.android.internal.util.ArrayUtils;
/**
* @hide
*/
public class TemporaryBuffer {
+ @UnsupportedAppUsage
public static char[] obtain(int len) {
char[] buf;
@@ -37,6 +39,7 @@
return buf;
}
+ @UnsupportedAppUsage
public static void recycle(char[] temp) {
if (temp.length > 1000) return;
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 18dd97f..522d7a5 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -25,6 +25,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.graphics.fonts.FontVariationAxis;
import android.net.Uri;
@@ -93,6 +94,7 @@
/** The NORMAL style of the default monospace typeface. */
public static final Typeface MONOSPACE;
+ @UnsupportedAppUsage
static Typeface[] sDefaults;
/**
@@ -119,12 +121,15 @@
private static final Object sDynamicCacheLock = new Object();
static Typeface sDefaultTypeface;
+ @UnsupportedAppUsage
static final Map<String, Typeface> sSystemFontMap;
+ @UnsupportedAppUsage
static final Map<String, FontFamily[]> sSystemFallbackMap;
/**
* @hide
*/
+ @UnsupportedAppUsage
public long native_instance;
/** @hide */
@@ -139,6 +144,7 @@
public static final int BOLD_ITALIC = 3;
/** @hide */ public static final int STYLE_MASK = 0x03;
+ @UnsupportedAppUsage
private @Style int mStyle = 0;
/**
@@ -162,6 +168,7 @@
private int[] mSupportedAxes;
private static final int[] EMPTY_AXES = {};
+ @UnsupportedAppUsage
private static void setDefault(Typeface t) {
sDefaultTypeface = t;
nativeSetDefault(t.native_instance);
@@ -891,6 +898,7 @@
*
* @param families array of font families
*/
+ @UnsupportedAppUsage
private static Typeface createFromFamilies(FontFamily[] families) {
long[] ptrArray = new long[families.length];
for (int i = 0; i < families.length; i++) {
@@ -904,6 +912,7 @@
* This method is used by supportlib-v27.
* TODO: Remove private API use in supportlib: http://b/72665240
*/
+ @UnsupportedAppUsage
private static Typeface createFromFamiliesWithDefault(FontFamily[] families, int weight,
int italic) {
return createFromFamiliesWithDefault(families, DEFAULT_FAMILY, weight, italic);
@@ -922,6 +931,7 @@
* closest to the regular weight and upright font is used.
* @param families array of font families
*/
+ @UnsupportedAppUsage
private static Typeface createFromFamiliesWithDefault(FontFamily[] families,
String fallbackName, int weight, int italic) {
FontFamily[] fallback = sSystemFallbackMap.get(fallbackName);
@@ -939,6 +949,7 @@
}
// don't allow clients to call this directly
+ @UnsupportedAppUsage
private Typeface(long ni) {
if (ni == 0) {
throw new RuntimeException("native typeface cannot be made");
@@ -1197,7 +1208,9 @@
// TODO: clean up: change List<FontVariationAxis> to FontVariationAxis[]
private static native long nativeCreateFromTypefaceWithVariation(
long native_instance, List<FontVariationAxis> axes);
+ @UnsupportedAppUsage
private static native long nativeCreateWeightAlias(long native_instance, int weight);
+ @UnsupportedAppUsage
private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic);
private static native int[] nativeGetSupportedAxes(long native_instance);
diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java
index a5da5d0..6f4adfd 100644
--- a/graphics/java/android/graphics/Xfermode.java
+++ b/graphics/java/android/graphics/Xfermode.java
@@ -21,6 +21,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* Xfermode is the base class for objects that are called to implement custom
* "transfer-modes" in the drawing pipeline. The static function Create(Modes)
@@ -30,5 +32,6 @@
*/
public class Xfermode {
static final int DEFAULT = PorterDuff.Mode.SRC_OVER.nativeInt;
+ @UnsupportedAppUsage
int porterDuffMode = DEFAULT;
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 4f467d9..3aaec31 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -19,6 +19,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -562,6 +563,7 @@
* callback, so no need to post.
*/
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
private void onAnimationEnd() {
if (mAnimationCallbacks != null) {
for (Animatable2.AnimationCallback callback : mAnimationCallbacks) {
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index d714ca8..b29fd4d 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.content.res.Resources;
@@ -202,11 +203,13 @@
R.styleable.AnimatedRotateDrawable_frameDuration, state.mFrameDuration));
}
+ @UnsupportedAppUsage
public void setFramesCount(int framesCount) {
mState.mFramesCount = framesCount;
mIncrement = 360.0f / mState.mFramesCount;
}
+ @UnsupportedAppUsage
public void setFramesDuration(int framesDuration) {
mState.mFrameDuration = framesDuration;
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index 3ed6a78..00380c5 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -20,6 +20,7 @@
import android.animation.TimeInterpolator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -66,6 +67,7 @@
private static final String ELEMENT_TRANSITION = "transition";
private static final String ELEMENT_ITEM = "item";
+ @UnsupportedAppUsage
private AnimatedStateListState mState;
/** The currently running transition, if any. */
@@ -558,7 +560,9 @@
int[] mAnimThemeAttrs;
+ @UnsupportedAppUsage
LongSparseLongArray mTransitions;
+ @UnsupportedAppUsage
SparseIntArray mStateIds;
AnimatedStateListState(@Nullable AnimatedStateListState orig,
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 8e9862c..76f2cfb 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -25,6 +25,7 @@
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
import android.app.Application;
import android.content.pm.ActivityInfo.Config;
@@ -305,6 +306,7 @@
private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
/** Local, mutable animator set. */
+ @UnsupportedAppUsage
private VectorDrawableAnimator mAnimatorSet;
/**
@@ -313,6 +315,7 @@
*/
private Resources mRes;
+ @UnsupportedAppUsage
private AnimatedVectorDrawableState mAnimatedVectorState;
/** The animator set that is parsed from the xml. */
@@ -641,6 +644,7 @@
* Force to animate on UI thread.
* @hide
*/
+ @UnsupportedAppUsage
public void forceAnimationOnUI() {
if (mAnimatorSet instanceof VectorDrawableAnimatorRT) {
VectorDrawableAnimatorRT animator = (VectorDrawableAnimatorRT) mAnimatorSet;
@@ -1771,6 +1775,7 @@
}
// onFinished: should be called from native
+ @UnsupportedAppUsage
private static void callOnFinished(VectorDrawableAnimatorRT set, int id) {
set.onAnimationEnd(id);
}
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 0fd1741..57764c2 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -24,6 +24,7 @@
import org.xmlpull.v1.XmlPullParserException;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
@@ -88,6 +89,7 @@
private AnimationState mAnimationState;
/** The current frame, ranging from 0 to {@link #mAnimationState#getChildCount() - 1} */
+ @UnsupportedAppUsage
private int mCurFrame = 0;
/** Whether the drawable has an animation callback posted. */
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 99bed60..9761901 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -17,6 +17,7 @@
package android.graphics.drawable;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -87,9 +88,11 @@
private final Rect mDstRect = new Rect(); // #updateDstRectAndInsetsIfDirty() sets this
+ @UnsupportedAppUsage
private BitmapState mBitmapState;
private PorterDuffColorFilter mTintFilter;
+ @UnsupportedAppUsage
private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
private boolean mDstRectAndInsetsDirty = true;
@@ -237,6 +240,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public void setBitmap(Bitmap bitmap) {
if (mBitmapState.mBitmap != bitmap) {
mBitmapState.mBitmap = bitmap;
@@ -692,6 +696,7 @@
/**
* @hide only needed by a hack within ProgressBar
*/
+ @UnsupportedAppUsage
public ColorStateList getTint() {
return mBitmapState.mTint;
}
@@ -699,6 +704,7 @@
/**
* @hide only needed by a hack within ProgressBar
*/
+ @UnsupportedAppUsage
public Mode getTintMode() {
return mBitmapState.mTintMode;
}
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index d925b6b..31fdb02 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
@@ -58,6 +59,7 @@
private final Rect mTmpRect = new Rect();
+ @UnsupportedAppUsage
private ClipState mState;
ClipDrawable() {
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index a601d6d..18b41fa 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -52,6 +53,7 @@
* @attr ref android.R.styleable#ColorDrawable_color
*/
public class ColorDrawable extends Drawable {
+ @UnsupportedAppUsage
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
@@ -336,6 +338,7 @@
int[] mThemeAttrs;
int mBaseColor; // base color, independent of setAlpha()
@ViewDebug.ExportedProperty
+ @UnsupportedAppUsage
int mUseColor; // basecolor modulated by setAlpha()
@Config int mChangingConfigurations;
ColorStateList mTint = null;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 986d0c1..e1f7263 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -22,6 +22,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -186,6 +187,7 @@
private int mLevel = 0;
private @Config int mChangingConfigurations = 0;
private Rect mBounds = ZERO_BOUNDS_RECT; // lazily becomes a new Rect()
+ @UnsupportedAppUsage
private WeakReference<Callback> mCallback = null;
private boolean mVisible = true;
@@ -204,6 +206,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
protected int mSrcDensityOverride = 0;
/**
@@ -714,6 +717,7 @@
*
* @hide magic!
*/
+ @UnsupportedAppUsage
public boolean isProjected() {
return false;
}
@@ -1389,6 +1393,7 @@
* @throws XmlPullParserException
* @throws IOException
*/
+ @UnsupportedAppUsage
void inflateWithAttributes(@NonNull @SuppressWarnings("unused") Resources r,
@NonNull @SuppressWarnings("unused") XmlPullParser parser, @NonNull TypedArray attrs,
@AttrRes int visibleAttr) throws XmlPullParserException, IOException {
@@ -1508,6 +1513,7 @@
* Ensures the tint filter is consistent with the current tint color and
* mode.
*/
+ @UnsupportedAppUsage
@Nullable PorterDuffColorFilter updateTintFilter(@Nullable PorterDuffColorFilter tintFilter,
@Nullable ColorStateList tint, @Nullable PorterDuff.Mode tintMode) {
if (tint == null || tintMode == null) {
@@ -1613,6 +1619,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static PorterDuff.Mode parseTintMode(int value, Mode defaultMode) {
switch (value) {
case 3: return Mode.SRC_OVER;
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index e7b383a..10f6fae 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -17,6 +17,7 @@
package android.graphics.drawable;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -54,9 +55,11 @@
* to improve the quality at negligible cost.
*/
private static final boolean DEFAULT_DITHER = true;
+ @UnsupportedAppUsage
private DrawableContainerState mDrawableContainerState;
private Rect mHotspotBounds;
private Drawable mCurrDrawable;
+ @UnsupportedAppUsage
private Drawable mLastDrawable;
private int mAlpha = 0xFF;
@@ -686,11 +689,13 @@
@Config int mChildrenChangingConfigurations;
SparseArray<ConstantState> mDrawableFutures;
+ @UnsupportedAppUsage
Drawable[] mDrawables;
int mNumChildren;
boolean mVariablePadding = false;
boolean mCheckedPadding;
+ @UnsupportedAppUsage
Rect mConstantPadding;
boolean mConstantSize = false;
@@ -720,6 +725,7 @@
boolean mAutoMirrored;
ColorFilter mColorFilter;
+ @UnsupportedAppUsage
boolean mHasColorFilter;
ColorStateList mTintList;
@@ -730,6 +736,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
protected DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
Resources res) {
mOwner = owner;
diff --git a/graphics/java/android/graphics/drawable/DrawableInflater.java b/graphics/java/android/graphics/drawable/DrawableInflater.java
index 0ee9071..bad3791 100644
--- a/graphics/java/android/graphics/drawable/DrawableInflater.java
+++ b/graphics/java/android/graphics/drawable/DrawableInflater.java
@@ -22,6 +22,7 @@
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -49,6 +50,7 @@
new HashMap<>();
private final Resources mRes;
+ @UnsupportedAppUsage
private final ClassLoader mClassLoader;
/**
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index a907ca5..4ee45bf 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -46,6 +47,7 @@
* Drawable container with only one child element.
*/
public abstract class DrawableWrapper extends Drawable implements Drawable.Callback {
+ @UnsupportedAppUsage
private DrawableWrapperState mState;
private Drawable mDrawable;
private boolean mMutated;
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 5629389..8740234 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -20,6 +20,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -155,10 +156,14 @@
private static final float DEFAULT_INNER_RADIUS_RATIO = 3.0f;
private static final float DEFAULT_THICKNESS_RATIO = 9.0f;
+ @UnsupportedAppUsage
private GradientState mGradientState;
+ @UnsupportedAppUsage
private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ @UnsupportedAppUsage
private Rect mPadding;
+ @UnsupportedAppUsage
private Paint mStrokePaint; // optional, set by the caller
private ColorFilter mColorFilter; // optional, set by the caller
private PorterDuffColorFilter mTintFilter;
@@ -1792,27 +1797,46 @@
final static class GradientState extends ConstantState {
public @Config int mChangingConfigurations;
+ @UnsupportedAppUsage
public @Shape int mShape = RECTANGLE;
+ @UnsupportedAppUsage
public @GradientType int mGradient = LINEAR_GRADIENT;
+ @UnsupportedAppUsage
public int mAngle = 0;
+ @UnsupportedAppUsage
public Orientation mOrientation;
+ @UnsupportedAppUsage
public ColorStateList mSolidColors;
public ColorStateList mStrokeColors;
+ @UnsupportedAppUsage
public @ColorInt int[] mGradientColors;
public @ColorInt int[] mTempColors; // no need to copy
public float[] mTempPositions; // no need to copy
+ @UnsupportedAppUsage
public float[] mPositions;
+ @UnsupportedAppUsage
public int mStrokeWidth = -1; // if >= 0 use stroking.
+ @UnsupportedAppUsage
public float mStrokeDashWidth = 0.0f;
+ @UnsupportedAppUsage
public float mStrokeDashGap = 0.0f;
+ @UnsupportedAppUsage
public float mRadius = 0.0f; // use this if mRadiusArray is null
+ @UnsupportedAppUsage
public float[] mRadiusArray = null;
+ @UnsupportedAppUsage
public Rect mPadding = null;
+ @UnsupportedAppUsage
public int mWidth = -1;
+ @UnsupportedAppUsage
public int mHeight = -1;
+ @UnsupportedAppUsage
public float mInnerRadiusRatio = DEFAULT_INNER_RADIUS_RATIO;
+ @UnsupportedAppUsage
public float mThicknessRatio = DEFAULT_THICKNESS_RATIO;
+ @UnsupportedAppUsage
public int mInnerRadius = -1;
+ @UnsupportedAppUsage
public int mThickness = -1;
public boolean mDither = false;
public Insets mOpticalInsets = Insets.NONE;
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 361fe0b..accc081 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -21,6 +21,7 @@
import android.annotation.IdRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -99,6 +100,7 @@
private static final int VERSION_STREAM_SERIALIZER = 1;
+ @UnsupportedAppUsage
private final int mType;
private ColorStateList mTintList;
@@ -115,6 +117,7 @@
// TYPE_RESOURCE: package name
// TYPE_URI: uri string
+ @UnsupportedAppUsage
private String mString1;
// TYPE_RESOURCE: resId
@@ -139,6 +142,7 @@
* @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon.
* @hide
*/
+ @UnsupportedAppUsage
public Bitmap getBitmap() {
if (mType != TYPE_BITMAP && mType != TYPE_ADAPTIVE_BITMAP) {
throw new IllegalStateException("called getBitmap() on " + this);
@@ -154,6 +158,7 @@
* @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon.
* @hide
*/
+ @UnsupportedAppUsage
public int getDataLength() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataLength() on " + this);
@@ -168,6 +173,7 @@
* valid compressed bitmap data is found.
* @hide
*/
+ @UnsupportedAppUsage
public int getDataOffset() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataOffset() on " + this);
@@ -182,6 +188,7 @@
* bitmap data.
* @hide
*/
+ @UnsupportedAppUsage
public byte[] getDataBytes() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataBytes() on " + this);
@@ -195,6 +202,7 @@
* @return The {@link android.content.res.Resources} for this {@link #TYPE_RESOURCE} Icon.
* @hide
*/
+ @UnsupportedAppUsage
public Resources getResources() {
if (mType != TYPE_RESOURCE) {
throw new IllegalStateException("called getResources() on " + this);
@@ -560,6 +568,7 @@
* Version of createWithResource that takes Resources. Do not use.
* @hide
*/
+ @UnsupportedAppUsage
public static Icon createWithResource(Resources res, @DrawableRes int resId) {
if (res == null) {
throw new IllegalArgumentException("Resource must not be null.");
@@ -692,6 +701,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public boolean hasTint() {
return (mTintList != null) || (mTintMode != DEFAULT_TINT_MODE);
}
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index ade4294..bc8a4cb 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -57,6 +58,7 @@
private final Rect mTmpRect = new Rect();
private final Rect mTmpInsetRect = new Rect();
+ @UnsupportedAppUsage
private InsetState mState;
/**
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 4725c2c..b4392c8 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -93,6 +94,7 @@
public static final int INSET_UNDEFINED = Integer.MIN_VALUE;
@NonNull
+ @UnsupportedAppUsage
LayerState mLayerState;
private int[] mPaddingL;
@@ -428,6 +430,7 @@
* @param layer The layer to add.
* @return The index of the layer.
*/
+ @UnsupportedAppUsage
int addLayer(@NonNull ChildDrawable layer) {
final LayerState st = mLayerState;
final int N = st.mChildren != null ? st.mChildren.length : 0;
@@ -1739,6 +1742,7 @@
/**
* Ensures the child padding caches are large enough.
*/
+ @UnsupportedAppUsage
void ensurePadding() {
final int N = mLayerState.mNumChildren;
if (mPaddingL != null && mPaddingL.length >= N) {
@@ -1820,6 +1824,7 @@
}
static class ChildDrawable {
+ @UnsupportedAppUsage
public Drawable mDrawable;
public int[] mThemeAttrs;
public int mDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -1922,6 +1927,7 @@
private int[] mThemeAttrs;
int mNumChildren;
+ @UnsupportedAppUsage
ChildDrawable[] mChildren;
int mDensity;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 7f23cea..b534771 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -70,6 +71,7 @@
/** Temporary rect used for density scaling. */
private Rect mTempRect;
+ @UnsupportedAppUsage
private NinePatchState mNinePatchState;
private PorterDuffColorFilter mTintFilter;
private Rect mPadding;
@@ -588,6 +590,7 @@
@Config int mChangingConfigurations;
// Values loaded during inflation.
+ @UnsupportedAppUsage
NinePatch mNinePatch = null;
ColorStateList mTint = null;
Mode mTintMode = DEFAULT_TINT_MODE;
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 266a6ac..1540cc2 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -120,6 +121,7 @@
private final Rect mDirtyBounds = new Rect();
/** Mirrors mLayerState with some extra information. */
+ @UnsupportedAppUsage
private RippleState mState;
/** The masking layer, e.g. the layer with id R.id.mask. */
@@ -157,6 +159,7 @@
private Paint mRipplePaint;
/** Target density of the display into which ripples are drawn. */
+ @UnsupportedAppUsage
private int mDensity;
/** Whether bounds are being overridden. */
@@ -857,6 +860,7 @@
mMask.draw(canvas);
}
+ @UnsupportedAppUsage
Paint getRipplePaint() {
if (mRipplePaint == null) {
mRipplePaint = new Paint();
@@ -945,6 +949,7 @@
* @param forceSoftware true if RenderThread animations should be disabled, false otherwise
* @hide
*/
+ @UnsupportedAppUsage
public void setForceSoftware(boolean forceSoftware) {
mForceSoftware = forceSoftware;
}
@@ -975,6 +980,7 @@
static class RippleState extends LayerState {
int[] mTouchThemeAttrs;
+ @UnsupportedAppUsage
ColorStateList mColor = ColorStateList.valueOf(Color.MAGENTA);
int mMaxRadius = RADIUS_AUTO;
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index c0dfe77..db5f082 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.content.res.Resources;
@@ -54,6 +55,7 @@
public class RotateDrawable extends DrawableWrapper {
private static final int MAX_LEVEL = 10000;
+ @UnsupportedAppUsage
private RotateState mState;
/**
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 51e143b..91ed061 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -66,6 +67,7 @@
private final Rect mTmpRect = new Rect();
+ @UnsupportedAppUsage
private ScaleState mState;
ScaleDrawable() {
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 67c3412..8de8f81 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -63,6 +64,7 @@
private static final boolean DEBUG = false;
+ @UnsupportedAppUsage
private StateListState mStateListState;
private boolean mMutated;
@@ -129,6 +131,7 @@
/**
* Updates the constant state from the values in the typed array.
*/
+ @UnsupportedAppUsage
private void updateStateFromTypedArray(TypedArray a) {
final StateListState state = mStateListState;
@@ -206,6 +209,7 @@
* @param attrs The attribute set.
* @return An array of state_ attributes.
*/
+ @UnsupportedAppUsage
int[] extractStateSet(AttributeSet attrs) {
int j = 0;
final int numAttrs = attrs.getAttributeCount();
@@ -329,6 +333,7 @@
mStateSets = stateSets;
}
+ @UnsupportedAppUsage
int addStateSet(int[] stateSet, Drawable drawable) {
final int pos = addChild(drawable);
mStateSets[pos] = stateSet;
diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java
index 3dfd680..276f366 100644
--- a/graphics/java/android/graphics/drawable/TransitionDrawable.java
+++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java
@@ -16,6 +16,7 @@
package android.graphics.drawable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -65,10 +66,13 @@
private boolean mReverse;
private long mStartTimeMillis;
private int mFrom;
+ @UnsupportedAppUsage
private int mTo;
private int mDuration;
private int mOriginalDuration;
+ @UnsupportedAppUsage
private int mAlpha = 0;
+ @UnsupportedAppUsage
private boolean mCrossFade;
/**
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index b5bd97f..040601c 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -16,6 +16,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.ComplexColor;
@@ -321,6 +322,7 @@
private VectorDrawableState mVectorState;
+ @UnsupportedAppUsage
private PorterDuffColorFilter mTintFilter;
private ColorFilter mColorFilter;
@@ -389,6 +391,7 @@
mMutated = false;
}
+ @UnsupportedAppUsage
Object getTargetByName(String name) {
return mVectorState.mVGTargetsMap.get(name);
}
@@ -867,6 +870,7 @@
return super.getChangingConfigurations() | mVectorState.getChangingConfigurations();
}
+ @UnsupportedAppUsage
void setAllowCaching(boolean allowCaching) {
nSetAllowCaching(mVectorState.getNativeRenderer(), allowCaching);
}
@@ -1498,6 +1502,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setRotation(float rotation) {
if (isTreeValid()) {
nSetRotation(mNativePtr, rotation);
@@ -1510,6 +1515,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setPivotX(float pivotX) {
if (isTreeValid()) {
nSetPivotX(mNativePtr, pivotX);
@@ -1522,6 +1528,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setPivotY(float pivotY) {
if (isTreeValid()) {
nSetPivotY(mNativePtr, pivotY);
@@ -1558,6 +1565,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setTranslateX(float translateX) {
if (isTreeValid()) {
nSetTranslateX(mNativePtr, translateX);
@@ -1570,6 +1578,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setTranslateY(float translateY) {
if (isTreeValid()) {
nSetTranslateY(mNativePtr, translateY);
diff --git a/graphics/java/android/graphics/fonts/FontVariationAxis.java b/graphics/java/android/graphics/fonts/FontVariationAxis.java
index 1b7408a..2a902c5 100644
--- a/graphics/java/android/graphics/fonts/FontVariationAxis.java
+++ b/graphics/java/android/graphics/fonts/FontVariationAxis.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.text.TextUtils;
import java.util.ArrayList;
@@ -27,8 +28,10 @@
* Class that holds information about single font variation axis.
*/
public final class FontVariationAxis {
+ @UnsupportedAppUsage
private final int mTag;
private final String mTagString;
+ @UnsupportedAppUsage
private final float mStyleValue;
/**
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 4a91705..1836f00 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Matrix;
@@ -118,6 +119,7 @@
private ParcelFileDescriptor mInput;
+ @UnsupportedAppUsage
private Page mCurrentPage;
/** @hide */
@@ -242,6 +244,7 @@
}
}
+ @UnsupportedAppUsage
private void doClose() {
if (mCurrentPage != null) {
mCurrentPage.close();
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 8502309..4f4ca3f 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -128,7 +128,11 @@
public static final int FLAG_STRONGBOX = 1 << 4;
// States
- public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
+ public enum State {
+ UNLOCKED,
+ LOCKED,
+ UNINITIALIZED
+ };
private int mError = NO_ERROR;
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 61c412d..bcff5bf 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -1794,18 +1794,17 @@
public @interface MediaError {}
/* Do not change these values without updating their counterparts
- * in include/media/mediaplayer2.h!
+ * in include/media/MediaPlayer2Types.h!
*/
/** Unspecified media player info.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
public static final int MEDIA_INFO_UNKNOWN = 1;
- /** The player switched to this datas source because it is the
- * next-to-be-played in the playlist.
+ /** The player just started the playback of this datas source.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
- public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
+ public static final int MEDIA_INFO_DATA_SOURCE_START = 2;
/** The player just pushed the very first video frame for rendering.
* @see android.media.MediaPlayer2.EventCallback#onInfo
@@ -1820,12 +1819,13 @@
/** The player just completed the playback of this data source.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
- public static final int MEDIA_INFO_PLAYBACK_COMPLETE = 5;
+ public static final int MEDIA_INFO_DATA_SOURCE_END = 5;
- /** The player just completed the playback of the full playlist.
+ /** The player just completed the playback of all data sources set by {@link #setDataSource},
+ * {@link #setNextDataSource} and {@link #setNextDataSources}.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
- public static final int MEDIA_INFO_PLAYLIST_END = 6;
+ public static final int MEDIA_INFO_DATA_SOURCE_LIST_END = 6;
/** The player just prepared a data source.
* @see android.media.MediaPlayer2.EventCallback#onInfo
@@ -1927,11 +1927,11 @@
*/
@IntDef(flag = false, prefix = "MEDIA_INFO", value = {
MEDIA_INFO_UNKNOWN,
- MEDIA_INFO_STARTED_AS_NEXT,
+ MEDIA_INFO_DATA_SOURCE_START,
MEDIA_INFO_VIDEO_RENDERING_START,
MEDIA_INFO_AUDIO_RENDERING_START,
- MEDIA_INFO_PLAYBACK_COMPLETE,
- MEDIA_INFO_PLAYLIST_END,
+ MEDIA_INFO_DATA_SOURCE_END,
+ MEDIA_INFO_DATA_SOURCE_LIST_END,
MEDIA_INFO_PREPARED,
MEDIA_INFO_VIDEO_TRACK_LAGGING,
MEDIA_INFO_BUFFERING_START,
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index d5dd46c..95ba00f 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -210,6 +210,22 @@
@Override
void process() {
stayAwake(true);
+
+ // TODO: remove this block when native code sends MEDIA_INFO_DATA_SOURCE_START
+ // when pipeline is created.
+ if (getState() == PLAYER_STATE_PREPARED) {
+ final DataSourceDesc dsd;
+ synchronized (mSrcLock) {
+ dsd = mCurrentDSD;
+ }
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ MediaPlayer2Impl.this, dsd, MEDIA_INFO_DATA_SOURCE_START, 0));
+ }
+ }
+ }
+
_start();
}
});
@@ -246,6 +262,22 @@
@Override
void process() {
stayAwake(false);
+
+ // TODO: remove this block when native code allows prepared -> pause
+ // and sends MEDIA_INFO_DATA_SOURCE_START when pipeline is created.
+ if (getState() == PLAYER_STATE_PREPARED) {
+ final DataSourceDesc dsd;
+ synchronized (mSrcLock) {
+ dsd = mCurrentDSD;
+ }
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ MediaPlayer2Impl.this, dsd, MEDIA_INFO_DATA_SOURCE_START, 0));
+ }
+ }
+ }
+
_pause();
}
});
@@ -888,23 +920,30 @@
private native void nativeHandleDataSourceCallback(
boolean isCurrent, long srcId, Media2DataSource dataSource);
+ /**
+ * @return true if there is a next data source, false otherwise.
+ */
// This function should be always called on |mHandlerThread|.
- private void prepareNextDataSource() {
+ private boolean prepareNextDataSource() {
if (Looper.myLooper() != mHandlerThread.getLooper()) {
Log.e(TAG, "prepareNextDataSource: called on wrong looper");
}
+ boolean hasNextDSD;
+ synchronized (mSrcLock) {
+ hasNextDSD = (mNextDSDs != null && !mNextDSDs.isEmpty());
+ }
+
int state = getState();
if (state == PLAYER_STATE_ERROR || state == PLAYER_STATE_IDLE) {
// Current source has not been prepared yet.
- return;
+ return hasNextDSD;
}
synchronized (mSrcLock) {
- if (mNextDSDs == null || mNextDSDs.isEmpty()
- || mNextSourceState != NEXT_SOURCE_STATE_INIT) {
+ if (!hasNextDSD || mNextSourceState != NEXT_SOURCE_STATE_INIT) {
// There is no next source or it's in preparing or prepared state.
- return;
+ return hasNextDSD;
}
try {
@@ -919,9 +958,10 @@
// make a new SrcId to obsolete notification for previous one.
mNextSrcId = mSrcIdGenerator++;
mNextSourceState = NEXT_SOURCE_STATE_INIT;
- prepareNextDataSource();
+ return prepareNextDataSource();
}
}
+ return hasNextDSD;
}
// This function should be always called on |mHandlerThread|.
@@ -930,40 +970,48 @@
Log.e(TAG, "playNextDataSource: called on wrong looper");
}
+ boolean hasNextDSD = false;
synchronized (mSrcLock) {
- if (mNextDSDs == null || mNextDSDs.isEmpty()) {
- return;
- }
+ if (mNextDSDs != null && !mNextDSDs.isEmpty()) {
+ hasNextDSD = true;
+ if (mNextSourceState == NEXT_SOURCE_STATE_PREPARED) {
+ // Switch to next source only when it has been prepared.
+ mCurrentDSD = mNextDSDs.get(0);
+ mCurrentSrcId = mNextSrcId;
+ mBufferedPercentageCurrent.set(mBufferedPercentageNext.get());
+ mNextDSDs.remove(0);
+ mNextSrcId = mSrcIdGenerator++; // make it different from |mCurrentSrcId|
+ mBufferedPercentageNext.set(0);
+ mNextSourceState = NEXT_SOURCE_STATE_INIT;
- if (mNextSourceState == NEXT_SOURCE_STATE_PREPARED) {
- // Switch to next source only when it has been prepared.
- mCurrentDSD = mNextDSDs.get(0);
- mCurrentSrcId = mNextSrcId;
- mBufferedPercentageCurrent.set(mBufferedPercentageNext.get());
- mNextDSDs.remove(0);
- mNextSrcId = mSrcIdGenerator++; // make it different from |mCurrentSrcId|
- mBufferedPercentageNext.set(0);
- mNextSourceState = NEXT_SOURCE_STATE_INIT;
+ long srcId = mCurrentSrcId;
+ try {
+ nativePlayNextDataSource(srcId);
+ } catch (Exception e) {
+ Message msg2 = mTaskHandler.obtainMessage(
+ MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
+ mTaskHandler.handleMessage(msg2, srcId);
+ // Keep |mNextSourcePlayPending|
+ hasNextDSD = prepareNextDataSource();
+ }
+ if (hasNextDSD) {
+ stayAwake(true);
- long srcId = mCurrentSrcId;
- try {
- nativePlayNextDataSource(srcId);
- } catch (Exception e) {
- Message msg2 = mTaskHandler.obtainMessage(
- MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
- mTaskHandler.handleMessage(msg2, srcId);
- // Keep |mNextSourcePlayPending|
- prepareNextDataSource();
- return;
+ // Now a new current src is playing.
+ // Wait for MEDIA_INFO_DATA_SOURCE_START to prepare next source.
+ mNextSourcePlayPending = false;
+ }
+ } else if (mNextSourceState == NEXT_SOURCE_STATE_INIT) {
+ hasNextDSD = prepareNextDataSource();
}
- stayAwake(true);
+ }
+ }
- // Now a new current src is playing.
- // Wait for MEDIA2_INFO_STARTED_AS_NEXT to prepare next source.
- mNextSourcePlayPending = false;
- } else {
- if (mNextSourceState == NEXT_SOURCE_STATE_INIT) {
- prepareNextDataSource();
+ if (!hasNextDSD) {
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ MediaPlayer2Impl.this, null, MEDIA_INFO_DATA_SOURCE_LIST_END, 0));
}
}
}
@@ -2767,7 +2815,7 @@
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
+ mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
}
}
stayAwake(false);
@@ -2869,7 +2917,7 @@
cb.first.execute(() -> cb.second.onError(
mMediaPlayer, dsd, what, extra));
cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
+ mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
}
}
stayAwake(false);
@@ -2878,8 +2926,15 @@
case MEDIA_INFO:
{
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ mMediaPlayer, dsd, what, extra));
+ }
+ }
+
switch (msg.arg1) {
- case MEDIA_INFO_STARTED_AS_NEXT:
+ case MEDIA_INFO_DATA_SOURCE_START:
if (isCurrentSrcId) {
prepareNextDataSource();
}
@@ -2916,13 +2971,6 @@
}
break;
}
-
- synchronized (mEventCbLock) {
- for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
- cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, dsd, what, extra));
- }
- }
// No real default action so far.
return;
}
@@ -3034,19 +3082,6 @@
}
switch (what) {
- case MEDIA_INFO:
- if (arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // this acquires the wakelock if needed, and sets the client side state
- mp.play();
- }
- }).start();
- Thread.yield();
- }
- break;
-
case MEDIA_DRM_INFO:
// We need to derive mDrmInfoImpl before prepare() returns so processing it here
// before the notification is sent to TaskHandler below. TaskHandler runs in the
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
index ff70e97..a7217ec 100644
--- a/packages/ExtServices/AndroidManifest.xml
+++ b/packages/ExtServices/AndroidManifest.xml
@@ -55,12 +55,6 @@
<intent-filter>
<action android:name="android.service.autofill.AutofillFieldClassificationService" />
</intent-filter>
- <meta-data
- android:name="android.autofill.field_classification.default_algorithm"
- android:resource="@string/autofill_field_classification_default_algorithm" />
- <meta-data
- android:name="android.autofill.field_classification.available_algorithms"
- android:resource="@array/autofill_field_classification_available_algorithms" />
</service>
<library android:name="android.ext.services"/>
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index a539b1f..9d19898 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -17,15 +17,16 @@
package android.ext.services.notification;
import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking
+ .USER_SENTIMENT_NEGATIVE;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
-import android.ext.services.R;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -193,23 +194,27 @@
if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey());
ArrayList<Notification.Action> actions =
mSmartActionsHelper.suggestActions(this, sbn);
- if (actions.isEmpty()) {
- return null;
- }
- return createEnqueuedNotificationAdjustment(sbn, actions);
+ ArrayList<CharSequence> replies = mSmartActionsHelper.suggestReplies(this, sbn);
+ return createEnqueuedNotificationAdjustment(sbn, actions, replies);
}
/** A convenience helper for creating an adjustment for an SBN. */
+ @Nullable
private Adjustment createEnqueuedNotificationAdjustment(
@NonNull StatusBarNotification statusBarNotification,
- @NonNull ArrayList<Notification.Action> smartActions) {
+ @NonNull ArrayList<Notification.Action> smartActions,
+ @NonNull ArrayList<CharSequence> smartReplies) {
+ if (smartActions.isEmpty() && smartReplies.isEmpty()) {
+ return null;
+ }
Bundle signals = new Bundle();
signals.putParcelableArrayList(Adjustment.KEY_SMART_ACTIONS, smartActions);
+ signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies);
return new Adjustment(
statusBarNotification.getPackageName(),
statusBarNotification.getKey(),
signals,
- "smart action" /* explanation */,
+ "smart action, reply" /* explanation */,
statusBarNotification.getUserId());
}
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index ed5cbab..9d33bd9 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -24,6 +24,7 @@
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Process;
+import android.os.SystemProperties;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -32,13 +33,13 @@
import android.view.textclassifier.TextClassifier;
import android.view.textclassifier.TextLinks;
-import com.android.internal.util.Preconditions;
-
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
public class SmartActionsHelper {
- private static final ArrayList<Notification.Action> EMPTY_LIST = new ArrayList<>();
+ private static final ArrayList<Notification.Action> EMPTY_ACTION_LIST = new ArrayList<>();
+ private static final ArrayList<CharSequence> EMPTY_REPLY_LIST = new ArrayList<>();
// If a notification has any of these flags set, it's inelgibile for actions being added.
private static final int FLAG_MASK_INELGIBILE_FOR_ACTIONS =
@@ -49,6 +50,10 @@
private static final int MAX_ACTION_EXTRACTION_TEXT_LENGTH = 400;
private static final int MAX_ACTIONS_PER_LINK = 1;
private static final int MAX_SMART_ACTIONS = Notification.MAX_ACTION_BUTTONS;
+ // Allow us to test out smart reply with dumb suggestions, it is disabled by default.
+ // TODO: Removed this once we have the model.
+ private static final String SYS_PROP_SMART_REPLIES_EXPERIMENT =
+ "persist.sys.smart_replies_experiment";
SmartActionsHelper() {}
@@ -62,14 +67,14 @@
ArrayList<Notification.Action> suggestActions(
@Nullable Context context, @NonNull StatusBarNotification sbn) {
if (!isEligibleForActionAdjustment(sbn)) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
if (context == null) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
TextClassificationManager tcm = context.getSystemService(TextClassificationManager.class);
if (tcm == null) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
Notification.Action[] actions = sbn.getNotification().actions;
int numOfExistingActions = actions == null ? 0: actions.length;
@@ -79,6 +84,18 @@
getMostSalientActionText(sbn.getNotification()), maxSmartActions);
}
+ ArrayList<CharSequence> suggestReplies(
+ @Nullable Context context, @NonNull StatusBarNotification sbn) {
+ if (!isEligibleForReplyAdjustment(sbn)) {
+ return EMPTY_REPLY_LIST;
+ }
+ if (context == null) {
+ return EMPTY_REPLY_LIST;
+ }
+ // TODO: replaced this with our model when it is ready.
+ return new ArrayList<>(Arrays.asList("Yes, please", "No, thanks"));
+ }
+
/**
* Returns whether a notification is eligible for action adjustments.
*
@@ -108,6 +125,17 @@
|| hasInlineReply(notification);
}
+ private boolean isEligibleForReplyAdjustment(@NonNull StatusBarNotification sbn) {
+ if (!SystemProperties.getBoolean(SYS_PROP_SMART_REPLIES_EXPERIMENT, false)) {
+ return false;
+ }
+ Notification notification = sbn.getNotification();
+ if (notification.actions == null) {
+ return false;
+ }
+ return hasInlineReply(sbn.getNotification());
+ }
+
private boolean hasInlineReply(Notification notification) {
Notification.Action[] actions = notification.actions;
if (actions == null) {
@@ -151,7 +179,7 @@
@NonNull TextClassificationManager tcm, @Nullable CharSequence text,
int maxSmartActions) {
if (TextUtils.isEmpty(text)) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
TextClassifier textClassifier = tcm.getTextClassifier();
diff --git a/packages/PackageInstaller/res/layout/uninstall_confirm.xml b/packages/PackageInstaller/res/layout/uninstall_confirm.xml
deleted file mode 100644
index 4c81771..0000000
--- a/packages/PackageInstaller/res/layout/uninstall_confirm.xml
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<!--
-
- Defines the layout of the confirmation screen that gets displayed when an
- application is about to be uninstalled. Includes ok and cancel buttons
- to let the uinstallation continue or abort.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <LinearLayout
- android:layout_weight="1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:orientation="vertical"
- android:paddingBottom="8dip">
-
- <!-- If an activity was specified, explains what package it's in. -->
- <TextView
- android:id="@+id/activity_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
- android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:visibility="gone" />
-
- <!-- The snippet (title & icon) about the application being uninstalled. -->
- <include
- layout="@layout/app_details"
- android:id="@+id/uninstall_activity_snippet" />
-
- <FrameLayout
- android:id="@+id/top_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="4dip"
- android:paddingStart="16dip"
- android:paddingEnd="16dip" >
- <ProgressBar
- android:id="@+id/progress_bar"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </FrameLayout>
-
- <!-- uninstall application confirmation text -->
- <TextView
- android:id="@+id/uninstall_confirm"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:paddingStart="24dip"
- android:paddingEnd="24dip" />
-
- </LinearLayout>
-
- <!-- OK confirm and cancel buttons. -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:divider="?android:attr/dividerHorizontal"
- android:showDividers="beginning"
- android:paddingTop="16dip">
-
- <LinearLayout
- style="?android:attr/buttonBarStyle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:measureWithLargestChild="true">
-
- <LinearLayout android:id="@+id/leftSpacer"
- android:layout_weight="0.25"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:visibility="gone" />
-
- <Button android:id="@+id/cancel_button"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_gravity="start"
- android:layout_weight="1"
- android:text="@string/cancel"
- android:maxLines="2"
- style="?android:attr/buttonBarButtonStyle" />
-
- <Button android:id="@+id/ok_button"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_gravity="end"
- android:layout_weight="1"
- android:text="@string/ok"
- android:maxLines="2"
- style="?android:attr/buttonBarButtonStyle" />
-
- <LinearLayout android:id="@+id/rightSpacer"
- android:layout_width="0dip"
- android:layout_weight="0.25"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:visibility="gone" />
-
- </LinearLayout>
- </LinearLayout>
-</LinearLayout>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 50d9c17..d30be58 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -189,9 +189,9 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"La configuració de la VPN no està disponible per a aquest usuari."</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"La configuració de compartició de xarxa no està disponible per a aquest usuari."</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"La configuració del nom del punt d\'accés no està disponible per a aquest usuari."</string>
- <string name="enable_adb" msgid="7982306934419797485">"Depuració USB"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"Depuració per USB"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"Activa el mode de depuració quan el dispositiu estigui connectat per USB"</string>
- <string name="clear_adb_keys" msgid="4038889221503122743">"Revoca autoritzacions de depuració USB"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Revoca autoritzacions de depuració per USB"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Drecera per a informe d\'errors"</string>
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Mostra un botó al menú d\'engegada per crear un informe d\'errors"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Pantalla sempre activa"</string>
@@ -251,9 +251,9 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Inspecció d\'atributs de visualització"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén les dades mòbils sempre actives, fins i tot quan la Wi‑Fi està activada (per canviar de xarxa ràpidament)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Fes servir l\'acceleració per maquinari per compartir la xarxa, si està disponible"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració USB?"</string>
- <string name="adb_warning_message" msgid="7316799925425402244">"La depuració USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
- <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració d\'USB dels ordinadors que has autoritzat anteriorment?"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració per USB?"</string>
+ <string name="adb_warning_message" msgid="7316799925425402244">"La depuració per USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració per USB dels ordinadors que has autoritzat anteriorment?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Vols permetre la conf. de desenvolupament?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"Aquesta configuració només està prevista per a usos de desenvolupament. Pot fer que el dispositiu i que les aplicacions s\'interrompin o tinguin un comportament inadequat."</string>
<string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifica aplicacions per USB"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 1579d8f..a90231a 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -189,9 +189,9 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"Nastavení sítě VPN pro tohoto uživatele není dostupné."</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"Nastavení sdíleného připojení pro tohoto uživatele není dostupné."</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"Nastavení přístupového bodu pro tohoto uživatele není dostupné."</string>
- <string name="enable_adb" msgid="7982306934419797485">"Ladění USB"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"Ladění přes USB"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"Povolit režim ladění s připojeným zařízením USB"</string>
- <string name="clear_adb_keys" msgid="4038889221503122743">"Zrušit autorizace k ladění USB"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Zrušit autorizace k ladění přes USB"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Zástupce hlášení chyb"</string>
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Zobrazit v hlavní nabídce tlačítko k vygenerování chybového hlášení"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Nevypínat obrazovku"</string>
@@ -251,9 +251,9 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Kontrola atributu zobrazení"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobilní data budou vždy ponechána aktivní, i když bude aktivní Wi-Fi (za účelem rychlého přepínání sítí)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Pokud je k dispozici hardwarová akceleraci tetheringu, použít ji"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění USB?"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění přes USB?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"Ladění prostřednictvím rozhraní USB je určeno pouze pro účely vývoje. Použijte je ke kopírování dat mezi počítačem a zařízením, instalaci aplikací do zařízení bez upozornění a čtení dat protokolů."</string>
- <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění přes USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Povolit nastavení pro vývojáře?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"Tato nastavení jsou určena pouze pro vývojáře. Mohou způsobit rozbití nebo nesprávné fungování zařízení a nainstalovaných aplikací."</string>
<string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Ověřit aplikace z USB"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index ec7bf98..0410977 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -165,7 +165,7 @@
<string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> motorraren ezarpenak"</string>
<string name="tts_engine_settings_button" msgid="1030512042040722285">"Abiarazi motorraren ezarpenak"</string>
<string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor hobetsia"</string>
- <string name="tts_general_section_title" msgid="4402572014604490502">"Orokorra"</string>
+ <string name="tts_general_section_title" msgid="4402572014604490502">"Orokorrak"</string>
<string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Berrezarri ahots-tonua"</string>
<string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Berrezarri testua esateko ahots-tonu lehenetsia."</string>
<string-array name="tts_rate_entries">
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 5eac8fa..e94dd73 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -371,10 +371,10 @@
<string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Temps restant en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>) : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="3463575350656389957">"Temps restant : <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de l\'utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de l\'utilisation"</string>
- <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by" msgid="6453537733650125582">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index d80e4ff..33c5551 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -162,7 +162,7 @@
Draws decorations about the screen in software (e.g. rounded corners, cutouts).
-### [com.android.systemui.fingerprint.FingerprintDialogImpl](/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java)
+### [com.android.systemui.biometrics.BiometricDialogImpl](/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java)
Fingerprint UI.
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index e6452e7..fa4c8b5 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -39,6 +39,6 @@
-keep class ** extends androidx.preference.PreferenceFragment
-keep class com.android.systemui.tuner.*
-keep class com.android.systemui.plugins.** {
- public protected *;
+ *;
}
-keep class androidx.core.app.CoreComponentFactory
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index 8379dbb..ee8d357 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -28,7 +28,7 @@
<ImageView android:id="@+id/user_avatar"
android:layout_width="@dimen/car_user_switcher_image_avatar_size"
android:layout_height="@dimen/car_user_switcher_image_avatar_size"
- android:background="@drawable/car_button_ripple_background_inverse"
+ android:background="@drawable/car_button_ripple_background_light"
android:gravity="center"/>
<TextView android:id="@+id/user_name"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index aecf494..19492a0 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -354,7 +354,7 @@
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
- <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
+ <item>com.android.systemui.biometrics.BiometricDialogImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
similarity index 63%
rename from packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
rename to packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index a81043e..6e62b0d 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.systemui.fingerprint;
+package com.android.systemui.biometrics;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -31,25 +31,28 @@
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.CommandQueue;
-public class FingerprintDialogImpl extends SystemUI implements CommandQueue.Callbacks {
+/**
+ * Receives messages sent from AuthenticationClient and shows the appropriate biometric UI (e.g.
+ * FingerprintDialogView).
+ */
+public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callbacks {
private static final String TAG = "FingerprintDialogImpl";
private static final boolean DEBUG = true;
- protected static final int MSG_SHOW_DIALOG = 1;
- protected static final int MSG_FINGERPRINT_AUTHENTICATED = 2;
- protected static final int MSG_FINGERPRINT_HELP = 3;
- protected static final int MSG_FINGERPRINT_ERROR = 4;
- protected static final int MSG_HIDE_DIALOG = 5;
- protected static final int MSG_BUTTON_NEGATIVE = 6;
- protected static final int MSG_USER_CANCELED = 7;
- protected static final int MSG_BUTTON_POSITIVE = 8;
- protected static final int MSG_CLEAR_MESSAGE = 9;
-
+ private static final int MSG_SHOW_DIALOG = 1;
+ private static final int MSG_BIOMETRIC_AUTHENTICATED = 2;
+ private static final int MSG_BIOMETRIC_HELP = 3;
+ private static final int MSG_BIOMETRIC_ERROR = 4;
+ private static final int MSG_HIDE_DIALOG = 5;
+ private static final int MSG_BUTTON_NEGATIVE = 6;
+ private static final int MSG_USER_CANCELED = 7;
+ private static final int MSG_BUTTON_POSITIVE = 8;
private FingerprintDialogView mDialogView;
private WindowManager mWindowManager;
private IBiometricPromptReceiver mReceiver;
private boolean mDialogShowing;
+ private Callback mCallback = new Callback();
private Handler mHandler = new Handler() {
@Override
@@ -58,14 +61,14 @@
case MSG_SHOW_DIALOG:
handleShowDialog((SomeArgs) msg.obj);
break;
- case MSG_FINGERPRINT_AUTHENTICATED:
- handleFingerprintAuthenticated();
+ case MSG_BIOMETRIC_AUTHENTICATED:
+ handleBiometricAuthenticated();
break;
- case MSG_FINGERPRINT_HELP:
- handleFingerprintHelp((String) msg.obj);
+ case MSG_BIOMETRIC_HELP:
+ handleBiometricHelp((String) msg.obj);
break;
- case MSG_FINGERPRINT_ERROR:
- handleFingerprintError((String) msg.obj);
+ case MSG_BIOMETRIC_ERROR:
+ handleBiometricError((String) msg.obj);
break;
case MSG_HIDE_DIALOG:
handleHideDialog((Boolean) msg.obj);
@@ -79,13 +82,33 @@
case MSG_BUTTON_POSITIVE:
handleButtonPositive();
break;
- case MSG_CLEAR_MESSAGE:
- handleClearMessage();
- break;
}
}
};
+ private class Callback implements DialogViewCallback {
+ @Override
+ public void onUserCanceled() {
+ mHandler.obtainMessage(BiometricDialogImpl.MSG_USER_CANCELED).sendToTarget();
+ }
+
+ @Override
+ public void onErrorShown() {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_HIDE_DIALOG,
+ false /* userCanceled */), BiometricPrompt.HIDE_DIALOG_DELAY);
+ }
+
+ @Override
+ public void onNegativePressed() {
+ mHandler.obtainMessage(BiometricDialogImpl.MSG_BUTTON_NEGATIVE).sendToTarget();
+ }
+
+ @Override
+ public void onPositivePressed() {
+ mHandler.obtainMessage(BiometricDialogImpl.MSG_BUTTON_POSITIVE).sendToTarget();
+ }
+ }
+
@Override
public void start() {
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
@@ -93,16 +116,16 @@
}
getComponent(CommandQueue.class).addCallbacks(this);
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- mDialogView = new FingerprintDialogView(mContext, mHandler);
+ mDialogView = new FingerprintDialogView(mContext, mCallback);
}
@Override
- public void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
- if (DEBUG) Log.d(TAG, "showFingerprintDialog");
+ public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
+ if (DEBUG) Log.d(TAG, "showBiometricDialog");
// Remove these messages as they are part of the previous client
- mHandler.removeMessages(MSG_FINGERPRINT_ERROR);
- mHandler.removeMessages(MSG_FINGERPRINT_HELP);
- mHandler.removeMessages(MSG_FINGERPRINT_AUTHENTICATED);
+ mHandler.removeMessages(MSG_BIOMETRIC_ERROR);
+ mHandler.removeMessages(MSG_BIOMETRIC_HELP);
+ mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED);
SomeArgs args = SomeArgs.obtain();
args.arg1 = bundle;
args.arg2 = receiver;
@@ -110,26 +133,26 @@
}
@Override
- public void onFingerprintAuthenticated() {
- if (DEBUG) Log.d(TAG, "onFingerprintAuthenticated");
- mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget();
+ public void onBiometricAuthenticated() {
+ if (DEBUG) Log.d(TAG, "onBiometricAuthenticated");
+ mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget();
}
@Override
- public void onFingerprintHelp(String message) {
- if (DEBUG) Log.d(TAG, "onFingerprintHelp: " + message);
- mHandler.obtainMessage(MSG_FINGERPRINT_HELP, message).sendToTarget();
+ public void onBiometricHelp(String message) {
+ if (DEBUG) Log.d(TAG, "onBiometricHelp: " + message);
+ mHandler.obtainMessage(MSG_BIOMETRIC_HELP, message).sendToTarget();
}
@Override
- public void onFingerprintError(String error) {
- if (DEBUG) Log.d(TAG, "onFingerprintError: " + error);
- mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, error).sendToTarget();
+ public void onBiometricError(String error) {
+ if (DEBUG) Log.d(TAG, "onBiometricError: " + error);
+ mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, error).sendToTarget();
}
@Override
- public void hideFingerprintDialog() {
- if (DEBUG) Log.d(TAG, "hideFingerprintDialog");
+ public void hideBiometricDialog() {
+ if (DEBUG) Log.d(TAG, "hideBiometricDialog");
mHandler.obtainMessage(MSG_HIDE_DIALOG, false /* userCanceled */).sendToTarget();
}
@@ -148,21 +171,23 @@
mDialogShowing = true;
}
- private void handleFingerprintAuthenticated() {
- if (DEBUG) Log.d(TAG, "handleFingerprintAuthenticated");
+ private void handleBiometricAuthenticated() {
+ if (DEBUG) Log.d(TAG, "handleBiometricAuthenticated");
+
+ // TODO: announce correct string depending on modality
mDialogView.announceForAccessibility(
mContext.getResources().getText(
com.android.internal.R.string.fingerprint_authenticated));
handleHideDialog(false /* userCanceled */);
}
- private void handleFingerprintHelp(String message) {
- if (DEBUG) Log.d(TAG, "handleFingerprintHelp: " + message);
+ private void handleBiometricHelp(String message) {
+ if (DEBUG) Log.d(TAG, "handleBiometricHelp: " + message);
mDialogView.showHelpMessage(message);
}
- private void handleFingerprintError(String error) {
- if (DEBUG) Log.d(TAG, "handleFingerprintError: " + error);
+ private void handleBiometricError(String error) {
+ if (DEBUG) Log.d(TAG, "handleBiometricError: " + error);
if (!mDialogShowing) {
if (DEBUG) Log.d(TAG, "Dialog already dismissed");
return;
@@ -216,10 +241,6 @@
handleHideDialog(false /* userCanceled */);
}
- private void handleClearMessage() {
- mDialogView.resetMessage();
- }
-
private void handleUserCanceled() {
handleHideDialog(true /* userCanceled */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/DialogViewCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/DialogViewCallback.java
new file mode 100644
index 0000000..f388d9c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/DialogViewCallback.java
@@ -0,0 +1,46 @@
+/*
+ * 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.systemui.biometrics;
+
+/**
+ * Callback interface for dialog views. These should be implemented by the controller (e.g.
+ * FingerprintDialogImpl) and passed into their views (e.g. FingerprintDialogView).
+ */
+public interface DialogViewCallback {
+ /**
+ * Invoked when the user cancels authentication by tapping outside the prompt, etc. The dialog
+ * should be dismissed.
+ */
+ void onUserCanceled();
+
+ /**
+ * Invoked when an error is shown. The dialog should be dismissed after a set amount of time.
+ */
+ void onErrorShown();
+
+ /**
+ * Invoked when the negative button is pressed. The client should be notified and the dialog
+ * should be dismissed.
+ */
+ void onNegativePressed();
+
+ /**
+ * Invoked when the positive button is pressed. The client should be notified and the dialog
+ * should be dismissed.
+ */
+ void onPositivePressed();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
rename to packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
index 8013a9e..68c2c42 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.systemui.fingerprint;
+package com.android.systemui.biometrics;
import android.content.Context;
import android.graphics.Color;
@@ -26,6 +26,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -56,6 +57,8 @@
private static final int ANIMATION_DURATION_SHOW = 250; // ms
private static final int ANIMATION_DURATION_AWAY = 350; // ms
+ private static final int MSG_CLEAR_MESSAGE = 1;
+
private static final int STATE_NONE = 0;
private static final int STATE_FINGERPRINT = 1;
private static final int STATE_FINGERPRINT_ERROR = 2;
@@ -68,18 +71,17 @@
private final int mErrorColor;
private final int mTextColor;
private final int mFingerprintColor;
+ private final float mDisplayWidth;
+ private final DialogViewCallback mCallback;
private ViewGroup mLayout;
private final TextView mErrorText;
- private Handler mHandler;
private Bundle mBundle;
private final LinearLayout mDialog;
private int mLastState;
private boolean mAnimatingAway;
private boolean mWasForceRemoved;
- private final float mDisplayWidth;
-
private final Runnable mShowAnimationRunnable = new Runnable() {
@Override
public void run() {
@@ -98,9 +100,23 @@
}
};
- public FingerprintDialogView(Context context, Handler handler) {
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case MSG_CLEAR_MESSAGE:
+ handleClearMessage();
+ break;
+ default:
+ Log.e(TAG, "Unhandled message: " + msg.what);
+ break;
+ }
+ }
+ };
+
+ public FingerprintDialogView(Context context, DialogViewCallback callback) {
super(context);
- mHandler = handler;
+ mCallback = callback;
mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mAnimationTranslationOffset = getResources()
@@ -138,7 +154,7 @@
downPressed = false;
} else if (event.getAction() == KeyEvent.ACTION_UP && downPressed == true) {
downPressed = false;
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_USER_CANCELED).sendToTarget();
+ mCallback.onUserCanceled();
}
return true;
}
@@ -155,11 +171,11 @@
setDismissesDialog(rightSpace);
negative.setOnClickListener((View v) -> {
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_BUTTON_NEGATIVE).sendToTarget();
+ mCallback.onNegativePressed();
});
positive.setOnClickListener((View v) -> {
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_BUTTON_POSITIVE).sendToTarget();
+ mCallback.onPositivePressed();
});
mLayout.setFocusableInTouchMode(true);
@@ -230,8 +246,7 @@
private void setDismissesDialog(View v) {
v.setClickable(true);
v.setOnTouchListener((View view, MotionEvent event) -> {
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_HIDE_DIALOG, true /* userCanceled */)
- .sendToTarget();
+ mCallback.onUserCanceled();
return true;
});
}
@@ -289,7 +304,7 @@
}
// Clears the temporary message and shows the help message.
- protected void resetMessage() {
+ private void handleClearMessage() {
updateFingerprintIcon(STATE_FINGERPRINT);
mErrorText.setText(R.string.fingerprint_dialog_touch_sensor);
mErrorText.setTextColor(mTextColor);
@@ -297,12 +312,12 @@
// Shows an error/help message
private void showTemporaryMessage(String message) {
- mHandler.removeMessages(FingerprintDialogImpl.MSG_CLEAR_MESSAGE);
+ mHandler.removeMessages(MSG_CLEAR_MESSAGE);
updateFingerprintIcon(STATE_FINGERPRINT_ERROR);
mErrorText.setText(message);
mErrorText.setTextColor(mErrorColor);
mErrorText.setContentDescription(message);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(FingerprintDialogImpl.MSG_CLEAR_MESSAGE),
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_MESSAGE),
BiometricPrompt.HIDE_DIALOG_DELAY);
}
@@ -312,8 +327,7 @@
public void showErrorMessage(String error) {
showTemporaryMessage(error);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(FingerprintDialogImpl.MSG_HIDE_DIALOG,
- false /* userCanceled */), BiometricPrompt.HIDE_DIALOG_DELAY);
+ mCallback.onErrorShown();
}
private void updateFingerprintIcon(int newState) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 8f30edd..03a573e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -65,6 +65,7 @@
private static final boolean ENABLE_FLING_DISMISS = false;
private static final int SHOW_DISMISS_AFFORDANCE_DELAY = 225;
+ private static final int BOTTOM_OFFSET_BUFFER_DP = 1;
// Allow dragging the PIP to a location to close it
private final boolean mEnableDimissDragToEdge;
@@ -314,8 +315,10 @@
// above the position as if shelf/IME shows, don't move the PIP window.
int movementBoundsAdjustment = toMovementBounds.bottom - mMovementBounds.bottom;
int offsetAdjustment = fromImeAdjustment ? mImeOffset : mShelfHeight;
+ final float bottomOffsetBufferInPx = BOTTOM_OFFSET_BUFFER_DP
+ * mContext.getResources().getDisplayMetrics().density;
if (toAdjustedBounds.bottom >= mMovementBounds.bottom
- && animatingBounds.top
+ && animatingBounds.top + Math.round(bottomOffsetBufferInPx)
< toAdjustedBounds.bottom - movementBoundsAdjustment - offsetAdjustment) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 145a246..909cd79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -85,11 +85,11 @@
private static final int MSG_SHOW_SHUTDOWN_UI = 36 << MSG_SHIFT;
private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR = 37 << MSG_SHIFT;
private static final int MSG_ROTATION_PROPOSAL = 38 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_SHOW = 39 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_AUTHENTICATED = 40 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_HELP = 41 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_ERROR = 42 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_HIDE = 43 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_SHOW = 39 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_AUTHENTICATED = 40 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_HELP = 41 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_ERROR = 42 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_HIDE = 43 << MSG_SHIFT;
private static final int MSG_SHOW_CHARGING_ANIMATION = 44 << MSG_SHIFT;
private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT;
private static final int MSG_SHOW_PINNING_TOAST_ESCAPE = 46 << MSG_SHIFT;
@@ -160,11 +160,11 @@
default void onRotationProposal(int rotation, boolean isValid) { }
- default void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) { }
- default void onFingerprintAuthenticated() { }
- default void onFingerprintHelp(String message) { }
- default void onFingerprintError(String error) { }
- default void hideFingerprintDialog() { }
+ default void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) { }
+ default void onBiometricAuthenticated() { }
+ default void onBiometricHelp(String message) { }
+ default void onBiometricError(String error) { }
+ default void hideBiometricDialog() { }
}
@VisibleForTesting
@@ -513,41 +513,41 @@
}
@Override
- public void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
+ public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
synchronized (mLock) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = bundle;
args.arg2 = receiver;
- mHandler.obtainMessage(MSG_FINGERPRINT_SHOW, args)
+ mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args)
.sendToTarget();
}
}
@Override
- public void onFingerprintAuthenticated() {
+ public void onBiometricAuthenticated() {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget();
}
}
@Override
- public void onFingerprintHelp(String message) {
+ public void onBiometricHelp(String message) {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_HELP, message).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_HELP, message).sendToTarget();
}
}
@Override
- public void onFingerprintError(String error) {
+ public void onBiometricError(String error) {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, error).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, error).sendToTarget();
}
}
@Override
- public void hideFingerprintDialog() {
+ public void hideBiometricDialog() {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_HIDE).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_HIDE).sendToTarget();
}
}
@@ -752,34 +752,34 @@
mCallbacks.get(i).onRotationProposal(msg.arg1, msg.arg2 != 0);
}
break;
- case MSG_FINGERPRINT_SHOW:
- mHandler.removeMessages(MSG_FINGERPRINT_ERROR);
- mHandler.removeMessages(MSG_FINGERPRINT_HELP);
- mHandler.removeMessages(MSG_FINGERPRINT_AUTHENTICATED);
+ case MSG_BIOMETRIC_SHOW:
+ mHandler.removeMessages(MSG_BIOMETRIC_ERROR);
+ mHandler.removeMessages(MSG_BIOMETRIC_HELP);
+ mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED);
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).showFingerprintDialog(
+ mCallbacks.get(i).showBiometricDialog(
(Bundle)((SomeArgs)msg.obj).arg1,
(IBiometricPromptReceiver)((SomeArgs)msg.obj).arg2);
}
break;
- case MSG_FINGERPRINT_AUTHENTICATED:
+ case MSG_BIOMETRIC_AUTHENTICATED:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onFingerprintAuthenticated();
+ mCallbacks.get(i).onBiometricAuthenticated();
}
break;
- case MSG_FINGERPRINT_HELP:
+ case MSG_BIOMETRIC_HELP:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onFingerprintHelp((String) msg.obj);
+ mCallbacks.get(i).onBiometricHelp((String) msg.obj);
}
break;
- case MSG_FINGERPRINT_ERROR:
+ case MSG_BIOMETRIC_ERROR:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onFingerprintError((String) msg.obj);
+ mCallbacks.get(i).onBiometricError((String) msg.obj);
}
break;
- case MSG_FINGERPRINT_HIDE:
+ case MSG_BIOMETRIC_HIDE:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).hideFingerprintDialog();
+ mCallbacks.get(i).hideBiometricDialog();
}
break;
case MSG_SHOW_CHARGING_ANIMATION:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
index 92bf821..47b7fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
@@ -27,6 +27,7 @@
import androidx.annotation.VisibleForTesting;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -38,18 +39,21 @@
public final String key;
public final List<Notification.Action> smartActions;
+ public final CharSequence[] smartReplies;
@VisibleForTesting
- NotificationUiAdjustment(String key, List<Notification.Action> smartActions) {
+ NotificationUiAdjustment(
+ String key, List<Notification.Action> smartActions, CharSequence[] smartReplies) {
this.key = key;
this.smartActions = smartActions == null
? Collections.emptyList()
: new ArrayList<>(smartActions);
+ this.smartReplies = smartReplies == null ? new CharSequence[0] : smartReplies.clone();
}
public static NotificationUiAdjustment extractFromNotificationEntry(
NotificationData.Entry entry) {
- return new NotificationUiAdjustment(entry.key, entry.smartActions);
+ return new NotificationUiAdjustment(entry.key, entry.smartActions, entry.smartReplies);
}
public static boolean needReinflate(
@@ -58,7 +62,13 @@
if (oldAdjustment == newAdjustment) {
return false;
}
- return areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions);
+ if (areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions)) {
+ return true;
+ }
+ if (!Arrays.equals(oldAdjustment.smartReplies, newAdjustment.smartReplies)) {
+ return true;
+ }
+ return false;
}
public static boolean areDifferent(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
index 81d6191..32fd054 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
@@ -147,7 +147,7 @@
return;
}
view.setTemp(mHvacManager.getFloatProperty(id, zone));
- } catch (CarNotConnectedException e) {
+ } catch (Exception e) {
view.setTemp(Float.NaN);
Log.e(TAG, "Failed to get value from hvac service", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
index ce8f224..804e842 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
@@ -112,6 +112,7 @@
public int userSentiment = Ranking.USER_SENTIMENT_NEUTRAL;
@NonNull
public List<Notification.Action> smartActions = Collections.emptyList();
+ public CharSequence[] smartReplies = new CharSequence[0];
private int mCachedContrastColor = COLOR_INVALID;
private int mCachedContrastColorIsFor = COLOR_INVALID;
@@ -155,6 +156,9 @@
userSentiment = ranking.getUserSentiment();
smartActions = ranking.getSmartActions() == null
? Collections.emptyList() : ranking.getSmartActions();
+ smartReplies = ranking.getSmartReplies() == null
+ ? new CharSequence[0]
+ : ranking.getSmartReplies().toArray(new CharSequence[0]);
}
public void setInterruption() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index da1fd3b..0110610 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -36,6 +36,7 @@
import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -1229,32 +1230,40 @@
boolean hasRemoteInput = false;
RemoteInput remoteInputWithChoices = null;
PendingIntent pendingIntentWithChoices = null;
+ CharSequence[] choices = null;
Notification.Action[] actions = entry.notification.getNotification().actions;
if (actions != null) {
for (Notification.Action a : actions) {
- if (a.getRemoteInputs() != null) {
- for (RemoteInput ri : a.getRemoteInputs()) {
- boolean showRemoteInputView = ri.getAllowFreeFormInput();
- boolean showSmartReplyView = enableSmartReplies && ri.getChoices() != null
- && ri.getChoices().length > 0;
- if (showRemoteInputView) {
- hasRemoteInput = true;
+ if (a.getRemoteInputs() == null) {
+ continue;
+ }
+ for (RemoteInput ri : a.getRemoteInputs()) {
+ boolean showRemoteInputView = ri.getAllowFreeFormInput();
+ boolean showSmartReplyView = enableSmartReplies
+ && (ArrayUtils.isEmpty(ri.getChoices())
+ || (showRemoteInputView && !ArrayUtils.isEmpty(entry.smartReplies)));
+ if (showRemoteInputView) {
+ hasRemoteInput = true;
+ }
+ if (showSmartReplyView) {
+ remoteInputWithChoices = ri;
+ pendingIntentWithChoices = a.actionIntent;
+ if (!ArrayUtils.isEmpty(ri.getChoices())) {
+ choices = ri.getChoices();
+ } else {
+ choices = entry.smartReplies;
}
- if (showSmartReplyView) {
- remoteInputWithChoices = ri;
- pendingIntentWithChoices = a.actionIntent;
- }
- if (showRemoteInputView || showSmartReplyView) {
- break;
- }
+ }
+ if (showRemoteInputView || showSmartReplyView) {
+ break;
}
}
}
}
applyRemoteInput(entry, hasRemoteInput);
- applySmartReplyView(remoteInputWithChoices, pendingIntentWithChoices, entry);
+ applySmartReplyView(remoteInputWithChoices, pendingIntentWithChoices, entry, choices);
}
private void applyRemoteInput(NotificationData.Entry entry, boolean hasRemoteInput) {
@@ -1356,10 +1365,10 @@
}
private void applySmartReplyView(RemoteInput remoteInput, PendingIntent pendingIntent,
- NotificationData.Entry entry) {
+ NotificationData.Entry entry, CharSequence[] choices) {
if (mExpandedChild != null) {
mExpandedSmartReplyView =
- applySmartReplyView(mExpandedChild, remoteInput, pendingIntent, entry);
+ applySmartReplyView(mExpandedChild, remoteInput, pendingIntent, entry, choices);
if (mExpandedSmartReplyView != null && remoteInput != null
&& remoteInput.getChoices() != null && remoteInput.getChoices().length > 0) {
mSmartReplyController.smartRepliesAdded(entry, remoteInput.getChoices().length);
@@ -1369,7 +1378,7 @@
private SmartReplyView applySmartReplyView(
View view, RemoteInput remoteInput, PendingIntent pendingIntent,
- NotificationData.Entry entry) {
+ NotificationData.Entry entry, CharSequence[] choices) {
View smartReplyContainerCandidate = view.findViewById(
com.android.internal.R.id.smart_reply_container);
if (!(smartReplyContainerCandidate instanceof LinearLayout)) {
@@ -1406,7 +1415,8 @@
}
if (smartReplyView != null) {
smartReplyView.setRepliesFromRemoteInput(remoteInput, pendingIntent,
- mSmartReplyController, entry, smartReplyContainer);
+ mSmartReplyController, entry, smartReplyContainer, choices
+ );
smartReplyContainer.setVisibility(View.VISIBLE);
}
return smartReplyView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 252ab22..c76a4b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -173,14 +173,14 @@
Math.max(getChildCount(), 1), DECREASING_MEASURED_WIDTH_WITHOUT_PADDING_COMPARATOR);
}
- public void setRepliesFromRemoteInput(RemoteInput remoteInput, PendingIntent pendingIntent,
+ public void setRepliesFromRemoteInput(
+ RemoteInput remoteInput, PendingIntent pendingIntent,
SmartReplyController smartReplyController, NotificationData.Entry entry,
- View smartReplyContainer) {
+ View smartReplyContainer, CharSequence[] choices) {
mSmartReplyContainer = smartReplyContainer;
removeAllViews();
mCurrentBackgroundColor = mDefaultBackgroundColor;
if (remoteInput != null && pendingIntent != null) {
- CharSequence[] choices = remoteInput.getChoices();
if (choices != null) {
for (int i = 0; i < choices.length; ++i) {
Button replyButton = inflateReplyButton(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 7855b47..02babac 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -148,6 +148,7 @@
private SafetyWarningDialog mSafetyWarning;
private boolean mHovering = false;
private boolean mShowActiveStreamOnly;
+ private boolean mConfigChanged = false;
public VolumeDialogImpl(Context context) {
mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
@@ -551,6 +552,11 @@
rescheduleTimeoutH();
mShowing = true;
+ if (mConfigChanged) {
+ initDialog();
+ mConfigurableTexts.update();
+ mConfigChanged = false;
+ }
initSettingsH();
mDialog.show();
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
@@ -1102,8 +1108,7 @@
@Override
public void onConfigurationChanged() {
mDialog.dismiss();
- initDialog();
- mConfigurableTexts.update();
+ mConfigChanged = true;
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
index ce47e60..db1e049 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
@@ -30,6 +30,7 @@
import org.junit.Test;
import java.util.Collections;
+import java.util.List;
@SmallTest
public class NotificationUiAdjustmentTest extends SysuiTestCase {
@@ -41,8 +42,8 @@
Notification.Action action =
createActionBuilder("first", R.drawable.ic_corp_icon, pendingIntent).build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.emptyList()),
- new NotificationUiAdjustment("second", Collections.singletonList(action))))
+ createUiAdjustmentFromSmartActions("first", Collections.emptyList()),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(action))))
.isTrue();
}
@@ -56,8 +57,8 @@
createActionBuilder("second", R.drawable.ic_corp_icon, pendingIntent).build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -72,8 +73,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -91,8 +92,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -116,8 +117,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -141,8 +142,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -163,8 +164,25 @@
.addRemoteInput(secondRemoteInput).build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions(
+ "second", Collections.singletonList(secondAction))))
+ .isFalse();
+ }
+
+ @Test
+ public void needReinflate_differentSmartReplies() {
+ assertThat(NotificationUiAdjustment.needReinflate(
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[]{"a", "b"}),
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[] {"b", "a"})))
+ .isTrue();
+ }
+
+ @Test
+ public void needReinflate_sameSmartReplies() {
+ assertThat(NotificationUiAdjustment.needReinflate(
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[] {"a", "b"}),
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[] {"a", "b"})))
.isFalse();
}
@@ -177,4 +195,14 @@
private RemoteInput createRemoteInput(String resultKey, String label, CharSequence[] choices) {
return new RemoteInput.Builder(resultKey).setLabel(label).setChoices(choices).build();
}
+
+ private NotificationUiAdjustment createUiAdjustmentFromSmartActions(
+ String key, List<Notification.Action> actions) {
+ return new NotificationUiAdjustment(key, actions, new CharSequence[0]);
+ }
+
+ private NotificationUiAdjustment createUiAdjustmentFromSmartReplies(
+ String key, CharSequence[] replies) {
+ return new NotificationUiAdjustment(key, Collections.emptyList(), replies);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
index c3683b3..de5a8a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
@@ -430,21 +430,22 @@
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
outRanking.canShowBadge(), outRanking.getUserSentiment(), true,
- null);
+ null, null);
} else if (key.equals(TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY)) {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
outRanking.getVisibilityOverride(), 255,
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
- outRanking.canShowBadge(), outRanking.getUserSentiment(), true, null);
+ outRanking.canShowBadge(), outRanking.getUserSentiment(), true, null, null);
} else {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
outRanking.getVisibilityOverride(), outRanking.getSuppressedVisualEffects(),
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), NOTIFICATION_CHANNEL, null, null,
- outRanking.canShowBadge(), outRanking.getUserSentiment(), false, null);
+ outRanking.canShowBadge(), outRanking.getUserSentiment(), false, null,
+ null);
}
return true;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 61c1ecb..6543bdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -157,7 +157,7 @@
0,
NotificationManager.IMPORTANCE_DEFAULT,
null, null,
- null, null, null, true, sentiment, false, null);
+ null, null, null, true, sentiment, false, null, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
@@ -176,7 +176,7 @@
null, null,
null, null, null, true,
NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL, false,
- smartActions);
+ smartActions, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 5ac2190..01e6307 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -375,7 +375,7 @@
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
new Intent(TEST_ACTION), 0);
RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).setChoices(choices).build();
- mView.setRepliesFromRemoteInput(input, pendingIntent, mLogger, mEntry, mContainer);
+ mView.setRepliesFromRemoteInput(input, pendingIntent, mLogger, mEntry, mContainer, choices);
}
/** Builds a {@link ViewGroup} whose measures and layout mirror a {@link SmartReplyView}. */
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 11b2343..cf08681 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -22,10 +22,8 @@
import android.util.DebugUtils;
import android.util.ExceptionUtils;
import android.util.Log;
-import android.util.Pools.SimplePool;
import android.util.Slog;
import android.util.SparseBooleanArray;
-import android.view.Choreographer;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputFilter;
@@ -104,31 +102,12 @@
| FLAG_FEATURE_AUTOCLICK | FLAG_FEATURE_TOUCH_EXPLORATION
| FLAG_FEATURE_SCREEN_MAGNIFIER | FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER;
- private final Runnable mProcessBatchedEventsRunnable = new Runnable() {
- @Override
- public void run() {
- final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
- if (DEBUG) {
- Slog.i(TAG, "Begin batch processing for frame: " + frameTimeNanos);
- }
- processBatchedEvents(frameTimeNanos);
- if (DEBUG) {
- Slog.i(TAG, "End batch processing.");
- }
- if (mEventQueue != null) {
- scheduleProcessBatchedEvents();
- }
- }
- };
-
private final Context mContext;
private final PowerManager mPm;
private final AccessibilityManagerService mAms;
- private final Choreographer mChoreographer;
-
private boolean mInstalled;
private int mUserId;
@@ -147,8 +126,6 @@
private EventStreamTransformation mEventHandler;
- private MotionEventHolder mEventQueue;
-
private EventStreamState mMouseStreamState;
private EventStreamState mTouchScreenStreamState;
@@ -160,7 +137,6 @@
mContext = context;
mAms = service;
mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- mChoreographer = Choreographer.getInstance();
}
@Override
@@ -274,7 +250,7 @@
return;
}
- batchMotionEvent(event, policyFlags);
+ handleMotionEvent(event, policyFlags);
}
private void processKeyEvent(EventStreamState state, KeyEvent event, int policyFlags) {
@@ -285,68 +261,14 @@
mEventHandler.onKeyEvent(event, policyFlags);
}
- private void scheduleProcessBatchedEvents() {
- mChoreographer.postCallback(Choreographer.CALLBACK_INPUT,
- mProcessBatchedEventsRunnable, null);
- }
-
- private void batchMotionEvent(MotionEvent event, int policyFlags) {
- if (DEBUG) {
- Slog.i(TAG, "Batching event: " + event + ", policyFlags: " + policyFlags);
- }
- if (mEventQueue == null) {
- mEventQueue = MotionEventHolder.obtain(event, policyFlags);
- scheduleProcessBatchedEvents();
- return;
- }
- if (mEventQueue.event.addBatch(event)) {
- return;
- }
- MotionEventHolder holder = MotionEventHolder.obtain(event, policyFlags);
- holder.next = mEventQueue;
- mEventQueue.previous = holder;
- mEventQueue = holder;
- }
-
- private void processBatchedEvents(long frameNanos) {
- MotionEventHolder current = mEventQueue;
- if (current == null) {
- return;
- }
- while (current.next != null) {
- current = current.next;
- }
- while (true) {
- if (current == null) {
- mEventQueue = null;
- break;
- }
- if (current.event.getEventTimeNano() >= frameNanos) {
- // Finished with this choreographer frame. Do the rest on the next one.
- current.next = null;
- break;
- }
- handleMotionEvent(current.event, current.policyFlags);
- MotionEventHolder prior = current;
- current = current.previous;
- prior.recycle();
- }
- }
-
private void handleMotionEvent(MotionEvent event, int policyFlags) {
if (DEBUG) {
- Slog.i(TAG, "Handling batched event: " + event + ", policyFlags: " + policyFlags);
+ Slog.i(TAG, "Handling motion event: " + event + ", policyFlags: " + policyFlags);
}
- // Since we do batch processing it is possible that by the time the
- // next batch is processed the event handle had been set to null.
- if (mEventHandler != null) {
- mPm.userActivity(event.getEventTime(), false);
- MotionEvent transformedEvent = MotionEvent.obtain(event);
- mEventHandler.onMotionEvent(transformedEvent, event, policyFlags);
- transformedEvent.recycle();
- } else {
- if (DEBUG) Slog.d(TAG, "mEventHandler == null for " + event);
- }
+ mPm.userActivity(event.getEventTime(), false);
+ MotionEvent transformedEvent = MotionEvent.obtain(event);
+ mEventHandler.onMotionEvent(transformedEvent, event, policyFlags);
+ transformedEvent.recycle();
}
@Override
@@ -469,9 +391,6 @@
}
private void disableFeatures() {
- // Give the features a chance to process any batched events so we'll keep a consistent
- // event stream
- processBatchedEvents(Long.MAX_VALUE);
if (mMotionEventInjector != null) {
mAms.setMotionEventInjector(null);
mMotionEventInjector.onDestroy();
@@ -515,36 +434,6 @@
/* ignore */
}
- private static class MotionEventHolder {
- private static final int MAX_POOL_SIZE = 32;
- private static final SimplePool<MotionEventHolder> sPool =
- new SimplePool<MotionEventHolder>(MAX_POOL_SIZE);
-
- public int policyFlags;
- public MotionEvent event;
- public MotionEventHolder next;
- public MotionEventHolder previous;
-
- public static MotionEventHolder obtain(MotionEvent event, int policyFlags) {
- MotionEventHolder holder = sPool.acquire();
- if (holder == null) {
- holder = new MotionEventHolder();
- }
- holder.event = MotionEvent.obtain(event);
- holder.policyFlags = policyFlags;
- return holder;
- }
-
- public void recycle() {
- event.recycle();
- event = null;
- policyFlags = 0;
- next = null;
- previous = null;
- sPool.release(this);
- }
- }
-
/**
* Keeps state of event streams observed for an input device with a certain source.
* Provides information about whether motion and key events should be processed by accessibility
diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
index 293f908e..8ee6571 100644
--- a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
+++ b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
@@ -17,8 +17,8 @@
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
-import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS;
-import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM;
+import static android.service.autofill.AutofillFieldClassificationService.RESOURCE_AVAILABLE_ALGORITHMS;
+import static android.service.autofill.AutofillFieldClassificationService.RESOURCE_DEFAULT_ALGORITHM;
import android.Manifest;
import android.annotation.MainThread;
@@ -226,7 +226,7 @@
*/
@Nullable
String[] getAvailableAlgorithms() {
- return getMetadataValue(SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS,
+ return getMetadataValue(RESOURCE_AVAILABLE_ALGORITHMS, "array",
(res, id) -> res.getStringArray(id));
}
@@ -235,11 +235,12 @@
*/
@Nullable
String getDefaultAlgorithm() {
- return getMetadataValue(SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM, (res, id) -> res.getString(id));
+ return getMetadataValue(RESOURCE_DEFAULT_ALGORITHM, "string",
+ (res, id) -> res.getString(id));
}
@Nullable
- private <T> T getMetadataValue(String field, MetadataParser<T> parser) {
+ private <T> T getMetadataValue(String field, String type, MetadataParser<T> parser) {
final ServiceInfo serviceInfo = getServiceInfo();
if (serviceInfo == null) return null;
@@ -253,7 +254,7 @@
return null;
}
- final int resourceId = serviceInfo.metaData.getInt(field);
+ final int resourceId = res.getIdentifier(field, type, serviceInfo.packageName);
return parser.get(res, resourceId);
}
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index ae2a36b..30ec8ab 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -9,6 +9,7 @@
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
+import android.app.backup.IBackupCallback;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
import android.content.pm.ApplicationInfo;
@@ -20,6 +21,7 @@
import android.util.Slog;
import com.android.internal.util.Preconditions;
+import com.android.server.backup.remote.ServiceBackupCallback;
import com.android.server.backup.utils.FullBackupUtils;
import libcore.io.IoUtils;
@@ -158,10 +160,17 @@
mBackupManagerService.prepareOperationTimeout(token, kvBackupAgentTimeoutMillis, null,
OP_TYPE_BACKUP_WAIT);
+ IBackupCallback callback =
+ new ServiceBackupCallback(
+ mBackupManagerService.getBackupManagerBinder(), token);
// Start backup and wait for BackupManagerService to get callback for success or timeout
agent.doBackup(
- mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
- mBackupManagerService.getBackupManagerBinder(), /*transportFlags=*/ 0);
+ mSavedState,
+ mBackupData,
+ mNewState,
+ /* quotaBytes */ Long.MAX_VALUE,
+ callback,
+ /* transportFlags */ 0);
if (!mBackupManagerService.waitUntilOperationComplete(token)) {
Slog.e(TAG, "Key-value backup failed on package " + packageName);
return false;
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index 69f08ae..66b6b37 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -38,7 +38,6 @@
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
-import com.android.server.backup.transport.TransportClient;
import com.android.server.backup.TransportManager;
import com.android.server.backup.fullbackup.PerformAdbBackupTask;
import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
@@ -52,6 +51,7 @@
import com.android.server.backup.params.RestoreParams;
import com.android.server.backup.restore.PerformAdbRestoreTask;
import com.android.server.backup.restore.PerformUnifiedRestoreTask;
+import com.android.server.backup.transport.TransportClient;
import java.util.ArrayList;
import java.util.Collections;
@@ -150,17 +150,22 @@
if (queue.size() > 0) {
// Spin up a backup state sequence and set it running
try {
- String dirName = transport.transportDirName();
OnTaskFinishedListener listener =
caller ->
transportManager
.disposeOfTransportClient(transportClient, caller);
- PerformBackupTask pbt = new PerformBackupTask(
- backupManagerService, transportClient, dirName, queue,
- oldJournal, null, null, listener, Collections.emptyList(), false,
- false /* nonIncremental */);
- Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
- sendMessage(pbtMessage);
+ PerformBackupTask.start(
+ backupManagerService,
+ transportClient,
+ transport.transportDirName(),
+ queue,
+ oldJournal,
+ /* observer */ null,
+ /* monitor */ null,
+ listener,
+ Collections.emptyList(),
+ /* userInitiated */ false,
+ /* nonIncremental */ false);
} catch (Exception e) {
// unable to ask the transport its dir name -- transient failure, since
// the above check succeeded. Try again next time.
@@ -405,13 +410,18 @@
backupManagerService.setBackupRunning(true);
backupManagerService.getWakelock().acquire();
- PerformBackupTask pbt = new PerformBackupTask(
+ PerformBackupTask.start(
backupManagerService,
- params.transportClient, params.dirName,
- kvQueue, null, params.observer, params.monitor, params.listener,
- params.fullPackages, true, params.nonIncrementalBackup);
- Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
- sendMessage(pbtMessage);
+ params.transportClient,
+ params.dirName,
+ kvQueue,
+ /* dataChangedJournal */ null,
+ params.observer,
+ params.monitor,
+ params.listener,
+ params.fullPackages,
+ /* userInitiated */ true,
+ params.nonIncrementalBackup);
break;
}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupState.java b/services/backup/java/com/android/server/backup/internal/BackupState.java
index 937b167..320b555 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupState.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupState.java
@@ -7,5 +7,6 @@
INITIAL,
BACKUP_PM,
RUNNING_QUEUE,
+ CANCELLED,
FINAL
}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 551b80f..c5df82e 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -16,16 +16,11 @@
package com.android.server.backup.internal;
-import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.DEBUG_BACKUP_TRACE;
import static com.android.server.backup.BackupManagerService.KEY_WIDGET_STATE;
-import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
import static com.android.server.backup.BackupManagerService.OP_PENDING;
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
-import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.BackupManagerService.PACKAGE_MANAGER_SENTINEL;
-import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
-import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
import android.annotation.Nullable;
import android.app.ApplicationThreadConstants;
@@ -36,14 +31,16 @@
import android.app.backup.BackupManager;
import android.app.backup.BackupManagerMonitor;
import android.app.backup.BackupTransport;
+import android.app.backup.IBackupCallback;
+import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Message;
+import android.os.ConditionVariable;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.UserHandle;
@@ -51,23 +48,24 @@
import android.system.ErrnoException;
import android.system.Os;
import android.util.EventLog;
+import android.util.Pair;
import android.util.Slog;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.util.Preconditions;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.backup.BackupAgentTimeoutParameters;
+import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
import com.android.server.backup.KeyValueBackupJob;
-import com.android.server.backup.PackageManagerBackupAgent;
-import com.android.server.backup.BackupManagerService;
import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.remote.RemoteCall;
+import com.android.server.backup.remote.RemoteCallable;
+import com.android.server.backup.remote.RemoteResult;
import com.android.server.backup.transport.TransportClient;
-import com.android.server.backup.transport.TransportUtils;
import com.android.server.backup.utils.AppBackupUtils;
import com.android.server.backup.utils.BackupManagerMonitorUtils;
import com.android.server.backup.utils.BackupObserverUtils;
@@ -85,85 +83,225 @@
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
/**
- * This class handles the process of backing up a given list of key/value backup packages.
- * Also takes in a list of pending dolly backups and kicks them off when key/value backups
- * are done.
+ * Represents the task of performing a sequence of key-value backups for a given list of packages.
+ * Method {@link #run()} executes the backups to the transport specified via the {@code
+ * transportClient} parameter in the constructor.
*
- * Flow:
- * If required, backup @pm@.
- * For each pending key/value backup package:
- * - Bind to agent.
- * - Call agent.doBackup()
- * - Wait either for cancel/timeout or operationComplete() callback from the agent.
- * Start task to perform dolly backups.
+ * <p>A few definitions:
*
- * There are three entry points into this class:
- * - execute() [Called from the handler thread]
- * - operationComplete(long result) [Called from the handler thread]
- * - handleCancel(boolean cancelAll) [Can be called from any thread]
- * These methods synchronize on mCancelLock.
+ * <ul>
+ * <li>State directory: {@link BackupManagerService#getBaseStateDir()}/<transport>
+ * <li>State file: {@link
+ * BackupManagerService#getBaseStateDir()}/<transport>/<package><br>
+ * Represents the state of the backup data for a specific package in the current dataset.
+ * <li>Stage directory: {@link BackupManagerService#getDataDir()}
+ * <li>Stage file: {@link BackupManagerService#getDataDir()}/<package>.data<br>
+ * Contains staged data that the agents wrote via {@link BackupDataOutput}, to be transmitted
+ * to the transport.
+ * </ul>
*
- * Interaction with mCurrentOperations:
- * - An entry for this task is put into mCurrentOperations for the entire lifetime of the
- * task. This is useful to cancel the task if required.
- * - An ephemeral entry is put into mCurrentOperations each time we are waiting on for
- * response from a backup agent. This is used to plumb timeouts and completion callbacks.
+ * If there is no PackageManager (PM) pseudo-package state file in the state directory, the
+ * specified transport will be initialized with {@link IBackupTransport#initializeDevice()}.
+ *
+ * <p>The PM pseudo-package is the first package to be backed-up and sent to the transport in case
+ * of incremental choice. If non-incremental, PM will only be backed-up if specified in the queue,
+ * and if it's the case it will be re-positioned at the head of the queue.
+ *
+ * <p>Before starting, this task will register itself in {@link BackupManagerService} current
+ * operations.
+ *
+ * <p>In summary, this task will for each package:
+ *
+ * <ul>
+ * <li>Bind to its {@link IBackupAgent}.
+ * <li>Request transport quota and flags.
+ * <li>Call {@link IBackupAgent#doBackup(ParcelFileDescriptor, ParcelFileDescriptor,
+ * ParcelFileDescriptor, long, int, IBackupManager, int)} via {@link RemoteCall} passing the
+ * old state file descriptor (read), the backup data file descriptor (write), the new state
+ * file descriptor (write), the quota and the transport flags. This will call {@link
+ * BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)} with
+ * the old state file to be read, a {@link BackupDataOutput} object to write the backup data
+ * and the new state file to write. By writing to {@link BackupDataOutput}, the agent will
+ * write data to the stage file. The task will block waiting for either:
+ * <ul>
+ * <li>Agent response.
+ * <li>Agent time-out (specified via {@link
+ * BackupManagerService#getAgentTimeoutParameters()}.
+ * <li>External cancellation or thread interrupt.
+ * </ul>
+ * <li>Unbind the agent.
+ * <li>Assuming agent response, send the staged data that the agent wrote to disk to the transport
+ * via {@link IBackupTransport#performBackup(PackageInfo, ParcelFileDescriptor, int)}.
+ * <li>Call {@link IBackupTransport#finishBackup()} if previous call was successful.
+ * <li>Save the new state in the state file. During the agent call it was being written to
+ * <state file>.new, here we rename it and replace the old one.
+ * <li>Delete the stage file.
+ * </ul>
+ *
+ * In the end, this task will:
+ *
+ * <ul>
+ * <li>Mark data-changed for the remaining packages in the queue (skipped packages).
+ * <li>Delete the {@link DataChangedJournal} provided. Note that this should not be the current
+ * journal.
+ * <li>Set {@link BackupManagerService} current token as {@link
+ * IBackupTransport#getCurrentRestoreSet()}, if applicable.
+ * <li>Add the transport to the list of transports pending initialization ({@link
+ * BackupManagerService#getPendingInits()}) and kick-off initialization if the transport ever
+ * returned {@link BackupTransport#TRANSPORT_NOT_INITIALIZED}.
+ * <li>Unregister the task in current operations.
+ * <li>Release the wakelock.
+ * <li>Kick-off {@link PerformFullTransportBackupTask} if a list of full-backup packages was
+ * provided.
+ * </ul>
+ *
+ * The caller can specify whether this should be an incremental or non-incremental backup. In the
+ * case of non-incremental the agents will be passed an empty old state file, which signals that a
+ * complete backup should be performed.
+ *
+ * <p>This task is designed to run on a dedicated thread, with the exception of the {@link
+ * #handleCancel(boolean)} method, which can be called from any thread.
*/
-public class PerformBackupTask implements BackupRestoreTask {
+// TODO: Stop poking into BMS state and doing things for it (e.g. synchronizing on public locks)
+// TODO: Consider having the caller responsible for some clean-up (like resetting state)
+// TODO: Distinguish between cancel and time-out where possible for logging/monitoring/observing
+public class PerformBackupTask implements BackupRestoreTask, Runnable {
private static final String TAG = "PerformBackupTask";
+ private static final boolean DEBUG = BackupManagerService.DEBUG || true;
+ private static final boolean MORE_DEBUG = BackupManagerService.MORE_DEBUG || false;
+ private static final int THREAD_PRIORITY = Process.THREAD_PRIORITY_BACKGROUND;
+ private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
private static final String BLANK_STATE_FILE_NAME = "blank_state";
@VisibleForTesting
public static final String STAGING_FILE_SUFFIX = ".data";
@VisibleForTesting
public static final String NEW_STATE_FILE_SUFFIX = ".new";
- private BackupManagerService backupManagerService;
- private final Object mCancelLock = new Object();
+ /**
+ * Creates a new {@link PerformBackupTask} for key-value backup operation, spins up a new
+ * dedicated thread and kicks off the operation in it.
+ *
+ * @param backupManagerService The {@link BackupManagerService} system service.
+ * @param transportClient The {@link TransportClient} that contains the transport used for the
+ * operation.
+ * @param transportDirName The value of {@link IBackupTransport#transportDirName()} for the
+ * transport whose {@link TransportClient} was provided above.
+ * @param queue The list of packages that will be backed-up, in the form of {@link
+ * BackupRequest}.
+ * @param dataChangedJournal The old data-changed journal file that will be deleted when the
+ * operation finishes (successfully or not) or {@code null}.
+ * @param observer A {@link IBackupObserver}.
+ * @param monitor A {@link IBackupManagerMonitor}.
+ * @param listener A {@link OnTaskFinishedListener} or {@code null}.
+ * @param pendingFullBackups The list of packages that will be passed for a new {@link
+ * PerformFullTransportBackupTask} operation, which will be started when this finishes.
+ * @param userInitiated Whether this was user-initiated or not.
+ * @param nonIncremental If {@code true}, this will be a complete backup for each package,
+ * otherwise it will be just an incremental one over the current dataset.
+ * @return The {@link PerformBackupTask} that was started.
+ */
+ public static PerformBackupTask start(
+ BackupManagerService backupManagerService,
+ TransportClient transportClient,
+ String transportDirName,
+ ArrayList<BackupRequest> queue,
+ @Nullable DataChangedJournal dataChangedJournal,
+ IBackupObserver observer,
+ IBackupManagerMonitor monitor,
+ @Nullable OnTaskFinishedListener listener,
+ List<String> pendingFullBackups,
+ boolean userInitiated,
+ boolean nonIncremental) {
+ PerformBackupTask task =
+ new PerformBackupTask(
+ backupManagerService,
+ transportClient,
+ transportDirName,
+ queue,
+ dataChangedJournal,
+ observer,
+ monitor,
+ listener,
+ pendingFullBackups,
+ userInitiated,
+ nonIncremental);
+ Thread thread = new Thread(task, "key-value-backup-" + THREAD_COUNT.incrementAndGet());
+ if (DEBUG) {
+ Slog.d(TAG, "Spinning thread " + thread.getName());
+ }
+ thread.start();
+ return task;
+ }
- private ArrayList<BackupRequest> mQueue;
- private ArrayList<BackupRequest> mOriginalQueue;
- private File mStateDir;
- @Nullable private DataChangedJournal mJournal;
- private BackupState mCurrentState;
- private List<String> mPendingFullBackups;
- private IBackupObserver mObserver;
- private IBackupManagerMonitor mMonitor;
-
+ private final BackupManagerService mBackupManagerService;
private final TransportClient mTransportClient;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
+ private final IBackupObserver mObserver;
private final OnTaskFinishedListener mListener;
- private final PerformFullTransportBackupTask mFullBackupTask;
+ private final boolean mUserInitiated;
+ private final boolean mNonIncremental;
private final int mCurrentOpToken;
- private volatile int mEphemeralOpToken;
+ private final File mStateDir;
+ private final ArrayList<BackupRequest> mOriginalQueue;
+ private final ArrayList<BackupRequest> mQueue;
+ private final List<String> mPendingFullBackups;
+ @Nullable private final DataChangedJournal mJournal;
+ private IBackupManagerMonitor mMonitor;
+ @Nullable private PerformFullTransportBackupTask mFullBackupTask;
- // carried information about the current in-flight operation
private IBackupAgent mAgentBinder;
private PackageInfo mCurrentPackage;
- private File mSavedStateName;
- private File mBackupDataName;
- private File mNewStateName;
+ private File mSavedStateFile;
+ private File mBackupDataFile;
+ private File mNewStateFile;
private ParcelFileDescriptor mSavedState;
private ParcelFileDescriptor mBackupData;
private ParcelFileDescriptor mNewState;
private int mStatus;
- private boolean mFinished;
- private final boolean mUserInitiated;
- private final boolean mNonIncremental;
- private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
- private volatile boolean mCancelAll;
+ /**
+ * This {@link ConditionVariable} is used to signal that the cancel operation has been
+ * received by the task and that no more transport calls will be made. Anyone can call {@link
+ * ConditionVariable#block()} to wait for these conditions to hold true, but there should only
+ * be one place where {@link ConditionVariable#open()} is called. Also there should be no calls
+ * to {@link ConditionVariable#close()}, which means there is only one cancel per backup -
+ * subsequent calls to block will return immediately.
+ */
+ private final ConditionVariable mCancelAcknowledged = new ConditionVariable(false);
- public PerformBackupTask(BackupManagerService backupManagerService,
- TransportClient transportClient, String dirName,
- ArrayList<BackupRequest> queue, @Nullable DataChangedJournal journal,
- IBackupObserver observer, IBackupManagerMonitor monitor,
- @Nullable OnTaskFinishedListener listener, List<String> pendingFullBackups,
- boolean userInitiated, boolean nonIncremental) {
- this.backupManagerService = backupManagerService;
+ /**
+ * Set it to {@code true} and block on {@code mCancelAcknowledged} to wait for the cancellation.
+ * DO NOT set it to {@code false}.
+ */
+ private volatile boolean mCancelled = false;
+
+ /**
+ * If non-{@code null} there is a pending agent call being made. This call can be cancelled (and
+ * control returned to this task) with {@link RemoteCall#cancel()}.
+ */
+ @Nullable private volatile RemoteCall mPendingCall;
+
+ @VisibleForTesting
+ public PerformBackupTask(
+ BackupManagerService backupManagerService,
+ TransportClient transportClient,
+ String transportDirName,
+ ArrayList<BackupRequest> queue,
+ @Nullable DataChangedJournal journal,
+ IBackupObserver observer,
+ IBackupManagerMonitor monitor,
+ @Nullable OnTaskFinishedListener listener,
+ List<String> pendingFullBackups,
+ boolean userInitiated,
+ boolean nonIncremental) {
+ mBackupManagerService = backupManagerService;
mTransportClient = transportClient;
mOriginalQueue = queue;
- mQueue = new ArrayList<>();
+ // We need to retain the original queue contents in case of transport failure
+ mQueue = new ArrayList<>(mOriginalQueue);
mJournal = journal;
mObserver = observer;
mMonitor = monitor;
@@ -171,92 +309,80 @@
mPendingFullBackups = pendingFullBackups;
mUserInitiated = userInitiated;
mNonIncremental = nonIncremental;
- mAgentTimeoutParameters = Preconditions.checkNotNull(
- backupManagerService.getAgentTimeoutParameters(),
- "Timeout parameters cannot be null");
-
- mStateDir = new File(backupManagerService.getBaseStateDir(), dirName);
+ mAgentTimeoutParameters =
+ Preconditions.checkNotNull(
+ backupManagerService.getAgentTimeoutParameters(),
+ "Timeout parameters cannot be null");
+ mStateDir = new File(backupManagerService.getBaseStateDir(), transportDirName);
mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
-
- mFinished = false;
-
- synchronized (backupManagerService.getCurrentOpLock()) {
- if (backupManagerService.isBackupOperationInProgress()) {
- if (DEBUG) {
- Slog.d(TAG, "Skipping backup since one is already in progress.");
- }
- mCancelAll = true;
- mFullBackupTask = null;
- mCurrentState = BackupState.FINAL;
- backupManagerService.addBackupTrace("Skipped. Backup already in progress.");
- } else {
- mCurrentState = BackupState.INITIAL;
- CountDownLatch latch = new CountDownLatch(1);
- String[] fullBackups =
- mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
- mFullBackupTask =
- new PerformFullTransportBackupTask(backupManagerService,
- transportClient,
- /*fullBackupRestoreObserver*/ null,
- fullBackups, /*updateSchedule*/ false, /*runningJob*/ null,
- latch,
- mObserver, mMonitor, mListener, mUserInitiated);
-
- registerTask();
- backupManagerService.addBackupTrace("STATE => INITIAL");
- }
- }
}
- /**
- * Put this task in the repository of running tasks.
- */
private void registerTask() {
- backupManagerService.putOperation(
+ mBackupManagerService.putOperation(
mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
}
- /**
- * Remove this task from repository of running tasks.
- */
private void unregisterTask() {
- backupManagerService.removeOperation(mCurrentOpToken);
+ mBackupManagerService.removeOperation(mCurrentOpToken);
}
- // Main entry point: perform one chunk of work, updating the state as appropriate
- // and reposting the next chunk to the primary backup handler thread.
@Override
- @GuardedBy("mCancelLock")
- public void execute() {
- synchronized (mCancelLock) {
- switch (mCurrentState) {
- case INITIAL:
- beginBackup();
- break;
+ public void run() {
+ Process.setThreadPriority(THREAD_PRIORITY);
+ BackupState state = beginBackup();
+ while (state == BackupState.RUNNING_QUEUE || state == BackupState.BACKUP_PM) {
+ if (mCancelled) {
+ state = BackupState.CANCELLED;
+ }
+ switch (state) {
case BACKUP_PM:
- backupPm();
+ state = backupPm();
break;
-
case RUNNING_QUEUE:
- invokeNextAgent();
- break;
-
- case FINAL:
- if (!mFinished) {
- finalizeBackup();
- } else {
- Slog.e(TAG, "Duplicate finish of K/V pass");
+ Pair<BackupState, RemoteResult> stateAndResult = invokeNextAgent();
+ state = stateAndResult.first;
+ if (state == null) {
+ state = processAgentInvocation(stateAndResult.second);
}
break;
}
}
+ if (state == BackupState.CANCELLED) {
+ finalizeCancelledBackup();
+ } else {
+ finalizeBackup();
+ }
}
- // We're starting a backup pass. Initialize the transport if we haven't already.
- private void beginBackup() {
+ private BackupState processAgentInvocation(RemoteResult result) {
+ if (result == RemoteResult.FAILED_THREAD_INTERRUPTED) {
+ // Not an explicit cancel, we need to flag it
+ mCancelled = true;
+ handleAgentCancelled();
+ return BackupState.CANCELLED;
+ }
+ if (result == RemoteResult.FAILED_CANCELLED) {
+ handleAgentCancelled();
+ return BackupState.CANCELLED;
+ }
+ if (result == RemoteResult.FAILED_TIMED_OUT) {
+ handleAgentTimeout();
+ return BackupState.RUNNING_QUEUE;
+ }
+ Preconditions.checkState(result.succeeded());
+ return handleAgentResult(result.get());
+ }
+
+ @Override
+ public void execute() {}
+
+ @Override
+ public void operationComplete(long unusedResult) {}
+
+ private BackupState beginBackup() {
if (DEBUG_BACKUP_TRACE) {
- backupManagerService.clearBackupTrace();
+ mBackupManagerService.clearBackupTrace();
StringBuilder b = new StringBuilder(256);
b.append("beginBackup: [");
for (BackupRequest req : mOriginalQueue) {
@@ -264,8 +390,34 @@
b.append(req.packageName);
}
b.append(" ]");
- backupManagerService.addBackupTrace(b.toString());
+ mBackupManagerService.addBackupTrace(b.toString());
}
+ synchronized (mBackupManagerService.getCurrentOpLock()) {
+ if (mBackupManagerService.isBackupOperationInProgress()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Skipping backup since one is already in progress.");
+ }
+ mBackupManagerService.addBackupTrace("Skipped. Backup already in progress.");
+ return BackupState.FINAL;
+ }
+ }
+
+ String[] fullBackups = mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
+ mFullBackupTask =
+ new PerformFullTransportBackupTask(
+ mBackupManagerService,
+ mTransportClient,
+ /* fullBackupRestoreObserver */ null,
+ fullBackups,
+ /* updateSchedule */ false,
+ /* runningJob */ null,
+ new CountDownLatch(1),
+ mObserver,
+ mMonitor,
+ mListener,
+ mUserInitiated);
+ registerTask();
+ mBackupManagerService.addBackupTrace("STATE => INITIAL");
mAgentBinder = null;
mStatus = BackupTransport.TRANSPORT_OK;
@@ -273,16 +425,10 @@
// Sanity check: if the queue is empty we have no work to do.
if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
- backupManagerService.addBackupTrace("queue empty at begin");
- executeNextState(BackupState.FINAL);
- return;
+ mBackupManagerService.addBackupTrace("queue empty at begin");
+ return BackupState.FINAL;
}
- // We need to retain the original queue contents in case of transport
- // failure, but we want a working copy that we can manipulate along
- // the way.
- mQueue = (ArrayList<BackupRequest>) mOriginalQueue.clone();
-
// When the transport is forcing non-incremental key/value payloads, we send the
// metadata only if it explicitly asks for it.
boolean skipPm = mNonIncremental;
@@ -292,8 +438,7 @@
// we performed a backup. Drop it from the working queue now that
// we're committed to evaluating it for backup regardless.
for (int i = 0; i < mQueue.size(); i++) {
- if (PACKAGE_MANAGER_SENTINEL.equals(
- mQueue.get(i).packageName)) {
+ if (PACKAGE_MANAGER_SENTINEL.equals(mQueue.get(i).packageName)) {
if (MORE_DEBUG) {
Slog.i(TAG, "Metadata in queue; eliding");
}
@@ -309,17 +454,17 @@
File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
try {
IBackupTransport transport = mTransportClient.connectOrThrow("PBT.beginBackup()");
- final String transportName = transport.transportDirName();
+ String transportName = transport.name();
EventLog.writeEvent(EventLogTags.BACKUP_START, transportName);
// If we haven't stored package manager metadata yet, we must init the transport.
- if (mStatus == BackupTransport.TRANSPORT_OK && pmState.length() <= 0) {
+ if (pmState.length() <= 0) {
Slog.i(TAG, "Initializing (wiping) backup state and transport storage");
- backupManagerService.addBackupTrace("initializing transport " + transportName);
- backupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ mBackupManagerService.addBackupTrace("initializing transport " + transportName);
+ mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
mStatus = transport.initializeDevice();
- backupManagerService.addBackupTrace("transport.initializeDevice() == " + mStatus);
+ mBackupManagerService.addBackupTrace("transport.initializeDevice() == " + mStatus);
if (mStatus == BackupTransport.TRANSPORT_OK) {
EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
} else {
@@ -327,82 +472,81 @@
Slog.e(TAG, "Transport error in initializeDevice()");
}
}
-
- if (skipPm) {
- Slog.d(TAG, "Skipping backup of package metadata.");
- executeNextState(BackupState.RUNNING_QUEUE);
- } else {
- // As the package manager is running here in the system process we can just set up
- // its agent directly. Thus we always run this pass because it's cheap and this way
- // we guarantee that we don't get out of step even if we're selecting among various
- // transports at run time.
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- executeNextState(BackupState.BACKUP_PM);
- }
- }
} catch (Exception e) {
Slog.e(TAG, "Error in backup thread during init", e);
- backupManagerService.addBackupTrace("Exception in backup thread during init: " + e);
+ mBackupManagerService.addBackupTrace("Exception in backup thread during init: " + e);
mStatus = BackupTransport.TRANSPORT_ERROR;
- } finally {
- // If we've succeeded so far, we will move to the BACKUP_PM state. If something has gone
- // wrong then that won't have happen so cleanup.
- backupManagerService.addBackupTrace("exiting prelim: " + mStatus);
- if (mStatus != BackupTransport.TRANSPORT_OK) {
- // if things went wrong at this point, we need to
- // restage everything and try again later.
- backupManagerService.resetBackupState(mStateDir); // Just to make sure.
- // In case of any other error, it's backup transport error.
- executeNextState(BackupState.FINAL);
- }
}
+ mBackupManagerService.addBackupTrace("exiting prelim: " + mStatus);
+
+ if (mStatus != BackupTransport.TRANSPORT_OK) {
+ // if things went wrong at this point, we need to
+ // restage everything and try again later.
+ mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ return BackupState.FINAL;
+ }
+
+ if (skipPm) {
+ Slog.d(TAG, "Skipping backup of package metadata.");
+ return BackupState.RUNNING_QUEUE;
+ }
+
+ return BackupState.BACKUP_PM;
}
- private void backupPm() {
+ private BackupState backupPm() {
+ RemoteResult agentResult = null;
+ BackupState nextState;
try {
// The package manager doesn't have a proper <application> etc, but since it's running
// here in the system process we can just set up its agent directly and use a synthetic
// BackupRequest.
- BackupAgent pmAgent = backupManagerService.makeMetadataAgent();
- mStatus = invokeAgentForBackup(
- PACKAGE_MANAGER_SENTINEL,
- IBackupAgent.Stub.asInterface(pmAgent.onBind()));
- backupManagerService.addBackupTrace("PMBA invoke: " + mStatus);
+ BackupAgent pmAgent = mBackupManagerService.makeMetadataAgent();
+ Pair<Integer, RemoteResult> statusAndResult =
+ invokeAgentForBackup(
+ PACKAGE_MANAGER_SENTINEL,
+ IBackupAgent.Stub.asInterface(pmAgent.onBind()));
+ mStatus = statusAndResult.first;
+ agentResult = statusAndResult.second;
- // Because the PMBA is a local instance, it has already executed its backup callback and
- // returned. Blow away the lingering (spurious) pending timeout message for it.
- backupManagerService.getBackupHandler().removeMessages(
- MSG_BACKUP_OPERATION_TIMEOUT);
+ mBackupManagerService.addBackupTrace("PMBA invoke: " + mStatus);
} catch (Exception e) {
Slog.e(TAG, "Error in backup thread during pm", e);
- backupManagerService.addBackupTrace("Exception in backup thread during pm: " + e);
+ mBackupManagerService.addBackupTrace("Exception in backup thread during pm: " + e);
mStatus = BackupTransport.TRANSPORT_ERROR;
- } finally {
- // If we've succeeded so far, invokeAgentForBackup() will have run the PM
- // metadata and its completion/timeout callback will continue the state
- // machine chain. If it failed that won't happen; we handle that now.
- backupManagerService.addBackupTrace("exiting backupPm: " + mStatus);
- if (mStatus != BackupTransport.TRANSPORT_OK) {
- // if things went wrong at this point, we need to
- // restage everything and try again later.
- backupManagerService.resetBackupState(mStateDir); // Just to make sure.
- executeNextState(BackupState.FINAL);
- }
}
+ mBackupManagerService.addBackupTrace("exiting backupPm: " + mStatus);
+
+ if (mStatus == BackupTransport.TRANSPORT_OK) {
+ Preconditions.checkNotNull(agentResult);
+ nextState = processAgentInvocation(agentResult);
+ } else {
+ // if things went wrong at this point, we need to
+ // restage everything and try again later.
+ mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ nextState = BackupState.FINAL;
+ }
+
+ return nextState;
}
- // Transport has been initialized and the PM metadata submitted successfully
- // if that was warranted. Now we process the single next thing in the queue.
- private void invokeNextAgent() {
+ /**
+ * Returns either:
+ *
+ * <ul>
+ * <li>(next state, {@code null}): In case we failed to call the agent.
+ * <li>({@code null}, agent result): In case we successfully called the agent.
+ * </ul>
+ */
+ private Pair<BackupState, RemoteResult> invokeNextAgent() {
mStatus = BackupTransport.TRANSPORT_OK;
- backupManagerService.addBackupTrace("invoke q=" + mQueue.size());
+ mBackupManagerService.addBackupTrace("invoke q=" + mQueue.size());
// Sanity check that we have work to do. If not, skip to the end where
// we reestablish the wakelock invariants etc.
if (mQueue.isEmpty()) {
if (MORE_DEBUG) Slog.i(TAG, "queue now empty");
- executeNextState(BackupState.FINAL);
- return;
+ return Pair.create(BackupState.FINAL, null);
}
// pop the entry we're going to process on this step
@@ -410,15 +554,16 @@
mQueue.remove(0);
Slog.d(TAG, "starting key/value backup of " + request);
- backupManagerService.addBackupTrace("launch agent for " + request.packageName);
+ mBackupManagerService.addBackupTrace("launch agent for " + request.packageName);
// Verify that the requested app exists; it might be something that
// requested a backup but was then uninstalled. The request was
// journalled and rather than tamper with the journal it's safer
// to sanity-check here. This also gives us the classname of the
// package's backup agent.
+ RemoteResult agentResult = null;
try {
- PackageManager pm = backupManagerService.getPackageManager();
+ PackageManager pm = mBackupManagerService.getPackageManager();
mCurrentPackage = pm.getPackageInfo(request.packageName,
PackageManager.GET_SIGNING_CERTIFICATES);
if (!AppBackupUtils.appIsEligibleForBackup(mCurrentPackage.applicationInfo, pm)) {
@@ -427,14 +572,13 @@
// backups.
Slog.i(TAG, "Package " + request.packageName
+ " no longer supports backup; skipping");
- backupManagerService.addBackupTrace("skipping - not eligible, completion is noop");
+ mBackupManagerService.addBackupTrace("skipping - not eligible, completion is noop");
// Shouldn't happen in case of requested backup, as pre-check was done in
// #requestBackup(), except to app update done concurrently
BackupObserverUtils.sendBackupOnPackageResult(mObserver,
mCurrentPackage.packageName,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
- executeNextState(BackupState.RUNNING_QUEUE);
- return;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
}
if (AppBackupUtils.appGetsFullBackup(mCurrentPackage)) {
@@ -443,42 +587,41 @@
// Don't proceed with a key/value backup for it in this case.
Slog.i(TAG, "Package " + request.packageName
+ " requests full-data rather than key/value; skipping");
- backupManagerService.addBackupTrace(
+ mBackupManagerService.addBackupTrace(
"skipping - fullBackupOnly, completion is noop");
// Shouldn't happen in case of requested backup, as pre-check was done in
// #requestBackup()
BackupObserverUtils.sendBackupOnPackageResult(mObserver,
mCurrentPackage.packageName,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
- executeNextState(BackupState.RUNNING_QUEUE);
- return;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
}
if (AppBackupUtils.appIsStopped(mCurrentPackage.applicationInfo)) {
// The app has been force-stopped or cleared or just installed,
// and not yet launched out of that state, so just as it won't
// receive broadcasts, we won't run it for backup.
- backupManagerService.addBackupTrace("skipping - stopped");
+ mBackupManagerService.addBackupTrace("skipping - stopped");
BackupObserverUtils.sendBackupOnPackageResult(mObserver,
mCurrentPackage.packageName,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
- executeNextState(BackupState.RUNNING_QUEUE);
- return;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
}
- IBackupAgent agent = null;
try {
- backupManagerService.setWorkSource(
+ mBackupManagerService.setWorkSource(
new WorkSource(mCurrentPackage.applicationInfo.uid));
- agent = backupManagerService.bindToAgentSynchronous(mCurrentPackage.applicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
- backupManagerService.addBackupTrace("agent bound; a? = " + (agent != null));
+ IBackupAgent agent =
+ mBackupManagerService.bindToAgentSynchronous(
+ mCurrentPackage.applicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
+ mBackupManagerService.addBackupTrace("agent bound; a? = " + (agent != null));
if (agent != null) {
mAgentBinder = agent;
- mStatus = invokeAgentForBackup(request.packageName, agent);
- // at this point we'll either get a completion callback from the
- // agent, or a timeout message on the main handler. either way, we're
- // done here as long as we're successful so far.
+ Pair<Integer, RemoteResult> statusAndResult =
+ invokeAgentForBackup(request.packageName, agent);
+ mStatus = statusAndResult.first;
+ agentResult = statusAndResult.second;
} else {
// Timeout waiting for the agent
mStatus = BackupTransport.AGENT_ERROR;
@@ -487,62 +630,59 @@
// Try for the next one.
Slog.d(TAG, "error in bind/backup", ex);
mStatus = BackupTransport.AGENT_ERROR;
- backupManagerService.addBackupTrace("agent SE");
+ mBackupManagerService.addBackupTrace("agent SE");
}
- } catch (NameNotFoundException e) {
+ } catch (PackageManager.NameNotFoundException e) {
Slog.d(TAG, "Package does not exist; skipping");
- backupManagerService.addBackupTrace("no such package");
+ mBackupManagerService.addBackupTrace("no such package");
mStatus = BackupTransport.AGENT_UNKNOWN;
} finally {
- backupManagerService.setWorkSource(null);
-
- // If there was an agent error, no timeout/completion handling will occur.
- // That means we need to direct to the next state ourselves.
- if (mStatus != BackupTransport.TRANSPORT_OK) {
- BackupState nextState = BackupState.RUNNING_QUEUE;
- mAgentBinder = null;
-
- // An agent-level failure means we reenqueue this one agent for
- // a later retry, but otherwise proceed normally.
- if (mStatus == BackupTransport.AGENT_ERROR) {
- if (MORE_DEBUG) {
- Slog.i(TAG, "Agent failure for " + request.packageName
- + " - restaging");
- }
- backupManagerService.dataChangedImpl(request.packageName);
- mStatus = BackupTransport.TRANSPORT_OK;
- if (mQueue.isEmpty()) nextState = BackupState.FINAL;
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
- BackupManager.ERROR_AGENT_FAILURE);
- } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
- // Failed lookup of the app, so we couldn't bring up an agent, but
- // we're otherwise fine. Just drop it and go on to the next as usual.
- mStatus = BackupTransport.TRANSPORT_OK;
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, request.packageName,
- BackupManager.ERROR_PACKAGE_NOT_FOUND);
- } else {
- // Transport-level failure means we reenqueue everything
- revertAndEndBackup();
- nextState = BackupState.FINAL;
- }
-
- executeNextState(nextState);
- } else {
- // success case
- backupManagerService.addBackupTrace("expecting completion/timeout callback");
- }
+ mBackupManagerService.setWorkSource(null);
}
+
+ if (mStatus != BackupTransport.TRANSPORT_OK) {
+ BackupState nextState = BackupState.RUNNING_QUEUE;
+ mAgentBinder = null;
+
+ // An agent-level failure means we re-enqueue this one agent for
+ // a later retry, but otherwise proceed normally.
+ if (mStatus == BackupTransport.AGENT_ERROR) {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Agent failure for " + request.packageName + " - restaging");
+ }
+ mBackupManagerService.dataChangedImpl(request.packageName);
+ mStatus = BackupTransport.TRANSPORT_OK;
+ BackupObserverUtils
+ .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+ BackupManager.ERROR_AGENT_FAILURE);
+ } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
+ // Failed lookup of the app, so we couldn't bring up an agent, but
+ // we're otherwise fine. Just drop it and go on to the next as usual.
+ mStatus = BackupTransport.TRANSPORT_OK;
+ BackupObserverUtils
+ .sendBackupOnPackageResult(mObserver, request.packageName,
+ BackupManager.ERROR_PACKAGE_NOT_FOUND);
+ } else {
+ // Transport-level failure means we re-enqueue everything
+ revertAndEndBackup();
+ nextState = BackupState.FINAL;
+ }
+
+ return Pair.create(nextState, null);
+ }
+
+ // Success: caller will figure out the state based on call result
+ mBackupManagerService.addBackupTrace("call made; result = " + agentResult);
+ return Pair.create(null, agentResult);
}
private void finalizeBackup() {
- backupManagerService.addBackupTrace("finishing");
+ mBackupManagerService.addBackupTrace("finishing");
// Mark packages that we didn't backup (because backup was cancelled, etc.) as needing
// backup.
for (BackupRequest req : mQueue) {
- backupManagerService.dataChangedImpl(req.packageName);
+ mBackupManagerService.dataChangedImpl(req.packageName);
}
// Either backup was successful, in which case we of course do not need
@@ -557,65 +697,62 @@
// done a backup, we can now record what the current backup dataset token
// is.
String callerLogString = "PBT.finalizeBackup()";
- if ((backupManagerService.getCurrentToken() == 0) && (mStatus
+ if ((mBackupManagerService.getCurrentToken() == 0) && (mStatus
== BackupTransport.TRANSPORT_OK)) {
- backupManagerService.addBackupTrace("success; recording token");
+ mBackupManagerService.addBackupTrace("success; recording token");
try {
- IBackupTransport transport =
- mTransportClient.connectOrThrow(callerLogString);
- backupManagerService.setCurrentToken(transport.getCurrentRestoreSet());
- backupManagerService.writeRestoreTokens();
+ IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString);
+ mBackupManagerService.setCurrentToken(transport.getCurrentRestoreSet());
+ mBackupManagerService.writeRestoreTokens();
} catch (Exception e) {
// nothing for it at this point, unfortunately, but this will be
// recorded the next time we fully succeed.
Slog.e(TAG, "Transport threw reporting restore set: " + e.getMessage());
- backupManagerService.addBackupTrace("transport threw returning token");
+ mBackupManagerService.addBackupTrace("transport threw returning token");
}
}
// Set up the next backup pass - at this point we can set mBackupRunning
- // to false to allow another pass to fire, because we're done with the
- // state machine sequence and the wakelock is refcounted.
- synchronized (backupManagerService.getQueueLock()) {
- backupManagerService.setBackupRunning(false);
+ // to false to allow another pass to fire
+ synchronized (mBackupManagerService.getQueueLock()) {
+ mBackupManagerService.setBackupRunning(false);
if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
// Make sure we back up everything and perform the one-time init
if (MORE_DEBUG) {
Slog.d(TAG, "Server requires init; rerunning");
}
- backupManagerService.addBackupTrace("init required; rerunning");
+ mBackupManagerService.addBackupTrace("init required; rerunning");
try {
- String name = backupManagerService.getTransportManager()
+ String name = mBackupManagerService.getTransportManager()
.getTransportName(mTransportClient.getTransportComponent());
- backupManagerService.getPendingInits().add(name);
+ mBackupManagerService.getPendingInits().add(name);
} catch (Exception e) {
Slog.w(TAG, "Failed to query transport name for init: " + e.getMessage());
// swallow it and proceed; we don't rely on this
}
clearMetadata();
- backupManagerService.backupNow();
+ mBackupManagerService.backupNow();
}
}
- backupManagerService.clearBackupTrace();
+ mBackupManagerService.clearBackupTrace();
unregisterTask();
- if (!mCancelAll && mStatus == BackupTransport.TRANSPORT_OK &&
+ if (!mCancelled && mStatus == BackupTransport.TRANSPORT_OK &&
mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
// Acquiring wakelock for PerformFullTransportBackupTask before its start.
- backupManagerService.getWakelock().acquire();
+ mBackupManagerService.getWakelock().acquire();
// The full-backup task is now responsible for calling onFinish() on mListener, which
// was the listener we passed it.
(new Thread(mFullBackupTask, "full-transport-requested")).start();
- } else if (mCancelAll) {
+ } else if (mCancelled) {
mListener.onFinished(callerLogString);
if (mFullBackupTask != null) {
mFullBackupTask.unregisterTask();
}
- BackupObserverUtils.sendBackupFinished(mObserver,
- BackupManager.ERROR_BACKUP_CANCELLED);
+ BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.ERROR_BACKUP_CANCELLED);
} else {
mListener.onFinished(callerLogString);
mFullBackupTask.unregisterTask();
@@ -623,8 +760,7 @@
case BackupTransport.TRANSPORT_OK:
case BackupTransport.TRANSPORT_QUOTA_EXCEEDED:
case BackupTransport.TRANSPORT_PACKAGE_REJECTED:
- BackupObserverUtils.sendBackupFinished(mObserver,
- BackupManager.SUCCESS);
+ BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.SUCCESS);
break;
case BackupTransport.TRANSPORT_NOT_INITIALIZED:
BackupObserverUtils.sendBackupFinished(mObserver,
@@ -637,10 +773,9 @@
break;
}
}
- mFinished = true;
Slog.i(TAG, "K/V backup pass finished.");
// Only once we're entirely finished do we release the wakelock for k/v backup.
- backupManagerService.getWakelock().release();
+ mBackupManagerService.getWakelock().release();
}
// Remove the PM metadata state. This will generate an init on the next pass.
@@ -649,27 +784,34 @@
if (pmState.exists()) pmState.delete();
}
- // Invoke an agent's doBackup() and start a timeout message spinning on the main
- // handler in case it doesn't get back to us.
- private int invokeAgentForBackup(String packageName, IBackupAgent agent) {
+ /**
+ * Returns a {@link Pair}. The first of the pair contains the status. In case the status is
+ * {@link BackupTransport#TRANSPORT_OK}, the second of the pair contains the agent result,
+ * otherwise {@code null}.
+ */
+ private Pair<Integer, RemoteResult> invokeAgentForBackup(
+ String packageName, IBackupAgent agent) {
if (DEBUG) {
Slog.d(TAG, "invokeAgentForBackup on " + packageName);
}
- backupManagerService.addBackupTrace("invoking " + packageName);
+ mBackupManagerService.addBackupTrace("invoking " + packageName);
- File blankStateName = new File(mStateDir, BLANK_STATE_FILE_NAME);
- mSavedStateName = new File(mStateDir, packageName);
- mBackupDataName =
- new File(backupManagerService.getDataDir(), packageName + STAGING_FILE_SUFFIX);
- mNewStateName = new File(mStateDir, packageName + NEW_STATE_FILE_SUFFIX);
- if (MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
+ File blankStateFile = new File(mStateDir, BLANK_STATE_FILE_NAME);
+ mSavedStateFile = new File(mStateDir, packageName);
+ mBackupDataFile =
+ new File(mBackupManagerService.getDataDir(), packageName + STAGING_FILE_SUFFIX);
+ mNewStateFile = new File(mStateDir, packageName + NEW_STATE_FILE_SUFFIX);
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "data file: " + mBackupDataFile);
+ }
+
mSavedState = null;
mBackupData = null;
mNewState = null;
boolean callingAgent = false;
- mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+ final RemoteResult agentResult;
try {
// Look up the package info & signatures. This is first so that if it
// throws an exception, there's no file setup yet that would need to
@@ -681,24 +823,21 @@
mCurrentPackage.packageName = packageName;
}
- // In a full backup, we pass a null ParcelFileDescriptor as
- // the saved-state "file". For key/value backups we pass the old state if
- // an incremental backup is required, and a blank state otherwise.
mSavedState = ParcelFileDescriptor.open(
- mNonIncremental ? blankStateName : mSavedStateName,
+ (mNonIncremental) ? blankStateFile : mSavedStateFile,
ParcelFileDescriptor.MODE_READ_ONLY |
ParcelFileDescriptor.MODE_CREATE); // Make an empty file if necessary
- mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+ mBackupData = ParcelFileDescriptor.open(mBackupDataFile,
ParcelFileDescriptor.MODE_READ_WRITE |
ParcelFileDescriptor.MODE_CREATE |
ParcelFileDescriptor.MODE_TRUNCATE);
- if (!SELinux.restorecon(mBackupDataName)) {
- Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataName);
+ if (!SELinux.restorecon(mBackupDataFile)) {
+ Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataFile);
}
- mNewState = ParcelFileDescriptor.open(mNewStateName,
+ mNewState = ParcelFileDescriptor.open(mNewStateFile,
ParcelFileDescriptor.MODE_READ_WRITE |
ParcelFileDescriptor.MODE_CREATE |
ParcelFileDescriptor.MODE_TRUNCATE);
@@ -710,36 +849,36 @@
callingAgent = true;
// Initiate the target's backup pass
- backupManagerService.addBackupTrace("setting timeout");
long kvBackupAgentTimeoutMillis =
mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
- backupManagerService.prepareOperationTimeout(
- mEphemeralOpToken, kvBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
- backupManagerService.addBackupTrace("calling agent doBackup()");
+ mBackupManagerService.addBackupTrace("calling agent doBackup()");
- agent.doBackup(
- mSavedState, mBackupData, mNewState, quota, mEphemeralOpToken,
- backupManagerService.getBackupManagerBinder(), transport.getTransportFlags());
+ agentResult =
+ remoteCall(
+ callback ->
+ agent.doBackup(
+ mSavedState,
+ mBackupData,
+ mNewState,
+ quota,
+ callback,
+ transport.getTransportFlags()),
+ kvBackupAgentTimeoutMillis);
} catch (Exception e) {
Slog.e(TAG, "Error invoking for backup on " + packageName + ". " + e);
- backupManagerService.addBackupTrace("exception: " + e);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName,
- e.toString());
+ mBackupManagerService.addBackupTrace("exception: " + e);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName, e.toString());
errorCleanup();
- return callingAgent ? BackupTransport.AGENT_ERROR
- : BackupTransport.TRANSPORT_ERROR;
+ int status =
+ callingAgent ? BackupTransport.AGENT_ERROR : BackupTransport.TRANSPORT_ERROR;
+ return Pair.create(status, null);
} finally {
if (mNonIncremental) {
- blankStateName.delete();
+ blankStateFile.delete();
}
}
- // At this point the agent is off and running. The next thing to happen will
- // either be a callback from the agent, at which point we'll process its data
- // for transport, or a timeout. Either way the next phase will happen in
- // response to the TimeoutHandler interface callbacks.
- backupManagerService.addBackupTrace("invoke success");
- return BackupTransport.TRANSPORT_OK;
+ return Pair.create(BackupTransport.TRANSPORT_OK, agentResult);
}
private void failAgent(IBackupAgent agent, String message) {
@@ -829,327 +968,319 @@
}
}
- @Override
- @GuardedBy("mCancelLock")
- public void operationComplete(long unusedResult) {
- backupManagerService.removeOperation(mEphemeralOpToken);
- synchronized (mCancelLock) {
- // The agent reported back to us!
- if (mFinished) {
- Slog.d(TAG, "operationComplete received after task finished.");
- return;
- }
+ private BackupState handleAgentResult(long unusedResult) {
+ Preconditions.checkState(mBackupData != null);
- if (mBackupData == null) {
- // This callback was racing with our timeout, so we've cleaned up the
- // agent state already and are on to the next thing. We have nothing
- // further to do here: agent state having been cleared means that we've
- // initiated the appropriate next operation.
- final String pkg = (mCurrentPackage != null)
- ? mCurrentPackage.packageName : "[none]";
- if (MORE_DEBUG) {
- Slog.i(TAG, "Callback after agent teardown: " + pkg);
- }
- backupManagerService.addBackupTrace("late opComplete; curPkg = " + pkg);
- return;
- }
-
- final String pkgName = mCurrentPackage.packageName;
- final long filepos = mBackupDataName.length();
- FileDescriptor fd = mBackupData.getFileDescriptor();
- try {
- // If it's a 3rd party app, see whether they wrote any protected keys
- // and complain mightily if they are attempting shenanigans.
- if (mCurrentPackage.applicationInfo != null &&
- (mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
- == 0) {
- ParcelFileDescriptor readFd = ParcelFileDescriptor.open(mBackupDataName,
- ParcelFileDescriptor.MODE_READ_ONLY);
- BackupDataInput in = new BackupDataInput(readFd.getFileDescriptor());
- try {
- while (in.readNextHeader()) {
- final String key = in.getKey();
- if (key != null && key.charAt(0) >= 0xff00) {
- // Not okay: crash them and bail.
- failAgent(mAgentBinder, "Illegal backup key: " + key);
- backupManagerService
- .addBackupTrace("illegal key " + key + " from " + pkgName);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
- "bad key");
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
- mCurrentPackage,
- BackupManagerMonitor
- .LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
- BackupManagerMonitorUtils.putMonitoringExtra(null,
- BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY,
- key));
- backupManagerService.getBackupHandler().removeMessages(
- MSG_BACKUP_OPERATION_TIMEOUT);
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_AGENT_FAILURE);
- errorCleanup();
- if (MORE_DEBUG) {
- Slog.i(TAG, "Agent failure for " + pkgName
- + " with illegal key: " + key + "; dropped");
- }
- executeNextState(mQueue.isEmpty() ? BackupState.FINAL
- : BackupState.RUNNING_QUEUE);
- return;
+ final String pkgName = mCurrentPackage.packageName;
+ final long filepos = mBackupDataFile.length();
+ FileDescriptor fd = mBackupData.getFileDescriptor();
+ try {
+ // If it's a 3rd party app, see whether they wrote any protected keys
+ // and complain mightily if they are attempting shenanigans.
+ if (mCurrentPackage.applicationInfo != null &&
+ (mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ == 0) {
+ ParcelFileDescriptor readFd = ParcelFileDescriptor.open(mBackupDataFile,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ BackupDataInput in = new BackupDataInput(readFd.getFileDescriptor());
+ try {
+ while (in.readNextHeader()) {
+ final String key = in.getKey();
+ if (key != null && key.charAt(0) >= 0xff00) {
+ // Not okay: crash them and bail.
+ failAgent(mAgentBinder, "Illegal backup key: " + key);
+ mBackupManagerService
+ .addBackupTrace("illegal key " + key + " from " + pkgName);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
+ "bad key");
+ mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
+ mCurrentPackage,
+ BackupManagerMonitor
+ .LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+ BackupManagerMonitorUtils.putMonitoringExtra(null,
+ BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY,
+ key));
+ BackupObserverUtils
+ .sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_AGENT_FAILURE);
+ errorCleanup();
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Agent failure for " + pkgName
+ + " with illegal key: " + key + "; dropped");
}
- in.skipEntityData();
+
+ return BackupState.RUNNING_QUEUE;
}
- } finally {
- if (readFd != null) {
- readFd.close();
- }
+ in.skipEntityData();
+ }
+ } finally {
+ if (readFd != null) {
+ readFd.close();
}
}
-
- // Piggyback the widget state payload, if any
- writeWidgetPayloadIfAppropriate(fd, pkgName);
- } catch (IOException e) {
- // Hard disk error; recovery/failure policy TBD. For now roll back,
- // but we may want to consider this a transport-level failure (i.e.
- // we're in such a bad state that we can't contemplate doing backup
- // operations any more during this pass).
- Slog.w(TAG, "Unable to save widget state for " + pkgName);
- try {
- Os.ftruncate(fd, filepos);
- } catch (ErrnoException ee) {
- Slog.w(TAG, "Unable to roll back!");
- }
}
- // Spin the data off to the transport and proceed with the next stage.
- if (MORE_DEBUG) {
- Slog.v(TAG, "operationComplete(): sending data to transport for "
- + pkgName);
- }
- backupManagerService.getBackupHandler().removeMessages(MSG_BACKUP_OPERATION_TIMEOUT);
- clearAgentState();
- backupManagerService.addBackupTrace("operation complete");
-
- IBackupTransport transport = mTransportClient.connect("PBT.operationComplete()");
- ParcelFileDescriptor backupData = null;
- mStatus = BackupTransport.TRANSPORT_OK;
- long size = 0;
+ // Piggyback the widget state payload, if any
+ writeWidgetPayloadIfAppropriate(fd, pkgName);
+ } catch (IOException e) {
+ // Hard disk error; recovery/failure policy TBD. For now roll back,
+ // but we may want to consider this a transport-level failure (i.e.
+ // we're in such a bad state that we can't contemplate doing backup
+ // operations any more during this pass).
+ Slog.w(TAG, "Unable read backup data or to save widget state for " + pkgName);
try {
- TransportUtils.checkTransportNotNull(transport);
- size = mBackupDataName.length();
- if (size > 0) {
- boolean isNonIncremental = mSavedStateName.length() == 0;
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- backupData = ParcelFileDescriptor.open(mBackupDataName,
- ParcelFileDescriptor.MODE_READ_ONLY);
- backupManagerService.addBackupTrace("sending data to transport");
+ Os.ftruncate(fd, filepos);
+ } catch (ErrnoException ee) {
+ Slog.w(TAG, "Unable to roll back!");
+ }
+ }
- int userInitiatedFlag =
- mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
- int incrementalFlag =
- isNonIncremental
+ clearAgentState();
+ mBackupManagerService.addBackupTrace("operation complete");
+
+ ParcelFileDescriptor backupData = null;
+ mStatus = BackupTransport.TRANSPORT_OK;
+ long size = 0;
+ try {
+ IBackupTransport transport = mTransportClient.connectOrThrow("PBT.handleAgentResult()");
+ size = mBackupDataFile.length();
+ if (size > 0) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Sending non-empty data to transport for " + pkgName);
+ }
+ boolean isNonIncremental = mSavedStateFile.length() == 0;
+ if (mStatus == BackupTransport.TRANSPORT_OK) {
+ backupData = ParcelFileDescriptor.open(mBackupDataFile,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ mBackupManagerService.addBackupTrace("sending data to transport");
+
+ int userInitiatedFlag =
+ mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
+ int incrementalFlag =
+ isNonIncremental
? BackupTransport.FLAG_NON_INCREMENTAL
: BackupTransport.FLAG_INCREMENTAL;
- int flags = userInitiatedFlag | incrementalFlag;
+ int flags = userInitiatedFlag | incrementalFlag;
- mStatus = transport.performBackup(mCurrentPackage, backupData, flags);
- }
+ mStatus = transport.performBackup(mCurrentPackage, backupData, flags);
+ }
- if (isNonIncremental
+ if (isNonIncremental
&& mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- // TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED is only valid if the backup was
- // incremental, as if the backup is non-incremental there is no state to
- // clear. This avoids us ending up in a retry loop if the transport always
- // returns this code.
- Slog.w(TAG,
- "Transport requested non-incremental but already the case, error");
- backupManagerService.addBackupTrace(
- "Transport requested non-incremental but already the case, error");
- mStatus = BackupTransport.TRANSPORT_ERROR;
- }
-
- // TODO - We call finishBackup() for each application backed up, because
- // we need to know now whether it succeeded or failed. Instead, we should
- // hold off on finishBackup() until the end, which implies holding off on
- // renaming *all* the output state files (see below) until that happens.
-
- backupManagerService.addBackupTrace("data delivered: " + mStatus);
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- backupManagerService.addBackupTrace("finishing op on transport");
- mStatus = transport.finishBackup();
- backupManagerService.addBackupTrace("finished: " + mStatus);
- } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- backupManagerService.addBackupTrace("transport rejected package");
- }
- } else {
- if (MORE_DEBUG) {
- Slog.i(TAG, "no backup data written; not calling transport");
- }
- backupManagerService.addBackupTrace("no data to send");
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
- null);
+ // TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED is only valid if the backup was
+ // incremental, as if the backup is non-incremental there is no state to
+ // clear. This avoids us ending up in a retry loop if the transport always
+ // returns this code.
+ Slog.w(TAG, "Transport requested non-incremental but already the case, error");
+ mBackupManagerService.addBackupTrace(
+ "Transport requested non-incremental but already the case, error");
+ mStatus = BackupTransport.TRANSPORT_ERROR;
}
+ mBackupManagerService.addBackupTrace("data delivered: " + mStatus);
if (mStatus == BackupTransport.TRANSPORT_OK) {
- // After successful transport, delete the now-stale data
- // and juggle the files so that next time we supply the agent
- // with the new state file it just created.
- mBackupDataName.delete();
- mNewStateName.renameTo(mSavedStateName);
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, pkgName, BackupManager.SUCCESS);
- EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
- backupManagerService.logBackupComplete(pkgName);
+ mBackupManagerService.addBackupTrace("finishing op on transport");
+ mStatus = transport.finishBackup();
+ mBackupManagerService.addBackupTrace("finished: " + mStatus);
} else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- // The transport has rejected backup of this specific package. Roll it
- // back but proceed with running the rest of the queue.
- mBackupDataName.delete();
- mNewStateName.delete();
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
- EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
- } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
- EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
-
- } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- Slog.i(TAG, "Transport lost data, retrying package");
- backupManagerService.addBackupTrace(
- "Transport lost data, retrying package:" + pkgName);
- BackupManagerMonitorUtils.monitorEvent(
- mMonitor,
- BackupManagerMonitor
- .LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
- /*extras=*/ null);
-
- mBackupDataName.delete();
- mSavedStateName.delete();
- mNewStateName.delete();
-
- // Immediately retry the package by adding it back to the front of the queue.
- // We cannot add @pm@ to the queue because we back it up separately at the start
- // of the backup pass in state BACKUP_PM. Instead we retry this state (see
- // below).
- if (!PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
- mQueue.add(0, new BackupRequest(pkgName));
- }
-
- } else {
- // Actual transport-level failure to communicate the data to the backend
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ mBackupManagerService.addBackupTrace("transport rejected package");
}
- } catch (Exception e) {
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- Slog.e(TAG, "Transport error backing up " + pkgName, e);
- EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
- mStatus = BackupTransport.TRANSPORT_ERROR;
- } finally {
- try {
- if (backupData != null) backupData.close();
- } catch (IOException e) {
+ } else {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "No backup data written; not calling transport");
}
+ mBackupManagerService.addBackupTrace("no data to send");
+ mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+ null);
}
- final BackupState nextState;
- if (mStatus == BackupTransport.TRANSPORT_OK
- || mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- // Success or single-package rejection. Proceed with the next app if any,
- // otherwise we're done.
- nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+ if (mStatus == BackupTransport.TRANSPORT_OK) {
+ // After successful transport, delete the now-stale data
+ // and juggle the files so that next time we supply the agent
+ // with the new state file it just created.
+ mBackupDataFile.delete();
+ mNewStateFile.renameTo(mSavedStateFile);
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, pkgName, BackupManager.SUCCESS);
+ EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
+ mBackupManagerService.logBackupComplete(pkgName);
+ } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+ // The transport has rejected backup of this specific package. Roll it
+ // back but proceed with running the rest of the queue.
+ mBackupDataFile.delete();
+ mNewStateFile.delete();
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+ EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
+ } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+ EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
} else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- // We want to immediately retry the current package.
- if (PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
- nextState = BackupState.BACKUP_PM;
- } else {
- // This is an ordinary package so we will have added it back into the queue
- // above. Thus, we proceed processing the queue.
- nextState = BackupState.RUNNING_QUEUE;
+ Slog.i(TAG, "Transport lost data, retrying package");
+ mBackupManagerService.addBackupTrace(
+ "Transport lost data, retrying package:" + pkgName);
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+ /*extras=*/ null);
+
+ mBackupDataFile.delete();
+ mSavedStateFile.delete();
+ mNewStateFile.delete();
+
+ // Immediately retry the package by adding it back to the front of the queue.
+ // We cannot add @pm@ to the queue because we back it up separately at the start
+ // of the backup pass in state BACKUP_PM. Instead we retry this state (see
+ // below).
+ if (!PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
+ mQueue.add(0, new BackupRequest(pkgName));
}
- } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
- if (MORE_DEBUG) {
- Slog.d(TAG, "Package " + mCurrentPackage.packageName +
- " hit quota limit on k/v backup");
- }
- if (mAgentBinder != null) {
- try {
- TransportUtils.checkTransportNotNull(transport);
- long quota = transport.getBackupQuota(mCurrentPackage.packageName, false);
- mAgentBinder.doQuotaExceeded(size, quota);
- } catch (Exception e) {
- Slog.e(TAG, "Unable to notify about quota exceeded: " + e.getMessage());
- }
- }
- nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
} else {
- // Any other error here indicates a transport-level failure. That means
- // we need to halt everything and reschedule everything for next time.
- revertAndEndBackup();
- nextState = BackupState.FINAL;
+ // Actual transport-level failure to communicate the data to the backend
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_ABORTED);
+ EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ }
+ } catch (Exception e) {
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_ABORTED);
+ Slog.e(TAG, "Transport error backing up " + pkgName, e);
+ EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ mStatus = BackupTransport.TRANSPORT_ERROR;
+ } finally {
+ try {
+ if (backupData != null) {
+ backupData.close();
+ }
+ } catch (IOException e) {
+ Slog.w(TAG, "Error closing backup data fd");
+ }
+ }
+
+ final BackupState nextState;
+ if (mStatus == BackupTransport.TRANSPORT_OK
+ || mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+ // Success or single-package rejection. Proceed with the next app if any,
+ // otherwise we're done.
+ nextState = BackupState.RUNNING_QUEUE;
+
+ } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
+ // We want to immediately retry the current package.
+ if (PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
+ nextState = BackupState.BACKUP_PM;
+ } else {
+ // This is an ordinary package so we will have added it back into the queue
+ // above. Thus, we proceed processing the queue.
+ nextState = BackupState.RUNNING_QUEUE;
}
- executeNextState(nextState);
+ } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + mCurrentPackage.packageName +
+ " hit quota limit on k/v backup");
+ }
+ if (mAgentBinder != null) {
+ try {
+ IBackupTransport transport =
+ mTransportClient.connectOrThrow("PBT.handleAgentResult()");
+ long quota = transport.getBackupQuota(mCurrentPackage.packageName, false);
+ mAgentBinder.doQuotaExceeded(size, quota);
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to notify about quota exceeded: " + e.getMessage());
+ }
+ }
+ nextState = BackupState.RUNNING_QUEUE;
+ } else {
+ // Any other error here indicates a transport-level failure. That means
+ // we need to halt everything and reschedule everything for next time.
+ revertAndEndBackup();
+ nextState = BackupState.FINAL;
}
+
+ return nextState;
}
-
+ /**
+ * Cancels this task. After this method returns there will be no more calls to the transport.
+ *
+ * <p>If this method is executed while an agent is performing a backup, we will stop waiting for
+ * it, disregard its backup data and finalize the task. However, if this method is executed in
+ * between agent calls, the backup data of the last called agent will be sent to
+ * the transport and we will not consider the next agent (nor the rest of the queue), proceeding
+ * to finalize the backup.
+ *
+ * @param cancelAll MUST be {@code true}. Will be removed.
+ */
@Override
- @GuardedBy("mCancelLock")
public void handleCancel(boolean cancelAll) {
- backupManagerService.removeOperation(mEphemeralOpToken);
- synchronized (mCancelLock) {
- if (mFinished) {
- // We have already cancelled this operation.
- if (MORE_DEBUG) {
- Slog.d(TAG, "Ignoring stale cancel. cancelAll=" + cancelAll);
- }
- return;
- }
- mCancelAll = cancelAll;
- final String logPackageName = (mCurrentPackage != null)
- ? mCurrentPackage.packageName
- : "no_package_yet";
- Slog.i(TAG, "Cancel backing up " + logPackageName);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, logPackageName);
- backupManagerService.addBackupTrace(
- "cancel of " + logPackageName + ", cancelAll=" + cancelAll);
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
- mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
- BackupManagerMonitorUtils.putMonitoringExtra(null,
- BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL,
- mCancelAll));
- errorCleanup();
- if (!cancelAll) {
- // The current agent either timed out or was cancelled running doBackup().
- // Restage it for the next time we run a backup pass.
- // !!! TODO: keep track of failure counts per agent, and blacklist those which
- // fail repeatedly (i.e. have proved themselves to be buggy).
- executeNextState(
- mQueue.isEmpty() ? BackupState.FINAL : BackupState.RUNNING_QUEUE);
- backupManagerService.dataChangedImpl(mCurrentPackage.packageName);
- } else {
- finalizeBackup();
- }
+ Preconditions.checkArgument(cancelAll, "Can't partially cancel a key-value backup task");
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Cancel received");
}
+ mCancelled = true;
+ RemoteCall pendingCall = mPendingCall;
+ if (pendingCall != null) {
+ pendingCall.cancel();
+ }
+ mCancelAcknowledged.block();
+ }
+
+ private void handleAgentTimeout() {
+ String packageName = getPackageNameForLog();
+ Slog.i(TAG, "Agent " + packageName + " timed out");
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+ mBackupManagerService.addBackupTrace("timeout of " + packageName);
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+ BackupManagerMonitorUtils.putMonitoringExtra(
+ null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, false));
+ errorCleanup();
+ }
+
+ private void handleAgentCancelled() {
+ String packageName = getPackageNameForLog();
+ Slog.i(TAG, "Cancel backing up " + packageName);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+ mBackupManagerService.addBackupTrace("cancel of " + packageName);
+ errorCleanup();
+ }
+
+ private void finalizeCancelledBackup() {
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+ BackupManagerMonitorUtils.putMonitoringExtra(
+ null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, true));
+ finalizeBackup();
+ // finalizeBackup() may call the transport, so we only acknowledge the cancellation here.
+ mCancelAcknowledged.open();
+ }
+
+ private String getPackageNameForLog() {
+ return (mCurrentPackage != null) ? mCurrentPackage.packageName : "no_package_yet";
}
private void revertAndEndBackup() {
if (MORE_DEBUG) {
Slog.i(TAG, "Reverting backup queue - restaging everything");
}
- backupManagerService.addBackupTrace("transport error; reverting");
+ mBackupManagerService.addBackupTrace("transport error; reverting");
// We want to reset the backup schedule based on whatever the transport suggests
// by way of retry/backoff time.
@@ -1162,59 +1293,65 @@
Slog.w(TAG, "Unable to contact transport for recommended backoff: " + e.getMessage());
delay = 0; // use the scheduler's default
}
- KeyValueBackupJob.schedule(backupManagerService.getContext(), delay,
- backupManagerService.getConstants());
+ KeyValueBackupJob.schedule(mBackupManagerService.getContext(), delay,
+ mBackupManagerService.getConstants());
for (BackupRequest request : mOriginalQueue) {
- backupManagerService.dataChangedImpl(request.packageName);
+ mBackupManagerService.dataChangedImpl(request.packageName);
}
-
}
private void errorCleanup() {
- mBackupDataName.delete();
- mNewStateName.delete();
+ mBackupDataFile.delete();
+ mNewStateFile.delete();
clearAgentState();
}
// Cleanup common to both success and failure cases
private void clearAgentState() {
try {
- if (mSavedState != null) mSavedState.close();
+ if (mSavedState != null) {
+ mSavedState.close();
+ }
} catch (IOException e) {
+ Slog.w(TAG, "Error closing old state fd");
}
try {
- if (mBackupData != null) mBackupData.close();
+ if (mBackupData != null) {
+ mBackupData.close();
+ }
} catch (IOException e) {
+ Slog.w(TAG, "Error closing backup data fd");
}
try {
- if (mNewState != null) mNewState.close();
+ if (mNewState != null) {
+ mNewState.close();
+ }
} catch (IOException e) {
+ Slog.w(TAG, "Error closing new state fd");
}
- synchronized (backupManagerService.getCurrentOpLock()) {
+ synchronized (mBackupManagerService.getCurrentOpLock()) {
// Current-operation callback handling requires the validity of these various
// bits of internal state as an invariant of the operation still being live.
// This means we make sure to clear all of the state in unison inside the lock.
- backupManagerService.getCurrentOperations().remove(mEphemeralOpToken);
mSavedState = mBackupData = mNewState = null;
}
- // If this was a pseudopackage there's no associated Activity Manager state
+ // If this was a pseudo-package there's no associated Activity Manager state
if (mCurrentPackage.applicationInfo != null) {
- backupManagerService.addBackupTrace("unbinding " + mCurrentPackage.packageName);
- backupManagerService.unbindAgent(mCurrentPackage.applicationInfo);
+ mBackupManagerService.addBackupTrace("unbinding " + mCurrentPackage.packageName);
+ mBackupManagerService.unbindAgent(mCurrentPackage.applicationInfo);
}
}
- private void executeNextState(BackupState nextState) {
+ private RemoteResult remoteCall(RemoteCallable<IBackupCallback> remoteCallable, long timeoutMs)
+ throws RemoteException {
+ mPendingCall = new RemoteCall(mCancelled, remoteCallable, timeoutMs);
+ RemoteResult result = mPendingCall.call();
if (MORE_DEBUG) {
- Slog.i(TAG, " => executing next step on "
- + this + " nextState=" + nextState);
+ Slog.v(TAG, "Agent call returned " + result);
}
- backupManagerService.addBackupTrace("executeNextState => " + nextState);
- mCurrentState = nextState;
- Message msg = backupManagerService.getBackupHandler().obtainMessage(
- MSG_BACKUP_RESTORE_STEP, this);
- backupManagerService.getBackupHandler().sendMessage(msg);
+ mPendingCall = null;
+ return result;
}
}
diff --git a/services/backup/java/com/android/server/backup/remote/FutureBackupCallback.java b/services/backup/java/com/android/server/backup/remote/FutureBackupCallback.java
new file mode 100644
index 0000000..1445cc3
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/FutureBackupCallback.java
@@ -0,0 +1,39 @@
+/*
+ * 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.backup.remote;
+
+import android.app.backup.IBackupCallback;
+import android.os.RemoteException;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * An implementation of {@link IBackupCallback} that completes the {@link CompletableFuture}
+ * provided in the constructor with a successful {@link RemoteResult}.
+ */
+public class FutureBackupCallback extends IBackupCallback.Stub {
+ private final CompletableFuture<RemoteResult> mFuture;
+
+ FutureBackupCallback(CompletableFuture<RemoteResult> future) {
+ mFuture = future;
+ }
+
+ @Override
+ public void operationComplete(long result) throws RemoteException {
+ mFuture.complete(RemoteResult.successful(result));
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/remote/RemoteCall.java b/services/backup/java/com/android/server/backup/remote/RemoteCall.java
new file mode 100644
index 0000000..ac84811
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/RemoteCall.java
@@ -0,0 +1,134 @@
+/*
+ * 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.backup.remote;
+
+import android.annotation.WorkerThread;
+import android.app.backup.IBackupCallback;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * A wrapper that encapsulates an outbound call from the system process, converting an asynchronous
+ * operation into a synchronous operation with time-out and cancellation built-in. This was built to
+ * be able to call one-way binder methods that accept a {@link IBackupCallback} as a callback and
+ * handle the result inline.
+ *
+ * <p>Create one {@link RemoteCall} object providing the actual call in the form of a {@link
+ * RemoteCallable} that accepts a {@link IBackupCallback}. Perform the call by calling {@link
+ * #call()}, at which point {@link RemoteCall} will execute the callable providing an implementation
+ * of the callback that communicates the result back to this object. Even if the call returns
+ * straight away (which is the case for one-way methods) the method will only return when either the
+ * callback is called, time-out happens, or someone calls {@link #cancel()}.
+ *
+ * <p>This class was designed to have the method {@link #call()} called only once.
+ */
+// TODO: Kick-off callable in dedicated thread (because of local calls, which are synchronous)
+public class RemoteCall {
+ private final RemoteCallable<IBackupCallback> mCallable;
+ private final CompletableFuture<RemoteResult> mFuture;
+ private final long mTimeoutMs;
+
+ /**
+ * Creates a new {@link RemoteCall} object for a given callable.
+ *
+ * @param callable A function that signals its completion by calling {@link
+ * IBackupCallback#operationComplete(long)} on the object provided as a parameter.
+ * @param timeoutMs The time in milliseconds after which {@link #call()} will return with {@link
+ * RemoteResult#FAILED_TIMED_OUT} if the callable hasn't completed and no one canceled. The
+ * time starts to be counted in {@link #call()}.
+ */
+ public RemoteCall(RemoteCallable<IBackupCallback> callable, long timeoutMs) {
+ this(false, callable, timeoutMs);
+ }
+
+ /**
+ * Same as {@link #RemoteCall(RemoteCallable, long)} but with parameter {@code cancelled}.
+ *
+ * @param cancelled Whether the call has already been canceled. It has the same effect of
+ * calling {@link #cancel()} before {@link #call()}.
+ * @see #RemoteCall(RemoteCallable, long)
+ */
+ public RemoteCall(boolean cancelled, RemoteCallable<IBackupCallback> callable, long timeoutMs) {
+ mCallable = callable;
+ mTimeoutMs = timeoutMs;
+ mFuture = new CompletableFuture<>();
+ if (cancelled) {
+ cancel();
+ }
+ }
+
+ /**
+ * Kicks-off the callable provided in the constructor and blocks before returning, waiting for
+ * the first of these to happen:
+ *
+ * <ul>
+ * <li>The callback passed to {@link RemoteCallable} is called with the result. We return a
+ * successful {@link RemoteResult} with the result.
+ * <li>Time-out happens. We return {@link RemoteResult#FAILED_TIMED_OUT}.
+ * <li>Someone calls {@link #cancel()} on this object. We return {@link
+ * RemoteResult#FAILED_CANCELLED}.
+ * </ul>
+ *
+ * <p>This method can't be called from the main thread and was designed to be called only once.
+ *
+ * @return A {@link RemoteResult} with the result of the operation.
+ * @throws RemoteException If the callable throws it.
+ */
+ @WorkerThread
+ public RemoteResult call() throws RemoteException {
+ // If called on the main-thread we would never get a time-out != 0
+ Preconditions.checkState(
+ !Looper.getMainLooper().isCurrentThread(), "Can't call call() on main thread");
+
+ if (!mFuture.isDone()) {
+ if (mTimeoutMs == 0L) {
+ timeOut();
+ } else {
+ Handler.getMain().postDelayed(this::timeOut, mTimeoutMs);
+ mCallable.call(new FutureBackupCallback(mFuture));
+ }
+ }
+ try {
+ return mFuture.get();
+ } catch (InterruptedException e) {
+ return RemoteResult.FAILED_THREAD_INTERRUPTED;
+ } catch (ExecutionException e) {
+ throw new IllegalStateException("Future unexpectedly completed with an exception");
+ }
+ }
+
+ /**
+ * Attempts to cancel the operation. It will only be successful if executed before the callback
+ * is called and before the time-out.
+ *
+ * <p>This method can be called from any thread, any time, including the same thread that called
+ * {@link #call()} (which is obviously only possible if the former is called before the latter).
+ */
+ public void cancel() {
+ mFuture.complete(RemoteResult.FAILED_CANCELLED);
+ }
+
+ private void timeOut() {
+ mFuture.complete(RemoteResult.FAILED_TIMED_OUT);
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/remote/RemoteCallable.java b/services/backup/java/com/android/server/backup/remote/RemoteCallable.java
new file mode 100644
index 0000000..d2671ff
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/RemoteCallable.java
@@ -0,0 +1,28 @@
+/*
+ * 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.backup.remote;
+
+import android.os.RemoteException;
+
+/**
+ * Implementations should perform a remote call in {@link #call(Object)}, possibly throwing {@link
+ * RemoteException}.
+ */
+@FunctionalInterface
+public interface RemoteCallable<T> {
+ void call(T input) throws RemoteException;
+}
diff --git a/services/backup/java/com/android/server/backup/remote/RemoteResult.java b/services/backup/java/com/android/server/backup/remote/RemoteResult.java
new file mode 100644
index 0000000..7f4f469
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/RemoteResult.java
@@ -0,0 +1,116 @@
+/*
+ * 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.backup.remote;
+
+import android.annotation.IntDef;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Represents the result of a {@link RemoteCall}. It can be either {@link #FAILED_TIMED_OUT}, {@link
+ * #FAILED_CANCELLED}, {@link #FAILED_THREAD_INTERRUPTED} or a successful result, in which case
+ * {@link #get()} returns its value.
+ *
+ * <p>Use {@link #succeeded()} to check for successful result, or direct identity comparison to
+ * check for specific failures, like {@code result == RemoteResult.FAILED_CANCELLED}.
+ */
+public class RemoteResult {
+ public static final RemoteResult FAILED_TIMED_OUT = new RemoteResult(Type.FAILED_TIMED_OUT, 0);
+ public static final RemoteResult FAILED_CANCELLED = new RemoteResult(Type.FAILED_CANCELLED, 0);
+ public static final RemoteResult FAILED_THREAD_INTERRUPTED =
+ new RemoteResult(Type.FAILED_THREAD_INTERRUPTED, 0);
+
+ public static RemoteResult successful(long value) {
+ return new RemoteResult(Type.SUCCESS, value);
+ }
+
+ @Type private final int mType;
+ private final long mValue;
+
+ private RemoteResult(@Type int type, long value) {
+ mType = type;
+ mValue = value;
+ }
+
+ public boolean succeeded() {
+ return mType == Type.SUCCESS;
+ }
+
+ /**
+ * Returns the value of this result.
+ *
+ * @throws IllegalStateException in case this is not a successful result.
+ */
+ public long get() {
+ Preconditions.checkState(succeeded(), "Can't obtain value of failed result");
+ return mValue;
+ }
+
+ @Override
+ public String toString() {
+ return "RemoteResult{" + toStringDescription() + "}";
+ }
+
+ private String toStringDescription() {
+ switch (mType) {
+ case Type.SUCCESS:
+ return Long.toString(mValue);
+ case Type.FAILED_TIMED_OUT:
+ return "FAILED_TIMED_OUT";
+ case Type.FAILED_CANCELLED:
+ return "FAILED_CANCELLED";
+ case Type.FAILED_THREAD_INTERRUPTED:
+ return "FAILED_THREAD_INTERRUPTED";
+ }
+ throw new AssertionError("Unknown type");
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof RemoteResult)) {
+ return false;
+ }
+ RemoteResult that = (RemoteResult) o;
+ return mType == that.mType && mValue == that.mValue;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mType, mValue);
+ }
+
+ @IntDef({
+ Type.SUCCESS,
+ Type.FAILED_TIMED_OUT,
+ Type.FAILED_CANCELLED,
+ Type.FAILED_THREAD_INTERRUPTED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface Type {
+ int SUCCESS = 0;
+ int FAILED_TIMED_OUT = 1;
+ int FAILED_CANCELLED = 2;
+ int FAILED_THREAD_INTERRUPTED = 3;
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/remote/ServiceBackupCallback.java b/services/backup/java/com/android/server/backup/remote/ServiceBackupCallback.java
new file mode 100644
index 0000000..28d85a6
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/ServiceBackupCallback.java
@@ -0,0 +1,43 @@
+/*
+ * 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.backup.remote;
+
+import android.app.backup.IBackupCallback;
+import android.app.backup.IBackupManager;
+import android.os.RemoteException;
+
+import com.android.server.backup.BackupManagerService;
+
+/**
+ * An implementation of {@link IBackupCallback} that routes the result to {@link
+ * BackupManagerService} via {@link IBackupManager#opComplete(int, long)} passing the token provided
+ * in the constructor.
+ */
+public class ServiceBackupCallback extends IBackupCallback.Stub {
+ private final IBackupManager mBackupManager;
+ private final int mToken;
+
+ public ServiceBackupCallback(IBackupManager backupManager, int token) {
+ mBackupManager = backupManager;
+ mToken = token;
+ }
+
+ @Override
+ public void operationComplete(long result) throws RemoteException {
+ mBackupManager.opComplete(mToken, result);
+ }
+}
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index c63b8f4..9a7c345 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -34,7 +34,6 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.BinderInternal;
-import com.android.server.LocalServices;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -131,6 +130,7 @@
public static class LifeCycle extends SystemService {
private BinderCallsStatsService mService;
+ private BinderCallsStats mBinderCallsStats;
public LifeCycle(Context context) {
super(context);
@@ -138,9 +138,9 @@
@Override
public void onStart() {
- BinderCallsStats binderCallsStats = new BinderCallsStats(new Random());
- mService = new BinderCallsStatsService(binderCallsStats);
- LocalServices.addService(Internal.class, new Internal(binderCallsStats));
+ mBinderCallsStats = new BinderCallsStats(new BinderCallsStats.Injector());
+ mService = new BinderCallsStatsService(mBinderCallsStats);
+ publishLocalService(Internal.class, new Internal(mBinderCallsStats));
publishBinderService("binder_calls_stats", mService);
boolean detailedTrackingEnabled = SystemProperties.getBoolean(
PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, false);
@@ -149,7 +149,7 @@
Slog.i(TAG, "Enabled CPU usage tracking for binder calls. Controlled by "
+ PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING
+ " or via dumpsys binder_calls_stats --enable-detailed-tracking");
- binderCallsStats.setDetailedTracking(true);
+ mBinderCallsStats.setDetailedTracking(true);
}
}
@@ -157,6 +157,7 @@
public void onBootPhase(int phase) {
if (SystemService.PHASE_SYSTEM_SERVICES_READY == phase) {
mService.systemReady(getContext());
+ mBinderCallsStats.systemReady(getContext());
}
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2054e0a..6b3f8f8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -500,6 +500,9 @@
private final IpConnectivityLog mMetricsLog;
+ @GuardedBy("mBandwidthRequests")
+ private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10);
+
@VisibleForTesting
final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
@@ -2107,6 +2110,18 @@
pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
}
mWakelockLogs.reverseDump(fd, pw, args);
+
+ pw.println();
+ pw.println("bandwidth update requests (by uid):");
+ pw.increaseIndent();
+ synchronized (mBandwidthRequests) {
+ for (int i = 0; i < mBandwidthRequests.size(); i++) {
+ pw.println("[" + mBandwidthRequests.keyAt(i)
+ + "]: " + mBandwidthRequests.valueAt(i));
+ }
+ }
+ pw.decreaseIndent();
+
pw.decreaseIndent();
}
}
@@ -4267,6 +4282,14 @@
}
if (nai != null) {
nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE);
+ synchronized (mBandwidthRequests) {
+ final int uid = Binder.getCallingUid();
+ Integer uidReqs = mBandwidthRequests.get(uid);
+ if (uidReqs == null) {
+ uidReqs = new Integer(0);
+ }
+ mBandwidthRequests.put(uid, ++uidReqs);
+ }
return true;
}
return false;
@@ -5863,4 +5886,4 @@
pw.println(" Get airplane mode.");
}
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 9631e46..abcd6ef 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1495,10 +1495,9 @@
}
try {
- mConnector.execute("idletimer", "add", iface, Integer.toString(timeout),
- Integer.toString(type));
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
@@ -1529,10 +1528,10 @@
}
try {
- mConnector.execute("idletimer", "remove", iface,
- Integer.toString(params.timeout), Integer.toString(params.type));
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.idletimerRemoveInterface(iface,
+ params.timeout, Integer.toString(params.type));
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
mActiveIdleTimers.remove(iface);
mDaemonHandler.post(new Runnable() {
diff --git a/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java
index 02cc6d5..10a1b90 100644
--- a/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java
@@ -114,7 +114,7 @@
if (mBundle != null) {
try {
if (acquiredInfo != BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
- mStatusBarService.onFingerprintHelp(
+ mStatusBarService.onBiometricHelp(
mFingerprintManager.getAcquiredString(acquiredInfo, vendorCode));
}
return false; // acquisition continues
@@ -143,7 +143,7 @@
}
if (mBundle != null) {
try {
- mStatusBarService.onFingerprintError(
+ mStatusBarService.onBiometricError(
mFingerprintManager.getErrorString(error, vendorCode));
} catch (RemoteException e) {
Slog.e(getLogTag(), "Remote exception when sending error", e);
@@ -162,9 +162,9 @@
if (mBundle != null) {
try {
if (authenticated) {
- mStatusBarService.onFingerprintAuthenticated();
+ mStatusBarService.onBiometricAuthenticated();
} else {
- mStatusBarService.onFingerprintHelp(getContext().getResources().getString(
+ mStatusBarService.onBiometricHelp(getContext().getResources().getString(
com.android.internal.R.string.fingerprint_not_recognized));
}
} catch (RemoteException e) {
@@ -224,7 +224,7 @@
// Send the lockout message to the system dialog
if (mBundle != null) {
- mStatusBarService.onFingerprintError(
+ mStatusBarService.onBiometricError(
mFingerprintManager.getErrorString(errorCode, 0 /* vendorCode */));
}
} catch (RemoteException e) {
@@ -263,7 +263,7 @@
// If authenticating with system dialog, show the dialog
if (mBundle != null) {
try {
- mStatusBarService.showFingerprintDialog(mBundle, mDialogReceiver);
+ mStatusBarService.showBiometricDialog(mBundle, mDialogReceiver);
} catch (RemoteException e) {
Slog.e(getLogTag(), "Unable to show fingerprint dialog", e);
}
@@ -301,7 +301,7 @@
// after BiometricPrompt.HIDE_DIALOG_DELAY
if (mBundle != null && !mDialogDismissed && !mInLockout) {
try {
- mStatusBarService.hideFingerprintDialog();
+ mStatusBarService.hideBiometricDialog();
} catch (RemoteException e) {
Slog.e(getLogTag(), "Unable to hide fingerprint dialog", e);
}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index dea9309..d154830 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -318,6 +318,17 @@
static final String PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT =
"persist.sys.hdmi.property_sytem_audio_device_arc_port";
+ /**
+ * Property to strip local audio of amplifier and use local speaker
+ * when TV does not support system audio mode.
+ *
+ * <p>This property applies to device with both audio system/playback types.
+ * <p>True means using local speaker when TV does not support system audio.
+ * <p>False means passing audio to TV. Default is true.
+ */
+ static final String PROPERTY_STRIP_AUDIO_TV_NO_SYSTEM_AUDIO =
+ "persist.sys.hdmi.property_strip_audio_tv_no_system_audio";
+
static final int RECORDING_TYPE_DIGITAL_RF = 1;
static final int RECORDING_TYPE_ANALOGUE_RF = 2;
static final int RECORDING_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 3;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index ca85249..14af15f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -327,18 +327,7 @@
!isPhysicalAddressMeOrBelow(targetPhysicalAddress)) {
switchToAudioInput();
}
- // Mute device when feature is turned off and unmute device when feature is turned on
- boolean currentMuteStatus =
- mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC);
- if (currentMuteStatus == newSystemAudioMode) {
- mService.getAudioManager()
- .adjustStreamVolume(
- AudioManager.STREAM_MUSIC,
- newSystemAudioMode
- ? AudioManager.ADJUST_UNMUTE
- : AudioManager.ADJUST_MUTE,
- 0);
- }
+ // TODO(b/80297700): Mute device when TV terminates the system audio control
updateAudioManagerForSystemAudio(newSystemAudioMode);
synchronized (mLock) {
if (mSystemAudioActivated != newSystemAudioMode) {
diff --git a/services/core/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java b/services/core/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java
index a3949a4..596a4c0 100644
--- a/services/core/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java
+++ b/services/core/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java
@@ -16,8 +16,6 @@
package com.android.server.job.controllers.idle;
-import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -35,20 +33,27 @@
private static final boolean DEBUG = JobSchedulerService.DEBUG
|| Log.isLoggable(TAG, Log.DEBUG);
- public static final String ACTION_FORCE_IDLE = "com.android.server.ACTION_FORCE_IDLE";
- public static final String ACTION_UNFORCE_IDLE = "com.android.server.ACTION_UNFORCE_IDLE";
+ public static final String ACTION_GARAGE_MODE_ON =
+ "com.android.server.jobscheduler.GARAGE_MODE_ON";
+ public static final String ACTION_GARAGE_MODE_OFF =
+ "com.android.server.jobscheduler.GARAGE_MODE_OFF";
+
+ public static final String ACTION_FORCE_IDLE = "com.android.server.jobscheduler.FORCE_IDLE";
+ public static final String ACTION_UNFORCE_IDLE = "com.android.server.jobscheduler.UNFORCE_IDLE";
// After construction, mutations of idle/screen-on state will only happen
// on the main looper thread, either in onReceive() or in an alarm callback.
private boolean mIdle;
- private boolean mScreenOn;
+ private boolean mGarageModeOn;
+ private boolean mForced;
private IdlenessListener mIdleListener;
public CarIdlenessTracker() {
// At boot we presume that the user has just "interacted" with the
// device in some meaningful way.
mIdle = false;
- mScreenOn = true;
+ mGarageModeOn = false;
+ mForced = false;
}
@Override
@@ -62,9 +67,9 @@
IntentFilter filter = new IntentFilter();
- // Screen state
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
+ // State of GarageMode
+ filter.addAction(ACTION_GARAGE_MODE_ON);
+ filter.addAction(ACTION_GARAGE_MODE_OFF);
// Debugging/instrumentation
filter.addAction(ACTION_FORCE_IDLE);
@@ -77,7 +82,7 @@
@Override
public void dump(PrintWriter pw) {
pw.print(" mIdle: "); pw.println(mIdle);
- pw.print(" mScreenOn: "); pw.println(mScreenOn);
+ pw.print(" mGarageModeOn: "); pw.println(mGarageModeOn);
}
@Override
@@ -88,47 +93,58 @@
// Check for forced actions
if (action.equals(ACTION_FORCE_IDLE)) {
logIfDebug("Forcing idle...");
- enterIdleState(true);
+ setForceIdleState(true);
} else if (action.equals(ACTION_UNFORCE_IDLE)) {
logIfDebug("Unforcing idle...");
- exitIdleState(true);
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- logIfDebug("Going idle...");
- mScreenOn = false;
- enterIdleState(false);
- } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
- logIfDebug("exiting idle...");
- mScreenOn = true;
- exitIdleState(true);
+ setForceIdleState(false);
+ } else if (action.equals(ACTION_GARAGE_MODE_ON)) {
+ logIfDebug("GarageMode is on...");
+ mGarageModeOn = true;
+ updateIdlenessState();
+ } else if (action.equals(ACTION_GARAGE_MODE_OFF)) {
+ logIfDebug("GarageMode is off...");
+ mGarageModeOn = false;
+ updateIdlenessState();
} else if (action.equals(ActivityManagerService.ACTION_TRIGGER_IDLE)) {
- if (!mScreenOn) {
+ if (!mGarageModeOn) {
logIfDebug("Idle trigger fired...");
- enterIdleState(false);
+ triggerIdlenessOnce();
} else {
logIfDebug("TRIGGER_IDLE received but not changing state; idle="
- + mIdle + " screen=" + mScreenOn);
+ + mIdle + " screen=" + mGarageModeOn);
}
}
}
- private void enterIdleState(boolean forced) {
- if (!forced && mIdle) {
- // Already idle and don't need to trigger callbacks since not forced
- logIfDebug("Device is already considered idle");
- return;
- }
- mIdle = true;
- mIdleListener.reportNewIdleState(mIdle);
+ private void setForceIdleState(boolean forced) {
+ mForced = forced;
+ updateIdlenessState();
}
- private void exitIdleState(boolean forced) {
- if (!forced && !mIdle) {
- // Already out of idle and don't need to trigger callbacks since not forced
- logIfDebug("Device is already considered not idle");
- return;
+ private void updateIdlenessState() {
+ final boolean newState = (mForced || mGarageModeOn);
+ if (mIdle != newState) {
+ // State of idleness changed. Notifying idleness controller
+ logIfDebug("Device idleness changed. New idle=" + newState);
+ mIdle = newState;
+ mIdleListener.reportNewIdleState(mIdle);
+ } else {
+ // Nothing changed, device idleness is in the same state as new state
+ logIfDebug("Device idleness is the same. Current idle=" + newState);
}
- mIdle = false;
- mIdleListener.reportNewIdleState(mIdle);
+ }
+
+ private void triggerIdlenessOnce() {
+ // This is simply triggering idleness once until some constraint will switch it back off
+ if (mIdle) {
+ // Already in idle state. Nothing to do
+ logIfDebug("Device is already idle");
+ } else {
+ // Going idle once
+ logIfDebug("Device is going idle once");
+ mIdle = true;
+ mIdleListener.reportNewIdleState(mIdle);
+ }
}
private void logIfDebug(String msg) {
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index 74930c8..4243f02 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -45,7 +45,7 @@
/*
* Local flag to enable debug logging.
*/
- private static final boolean DEBUG_LOG_ENABLED = true;
+ private static final boolean DEBUG_LOG_ENABLED = false;
/*
* The context of the service.
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index dc95d41..27509de 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -77,6 +77,11 @@
private static final int OS_APP_INSTANCE = -1;
+ /*
+ * Local flag to enable debug logging.
+ */
+ private static final boolean DEBUG_LOG_ENABLED = false;
+
private final Context mContext;
private final Map<Integer, ContextHubInfo> mContextHubIdToInfoMap;
@@ -779,12 +784,16 @@
int msgVersion = 0;
int callbacksCount = mCallbacksList.beginBroadcast();
- Log.d(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle " +
- contextHubHandle + ", appInstance " + appInstance + ", callBackCount "
- + callbacksCount);
+ if (DEBUG_LOG_ENABLED) {
+ Log.v(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle "
+ + contextHubHandle + ", appInstance " + appInstance + ", callBackCount "
+ + callbacksCount);
+ }
if (callbacksCount < 1) {
- Log.v(TAG, "No message callbacks registered.");
+ if (DEBUG_LOG_ENABLED) {
+ Log.v(TAG, "No message callbacks registered.");
+ }
return 0;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d0789b7..de53427 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4031,6 +4031,7 @@
+ " notification=" + notification);
}
checkCallerIsSystemOrSameApp(pkg);
+ checkRestrictedCategories(notification);
final int userId = ActivityManager.handleIncomingUser(callingPid,
callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
@@ -5272,6 +5273,7 @@
ArrayList<Integer> userSentimentBefore = new ArrayList<>(N);
ArrayList<Integer> suppressVisuallyBefore = new ArrayList<>(N);
ArrayList<ArrayList<Notification.Action>> smartActionsBefore = new ArrayList<>(N);
+ ArrayList<ArrayList<CharSequence>> smartRepliesBefore = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
final NotificationRecord r = mNotificationList.get(i);
orderBefore.add(r.getKey());
@@ -5284,6 +5286,7 @@
userSentimentBefore.add(r.getUserSentiment());
suppressVisuallyBefore.add(r.getSuppressedVisualEffects());
smartActionsBefore.add(r.getSmartActions());
+ smartRepliesBefore.add(r.getSmartReplies());
mRankingHelper.extractSignals(r);
}
mRankingHelper.sort(mNotificationList);
@@ -5299,7 +5302,8 @@
|| !Objects.equals(userSentimentBefore.get(i), r.getUserSentiment())
|| !Objects.equals(suppressVisuallyBefore.get(i),
r.getSuppressedVisualEffects())
- || !Objects.equals(smartActionsBefore.get(i), r.getSmartActions())) {
+ || !Objects.equals(smartActionsBefore.get(i), r.getSmartActions())
+ || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies())) {
mHandler.scheduleSendRankingUpdate();
return;
}
@@ -6197,6 +6201,26 @@
checkCallerIsSameApp(pkg);
}
+ /**
+ * Check if the notification is of a category type that is restricted to system use only,
+ * if so throw SecurityException
+ */
+ private void checkRestrictedCategories(final Notification notification) {
+ try {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0)) {
+ return;
+ }
+ } catch (RemoteException re) {
+ if (DBG) Log.e(TAG, "Unable to confirm if it's safe to skip category "
+ + "restrictions check thus the check will be done anyway");
+ }
+ if (Notification.CATEGORY_CAR_EMERGENCY.equals(notification.category)
+ || Notification.CATEGORY_CAR_WARNING.equals(notification.category)
+ || Notification.CATEGORY_CAR_INFORMATION.equals(notification.category)) {
+ checkCallerIsSystem();
+ }
+ }
+
private boolean isCallerInstantApp(String pkg) {
// System is always allowed to act for ephemeral apps.
if (isCallerSystemOrPhone()) {
@@ -6276,6 +6300,7 @@
Bundle userSentiment = new Bundle();
Bundle hidden = new Bundle();
Bundle smartActions = new Bundle();
+ Bundle smartReplies = new Bundle();
for (int i = 0; i < N; i++) {
NotificationRecord record = mNotificationList.get(i);
if (!isVisibleToListener(record.sbn, info)) {
@@ -6304,6 +6329,7 @@
userSentiment.putInt(key, record.getUserSentiment());
hidden.putBoolean(key, record.isHidden());
smartActions.putParcelableArrayList(key, record.getSmartActions());
+ smartReplies.putCharSequenceArrayList(key, record.getSmartReplies());
}
final int M = keys.size();
String[] keysAr = keys.toArray(new String[M]);
@@ -6315,7 +6341,7 @@
return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden,
- smartActions);
+ smartActions, smartReplies);
}
boolean hasCompanionDevice(ManagedServiceInfo info) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index f32b338..469828b 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -162,6 +162,7 @@
private String mGroupLogTag;
private String mChannelIdLogTag;
private ArrayList<Notification.Action> mSmartActions;
+ private ArrayList<CharSequence> mSmartReplies;
private final List<Adjustment> mAdjustments;
private final NotificationStats mStats;
@@ -637,6 +638,9 @@
if (signals.containsKey(Adjustment.KEY_SMART_ACTIONS)) {
setSmartActions(signals.getParcelableArrayList(Adjustment.KEY_SMART_ACTIONS));
}
+ if (signals.containsKey(Adjustment.KEY_SMART_REPLIES)) {
+ setSmartReplies(signals.getCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES));
+ }
}
}
}
@@ -1064,6 +1068,14 @@
return mSmartActions;
}
+ public void setSmartReplies(ArrayList<CharSequence> smartReplies) {
+ mSmartReplies = smartReplies;
+ }
+
+ public ArrayList<CharSequence> getSmartReplies() {
+ return mSmartReplies;
+ }
+
/**
* @return all {@link Uri} that should have permission granted to whoever
* will be rendering it. This list has already been vetted to only
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e46c03e..a8b92a6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -288,6 +288,8 @@
import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
import com.android.server.wm.AppTransition;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.DisplayPolicy;
+import com.android.server.wm.DisplayRotation;
import com.android.server.wm.WindowFrames;
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
@@ -500,8 +502,6 @@
WindowState mStatusBar = null;
private final int[] mStatusBarHeightForRotation = new int[4];
WindowState mNavigationBar = null;
- boolean mHasNavigationBar = false;
- boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side?
@NavigationBarPosition
int mNavigationBarPosition = NAV_BAR_BOTTOM;
int[] mNavigationBarHeightForRotationDefault = new int[4];
@@ -556,8 +556,6 @@
volatile boolean mRecentsVisible;
volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled = true;
volatile boolean mPictureInPictureVisible;
- // Written by vr manager thread, only read in this class.
- volatile private boolean mPersistentVrModeEnabled;
volatile private boolean mDismissImeOnBackKeyPressed;
// Used to hold the last user key used to wake the device. This helps us prevent up events
@@ -567,40 +565,18 @@
int mRecentAppsHeldModifiers;
boolean mLanguageSwitchKeyPressed;
- int mLidState = LID_ABSENT;
int mCameraLensCoverState = CAMERA_LENS_COVER_ABSENT;
boolean mHaveBuiltInKeyboard;
boolean mSystemReady;
boolean mSystemBooted;
- boolean mHdmiPlugged;
HdmiControl mHdmiControl;
IUiModeManager mUiModeManager;
int mUiMode;
- int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
- int mLidOpenRotation;
- int mCarDockRotation;
- int mDeskDockRotation;
- int mUndockedHdmiRotation;
- int mDemoHdmiRotation;
- boolean mDemoHdmiRotationLock;
- int mDemoRotation;
- boolean mDemoRotationLock;
boolean mWakeGestureEnabledSetting;
MyWakeGestureListener mWakeGestureListener;
- // Default display does not rotate, apps that require non-default orientation will have to
- // have the orientation emulated.
- private boolean mForceDefaultOrientation = false;
-
- int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
- int mUserRotation = Surface.ROTATION_0;
-
- boolean mSupportAutoRotation;
- int mAllowAllRotations = -1;
- boolean mCarDockEnablesAccelerometer;
- boolean mDeskDockEnablesAccelerometer;
int mLidKeyboardAccessibility;
int mLidNavigationAccessibility;
boolean mLidControlsScreenLock;
@@ -613,14 +589,6 @@
int mLongPressOnBackBehavior;
int mShortPressOnSleepBehavior;
int mShortPressOnWindowBehavior;
- volatile boolean mAwake;
- boolean mScreenOnEarly;
- boolean mScreenOnFully;
- ScreenOnListener mScreenOnListener;
- boolean mKeyguardDrawComplete;
- boolean mWindowManagerDrawComplete;
- boolean mOrientationSensorEnabled = false;
- int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
boolean mTranslucentDecorEnabled = true;
boolean mUseTvRouting;
@@ -729,18 +697,14 @@
// Behavior of Back button while in-call and screen on
int mIncallBackBehavior;
- // Behavior of rotation suggestions. (See Settings.Secure.SHOW_ROTATION_SUGGESTION)
- int mShowRotationSuggestions;
-
// Whether system navigation keys are enabled
boolean mSystemNavigationKeysEnabled;
- Display mDisplay;
-
- int mLandscapeRotation = 0; // default landscape rotation
- int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
- int mPortraitRotation = 0; // default portrait rotation
- int mUpsideDownRotation = 0; // "other" portrait rotation
+ // TODO(b/111361251): Remove default when the dependencies are multi-display ready.
+ Display mDefaultDisplay;
+ DisplayRotation mDefaultDisplayRotation;
+ DisplayPolicy mDefaultDisplayPolicy;
+ WindowOrientationListener mDefaultOrientationListener;
// What we do when the user long presses on home
private int mLongPressOnHomeBehavior;
@@ -963,7 +927,7 @@
private UEventObserver mHDMIObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
- setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
+ mDefaultDisplayPolicy.setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
}
};
@@ -988,12 +952,6 @@
Settings.Secure.WAKE_GESTURE_ENABLED), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.ACCELEROMETER_ROTATION), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.USER_ROTATION), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
@@ -1006,9 +964,6 @@
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.SHOW_ROTATION_SUGGESTIONS), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.VOLUME_HUSH_GESTURE), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
@@ -1043,53 +998,11 @@
}
}
- class MyOrientationListener extends WindowOrientationListener {
-
- private SparseArray<Runnable> mRunnableCache;
-
- MyOrientationListener(Context context, Handler handler) {
- super(context, handler);
- mRunnableCache = new SparseArray<>(5);
- }
-
- private class UpdateRunnable implements Runnable {
- private final int mRotation;
- UpdateRunnable(int rotation) {
- mRotation = rotation;
- }
-
- @Override
- public void run() {
- // send interaction hint to improve redraw performance
- mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
- if (isRotationChoicePossible(mCurrentAppOrientation)) {
- final boolean isValid = isValidRotationChoice(mCurrentAppOrientation,
- mRotation);
- sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
- } else {
- updateRotation(false);
- }
- }
- }
-
- @Override
- public void onProposedRotationChanged(int rotation) {
- if (localLOGV) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
- Runnable r = mRunnableCache.get(rotation, null);
- if (r == null){
- r = new UpdateRunnable(rotation);
- mRunnableCache.put(rotation, r);
- }
- mHandler.post(r);
- }
- }
- MyOrientationListener mOrientationListener;
-
final IPersistentVrStateCallbacks mPersistentVrModeListener =
new IPersistentVrStateCallbacks.Stub() {
@Override
public void onPersistentVrStateChanged(boolean enabled) {
- mPersistentVrModeEnabled = enabled;
+ mDefaultDisplayPolicy.setPersistentVrModeEnabled(enabled);
}
};
@@ -1171,100 +1084,6 @@
}
}
- /*
- * We always let the sensor be switched on by default except when
- * the user has explicitly disabled sensor based rotation or when the
- * screen is switched off.
- */
- boolean needSensorRunningLp() {
- if (mSupportAutoRotation) {
- if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
- // If the application has explicitly requested to follow the
- // orientation, then we need to turn the sensor on.
- return true;
- }
- }
- if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) ||
- (mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) {
- // enable accelerometer if we are docked in a dock that enables accelerometer
- // orientation management,
- return true;
- }
- if (mUserRotationMode == USER_ROTATION_LOCKED) {
- // If the setting for using the sensor by default is enabled, then
- // we will always leave it on. Note that the user could go to
- // a window that forces an orientation that does not use the
- // sensor and in theory we could turn it off... however, when next
- // turning it on we won't have a good value for the current
- // orientation for a little bit, which can cause orientation
- // changes to lag, so we'd like to keep it always on. (It will
- // still be turned off when the screen is off.)
-
- // When locked we can provide rotation suggestions users can approve to change the
- // current screen rotation. To do this the sensor needs to be running.
- return mSupportAutoRotation &&
- mShowRotationSuggestions == Settings.Secure.SHOW_ROTATION_SUGGESTIONS_ENABLED;
- }
- return mSupportAutoRotation;
- }
-
- /*
- * Various use cases for invoking this function
- * screen turning off, should always disable listeners if already enabled
- * screen turned on and current app has sensor based orientation, enable listeners
- * if not already enabled
- * screen turned on and current app does not have sensor orientation, disable listeners if
- * already enabled
- * screen turning on and current app has sensor based orientation, enable listeners if needed
- * screen turning on and current app has nosensor based orientation, do nothing
- */
- void updateOrientationListenerLp() {
- if (!mOrientationListener.canDetectOrientation()) {
- // If sensor is turned off or nonexistent for some reason
- return;
- }
- // Could have been invoked due to screen turning on or off or
- // change of the currently visible window's orientation.
- if (localLOGV) Slog.v(TAG, "mScreenOnEarly=" + mScreenOnEarly
- + ", mAwake=" + mAwake + ", mCurrentAppOrientation=" + mCurrentAppOrientation
- + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled
- + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
- + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
-
- boolean disable = true;
- // Note: We postpone the rotating of the screen until the keyguard as well as the
- // window manager have reported a draw complete or the keyguard is going away in dismiss
- // mode.
- if (mScreenOnEarly && mAwake && ((mKeyguardDrawComplete && mWindowManagerDrawComplete))) {
- if (needSensorRunningLp()) {
- disable = false;
- //enable listener if not already enabled
- if (!mOrientationSensorEnabled) {
- // Don't clear the current sensor orientation if the keyguard is going away in
- // dismiss mode. This allows window manager to use the last sensor reading to
- // determine the orientation vs. falling back to the last known orientation if
- // the sensor reading was cleared which can cause it to relaunch the app that
- // will show in the wrong orientation first before correcting leading to app
- // launch delays.
- mOrientationListener.enable(true /* clearCurrentRotation */);
- if(localLOGV) Slog.v(TAG, "Enabling listeners");
- mOrientationSensorEnabled = true;
- }
- }
- }
- //check if sensors need to be disabled
- if (disable && mOrientationSensorEnabled) {
- mOrientationListener.disable();
- if(localLOGV) Slog.v(TAG, "Disabling listeners");
- mOrientationSensorEnabled = false;
- }
- }
-
private void interceptBackKeyDown() {
MetricsLogger.count(mContext, "key_back_down", 1);
// Reset back key state for long press
@@ -1490,7 +1309,7 @@
}
private void powerPress(long eventTime, boolean interactive, int count) {
- if (mScreenOnEarly && !mScreenOnFully) {
+ if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
return;
@@ -1990,6 +1809,14 @@
return mContext.getResources().getConfiguration().isScreenRound();
}
+ @Override
+ public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
+ mDefaultDisplay = displayContentInfo.getDisplay();
+ mDefaultDisplayRotation = displayContentInfo.getDisplayRotation();
+ mDefaultDisplayPolicy = mDefaultDisplayRotation.getDisplayPolicy();
+ mDefaultOrientationListener = mDefaultDisplayRotation.getOrientationListener();
+ }
+
/** {@inheritDoc} */
@Override
public void init(Context context, IWindowManager windowManager,
@@ -2046,10 +1873,6 @@
mHandler = new PolicyHandler();
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
- mOrientationListener = new MyOrientationListener(mContext, mHandler);
- try {
- mOrientationListener.setCurrentRotation(windowManager.getDefaultDisplayRotation());
- } catch (RemoteException ex) { }
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context);
@@ -2080,20 +1903,6 @@
mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"PhoneWindowManager.mPowerKeyWakeLock");
mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
- mSupportAutoRotation = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_supportAutoRotation);
- mLidOpenRotation = readRotation(
- com.android.internal.R.integer.config_lidOpenRotation);
- mCarDockRotation = readRotation(
- com.android.internal.R.integer.config_carDockRotation);
- mDeskDockRotation = readRotation(
- com.android.internal.R.integer.config_deskDockRotation);
- mUndockedHdmiRotation = readRotation(
- com.android.internal.R.integer.config_undockedHdmiRotation);
- mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_carDockEnablesAccelerometer);
- mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
mLidKeyboardAccessibility = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lidKeyboardAccessibility);
mLidNavigationAccessibility = mContext.getResources().getInteger(
@@ -2167,8 +1976,8 @@
Intent intent = context.registerReceiver(mDockReceiver, filter);
if (intent != null) {
// Retrieve current sticky dock event broadcast.
- mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
- Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ mDefaultDisplayPolicy.setDockMode(intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+ Intent.EXTRA_DOCK_STATE_UNDOCKED));
}
// register for dream-related broadcasts
@@ -2222,11 +2031,11 @@
}
@Override
public void onDown() {
- mOrientationListener.onTouchStart();
+ mDefaultOrientationListener.onTouchStart();
}
@Override
public void onUpOrCancel() {
- mOrientationListener.onTouchEnd();
+ mDefaultOrientationListener.onTouchEnd();
}
@Override
public void onMouseHoverAtTop() {
@@ -2333,110 +2142,12 @@
com.android.internal.R.integer.config_navBarOpacityMode);
}
- @Override
- public void setInitialDisplaySize(Display display, int width, int height, int density) {
- // This method might be called before the policy has been fully initialized
- // or for other displays we don't care about.
- // TODO(multi-display): Define policy for secondary displays.
- if (mContext == null || display.getDisplayId() != DEFAULT_DISPLAY) {
- return;
- }
- mDisplay = display;
-
- final Resources res = mContext.getResources();
- int shortSize, longSize;
- if (width > height) {
- shortSize = height;
- longSize = width;
- mLandscapeRotation = Surface.ROTATION_0;
- mSeascapeRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
- mPortraitRotation = Surface.ROTATION_90;
- mUpsideDownRotation = Surface.ROTATION_270;
- } else {
- mPortraitRotation = Surface.ROTATION_270;
- mUpsideDownRotation = Surface.ROTATION_90;
- }
- } else {
- shortSize = width;
- longSize = height;
- mPortraitRotation = Surface.ROTATION_0;
- mUpsideDownRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
- mLandscapeRotation = Surface.ROTATION_270;
- mSeascapeRotation = Surface.ROTATION_90;
- } else {
- mLandscapeRotation = Surface.ROTATION_90;
- mSeascapeRotation = Surface.ROTATION_270;
- }
- }
-
- // SystemUI (status bar) layout policy
- int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
- int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
-
- // Allow the navigation bar to move on non-square small devices (phones).
- mNavigationBarCanMove = width != height && shortSizeDp < 600;
-
- mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
-
- // Allow a system property to override this. Used by the emulator.
- // See also hasNavigationBar().
- String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
- if ("1".equals(navBarOverride)) {
- mHasNavigationBar = false;
- } else if ("0".equals(navBarOverride)) {
- mHasNavigationBar = true;
- }
-
- // For demo purposes, allow the rotation of the HDMI display to be controlled.
- // By default, HDMI locks rotation to landscape.
- if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
- mDemoHdmiRotation = mPortraitRotation;
- } else {
- mDemoHdmiRotation = mLandscapeRotation;
- }
- mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
-
- // For demo purposes, allow the rotation of the remote display to be controlled.
- // By default, remote display locks rotation to landscape.
- if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) {
- mDemoRotation = mPortraitRotation;
- } else {
- mDemoRotation = mLandscapeRotation;
- }
- mDemoRotationLock = SystemProperties.getBoolean(
- "persist.demo.rotationlock", false);
-
- // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
- // http://developer.android.com/guide/practices/screens_support.html#range
- // For car, ignore the dp limitation. It's physically impossible to rotate the car's screen
- // so if the orientation is forced, we need to respect that no matter what.
- final boolean isCar = mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_AUTOMOTIVE);
- // For TV, it's usually 960dp x 540dp, ignore the size limitation.
- // so if the orientation is forced, we need to respect that no matter what.
- final boolean isTv = mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_LEANBACK);
- mForceDefaultOrientation = ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar || isTv) &&
- res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
- // For debug purposes the next line turns this feature off with:
- // $ adb shell setprop config.override_forced_orient true
- // $ adb shell wm size reset
- !"true".equals(SystemProperties.get("config.override_forced_orient"));
- }
-
/**
* @return whether the navigation bar can be hidden, e.g. the device has a
* navigation bar and touch exploration is not enabled
*/
private boolean canHideNavigationBar() {
- return mHasNavigationBar;
- }
-
- @Override
- public boolean isDefaultOrientationForced() {
- return mForceDefaultOrientation;
+ return mDefaultDisplayPolicy.hasNavigationBar();
}
public void updateSettings() {
@@ -2465,15 +2176,6 @@
.getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
mRingerToggleChord = Settings.Secure.VOLUME_HUSH_OFF;
}
- // Configure rotation suggestions.
- int showRotationSuggestions = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
- Settings.Secure.SHOW_ROTATION_SUGGESTIONS_DEFAULT,
- UserHandle.USER_CURRENT);
- if (mShowRotationSuggestions != showRotationSuggestions) {
- mShowRotationSuggestions = showRotationSuggestions;
- updateOrientationListenerLp(); // Enable, disable the orientation listener
- }
// Configure wake gesture.
boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
@@ -2484,24 +2186,6 @@
updateWakeGestureListenerLp();
}
- // Configure rotation lock.
- int userRotation = Settings.System.getIntForUser(resolver,
- Settings.System.USER_ROTATION, Surface.ROTATION_0,
- UserHandle.USER_CURRENT);
- if (mUserRotation != userRotation) {
- mUserRotation = userRotation;
- updateRotation = true;
- }
- int userRotationMode = Settings.System.getIntForUser(resolver,
- Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
- WindowManagerPolicy.USER_ROTATION_FREE :
- WindowManagerPolicy.USER_ROTATION_LOCKED;
- if (mUserRotationMode != userRotationMode) {
- mUserRotationMode = userRotationMode;
- updateRotation = true;
- updateOrientationListenerLp();
- }
-
if (mSystemReady) {
int pointerLocation = Settings.System.getIntForUser(resolver,
Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT);
@@ -2542,8 +2226,8 @@
}
private boolean shouldEnableWakeGestureLp() {
- return mWakeGestureEnabledSetting && !mAwake
- && (!mLidControlsSleep || mLidState != LID_CLOSED)
+ return mWakeGestureEnabledSetting && !mDefaultDisplayPolicy.isAwake()
+ && (!mLidControlsSleep || mDefaultDisplayPolicy.getLidState() != LID_CLOSED)
&& mWakeGestureListener.isSupported();
}
@@ -2583,24 +2267,6 @@
}
}
- private int readRotation(int resID) {
- try {
- int rotation = mContext.getResources().getInteger(resID);
- switch (rotation) {
- case 0:
- return Surface.ROTATION_0;
- case 90:
- return Surface.ROTATION_90;
- case 180:
- return Surface.ROTATION_180;
- case 270:
- return Surface.ROTATION_270;
- }
- } catch (Resources.NotFoundException e) {
- // fall through
- }
- return -1;
- }
/** {@inheritDoc} */
@Override
@@ -2829,7 +2495,7 @@
}
void readLidState() {
- mLidState = mWindowManagerFuncs.getLidState();
+ mDefaultDisplayPolicy.setLidState(mWindowManagerFuncs.getLidState());
}
private void readCameraLensCoverState() {
@@ -2837,11 +2503,12 @@
}
private boolean isHidden(int accessibilityMode) {
+ final int lidState = mDefaultDisplayPolicy.getLidState();
switch (accessibilityMode) {
case 1:
- return mLidState == LID_CLOSED;
+ return lidState == LID_CLOSED;
case 2:
- return mLidState == LID_OPEN;
+ return lidState == LID_OPEN;
default:
return false;
}
@@ -2873,53 +2540,62 @@
}
@Override
- public void onOverlayChangedLw() {
- onConfigurationChanged();
+ public void onOverlayChangedLw(DisplayContentInfo displayContentInfo) {
+ onConfigurationChanged(displayContentInfo);
}
@Override
- public void onConfigurationChanged() {
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo) {
+ final DisplayRotation displayRotation = displayContentInfo.getDisplayRotation();
// TODO(multi-display): Define policy for secondary displays.
- Context uiContext = getSystemUiContext();
- final Resources res = uiContext.getResources();
+ if (!displayRotation.isDefaultDisplay) {
+ return;
+ }
- mStatusBarHeightForRotation[mPortraitRotation] =
- mStatusBarHeightForRotation[mUpsideDownRotation] = res.getDimensionPixelSize(
+ final Context uiContext = getSystemUiContext();
+ final Resources res = uiContext.getResources();
+ final int portraitRotation = displayRotation.getPortraitRotation();
+ final int upsideDownRotation = displayRotation.getUpsideDownRotation();
+ final int landscapeRotation = displayRotation.getLandscapeRotation();
+ final int seascapeRotation = displayRotation.getSeascapeRotation();
+
+ mStatusBarHeightForRotation[portraitRotation] =
+ mStatusBarHeightForRotation[upsideDownRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height_portrait);
- mStatusBarHeightForRotation[mLandscapeRotation] =
- mStatusBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
+ mStatusBarHeightForRotation[landscapeRotation] =
+ mStatusBarHeightForRotation[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height_landscape);
// Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotationDefault[mPortraitRotation] =
- mNavigationBarHeightForRotationDefault[mUpsideDownRotation] =
+ mNavigationBarHeightForRotationDefault[portraitRotation] =
+ mNavigationBarHeightForRotationDefault[upsideDownRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
- mNavigationBarHeightForRotationDefault[mLandscapeRotation] =
- mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize(
+ mNavigationBarHeightForRotationDefault[landscapeRotation] =
+ mNavigationBarHeightForRotationDefault[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape);
// Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotationDefault[mPortraitRotation] =
- mNavigationBarWidthForRotationDefault[mUpsideDownRotation] =
- mNavigationBarWidthForRotationDefault[mLandscapeRotation] =
- mNavigationBarWidthForRotationDefault[mSeascapeRotation] =
+ mNavigationBarWidthForRotationDefault[portraitRotation] =
+ mNavigationBarWidthForRotationDefault[upsideDownRotation] =
+ mNavigationBarWidthForRotationDefault[landscapeRotation] =
+ mNavigationBarWidthForRotationDefault[seascapeRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
if (ALTERNATE_CAR_MODE_NAV_SIZE) {
// Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotationInCarMode[mPortraitRotation] =
- mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] =
+ mNavigationBarHeightForRotationInCarMode[portraitRotation] =
+ mNavigationBarHeightForRotationInCarMode[upsideDownRotation] =
res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_car_mode);
- mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] =
- mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize(
+ mNavigationBarHeightForRotationInCarMode[landscapeRotation] =
+ mNavigationBarHeightForRotationInCarMode[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode);
// Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotationInCarMode[mPortraitRotation] =
- mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] =
- mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] =
- mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] =
+ mNavigationBarWidthForRotationInCarMode[portraitRotation] =
+ mNavigationBarWidthForRotationInCarMode[upsideDownRotation] =
+ mNavigationBarWidthForRotationInCarMode[landscapeRotation] =
+ mNavigationBarWidthForRotationInCarMode[seascapeRotation] =
res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width_car_mode);
}
@@ -2948,10 +2624,10 @@
int displayId, DisplayCutout displayCutout) {
int width = fullWidth;
// TODO(multi-display): Support navigation bar on secondary displays.
- if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
+ if (displayId == DEFAULT_DISPLAY && mDefaultDisplayPolicy.hasNavigationBar()) {
// For a basic navigation bar, when we are in landscape mode we place
// the navigation bar to the side.
- if (mNavigationBarCanMove && fullWidth > fullHeight) {
+ if (mDefaultDisplayPolicy.navigationBarCanMove() && fullWidth > fullHeight) {
width -= getNavigationBarWidth(rotation, uiMode);
}
}
@@ -2974,10 +2650,10 @@
int displayId, DisplayCutout displayCutout) {
int height = fullHeight;
// TODO(multi-display): Support navigation bar on secondary displays.
- if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
+ if (displayId == DEFAULT_DISPLAY && mDefaultDisplayPolicy.hasNavigationBar()) {
// For a basic navigation bar, when we are in portrait mode we place
// the navigation bar to the bottom.
- if (!mNavigationBarCanMove || fullWidth < fullHeight) {
+ if (!mDefaultDisplayPolicy.navigationBarCanMove() || fullWidth < fullHeight) {
height -= getNavigationBarHeight(rotation, uiMode);
}
}
@@ -3065,8 +2741,8 @@
// In that case, we want to continue hiding the IME until the windows have completed
// drawing. This way, we know that the IME can be safely shown since the other windows are
// now shown.
- final boolean hideIme =
- win.isInputMethodWindow() && (mAodShowing || !mWindowManagerDrawComplete);
+ final boolean hideIme = win.isInputMethodWindow()
+ && (mAodShowing || !mDefaultDisplayPolicy.isWindowManagerDrawComplete());
return (keyguardLocked && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY)
|| hideDockDivider || hideIme;
}
@@ -3444,7 +3120,7 @@
@Override
public void selectRotationAnimationLw(int anim[]) {
// If the screen is off or non-interactive, force a jumpcut.
- final boolean forceJumpcut = !mScreenOnFully || !okToAnimate();
+ final boolean forceJumpcut = !mDefaultDisplayPolicy.isScreenOnFully() || !okToAnimate();
if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen="
+ mTopFullscreenOpaqueWindowState + " rotationAnimation="
+ (mTopFullscreenOpaqueWindowState == null ?
@@ -3851,7 +3527,7 @@
// If the device is in VR mode and keys are "internal" (e.g. on the side of the
// device), then drop the volume keys and don't forward it to the application/dispatch
// the audio event.
- if (mPersistentVrModeEnabled) {
+ if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) {
final InputDevice d = event.getDevice();
if (d != null && !d.isExternal()) {
return -1;
@@ -4941,7 +4617,7 @@
@NavigationBarPosition
private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
- if (mNavigationBarCanMove && displayWidth > displayHeight) {
+ if (mDefaultDisplayPolicy.navigationBarCanMove() && displayWidth > displayHeight) {
if (displayRotation == Surface.ROTATION_270) {
return NAV_BAR_LEFT;
} else {
@@ -5075,7 +4751,7 @@
mWindowFrames.setParentFrameWasClippedByDisplayCutout(false);
mWindowFrames.setDisplayCutout(displayFrames.mDisplayCutout);
- final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar
+ final boolean hasNavBar = (isDefaultDisplay && mDefaultDisplayPolicy.hasNavigationBar()
&& mNavigationBar != null && mNavigationBar.isVisibleLw());
final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
@@ -5884,11 +5560,11 @@
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
// lid changed state
final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED;
- if (newLidState == mLidState) {
+ if (newLidState == mDefaultDisplayPolicy.getLidState()) {
return;
}
- mLidState = newLidState;
+ mDefaultDisplayPolicy.setLidState(newLidState);
applyLidSwitchState();
updateRotation(true);
@@ -5923,17 +5599,6 @@
mCameraLensCoverState = lensCoverState;
}
- void setHdmiPlugged(boolean plugged) {
- if (mHdmiPlugged != plugged) {
- mHdmiPlugged = plugged;
- updateRotation(true, true);
- Intent intent = new Intent(ACTION_HDMI_PLUGGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
- }
-
void initializeHdmiState() {
final int oldMask = StrictMode.allowThreadDiskReadsMask();
try {
@@ -5973,8 +5638,7 @@
}
// This dance forces the code in setHdmiPlugged to run.
// Always do this so the sticky intent is stuck (to false) if there is no hdmi.
- mHdmiPlugged = !plugged;
- setHdmiPlugged(!mHdmiPlugged);
+ mDefaultDisplayPolicy.setHdmiPlugged(plugged, true /* force */);
}
@@ -6414,16 +6078,6 @@
}
/**
- * Notify the StatusBar that system rotation suggestion has changed.
- */
- private void sendProposedRotationChangeToStatusBarInternal(int rotation, boolean isValid) {
- StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
- if (statusBar != null) {
- statusBar.onProposedRotationChanged(rotation, isValid);
- }
- }
-
- /**
* Returns true if the key can have global actions attached to it.
* We reserve all power management keys for the system since they require
* very careful handling.
@@ -6452,7 +6106,7 @@
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE:
- return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED;
+ return mDefaultDisplayPolicy.getDockMode() != Intent.EXTRA_DOCK_STATE_UNDOCKED;
// ignore media and camera keys
case KeyEvent.KEYCODE_MUTE:
@@ -6500,7 +6154,8 @@
}
private boolean shouldDispatchInputWhenNonInteractive(KeyEvent event) {
- final boolean displayOff = (mDisplay == null || mDisplay.getState() == STATE_OFF);
+ final boolean displayOff = (mDefaultDisplay == null
+ || mDefaultDisplay.getState() == STATE_OFF);
if (displayOff && !mHasFeatureWatch) {
return false;
@@ -6650,8 +6305,8 @@
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
- mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
- Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ mDefaultDisplayPolicy.setDockMode(intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+ Intent.EXTRA_DOCK_STATE_UNDOCKED));
} else {
try {
IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
@@ -6661,9 +6316,7 @@
}
}
updateRotation(true);
- synchronized (mLock) {
- updateOrientationListenerLp();
- }
+ mDefaultDisplayRotation.updateOrientationListener();
}
};
@@ -6691,6 +6344,7 @@
// and then updates our own bookkeeping based on the now-
// current user.
mSettingsObserver.onChange(false);
+ mDefaultDisplayRotation.onUserSwitch();
// force a re-application of focused window sysui visibility.
// the window may never have been shown for this user
@@ -6764,15 +6418,16 @@
mGoingToSleep = false;
mRequestedOrGoingToSleep = false;
+ mDefaultDisplayPolicy.setAwake(false);
// We must get this work done here because the power manager will drop
// the wake lock and let the system suspend once this function returns.
synchronized (mLock) {
- mAwake = false;
updateWakeGestureListenerLp();
- updateOrientationListenerLp();
updateLockScreenTimeout();
}
+ mDefaultDisplayRotation.updateOrientationListener();
+
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onFinishedGoingToSleep(why,
mCameraGestureTriggeredDuringGoingToSleep);
@@ -6786,17 +6441,17 @@
EventLog.writeEvent(70000, 1);
if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
+ mDefaultDisplayPolicy.setAwake(true);
+
// Since goToSleep performs these functions synchronously, we must
// do the same here. We cannot post this work to a handler because
// that might cause it to become reordered with respect to what
// may happen in a future call to goToSleep.
synchronized (mLock) {
- mAwake = true;
-
updateWakeGestureListenerLp();
- updateOrientationListenerLp();
updateLockScreenTimeout();
}
+ mDefaultDisplayRotation.updateOrientationListener();
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onStartedWakingUp();
@@ -6833,16 +6488,14 @@
}
private void finishKeyguardDrawn() {
- synchronized (mLock) {
- if (!mScreenOnEarly || mKeyguardDrawComplete) {
- return; // We are not awake yet or we have already informed of this event.
- }
+ if (!mDefaultDisplayPolicy.finishKeyguardDrawn()) {
+ return;
+ }
- mKeyguardDrawComplete = true;
+ synchronized (mLock) {
if (mKeyguardDelegate != null) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
}
- mWindowManagerDrawComplete = false;
}
// ... eventually calls finishWindowsDrawn which will finalize our screen turn on
@@ -6857,18 +6510,13 @@
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");
updateScreenOffSleepToken(true);
+ mDefaultDisplayPolicy.screenTurnedOff();
synchronized (mLock) {
- mScreenOnEarly = false;
- mScreenOnFully = false;
- mKeyguardDrawComplete = false;
- mWindowManagerDrawComplete = false;
- mScreenOnListener = null;
- updateOrientationListenerLp();
-
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onScreenTurnedOff();
}
}
+ mDefaultDisplayRotation.updateOrientationListener();
reportScreenStateToVrManager(false);
}
@@ -6885,13 +6533,9 @@
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
updateScreenOffSleepToken(false);
- synchronized (mLock) {
- mScreenOnEarly = true;
- mScreenOnFully = false;
- mKeyguardDrawComplete = false;
- mWindowManagerDrawComplete = false;
- mScreenOnListener = screenOnListener;
+ mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
+ synchronized (mLock) {
if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
@@ -6934,46 +6578,29 @@
}
private void finishWindowsDrawn() {
- synchronized (mLock) {
- if (!mScreenOnEarly || mWindowManagerDrawComplete) {
- return; // Screen is not turned on or we did already handle this case earlier.
- }
-
- mWindowManagerDrawComplete = true;
+ if (!mDefaultDisplayPolicy.finishWindowsDrawn()) {
+ return;
}
finishScreenTurningOn();
}
private void finishScreenTurningOn() {
- synchronized (mLock) {
- // We have just finished drawing screen content. Since the orientation listener
- // gets only installed when all windows are drawn, we try to install it again.
- updateOrientationListenerLp();
+ // We have just finished drawing screen content. Since the orientation listener
+ // gets only installed when all windows are drawn, we try to install it again.
+ mDefaultDisplayRotation.updateOrientationListener();
+
+ final ScreenOnListener listener = mDefaultDisplayPolicy.getScreenOnListener();
+ if (!mDefaultDisplayPolicy.finishScreenTurningOn()) {
+ return; // Spurious or not ready yet.
}
- final ScreenOnListener listener;
+
final boolean enableScreen;
+ final boolean awake = mDefaultDisplayPolicy.isAwake();
synchronized (mLock) {
- if (DEBUG_WAKEUP) Slog.d(TAG,
- "finishScreenTurningOn: mAwake=" + mAwake
- + ", mScreenOnEarly=" + mScreenOnEarly
- + ", mScreenOnFully=" + mScreenOnFully
- + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
- + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
-
- if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete
- || (mAwake && !mKeyguardDrawComplete)) {
- return; // spurious or not ready yet
- }
-
- if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on...");
- listener = mScreenOnListener;
- mScreenOnListener = null;
- mScreenOnFully = true;
-
// Remember the first time we draw the keyguard so we know when we're done with
// the main part of booting and can enable the screen and hide boot messages.
- if (!mKeyguardDrawnOnce && mAwake) {
+ if (!mKeyguardDrawnOnce && awake) {
mKeyguardDrawnOnce = true;
enableScreen = true;
if (mBootMessageNeedsHiding) {
@@ -7014,14 +6641,12 @@
@Override
public boolean isScreenOn() {
- synchronized (mLock) {
- return mScreenOnEarly;
- }
+ return mDefaultDisplayPolicy.isScreenOnEarly();
}
@Override
public boolean okToAnimate() {
- return mAwake && !mGoingToSleep;
+ return mDefaultDisplayPolicy.isAwake() && !mGoingToSleep;
}
/** {@inheritDoc} */
@@ -7131,7 +6756,7 @@
outInsets.setEmpty();
// Only navigation bar
- if (mHasNavigationBar) {
+ if (mDefaultDisplayPolicy.hasNavigationBar()) {
int position = navigationBarPosition(displayWidth, displayHeight, displayRotation);
if (position == NAV_BAR_BOTTOM) {
outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode);
@@ -7165,7 +6790,8 @@
public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
int displayHeight, int displayRotation) {
final int barPosition = navigationBarPosition(displayWidth, displayHeight, displayRotation);
- return isDockSideAllowed(dockSide, originalDockSide, barPosition, mNavigationBarCanMove);
+ return isDockSideAllowed(dockSide, originalDockSide, barPosition,
+ mDefaultDisplayPolicy.navigationBarCanMove());
}
@VisibleForTesting
@@ -7202,293 +6828,6 @@
}
@Override
- public int rotationForOrientationLw(int orientation, int lastRotation, boolean defaultDisplay) {
- if (false) {
- Slog.v(TAG, "rotationForOrientationLw(orient="
- + orientation + ", last=" + lastRotation
- + "); user=" + mUserRotation + " "
- + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
- ? "USER_ROTATION_LOCKED" : "")
- );
- }
-
- if (mForceDefaultOrientation) {
- return Surface.ROTATION_0;
- }
-
- synchronized (mLock) {
- int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
- if (sensorRotation < 0) {
- sensorRotation = lastRotation;
- }
-
- final int preferredRotation;
- if (!defaultDisplay) {
- // For secondary displays we ignore things like displays sensors, docking mode and
- // rotation lock, and always prefer a default rotation.
- preferredRotation = Surface.ROTATION_0;
- } else if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
- // Ignore sensor when lid switch is open and rotation is forced.
- preferredRotation = mLidOpenRotation;
- } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
- && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
- // Ignore sensor when in car dock unless explicitly enabled.
- // This case can override the behavior of NOSENSOR, and can also
- // enable 180 degree rotation while docked.
- preferredRotation = mCarDockEnablesAccelerometer
- ? sensorRotation : mCarDockRotation;
- } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
- && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
- // Ignore sensor when in desk dock unless explicitly enabled.
- // This case can override the behavior of NOSENSOR, and can also
- // enable 180 degree rotation while docked.
- preferredRotation = mDeskDockEnablesAccelerometer
- ? sensorRotation : mDeskDockRotation;
- } else if (mHdmiPlugged && mDemoHdmiRotationLock) {
- // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.
- // Note that the dock orientation overrides the HDMI orientation.
- preferredRotation = mDemoHdmiRotation;
- } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
- && mUndockedHdmiRotation >= 0) {
- // Ignore sensor when plugged into HDMI and an undocked orientation has
- // been specified in the configuration (only for legacy devices without
- // full multi-display support).
- // Note that the dock orientation overrides the HDMI orientation.
- preferredRotation = mUndockedHdmiRotation;
- } else if (mDemoRotationLock) {
- // Ignore sensor when demo rotation lock is enabled.
- // Note that the dock orientation and HDMI rotation lock override this.
- preferredRotation = mDemoRotation;
- } else if (mPersistentVrModeEnabled) {
- // While in VR, apps always prefer a portrait rotation. This does not change
- // any apps that explicitly set landscape, but does cause sensors be ignored,
- // and ignored any orientation lock that the user has set (this conditional
- // should remain above the ORIENTATION_LOCKED conditional below).
- preferredRotation = mPortraitRotation;
- } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
- // Application just wants to remain locked in the last rotation.
- preferredRotation = lastRotation;
- } else if (!mSupportAutoRotation) {
- // If we don't support auto-rotation then bail out here and ignore
- // the sensor and any rotation lock settings.
- preferredRotation = -1;
- } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
- && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
- || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
- || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
- || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
- // Otherwise, use sensor only if requested by the application or enabled
- // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
- if (mAllowAllRotations < 0) {
- // Can't read this during init() because the context doesn't
- // have display metrics at that time so we cannot determine
- // tablet vs. phone then.
- mAllowAllRotations = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
- }
- if (sensorRotation != Surface.ROTATION_180
- || mAllowAllRotations == 1
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
- preferredRotation = sensorRotation;
- } else {
- preferredRotation = lastRotation;
- }
- } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
- && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
- // Apply rotation lock. Does not apply to NOSENSOR.
- // The idea is that the user rotation expresses a weak preference for the direction
- // of gravity and as NOSENSOR is never affected by gravity, then neither should
- // NOSENSOR be affected by rotation lock (although it will be affected by docks).
- preferredRotation = mUserRotation;
- } else {
- // No overriding preference.
- // We will do exactly what the application asked us to do.
- preferredRotation = -1;
- }
-
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- // Return portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mPortraitRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- // Return landscape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- // Return reverse portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mUpsideDownRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- // Return seascape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mSeascapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- // Return either landscape rotation.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- if (isLandscapeOrSeascape(lastRotation)) {
- return lastRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // Return either portrait rotation.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- if (isAnyPortrait(lastRotation)) {
- return lastRotation;
- }
- return mPortraitRotation;
-
- default:
- // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
- // just return the preferred orientation we already calculated.
- if (preferredRotation >= 0) {
- return preferredRotation;
- }
- return Surface.ROTATION_0;
- }
- }
- }
-
- @Override
- public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- return isAnyPortrait(rotation);
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
- return isLandscapeOrSeascape(rotation);
-
- default:
- return true;
- }
- }
-
- @Override
- public void setRotationLw(int rotation) {
- mOrientationListener.setCurrentRotation(rotation);
- }
-
- public boolean isRotationChoicePossible(int orientation) {
- // Rotation choice is only shown when the user is in locked mode.
- if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
-
- // We should only enable rotation choice if the rotation isn't forced by the lid, dock,
- // demo, hdmi, vr, etc mode
-
- // Determine if the rotation is currently forced
- if (mForceDefaultOrientation) {
- return false; // Rotation is forced to default orientation
-
- } else if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
- return false; // Rotation is forced mLidOpenRotation
-
- } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && !mCarDockEnablesAccelerometer) {
- return false; // Rotation forced to mCarDockRotation
-
- } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
- && !mDeskDockEnablesAccelerometer) {
- return false; // Rotation forced to mDeskDockRotation
-
- } else if (mHdmiPlugged && mDemoHdmiRotationLock) {
- return false; // Rotation forced to mDemoHdmiRotation
-
- } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
- && mUndockedHdmiRotation >= 0) {
- return false; // Rotation forced to mUndockedHdmiRotation
-
- } else if (mDemoRotationLock) {
- return false; // Rotation forced to mDemoRotation
-
- } else if (mPersistentVrModeEnabled) {
- return false; // Rotation forced to mPortraitRotation
-
- } else if (!mSupportAutoRotation) {
- return false;
- }
-
- // Ensure that some rotation choice is possible for the given orientation
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
- case ActivityInfo.SCREEN_ORIENTATION_USER:
- case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // NOSENSOR description is ambiguous, in reality WM ignores user choice
- return true;
- }
-
- // Rotation is forced, should be controlled by system
- return false;
- }
-
- public boolean isValidRotationChoice(int orientation, final int preferredRotation) {
- // Determine if the given app orientation is compatible with the provided rotation choice
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
- // Works with any of the 4 rotations
- return preferredRotation >= 0;
-
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // It's possible for the user pref to be set at 180 because of FULL_USER. This would
- // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
- // but never to go to 180.
- return preferredRotation == mPortraitRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- // Works landscape or seascape
- return isLandscapeOrSeascape(preferredRotation);
-
- case ActivityInfo.SCREEN_ORIENTATION_USER:
- case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
- // Works with any rotation except upside down
- return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
- }
-
- return false;
- }
-
- private boolean isLandscapeOrSeascape(int rotation) {
- return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
- }
-
- private boolean isAnyPortrait(int rotation) {
- return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
- }
-
- @Override
public int getUserRotationMode() {
return Settings.System.getIntForUser(mContext.getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
@@ -7560,8 +6899,8 @@
readCameraLensCoverState();
updateUiMode();
+ mDefaultDisplayRotation.updateOrientationListener();
synchronized (mLock) {
- updateOrientationListenerLp();
mSystemReady = true;
mHandler.post(new Runnable() {
@Override
@@ -7599,9 +6938,7 @@
@Override
public boolean canDismissBootAnimation() {
- synchronized (mLock) {
- return mKeyguardDrawComplete;
- }
+ return mDefaultDisplayPolicy.isKeyguardDrawComplete();
}
ProgressDialog mBootMsgDialog = null;
@@ -7701,7 +7038,7 @@
}
}
- if (mAwake && mNotifyUserActivity) {
+ if (mDefaultDisplayPolicy.isAwake() && mNotifyUserActivity) {
mHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
USER_ACTIVITY_NOTIFICATION_DELAY);
mNotifyUserActivity = false;
@@ -7744,7 +7081,7 @@
private void updateLockScreenTimeout() {
synchronized (mScreenLockTimeout) {
- boolean enable = (mAllowLockscreenWhenOn && mAwake &&
+ final boolean enable = (mAllowLockscreenWhenOn && mDefaultDisplayPolicy.isAwake() &&
mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId));
if (mLockScreenTimerActive != enable) {
if (enable) {
@@ -7799,10 +7136,11 @@
}
private void applyLidSwitchState() {
- if (mLidState == LID_CLOSED && mLidControlsSleep) {
+ final int lidState = mDefaultDisplayPolicy.getLidState();
+ if (lidState == LID_CLOSED && mLidControlsSleep) {
goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) {
+ } else if (lidState == LID_CLOSED && mLidControlsScreenLock) {
mWindowManagerFuncs.lockDeviceNow();
}
@@ -7824,17 +7162,8 @@
void updateRotation(boolean alwaysSendConfiguration) {
try {
- //set orientation on WindowManager
- mWindowManager.updateRotation(alwaysSendConfiguration, false);
- } catch (RemoteException e) {
- // Ignore
- }
- }
-
- void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
- try {
- //set orientation on WindowManager
- mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout);
+ // Set orientation on WindowManager.
+ mWindowManager.updateRotation(alwaysSendConfiguration, false /* forceRelayout */);
} catch (RemoteException e) {
// Ignore
}
@@ -7867,12 +7196,14 @@
if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
intent = mDeskDockIntent;
}
- } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH
- && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) {
- // Always launch dock home from home when watch is docked, if it exists.
- intent = mDeskDockIntent;
+ } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH) {
+ final int dockMode = mDefaultDisplayPolicy.getDockMode();
+ if (dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK) {
+ // Always launch dock home from home when watch is docked, if it exists.
+ intent = mDeskDockIntent;
+ }
} else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) {
if (ENABLE_VR_HEADSET_HOME_CAPTURE) {
intent = mVrHeadsetHomeIntent;
@@ -7987,16 +7318,6 @@
return true;
}
- @Override
- public void setCurrentOrientationLw(int newOrientation) {
- synchronized (mLock) {
- if (newOrientation != mCurrentAppOrientation) {
- mCurrentAppOrientation = newOrientation;
- updateOrientationListenerLp();
- }
- }
- }
-
private boolean isTheaterModeEnabled() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 1;
@@ -8323,7 +7644,8 @@
final long now = SystemClock.uptimeMillis();
final boolean pendingPanic = mPendingPanicGestureUptime != 0
&& now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;
- if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) {
+ if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard()
+ && mDefaultDisplayPolicy.isKeyguardDrawComplete()) {
// The user performed the panic gesture recently, we're about to hide the bars,
// we're no longer on the Keyguard and the screen is ready. We can now request the bars.
mPendingPanicGestureUptime = 0;
@@ -8466,7 +7788,7 @@
// overridden by qemu.hw.mainkeys in the emulator.
@Override
public boolean hasNavigationBar() {
- return mHasNavigationBar;
+ return mDefaultDisplayPolicy.hasNavigationBar();
}
@Override
@@ -8511,19 +7833,21 @@
}
@Override
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
+ int newRotation) {
// For the upside down rotation we don't rotate seamlessly as the navigation
// bar moves position.
// Note most apps (using orientation:sensor or user as opposed to fullSensor)
// will not enter the reverse portrait orientation, so actually the
// orientation won't change at all.
- if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
+ if (oldRotation == displayRotation.getUpsideDownRotation()
+ || newRotation == displayRotation.getUpsideDownRotation()) {
return false;
}
// If the navigation bar can't change sides, then it will
// jump when we change orientations and we don't rotate
// seamlessly.
- if (!mNavigationBarCanMove) {
+ if (!displayRotation.getDisplayPolicy().navigationBarCanMove()) {
return false;
}
int delta = newRotation - oldRotation;
@@ -8557,12 +7881,13 @@
public void writeToProto(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(LAST_SYSTEM_UI_FLAGS, mLastSystemUiFlags);
- proto.write(ROTATION_MODE, mUserRotationMode);
- proto.write(ROTATION, mUserRotation);
- proto.write(ORIENTATION, mCurrentAppOrientation);
- proto.write(SCREEN_ON_FULLY, mScreenOnFully);
- proto.write(KEYGUARD_DRAW_COMPLETE, mKeyguardDrawComplete);
- proto.write(WINDOW_MANAGER_DRAW_COMPLETE, mWindowManagerDrawComplete);
+ proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode());
+ proto.write(ROTATION, mDefaultDisplayRotation.getUserRotation());
+ proto.write(ORIENTATION, mDefaultDisplayRotation.getCurrentAppOrientation());
+ proto.write(SCREEN_ON_FULLY, mDefaultDisplayPolicy.isScreenOnFully());
+ proto.write(KEYGUARD_DRAW_COMPLETE, mDefaultDisplayPolicy.isKeyguardDrawComplete());
+ proto.write(WINDOW_MANAGER_DRAW_COMPLETE,
+ mDefaultDisplayPolicy.isWindowManagerDrawComplete());
if (mFocusedApp != null) {
proto.write(FOCUSED_APP_TOKEN, mFocusedApp.toString());
}
@@ -8584,8 +7909,8 @@
proto.write(FORCE_STATUS_BAR_FROM_KEYGUARD, mForceStatusBarFromKeyguard);
mStatusBarController.writeToProto(proto, STATUS_BAR);
mNavigationBarController.writeToProto(proto, NAVIGATION_BAR);
- if (mOrientationListener != null) {
- mOrientationListener.writeToProto(proto, ORIENTATION_LISTENER);
+ if (mDefaultOrientationListener != null) {
+ mDefaultOrientationListener.writeToProto(proto, ORIENTATION_LISTENER);
}
if (mKeyguardDelegate != null) {
mKeyguardDelegate.writeToProto(proto, KEYGUARD_DELEGATE);
@@ -8598,13 +7923,8 @@
pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
pw.print(" mSystemReady="); pw.print(mSystemReady);
pw.print(" mSystemBooted="); pw.println(mSystemBooted);
- pw.print(prefix); pw.print("mLidState=");
- pw.print(WindowManagerFuncs.lidStateToString(mLidState));
- pw.print(" mLidOpenRotation=");
- pw.println(Surface.rotationToString(mLidOpenRotation));
pw.print(prefix); pw.print("mCameraLensCoverState=");
- pw.print(WindowManagerFuncs.cameraLensStateToString(mCameraLensCoverState));
- pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged);
+ pw.println(WindowManagerFuncs.cameraLensStateToString(mCameraLensCoverState));
if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0
|| mForceClearedSystemUiFlags != 0) {
pw.print(prefix); pw.print("mLastSystemUiFlags=0x");
@@ -8622,27 +7942,9 @@
pw.println(mWakeGestureEnabledSetting);
pw.print(prefix);
- pw.print("mSupportAutoRotation="); pw.print(mSupportAutoRotation);
- pw.print(" mOrientationSensorEnabled="); pw.println(mOrientationSensorEnabled);
- pw.print(prefix); pw.print("mUiMode="); pw.print(Configuration.uiModeToString(mUiMode));
- pw.print(" mDockMode="); pw.println(Intent.dockStateToString(mDockMode));
- pw.print(prefix); pw.print("mEnableCarDockHomeCapture=");
- pw.print(mEnableCarDockHomeCapture);
- pw.print(" mCarDockRotation=");
- pw.print(Surface.rotationToString(mCarDockRotation));
- pw.print(" mDeskDockRotation=");
- pw.println(Surface.rotationToString(mDeskDockRotation));
- pw.print(prefix); pw.print("mUserRotationMode=");
- pw.print(WindowManagerPolicy.userRotationModeToString(mUserRotationMode));
- pw.print(" mUserRotation="); pw.print(Surface.rotationToString(mUserRotation));
- pw.print(" mAllowAllRotations=");
- pw.println(allowAllRotationsToString(mAllowAllRotations));
- pw.print(prefix); pw.print("mCurrentAppOrientation=");
- pw.println(ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
- pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
- pw.print(mCarDockEnablesAccelerometer);
- pw.print(" mDeskDockEnablesAccelerometer=");
- pw.println(mDeskDockEnablesAccelerometer);
+ pw.print("mUiMode=");
+ pw.print(Configuration.uiModeToString(mUiMode));
+ pw.print("mEnableCarDockHomeCapture="); pw.println(mEnableCarDockHomeCapture);
pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
pw.print(mLidKeyboardAccessibility);
pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
@@ -8692,12 +7994,6 @@
pw.print(" mEndcallBehavior=");
pw.println(endcallBehaviorToString(mEndcallBehavior));
pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed);
- pw.print(prefix);
- pw.print("mAwake="); pw.print(mAwake);
- pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
- pw.print(" mScreenOnFully="); pw.println(mScreenOnFully);
- pw.print(prefix); pw.print("mKeyguardDrawComplete="); pw.print(mKeyguardDrawComplete);
- pw.print(" mWindowManagerDrawComplete="); pw.println(mWindowManagerDrawComplete);
pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer);
pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream);
@@ -8752,19 +8048,6 @@
pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
- pw.print(prefix); pw.print("mLandscapeRotation=");
- pw.print(Surface.rotationToString(mLandscapeRotation));
- pw.print(" mSeascapeRotation=");
- pw.println(Surface.rotationToString(mSeascapeRotation));
- pw.print(prefix); pw.print("mPortraitRotation=");
- pw.print(Surface.rotationToString(mPortraitRotation));
- pw.print(" mUpsideDownRotation=");
- pw.println(Surface.rotationToString(mUpsideDownRotation));
- pw.print(prefix); pw.print("mDemoHdmiRotation=");
- pw.print(Surface.rotationToString(mDemoHdmiRotation));
- pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock);
- pw.print(prefix); pw.print("mUndockedHdmiRotation=");
- pw.println(Surface.rotationToString(mUndockedHdmiRotation));
if (mHasFeatureLeanback) {
pw.print(prefix);
pw.print("mAccessibilityTvKey1Pressed="); pw.println(mAccessibilityTvKey1Pressed);
@@ -8782,8 +8065,8 @@
if (mWakeGestureListener != null) {
mWakeGestureListener.dump(pw, prefix);
}
- if (mOrientationListener != null) {
- mOrientationListener.dump(pw, prefix);
+ if (mDefaultOrientationListener != null) {
+ mDefaultOrientationListener.dump(pw, prefix);
}
if (mBurnInProtectionHelper != null) {
mBurnInProtectionHelper.dump(prefix, pw);
@@ -8796,19 +8079,6 @@
mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " ");
}
- private static String allowAllRotationsToString(int allowAll) {
- switch (allowAll) {
- case -1:
- return "unknown";
- case 0:
- return "false";
- case 1:
- return "true";
- default:
- return Integer.toString(allowAll);
- }
- }
-
private static String endcallBehaviorToString(int behavior) {
StringBuilder sb = new StringBuilder();
if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0 ) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 0060328..cc39217 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -93,6 +93,7 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.DisplayRotation;
import com.android.server.wm.WindowFrames;
import com.android.server.wm.utils.WmDisplayCutout;
@@ -177,7 +178,7 @@
/**
* Called when the resource overlays change.
*/
- default void onOverlayChangedLw() {}
+ default void onOverlayChangedLw(DisplayContentInfo displayContentInfo) {}
/**
* Interface to the Window Manager state associated with a particular
@@ -638,6 +639,27 @@
* The keyguard showing state has changed
*/
void onKeyguardShowingAndNotOccludedChanged();
+
+ DisplayContentInfo getDefaultDisplayContentInfo();
+ }
+
+ /**
+ * Provides the rotation of a device.
+ *
+ * @see com.android.server.policy.WindowOrientationListener
+ */
+ public interface RotationSource {
+ int getProposedRotation();
+
+ void setCurrentRotation(int rotation);
+ }
+
+ /**
+ * Interface to get public information of a display content.
+ */
+ public interface DisplayContentInfo {
+ DisplayRotation getDisplayRotation();
+ Display getDisplay();
}
/** Window has been added to the screen. */
@@ -669,6 +691,11 @@
public final int USER_ROTATION_LOCKED = 1;
/**
+ * Set the default display content to provide basic functions for the policy.
+ */
+ public void setDefaultDisplay(DisplayContentInfo displayContentInfo);
+
+ /**
* Perform initialization of the policy.
*
* @param context The system context we are running in.
@@ -677,17 +704,6 @@
WindowManagerFuncs windowManagerFuncs);
/**
- * @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true.
- */
- public boolean isDefaultOrientationForced();
-
- /**
- * Called by window manager once it has the initial, default native
- * display dimensions.
- */
- public void setInitialDisplaySize(Display display, int width, int height, int density);
-
- /**
* Check permissions when adding a window.
*
* @param attrs The window's LayoutParams.
@@ -1410,44 +1426,6 @@
public boolean isShowingDreamLw();
/**
- * Given an orientation constant, returns the appropriate surface rotation,
- * taking into account sensors, docking mode, rotation lock, and other factors.
- *
- * @param orientation An orientation constant, such as
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
- * @param lastRotation The most recently used rotation.
- * @param defaultDisplay Flag indicating whether the rotation is computed for the default
- * display. Currently for all non-default displays sensors, docking mode,
- * rotation lock and other factors are ignored.
- * @return The surface rotation to use.
- */
- public int rotationForOrientationLw(@ActivityInfo.ScreenOrientation int orientation,
- int lastRotation, boolean defaultDisplay);
-
- /**
- * Given an orientation constant and a rotation, returns true if the rotation
- * has compatible metrics to the requested orientation. For example, if
- * the application requested landscape and got seascape, then the rotation
- * has compatible metrics; if the application requested portrait and got landscape,
- * then the rotation has incompatible metrics; if the application did not specify
- * a preference, then anything goes.
- *
- * @param orientation An orientation constant, such as
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
- * @param rotation The rotation to check.
- * @return True if the rotation is compatible with the requested orientation.
- */
- public boolean rotationHasCompatibleMetricsLw(@ActivityInfo.ScreenOrientation int orientation,
- int rotation);
-
- /**
- * Called by the window manager when the rotation changes.
- *
- * @param rotation The new rotation.
- */
- public void setRotationLw(int rotation);
-
- /**
* Called when the system is mostly done booting to set whether
* the system should go into safe mode.
*/
@@ -1487,8 +1465,6 @@
*/
public void enableScreenAfterBoot();
- public void setCurrentOrientationLw(@ActivityInfo.ScreenOrientation int newOrientation);
-
/**
* Call from application to perform haptic feedback on its window.
*/
@@ -1702,9 +1678,10 @@
/**
* Called when the configuration has changed, and it's safe to load new values from resources.
*/
- public void onConfigurationChanged();
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo);
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation);
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation,
+ int oldRotation, int newRotation);
/**
* Called when System UI has been started.
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 1508c9e..d5adb5e 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -204,6 +204,10 @@
}
}
+ public Handler getHandler() {
+ return mHandler;
+ }
+
/**
* Sets the current rotation.
*
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index d6ccf3b..556038f 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -328,6 +328,7 @@
PackageManager pm = context.getPackageManager();
String app = intent.getData().getSchemeSpecificPart();
sStatsd.informOnePackageRemoved(app, uid);
+ StatsLog.write(StatsLog.GENERIC_ATOM, uid, 1000);
}
} else {
PackageManager pm = context.getPackageManager();
@@ -336,6 +337,7 @@
String app = intent.getData().getSchemeSpecificPart();
PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
sStatsd.informOnePackage(app, uid, pi.getLongVersionCode());
+ StatsLog.write(StatsLog.GENERIC_ATOM, uid, 1001);
}
} catch (Exception e) {
Slog.w(TAG, "Failed to inform statsd of an app update", e);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 738b0ca..519881e 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -547,50 +547,50 @@
}
@Override
- public void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
+ public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
if (mBar != null) {
try {
- mBar.showFingerprintDialog(bundle, receiver);
+ mBar.showBiometricDialog(bundle, receiver);
} catch (RemoteException ex) {
}
}
}
@Override
- public void onFingerprintAuthenticated() {
+ public void onBiometricAuthenticated() {
if (mBar != null) {
try {
- mBar.onFingerprintAuthenticated();
+ mBar.onBiometricAuthenticated();
} catch (RemoteException ex) {
}
}
}
@Override
- public void onFingerprintHelp(String message) {
+ public void onBiometricHelp(String message) {
if (mBar != null) {
try {
- mBar.onFingerprintHelp(message);
+ mBar.onBiometricHelp(message);
} catch (RemoteException ex) {
}
}
}
@Override
- public void onFingerprintError(String error) {
+ public void onBiometricError(String error) {
if (mBar != null) {
try {
- mBar.onFingerprintError(error);
+ mBar.onBiometricError(error);
} catch (RemoteException ex) {
}
}
}
@Override
- public void hideFingerprintDialog() {
+ public void hideBiometricDialog() {
if (mBar != null) {
try {
- mBar.hideFingerprintDialog();
+ mBar.hideBiometricDialog();
} catch (RemoteException ex) {
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 218fcb7..d7d5cf8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -173,7 +173,8 @@
* IMPORTANT: No method from this class should ever be used without holding
* WindowManagerService.mWindowMap.
*/
-class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
+class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>
+ implements WindowManagerPolicy.DisplayContentInfo {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
/** Unique identifier of this stack. */
@@ -234,6 +235,8 @@
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final Display mDisplay;
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+ private final DisplayPolicy mDisplayPolicy;
+ private DisplayRotation mDisplayRotation;
DisplayFrames mDisplayFrames;
/**
@@ -304,8 +307,11 @@
private boolean mLayoutNeeded;
int pendingLayoutChanges;
int mDeferredRotationPauseCount;
+
// TODO(multi-display): remove some of the usages.
+ @VisibleForTesting
boolean isDefaultDisplay;
+
/**
* Flag indicating whether WindowManager should override info for this display in
* DisplayManager.
@@ -762,6 +768,13 @@
mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
initializeDisplayBaseInfo();
+ mDisplayPolicy = new DisplayPolicy(service);
+ mDisplayRotation = new DisplayRotation(service, this);
+ if (isDefaultDisplay) {
+ // The policy may be invoked right after here, so it requires the necessary default
+ // fields of this display content.
+ mService.mPolicy.setDefaultDisplay(this);
+ }
mDividerControllerLocked = new DockedStackDividerController(service, this);
mPinnedStackControllerLocked = new PinnedStackController(service, this);
@@ -801,7 +814,9 @@
// {@link DisplayContent} ready for use.
mDisplayReady = true;
- mInputMonitor = new InputMonitor(service, mDisplayId);
+ // TODO(b/112081256): Use independent InputMonitor.
+ mInputMonitor = isDefaultDisplay ? new InputMonitor(service, mDisplayId)
+ : mService.getDefaultDisplayContentLocked().mInputMonitor;
}
boolean isReady() {
@@ -905,7 +920,8 @@
appToken.onRemovedFromDisplay();
}
- Display getDisplay() {
+ @Override
+ public Display getDisplay() {
return mDisplay;
}
@@ -917,6 +933,20 @@
return mDisplayMetrics;
}
+ DisplayPolicy getDisplayPolicy() {
+ return mDisplayPolicy;
+ }
+
+ @Override
+ public DisplayRotation getDisplayRotation() {
+ return mDisplayRotation;
+ }
+
+ @VisibleForTesting
+ void setDisplayRotation(DisplayRotation displayRotation) {
+ mDisplayRotation = displayRotation;
+ }
+
int getRotation() {
return mRotation;
}
@@ -924,6 +954,7 @@
@VisibleForTesting
void setRotation(int newRotation) {
mRotation = newRotation;
+ mDisplayRotation.setRotation(newRotation);
}
int getLastOrientation() {
@@ -969,14 +1000,45 @@
mDeferredRotationPauseCount--;
if (mDeferredRotationPauseCount == 0) {
- final boolean changed = updateRotationUnchecked();
- if (changed) {
- mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
- }
+ updateRotationAndSendNewConfigIfNeeded();
}
}
/**
+ * If this is true we have updated our desired orientation, but not yet changed the real
+ * orientation our applied our screen rotation animation. For example, because a previous
+ * screen rotation was in progress.
+ *
+ * @return {@code true} if the there is an ongoing rotation change.
+ */
+ boolean rotationNeedsUpdate() {
+ final int lastOrientation = getLastOrientation();
+ final int oldRotation = getRotation();
+ final boolean oldAltOrientation = getAltOrientation();
+
+ final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
+ final boolean altOrientation = !mDisplayRotation.rotationHasCompatibleMetrics(
+ lastOrientation, rotation);
+ if (oldRotation == rotation && oldAltOrientation == altOrientation) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Update rotation of the display and send configuration if the rotation is changed.
+ *
+ * @return {@code true} if the rotation has been changed and the new config is sent.
+ */
+ boolean updateRotationAndSendNewConfigIfNeeded() {
+ final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
+ if (changed) {
+ mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
+ }
+ return changed;
+ }
+
+ /**
* Update rotation of the display.
*
* @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
@@ -1034,13 +1096,12 @@
final int oldRotation = mRotation;
final int lastOrientation = mLastOrientation;
final boolean oldAltOrientation = mAltOrientation;
- final int rotation = mService.mPolicy.rotationForOrientationLw(lastOrientation, oldRotation,
- isDefaultDisplay);
+ final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id="
+ mDisplayId + " based on lastOrientation=" + lastOrientation
+ " and oldRotation=" + oldRotation);
- boolean mayRotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(oldRotation,
- rotation);
+ boolean mayRotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(mDisplayRotation,
+ oldRotation, rotation);
if (mayRotateSeamlessly) {
final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
@@ -1071,7 +1132,7 @@
// an orientation that has different metrics than it expected.
// eg. Portrait instead of Landscape.
- final boolean altOrientation = !mService.mPolicy.rotationHasCompatibleMetricsLw(
+ final boolean altOrientation = !mDisplayRotation.rotationHasCompatibleMetrics(
lastOrientation, rotation);
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
@@ -1093,11 +1154,8 @@
mService.mWaitingForConfig = true;
}
- mRotation = rotation;
+ setRotation(rotation);
mAltOrientation = altOrientation;
- if (isDefaultDisplay) {
- mService.mPolicy.setRotationLw(rotation);
- }
mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
mService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,
@@ -1191,8 +1249,23 @@
}
void configureDisplayPolicy() {
- mService.mPolicy.setInitialDisplaySize(getDisplay(),
- mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity);
+ final int width = mBaseDisplayWidth;
+ final int height = mBaseDisplayHeight;
+ final int shortSize;
+ final int longSize;
+ if (width > height) {
+ shortSize = height;
+ longSize = width;
+ } else {
+ shortSize = width;
+ longSize = height;
+ }
+
+ final int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
+ final int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
+
+ mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
+ mDisplayPolicy.configure(width, height, shortSizeDp);
mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
@@ -2367,6 +2440,10 @@
pw.println();
mDisplayFrames.dump(prefix, pw);
pw.println();
+ mDisplayPolicy.dump(prefix, pw);
+ pw.println();
+ mDisplayRotation.dump(prefix, pw);
+ pw.println();
mInputMonitor.dump(pw, " ");
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
new file mode 100644
index 0000000..9151ddf
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -0,0 +1,260 @@
+/*
+ * 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.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED;
+import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE;
+import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.content.Intent;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.server.policy.WindowManagerPolicy.ScreenOnListener;
+import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
+
+import java.io.PrintWriter;
+
+/**
+ * The policy that provides the basic behaviors and states of a display to show UI.
+ */
+public class DisplayPolicy {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayPolicy" : TAG_WM;
+
+ private final WindowManagerService mService;
+ private final Object mLock;
+
+ private final boolean mCarDockEnablesAccelerometer;
+ private final boolean mDeskDockEnablesAccelerometer;
+
+ private volatile int mLidState = LID_ABSENT;
+ private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+ private volatile boolean mHdmiPlugged;
+
+ private volatile boolean mHasNavigationBar;
+ // Can the navigation bar ever move to the side?
+ private volatile boolean mNavigationBarCanMove;
+
+ // Written by vr manager thread, only read in this class.
+ private volatile boolean mPersistentVrModeEnabled;
+
+ private volatile boolean mAwake;
+ private volatile boolean mScreenOnEarly;
+ private volatile boolean mScreenOnFully;
+ private volatile ScreenOnListener mScreenOnListener;
+
+ private volatile boolean mKeyguardDrawComplete;
+ private volatile boolean mWindowManagerDrawComplete;
+
+ DisplayPolicy(WindowManagerService service) {
+ mService = service;
+ mLock = service.getWindowManagerLock();
+ mCarDockEnablesAccelerometer = service.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_carDockEnablesAccelerometer);
+ mDeskDockEnablesAccelerometer = service.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
+ }
+
+ void configure(int width, int height, int shortSizeDp) {
+ // Allow the navigation bar to move on non-square small devices (phones).
+ mNavigationBarCanMove = width != height && shortSizeDp < 600;
+
+ mHasNavigationBar = mService.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_showNavigationBar);
+
+ // Allow a system property to override this. Used by the emulator.
+ // See also hasNavigationBar().
+ String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+ if ("1".equals(navBarOverride)) {
+ mHasNavigationBar = false;
+ } else if ("0".equals(navBarOverride)) {
+ mHasNavigationBar = true;
+ }
+ }
+
+ public void setHdmiPlugged(boolean plugged) {
+ setHdmiPlugged(plugged, false /* force */);
+ }
+
+ public void setHdmiPlugged(boolean plugged, boolean force) {
+ if (force || mHdmiPlugged != plugged) {
+ mHdmiPlugged = plugged;
+ mService.updateRotation(true /* alwaysSendConfiguration */, true /* forceRelayout */);
+ final Intent intent = new Intent(ACTION_HDMI_PLUGGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
+ mService.mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
+ }
+
+ boolean isHdmiPlugged() {
+ return mHdmiPlugged;
+ }
+
+ boolean isCarDockEnablesAccelerometer() {
+ return mCarDockEnablesAccelerometer;
+ }
+
+ boolean isDeskDockEnablesAccelerometer() {
+ return mDeskDockEnablesAccelerometer;
+ }
+
+ public void setPersistentVrModeEnabled(boolean persistentVrModeEnabled) {
+ mPersistentVrModeEnabled = persistentVrModeEnabled;
+ }
+
+ public boolean isPersistentVrModeEnabled() {
+ return mPersistentVrModeEnabled;
+ }
+
+ public void setDockMode(int dockMode) {
+ mDockMode = dockMode;
+ }
+
+ public int getDockMode() {
+ return mDockMode;
+ }
+
+ public boolean hasNavigationBar() {
+ return mHasNavigationBar;
+ }
+
+ public boolean navigationBarCanMove() {
+ return mNavigationBarCanMove;
+ }
+
+ public void setLidState(int lidState) {
+ mLidState = lidState;
+ }
+
+ public int getLidState() {
+ return mLidState;
+ }
+
+ public void setAwake(boolean awake) {
+ mAwake = awake;
+ }
+
+ public boolean isAwake() {
+ return mAwake;
+ }
+
+ public boolean isScreenOnEarly() {
+ return mScreenOnEarly;
+ }
+
+ public boolean isScreenOnFully() {
+ return mScreenOnFully;
+ }
+
+ public boolean isKeyguardDrawComplete() {
+ return mKeyguardDrawComplete;
+ }
+
+ public boolean isWindowManagerDrawComplete() {
+ return mWindowManagerDrawComplete;
+ }
+
+ public ScreenOnListener getScreenOnListener() {
+ return mScreenOnListener;
+ }
+
+ public void screenTurnedOn(ScreenOnListener screenOnListener) {
+ synchronized (mLock) {
+ mScreenOnEarly = true;
+ mScreenOnFully = false;
+ mKeyguardDrawComplete = false;
+ mWindowManagerDrawComplete = false;
+ mScreenOnListener = screenOnListener;
+ }
+ }
+
+ public void screenTurnedOff() {
+ synchronized (mLock) {
+ mScreenOnEarly = false;
+ mScreenOnFully = false;
+ mKeyguardDrawComplete = false;
+ mWindowManagerDrawComplete = false;
+ mScreenOnListener = null;
+ }
+ }
+
+ /** Return false if we are not awake yet or we have already informed of this event. */
+ public boolean finishKeyguardDrawn() {
+ synchronized (mLock) {
+ if (!mScreenOnEarly || mKeyguardDrawComplete) {
+ return false;
+ }
+
+ mKeyguardDrawComplete = true;
+ mWindowManagerDrawComplete = false;
+ }
+ return true;
+ }
+
+ /** Return false if screen is not turned on or we did already handle this case earlier. */
+ public boolean finishWindowsDrawn() {
+ synchronized (mLock) {
+ if (!mScreenOnEarly || mWindowManagerDrawComplete) {
+ return false;
+ }
+
+ mWindowManagerDrawComplete = true;
+ }
+ return true;
+ }
+
+ /** Return false if it is not ready to turn on. */
+ public boolean finishScreenTurningOn() {
+ synchronized (mLock) {
+ if (DEBUG_SCREEN_ON) Slog.d(TAG,
+ "finishScreenTurningOn: mAwake=" + mAwake
+ + ", mScreenOnEarly=" + mScreenOnEarly
+ + ", mScreenOnFully=" + mScreenOnFully
+ + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
+ + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+
+ if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete
+ || (mAwake && !mKeyguardDrawComplete)) {
+ return false;
+ }
+
+ if (DEBUG_SCREEN_ON) Slog.i(TAG, "Finished screen turning on...");
+ mScreenOnListener = null;
+ mScreenOnFully = true;
+ }
+ return true;
+ }
+
+ void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "DisplayPolicy");
+ pw.print(prefix + " mCarDockEnablesAccelerometer=" + mCarDockEnablesAccelerometer);
+ pw.println(" mDeskDockEnablesAccelerometer=" + mDeskDockEnablesAccelerometer);
+ pw.print(prefix + " mDockMode=" + Intent.dockStateToString(mDockMode));
+ pw.println(" mLidState=" + WindowManagerFuncs.lidStateToString(mLidState));
+ pw.print(prefix + " mAwake=" + mAwake);
+ pw.print(" mScreenOnEarly=" + mScreenOnEarly);
+ pw.println(" mScreenOnFully=" + mScreenOnFully);
+ pw.print(prefix + " mKeyguardDrawComplete=" + mKeyguardDrawComplete);
+ pw.println(" mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+ pw.println(prefix + " mHdmiPlugged=" + mHdmiPlugged);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
new file mode 100644
index 0000000..685c444
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -0,0 +1,881 @@
+/*
+ * 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 com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.hardware.power.V1_0.PowerHint;
+import android.os.Handler;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.Surface;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+import com.android.server.UiThread;
+import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.policy.WindowOrientationListener;
+import com.android.server.statusbar.StatusBarManagerInternal;
+
+import java.io.PrintWriter;
+
+/**
+ * Defines the mapping between orientation and rotation of a display.
+ * Non-public methods are assumed to run inside WM lock.
+ */
+public class DisplayRotation {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;
+
+ private final WindowManagerService mService;
+ private final DisplayPolicy mDisplayPolicy;
+ private final Context mContext;
+ private final Object mLock;
+
+ public final boolean isDefaultDisplay;
+ private final boolean mSupportAutoRotation;
+ private final int mLidOpenRotation;
+ private final int mCarDockRotation;
+ private final int mDeskDockRotation;
+ private final int mUndockedHdmiRotation;
+
+ private OrientationListener mOrientationListener;
+ private StatusBarManagerInternal mStatusBarManagerInternal;
+ private SettingsObserver mSettingsObserver;
+
+ // Default display does not rotate, apps that require non-default orientation will have to
+ // have the orientation emulated.
+ private boolean mForceDefaultOrientation;
+
+ private int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+ @VisibleForTesting
+ int mLandscapeRotation; // default landscape
+ @VisibleForTesting
+ int mSeascapeRotation; // "other" landscape, 180 degrees from mLandscapeRotation
+ @VisibleForTesting
+ int mPortraitRotation; // default portrait
+ @VisibleForTesting
+ int mUpsideDownRotation; // "other" portrait
+
+ // Behavior of rotation suggestions. (See Settings.Secure.SHOW_ROTATION_SUGGESTION)
+ private int mShowRotationSuggestions;
+
+ private int mAllowAllRotations = -1;
+ private int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+ private int mUserRotation = Surface.ROTATION_0;
+
+ private int mDemoHdmiRotation;
+ private int mDemoRotation;
+ private boolean mDemoHdmiRotationLock;
+ private boolean mDemoRotationLock;
+
+ DisplayRotation(WindowManagerService service, DisplayContent displayContent) {
+ this(service, displayContent, displayContent.getDisplayPolicy(),
+ service.mContext, service.getWindowManagerLock());
+ }
+
+ @VisibleForTesting
+ DisplayRotation(WindowManagerService service, DisplayContent displayContent,
+ DisplayPolicy displayPolicy, Context context, Object lock) {
+ mService = service;
+ mDisplayPolicy = displayPolicy;
+ mContext = context;
+ mLock = lock;
+ isDefaultDisplay = displayContent.isDefaultDisplay;
+
+ mSupportAutoRotation = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_supportAutoRotation);
+ mLidOpenRotation = readRotation(
+ com.android.internal.R.integer.config_lidOpenRotation);
+ mCarDockRotation = readRotation(
+ com.android.internal.R.integer.config_carDockRotation);
+ mDeskDockRotation = readRotation(
+ com.android.internal.R.integer.config_deskDockRotation);
+ mUndockedHdmiRotation = readRotation(
+ com.android.internal.R.integer.config_undockedHdmiRotation);
+
+ if (isDefaultDisplay) {
+ final Handler uiHandler = UiThread.getHandler();
+ mOrientationListener = new OrientationListener(mContext, uiHandler);
+ mOrientationListener.setCurrentRotation(displayContent.getRotation());
+ mSettingsObserver = new SettingsObserver(uiHandler);
+ mSettingsObserver.observe();
+ }
+ }
+
+ private int readRotation(int resID) {
+ try {
+ final int rotation = mContext.getResources().getInteger(resID);
+ switch (rotation) {
+ case 0:
+ return Surface.ROTATION_0;
+ case 90:
+ return Surface.ROTATION_90;
+ case 180:
+ return Surface.ROTATION_180;
+ case 270:
+ return Surface.ROTATION_270;
+ }
+ } catch (Resources.NotFoundException e) {
+ // fall through
+ }
+ return -1;
+ }
+
+ void configure(int width, int height, int shortSizeDp, int longSizeDp) {
+ final Resources res = mContext.getResources();
+ if (width > height) {
+ mLandscapeRotation = Surface.ROTATION_0;
+ mSeascapeRotation = Surface.ROTATION_180;
+ if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ mPortraitRotation = Surface.ROTATION_90;
+ mUpsideDownRotation = Surface.ROTATION_270;
+ } else {
+ mPortraitRotation = Surface.ROTATION_270;
+ mUpsideDownRotation = Surface.ROTATION_90;
+ }
+ } else {
+ mPortraitRotation = Surface.ROTATION_0;
+ mUpsideDownRotation = Surface.ROTATION_180;
+ if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ mLandscapeRotation = Surface.ROTATION_270;
+ mSeascapeRotation = Surface.ROTATION_90;
+ } else {
+ mLandscapeRotation = Surface.ROTATION_90;
+ mSeascapeRotation = Surface.ROTATION_270;
+ }
+ }
+
+ // For demo purposes, allow the rotation of the HDMI display to be controlled.
+ // By default, HDMI locks rotation to landscape.
+ if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
+ mDemoHdmiRotation = mPortraitRotation;
+ } else {
+ mDemoHdmiRotation = mLandscapeRotation;
+ }
+ mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
+
+ // For demo purposes, allow the rotation of the remote display to be controlled.
+ // By default, remote display locks rotation to landscape.
+ if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) {
+ mDemoRotation = mPortraitRotation;
+ } else {
+ mDemoRotation = mLandscapeRotation;
+ }
+ mDemoRotationLock = SystemProperties.getBoolean("persist.demo.rotationlock", false);
+
+ // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
+ // http://developer.android.com/guide/practices/screens_support.html#range
+ // For car, ignore the dp limitation. It's physically impossible to rotate the car's screen
+ // so if the orientation is forced, we need to respect that no matter what.
+ final boolean isCar = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE);
+ // For TV, it's usually 960dp x 540dp, ignore the size limitation.
+ // so if the orientation is forced, we need to respect that no matter what.
+ final boolean isTv = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LEANBACK);
+ mForceDefaultOrientation = ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar || isTv) &&
+ res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
+ // For debug purposes the next line turns this feature off with:
+ // $ adb shell setprop config.override_forced_orient true
+ // $ adb shell wm size reset
+ !"true".equals(SystemProperties.get("config.override_forced_orient"));
+ }
+
+ void setRotation(int rotation) {
+ if (mOrientationListener != null) {
+ mOrientationListener.setCurrentRotation(rotation);
+ }
+ }
+
+ void setCurrentOrientation(int newOrientation) {
+ if (newOrientation != mCurrentAppOrientation) {
+ mCurrentAppOrientation = newOrientation;
+ if (isDefaultDisplay) {
+ updateOrientationListenerLw();
+ }
+ }
+ }
+
+ /** @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true. */
+ boolean isDefaultOrientationForced() {
+ return mForceDefaultOrientation;
+ }
+
+ public int getLandscapeRotation() {
+ return mLandscapeRotation;
+ }
+
+ public int getSeascapeRotation() {
+ return mSeascapeRotation;
+ }
+
+ public int getPortraitRotation() {
+ return mPortraitRotation;
+ }
+
+ public int getUpsideDownRotation() {
+ return mUpsideDownRotation;
+ }
+
+ public int getCurrentAppOrientation() {
+ return mCurrentAppOrientation;
+ }
+
+ public DisplayPolicy getDisplayPolicy() {
+ return mDisplayPolicy;
+ }
+
+ public WindowOrientationListener getOrientationListener() {
+ return mOrientationListener;
+ }
+
+ public int getUserRotation() {
+ return mUserRotation;
+ }
+
+ public int getUserRotationMode() {
+ return mUserRotationMode;
+ }
+
+ public void updateOrientationListener() {
+ synchronized (mLock) {
+ updateOrientationListenerLw();
+ }
+ }
+
+ /**
+ * Various use cases for invoking this function:
+ * <li>Screen turning off, should always disable listeners if already enabled.</li>
+ * <li>Screen turned on and current app has sensor based orientation, enable listeners
+ * if not already enabled.</li>
+ * <li>Screen turned on and current app does not have sensor orientation, disable listeners
+ * if already enabled.</li>
+ * <li>Screen turning on and current app has sensor based orientation, enable listeners
+ * if needed.</li>
+ * <li>screen turning on and current app has nosensor based orientation, do nothing.</li>
+ */
+ private void updateOrientationListenerLw() {
+ if (mOrientationListener == null || !mOrientationListener.canDetectOrientation()) {
+ // If sensor is turned off or nonexistent for some reason.
+ return;
+ }
+
+ final boolean screenOnEarly = mDisplayPolicy.isScreenOnEarly();
+ final boolean awake = mDisplayPolicy.isAwake();
+ final boolean keyguardDrawComplete = mDisplayPolicy.isKeyguardDrawComplete();
+ final boolean windowManagerDrawComplete = mDisplayPolicy.isWindowManagerDrawComplete();
+
+ // Could have been invoked due to screen turning on or off or
+ // change of the currently visible window's orientation.
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "screenOnEarly=" + screenOnEarly
+ + ", awake=" + awake + ", currentAppOrientation=" + mCurrentAppOrientation
+ + ", orientationSensorEnabled=" + mOrientationListener.mEnabled
+ + ", keyguardDrawComplete=" + keyguardDrawComplete
+ + ", windowManagerDrawComplete=" + windowManagerDrawComplete);
+
+ boolean disable = true;
+ // Note: We postpone the rotating of the screen until the keyguard as well as the
+ // window manager have reported a draw complete or the keyguard is going away in dismiss
+ // mode.
+ if (screenOnEarly && awake && ((keyguardDrawComplete && windowManagerDrawComplete))) {
+ if (needSensorRunning()) {
+ disable = false;
+ // Enable listener if not already enabled.
+ if (!mOrientationListener.mEnabled) {
+ // Don't clear the current sensor orientation if the keyguard is going away in
+ // dismiss mode. This allows window manager to use the last sensor reading to
+ // determine the orientation vs. falling back to the last known orientation if
+ // the sensor reading was cleared which can cause it to relaunch the app that
+ // will show in the wrong orientation first before correcting leading to app
+ // launch delays.
+ mOrientationListener.enable(true /* clearCurrentRotation */);
+ }
+ }
+ }
+ // Check if sensors need to be disabled.
+ if (disable && mOrientationListener.mEnabled) {
+ mOrientationListener.disable();
+ }
+ }
+
+ /**
+ * We always let the sensor be switched on by default except when
+ * the user has explicitly disabled sensor based rotation or when the
+ * screen is switched off.
+ */
+ private boolean needSensorRunning() {
+ if (mSupportAutoRotation) {
+ if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
+ // If the application has explicitly requested to follow the
+ // orientation, then we need to turn the sensor on.
+ return true;
+ }
+ }
+
+ final int dockMode = mDisplayPolicy.getDockMode();
+ if ((mDisplayPolicy.isCarDockEnablesAccelerometer()
+ && dockMode == Intent.EXTRA_DOCK_STATE_CAR)
+ || (mDisplayPolicy.isDeskDockEnablesAccelerometer()
+ && (dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) {
+ // Enable accelerometer if we are docked in a dock that enables accelerometer
+ // orientation management.
+ return true;
+ }
+
+ if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
+ // If the setting for using the sensor by default is enabled, then
+ // we will always leave it on. Note that the user could go to
+ // a window that forces an orientation that does not use the
+ // sensor and in theory we could turn it off... however, when next
+ // turning it on we won't have a good value for the current
+ // orientation for a little bit, which can cause orientation
+ // changes to lag, so we'd like to keep it always on. (It will
+ // still be turned off when the screen is off.)
+
+ // When locked we can provide rotation suggestions users can approve to change the
+ // current screen rotation. To do this the sensor needs to be running.
+ return mSupportAutoRotation &&
+ mShowRotationSuggestions == Settings.Secure.SHOW_ROTATION_SUGGESTIONS_ENABLED;
+ }
+ return mSupportAutoRotation;
+ }
+
+ /**
+ * Given an orientation constant, returns the appropriate surface rotation,
+ * taking into account sensors, docking mode, rotation lock, and other factors.
+ *
+ * @param orientation An orientation constant, such as
+ * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+ * @param lastRotation The most recently used rotation.
+ * @param defaultDisplay Flag indicating whether the rotation is computed for the default
+ * display. Currently for all non-default displays sensors, docking mode,
+ * rotation lock and other factors are ignored.
+ * @return The surface rotation to use.
+ */
+ int rotationForOrientation(int orientation, int lastRotation) {
+ if (DEBUG_ORIENTATION) {
+ Slog.v(TAG, "rotationForOrientation(orient="
+ + orientation + ", last=" + lastRotation
+ + "); user=" + mUserRotation + " "
+ + (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
+ ? "USER_ROTATION_LOCKED" : "")
+ );
+ }
+
+ if (mForceDefaultOrientation) {
+ return Surface.ROTATION_0;
+ }
+
+ int sensorRotation = mOrientationListener != null
+ ? mOrientationListener.getProposedRotation() // may be -1
+ : -1;
+ if (sensorRotation < 0) {
+ sensorRotation = lastRotation;
+ }
+
+ final int lidState = mDisplayPolicy.getLidState();
+ final int dockMode = mDisplayPolicy.getDockMode();
+ final boolean hdmiPlugged = mDisplayPolicy.isHdmiPlugged();
+ final boolean carDockEnablesAccelerometer =
+ mDisplayPolicy.isCarDockEnablesAccelerometer();
+ final boolean deskDockEnablesAccelerometer =
+ mDisplayPolicy.isDeskDockEnablesAccelerometer();
+
+ final int preferredRotation;
+ if (!isDefaultDisplay) {
+ // For secondary displays we ignore things like displays sensors, docking mode and
+ // rotation lock, and always prefer a default rotation.
+ preferredRotation = Surface.ROTATION_0;
+ } else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
+ // Ignore sensor when lid switch is open and rotation is forced.
+ preferredRotation = mLidOpenRotation;
+ } else if (dockMode == Intent.EXTRA_DOCK_STATE_CAR
+ && (carDockEnablesAccelerometer || mCarDockRotation >= 0)) {
+ // Ignore sensor when in car dock unless explicitly enabled.
+ // This case can override the behavior of NOSENSOR, and can also
+ // enable 180 degree rotation while docked.
+ preferredRotation = carDockEnablesAccelerometer ? sensorRotation : mCarDockRotation;
+ } else if ((dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
+ && (deskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
+ // Ignore sensor when in desk dock unless explicitly enabled.
+ // This case can override the behavior of NOSENSOR, and can also
+ // enable 180 degree rotation while docked.
+ preferredRotation = deskDockEnablesAccelerometer ? sensorRotation : mDeskDockRotation;
+ } else if (hdmiPlugged && mDemoHdmiRotationLock) {
+ // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.
+ // Note that the dock orientation overrides the HDMI orientation.
+ preferredRotation = mDemoHdmiRotation;
+ } else if (hdmiPlugged && dockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
+ && mUndockedHdmiRotation >= 0) {
+ // Ignore sensor when plugged into HDMI and an undocked orientation has
+ // been specified in the configuration (only for legacy devices without
+ // full multi-display support).
+ // Note that the dock orientation overrides the HDMI orientation.
+ preferredRotation = mUndockedHdmiRotation;
+ } else if (mDemoRotationLock) {
+ // Ignore sensor when demo rotation lock is enabled.
+ // Note that the dock orientation and HDMI rotation lock override this.
+ preferredRotation = mDemoRotation;
+ } else if (mDisplayPolicy.isPersistentVrModeEnabled()) {
+ // While in VR, apps always prefer a portrait rotation. This does not change
+ // any apps that explicitly set landscape, but does cause sensors be ignored,
+ // and ignored any orientation lock that the user has set (this conditional
+ // should remain above the ORIENTATION_LOCKED conditional below).
+ preferredRotation = mPortraitRotation;
+ } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
+ // Application just wants to remain locked in the last rotation.
+ preferredRotation = lastRotation;
+ } else if (!mSupportAutoRotation) {
+ // If we don't support auto-rotation then bail out here and ignore
+ // the sensor and any rotation lock settings.
+ preferredRotation = -1;
+ } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+ && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
+ // Otherwise, use sensor only if requested by the application or enabled
+ // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
+ if (mAllowAllRotations < 0) {
+ // Can't read this during init() because the context doesn't
+ // have display metrics at that time so we cannot determine
+ // tablet vs. phone then.
+ mAllowAllRotations = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
+ }
+ if (sensorRotation != Surface.ROTATION_180
+ || mAllowAllRotations == 1
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
+ preferredRotation = sensorRotation;
+ } else {
+ preferredRotation = lastRotation;
+ }
+ } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
+ && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
+ // Apply rotation lock. Does not apply to NOSENSOR.
+ // The idea is that the user rotation expresses a weak preference for the direction
+ // of gravity and as NOSENSOR is never affected by gravity, then neither should
+ // NOSENSOR be affected by rotation lock (although it will be affected by docks).
+ preferredRotation = mUserRotation;
+ } else {
+ // No overriding preference.
+ // We will do exactly what the application asked us to do.
+ preferredRotation = -1;
+ }
+
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ // Return portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mPortraitRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ // Return landscape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mLandscapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ // Return reverse portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mUpsideDownRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ // Return seascape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mSeascapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ // Return either landscape rotation.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ if (isLandscapeOrSeascape(lastRotation)) {
+ return lastRotation;
+ }
+ return mLandscapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // Return either portrait rotation.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ if (isAnyPortrait(lastRotation)) {
+ return lastRotation;
+ }
+ return mPortraitRotation;
+
+ default:
+ // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
+ // just return the preferred orientation we already calculated.
+ if (preferredRotation >= 0) {
+ return preferredRotation;
+ }
+ return Surface.ROTATION_0;
+ }
+ }
+
+ private boolean isLandscapeOrSeascape(int rotation) {
+ return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
+ }
+
+ private boolean isAnyPortrait(int rotation) {
+ return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
+ }
+
+ /**
+ * Given an orientation constant and a rotation, returns true if the rotation
+ * has compatible metrics to the requested orientation. For example, if
+ * the application requested landscape and got seascape, then the rotation
+ * has compatible metrics; if the application requested portrait and got landscape,
+ * then the rotation has incompatible metrics; if the application did not specify
+ * a preference, then anything goes.
+ *
+ * @param orientation An orientation constant, such as
+ * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+ * @param rotation The rotation to check.
+ * @return True if the rotation is compatible with the requested orientation.
+ */
+ boolean rotationHasCompatibleMetrics(int orientation, int rotation) {
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ return isAnyPortrait(rotation);
+
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ return isLandscapeOrSeascape(rotation);
+
+ default:
+ return true;
+ }
+ }
+
+ private boolean isValidRotationChoice(final int preferredRotation) {
+ // Determine if the given app orientation is compatible with the provided rotation choice.
+ switch (mCurrentAppOrientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
+ // Works with any of the 4 rotations.
+ return preferredRotation >= 0;
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // It's possible for the user pref to be set at 180 because of FULL_USER. This would
+ // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
+ // but never to go to 180.
+ return preferredRotation == mPortraitRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ // Works landscape or seascape.
+ return isLandscapeOrSeascape(preferredRotation);
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+ // Works with any rotation except upside down.
+ return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
+ }
+
+ return false;
+ }
+
+ private boolean isRotationChoicePossible(int orientation) {
+ // Rotation choice is only shown when the user is in locked mode.
+ if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
+
+ // We should only enable rotation choice if the rotation isn't forced by the lid, dock,
+ // demo, hdmi, vr, etc mode.
+
+ // Determine if the rotation is currently forced.
+ if (mForceDefaultOrientation) {
+ return false; // Rotation is forced to default orientation.
+ }
+
+ final int lidState = mDisplayPolicy.getLidState();
+ if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
+ return false; // Rotation is forced mLidOpenRotation.
+ }
+
+ final int dockMode = mDisplayPolicy.getDockMode();
+ final boolean carDockEnablesAccelerometer = false;
+ if (dockMode == Intent.EXTRA_DOCK_STATE_CAR && !carDockEnablesAccelerometer) {
+ return false; // Rotation forced to mCarDockRotation.
+ }
+
+ final boolean deskDockEnablesAccelerometer =
+ mDisplayPolicy.isDeskDockEnablesAccelerometer();
+ if ((dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
+ && !deskDockEnablesAccelerometer) {
+ return false; // Rotation forced to mDeskDockRotation.
+ }
+
+ final boolean hdmiPlugged = mDisplayPolicy.isHdmiPlugged();
+ if (hdmiPlugged && mDemoHdmiRotationLock) {
+ return false; // Rotation forced to mDemoHdmiRotation.
+
+ } else if (hdmiPlugged && dockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
+ && mUndockedHdmiRotation >= 0) {
+ return false; // Rotation forced to mUndockedHdmiRotation.
+
+ } else if (mDemoRotationLock) {
+ return false; // Rotation forced to mDemoRotation.
+
+ } else if (mDisplayPolicy.isPersistentVrModeEnabled()) {
+ return false; // Rotation forced to mPortraitRotation.
+
+ } else if (!mSupportAutoRotation) {
+ return false;
+ }
+
+ // Ensure that some rotation choice is possible for the given orientation.
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // NOSENSOR description is ambiguous, in reality WM ignores user choice.
+ return true;
+ }
+
+ // Rotation is forced, should be controlled by system.
+ return false;
+ }
+
+ /** Notify the StatusBar that system rotation suggestion has changed. */
+ private void sendProposedRotationChangeToStatusBarInternal(int rotation, boolean isValid) {
+ if (mStatusBarManagerInternal == null) {
+ mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
+ }
+ if (mStatusBarManagerInternal != null) {
+ mStatusBarManagerInternal.onProposedRotationChanged(rotation, isValid);
+ }
+ }
+
+ private static String allowAllRotationsToString(int allowAll) {
+ switch (allowAll) {
+ case -1:
+ return "unknown";
+ case 0:
+ return "false";
+ case 1:
+ return "true";
+ default:
+ return Integer.toString(allowAll);
+ }
+ }
+
+ public void onUserSwitch() {
+ if (mSettingsObserver != null) {
+ mSettingsObserver.onChange(false);
+ }
+ }
+
+ /** Return whether the rotation settings has changed. */
+ private boolean updateSettings() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ boolean shouldUpdateRotation = false;
+
+ synchronized (mLock) {
+ boolean shouldUpdateOrientationListener = false;
+
+ // Configure rotation suggestions.
+ final int showRotationSuggestions = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
+ Settings.Secure.SHOW_ROTATION_SUGGESTIONS_DEFAULT,
+ UserHandle.USER_CURRENT);
+ if (mShowRotationSuggestions != showRotationSuggestions) {
+ mShowRotationSuggestions = showRotationSuggestions;
+ shouldUpdateOrientationListener = true;
+ }
+
+ // Configure rotation lock.
+ final int userRotation = Settings.System.getIntForUser(resolver,
+ Settings.System.USER_ROTATION, Surface.ROTATION_0,
+ UserHandle.USER_CURRENT);
+ if (mUserRotation != userRotation) {
+ mUserRotation = userRotation;
+ shouldUpdateRotation = true;
+ }
+
+ final int userRotationMode = Settings.System.getIntForUser(resolver,
+ Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0
+ ? WindowManagerPolicy.USER_ROTATION_FREE
+ : WindowManagerPolicy.USER_ROTATION_LOCKED;
+ if (mUserRotationMode != userRotationMode) {
+ mUserRotationMode = userRotationMode;
+ shouldUpdateOrientationListener = true;
+ shouldUpdateRotation = true;
+ }
+
+ if (shouldUpdateOrientationListener) {
+ updateOrientationListenerLw(); // Enable or disable the orientation listener.
+ }
+ }
+
+ return shouldUpdateRotation;
+ }
+
+ void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "DisplayRotation");
+ pw.println(prefix + " mCurrentAppOrientation="
+ + ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
+ pw.print(prefix + " mLandscapeRotation=" + Surface.rotationToString(mLandscapeRotation));
+ pw.println(" mSeascapeRotation=" + Surface.rotationToString(mSeascapeRotation));
+ pw.print(prefix + " mPortraitRotation=" + Surface.rotationToString(mPortraitRotation));
+ pw.println(" mUpsideDownRotation=" + Surface.rotationToString(mUpsideDownRotation));
+
+ pw.print(prefix + " mSupportAutoRotation=" + mSupportAutoRotation);
+ if (mOrientationListener != null) {
+ pw.print(" mOrientationSensorEnabled=" + mOrientationListener.mEnabled);
+ }
+ pw.println();
+
+ pw.print(prefix + " mCarDockRotation=" + Surface.rotationToString(mCarDockRotation));
+ pw.println(" mDeskDockRotation=" + Surface.rotationToString(mDeskDockRotation));
+ pw.print(prefix + " mUserRotationMode="
+ + WindowManagerPolicy.userRotationModeToString(mUserRotationMode));
+ pw.print(" mUserRotation=" + Surface.rotationToString(mUserRotation));
+ pw.println(" mAllowAllRotations=" + allowAllRotationsToString(mAllowAllRotations));
+
+ pw.print(prefix + " mDemoHdmiRotation=" + Surface.rotationToString(mDemoHdmiRotation));
+ pw.print(" mDemoHdmiRotationLock=" + mDemoHdmiRotationLock);
+ pw.println(" mUndockedHdmiRotation=" + Surface.rotationToString(mUndockedHdmiRotation));
+ pw.println(prefix + " mLidOpenRotation=" + Surface.rotationToString(mLidOpenRotation));
+ }
+
+ private class OrientationListener extends WindowOrientationListener {
+ final SparseArray<Runnable> mRunnableCache = new SparseArray<>(5);
+ boolean mEnabled;
+
+ OrientationListener(Context context, Handler handler) {
+ super(context, handler);
+ }
+
+ private class UpdateRunnable implements Runnable {
+ final int mRotation;
+
+ UpdateRunnable(int rotation) {
+ mRotation = rotation;
+ }
+
+ @Override
+ public void run() {
+ // Send interaction hint to improve redraw performance.
+ mService.mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
+ if (isRotationChoicePossible(mCurrentAppOrientation)) {
+ final boolean isValid = isValidRotationChoice(mRotation);
+ sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
+ } else {
+ mService.updateRotation(false /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ }
+ }
+ }
+
+ @Override
+ public void onProposedRotationChanged(int rotation) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
+ Runnable r = mRunnableCache.get(rotation, null);
+ if (r == null) {
+ r = new UpdateRunnable(rotation);
+ mRunnableCache.put(rotation, r);
+ }
+ getHandler().post(r);
+ }
+
+ @Override
+ public void enable(boolean clearCurrentRotation) {
+ super.enable(clearCurrentRotation);
+ mEnabled = true;
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Enabling listeners");
+ }
+
+ @Override
+ public void disable() {
+ super.disable();
+ mEnabled = false;
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Disabling listeners");
+ }
+ }
+
+ private class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.SHOW_ROTATION_SUGGESTIONS), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.ACCELEROMETER_ROTATION), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.USER_ROTATION), false, this,
+ UserHandle.USER_ALL);
+ updateSettings();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ if (updateSettings()) {
+ mService.updateRotation(true /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index d53a21b..c4beb55 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -399,7 +399,8 @@
this.inDrag = inDrag;
wallpaperController = mService.mRoot.mWallpaperController;
- mService.mRoot.getDisplayContent(mDisplayId).forAllWindows(this,
+ // TODO(b/112081256): Use independent InputMonitor for each display.
+ mService.mRoot/*.getDisplayContent(mDisplayId)*/.forAllWindows(this,
true /* traverseTopToBottom */);
if (mAddWallpaperInputConsumerHandle) {
// No visible wallpaper found, add the wallpaper input consumer at the end.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 3df4eb7..ca4fa64 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -134,6 +134,9 @@
// transaction from the global transaction.
private final SurfaceControl.Transaction mDisplayTransaction = new SurfaceControl.Transaction();
+ private final Consumer<DisplayContent> mDisplayContentConfigChangesConsumer =
+ mService.mPolicy::onConfigurationChanged;
+
private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
if (w.mHasSurface) {
try {
@@ -379,7 +382,7 @@
prepareFreezingTaskBounds();
super.onConfigurationChanged(newParentConfig);
- mService.mPolicy.onConfigurationChanged();
+ forAllDisplays(mDisplayContentConfigChangesConsumer);
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9b792e3..ea68e17 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2480,10 +2480,7 @@
dc.setLastOrientation(req);
//send a message to Policy indicating orientation change to take
//action like disabling/enabling sensors etc.,
- // TODO(multi-display): Implement policy for secondary displays.
- if (dc.isDefaultDisplay) {
- mPolicy.setCurrentOrientationLw(req);
- }
+ dc.getDisplayRotation().setCurrentOrientation(req);
return dc.updateRotationUnchecked(forceUpdate);
}
return false;
@@ -2492,27 +2489,6 @@
}
}
- // If this is true we have updated our desired orientation, but not yet
- // changed the real orientation our applied our screen rotation animation.
- // For example, because a previous screen rotation was in progress.
- boolean rotationNeedsUpdateLocked() {
- // TODO(multi-display): Check for updates on all displays. Need to have per-display policy
- // to implement WindowManagerPolicy#rotationForOrientationLw() correctly.
- final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
- final int lastOrientation = defaultDisplayContent.getLastOrientation();
- final int oldRotation = defaultDisplayContent.getRotation();
- final boolean oldAltOrientation = defaultDisplayContent.getAltOrientation();
-
- final int rotation = mPolicy.rotationForOrientationLw(lastOrientation, oldRotation,
- true /* defaultDisplay */);
- boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
- lastOrientation, rotation);
- if (oldRotation == rotation && oldAltOrientation == altOrientation) {
- return false;
- }
- return true;
- }
-
@Override
public int[] setNewDisplayOverrideConfiguration(Configuration overrideConfig, int displayId) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "setNewDisplayOverrideConfiguration()")) {
@@ -3841,28 +3817,31 @@
long origId = Binder.clearCallingIdentity();
try {
- // TODO(multi-display): Update rotation for different displays separately.
- final boolean rotationChanged;
- final int displayId;
synchronized (mWindowMap) {
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
- rotationChanged = displayContent.updateRotationUnchecked();
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- if (!rotationChanged || forceRelayout) {
- displayContent.setLayoutNeeded();
+ boolean layoutNeeded = false;
+ final int displayCount = mRoot.mChildren.size();
+ for (int i = 0; i < displayCount; ++i) {
+ final DisplayContent displayContent = mRoot.mChildren.get(i);
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
+ final boolean rotationChanged = displayContent.updateRotationUnchecked();
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+
+ if (!rotationChanged || forceRelayout) {
+ displayContent.setLayoutNeeded();
+ layoutNeeded = true;
+ }
+ if (rotationChanged || alwaysSendConfiguration) {
+ mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
+ .sendToTarget();
+ }
+ }
+
+ if (layoutNeeded) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"updateRotation: performSurfacePlacement");
mWindowPlacerLocked.performSurfacePlacement();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
- displayId = displayContent.getDisplayId();
- }
-
- if (rotationChanged || alwaysSendConfiguration) {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: sendNewConfiguration");
- sendNewConfiguration(displayId);
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -3871,6 +3850,13 @@
}
@Override
+ public WindowManagerPolicy.DisplayContentInfo getDefaultDisplayContentInfo() {
+ synchronized (mWindowMap) {
+ return getDefaultDisplayContentLocked();
+ }
+ }
+
+ @Override
public int getDefaultDisplayRotation() {
synchronized (mWindowMap) {
return getDefaultDisplayContentLocked().getRotation();
@@ -5792,7 +5778,7 @@
displayContent.updateDisplayInfo();
screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
- mPolicy.isDefaultOrientationForced(), isSecure,
+ displayContent.getDisplayRotation().isDefaultOrientationForced(), isSecure,
this);
mAnimator.setScreenRotationAnimationLocked(mFrozenDisplayId,
screenRotationAnimation);
@@ -6082,23 +6068,26 @@
@Override
public void createInputConsumer(IBinder token, String name, InputChannel inputChannel) {
synchronized (mWindowMap) {
- mRoot.forAllDisplays(dc -> {
- dc.getInputMonitor().createInputConsumer(token, name, inputChannel,
+ // TODO(b/112049699): Fix this for multiple displays. There is only one inputChannel
+ // here to accept the return value.
+ DisplayContent display = mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
+ if (display != null) {
+ display.getInputMonitor().createInputConsumer(token, name, inputChannel,
Binder.getCallingPid(), Binder.getCallingUserHandle());
- });
+ }
}
}
@Override
public boolean destroyInputConsumer(String name) {
synchronized (mWindowMap) {
- AtomicBoolean retValue = new AtomicBoolean(true);
- mRoot.forAllDisplays(dc -> {
- if (!dc.getInputMonitor().destroyInputConsumer(name)) {
- retValue.set(false);
- }
- });
- return retValue.get();
+ // TODO(b/112049699): Fix this for multiple displays. For consistency with
+ // createInputConsumer above.
+ DisplayContent display = mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
+ if (display != null) {
+ return display.getInputMonitor().destroyInputConsumer(name);
+ }
+ return false;
}
}
@@ -6761,8 +6750,10 @@
public void onOverlayChanged() {
synchronized (mWindowMap) {
- mPolicy.onOverlayChangedLw();
- getDefaultDisplayContentLocked().updateDisplayInfo();
+ mRoot.forAllDisplays(displayContent -> {
+ mPolicy.onOverlayChangedLw(displayContent);
+ displayContent.updateDisplayInfo();
+ });
requestTraversal();
}
}
@@ -7090,19 +7081,24 @@
@Override
public void dontOverrideDisplayInfo(int displayId) {
- synchronized (mWindowMap) {
- final DisplayContent dc = getDisplayContentOrCreate(displayId);
- if (dc == null) {
- throw new IllegalArgumentException(
- "Trying to register a non existent display.");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mWindowMap) {
+ final DisplayContent dc = getDisplayContentOrCreate(displayId);
+ if (dc == null) {
+ throw new IllegalArgumentException(
+ "Trying to register a non existent display.");
+ }
+ // We usually set the override info in DisplayManager so that we get consistent
+ // values when displays are changing. However, we don't do this for displays that
+ // serve as containers for ActivityViews because we don't want letter-/pillar-boxing
+ // during resize.
+ dc.mShouldOverrideDisplayConfiguration = false;
+ mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId,
+ null /* info */);
}
- // We usually set the override info in DisplayManager so that we get consistent
- // values when displays are changing. However, we don't do this for displays that
- // serve as containers for ActivityViews because we don't want letter-/pillar-boxing
- // during resize.
- dc.mShouldOverrideDisplayConfiguration = false;
- mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId,
- null /* info */);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -7141,11 +7137,7 @@
}
finishSeamlessRotation();
- final DisplayContent displayContent = w.getDisplayContent();
- if (displayContent.updateRotationUnchecked()) {
- mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
- .sendToTarget();
- }
+ w.getDisplayContent().updateRotationAndSendNewConfigIfNeeded();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index aced8e4..08decdf 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -569,7 +569,7 @@
// animation after the old one finally finishes. It's better to defer the
// app transition.
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
- mService.rotationNeedsUpdateLocked()) {
+ mService.getDefaultDisplayContentLocked().rotationNeedsUpdate()) {
if (DEBUG_APP_TRANSITIONS) {
Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
}
diff --git a/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java b/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java
new file mode 100644
index 0000000..dd0a58d
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Handler;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class KeyValueBackupJobTest {
+ private Context mContext;
+ private BackupManagerConstants mConstants;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = RuntimeEnvironment.application;
+ mConstants = new BackupManagerConstants(Handler.getMain(), mContext.getContentResolver());
+ mConstants.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mConstants.stop();
+ KeyValueBackupJob.cancel(mContext);
+ }
+
+ @Test
+ public void testIsScheduled_beforeScheduling_returnsFalse() {
+ boolean isScheduled = KeyValueBackupJob.isScheduled();
+
+ assertThat(isScheduled).isFalse();
+ }
+
+ @Test
+ public void testIsScheduled_afterScheduling_returnsTrue() {
+ KeyValueBackupJob.schedule(mContext, mConstants);
+
+ boolean isScheduled = KeyValueBackupJob.isScheduled();
+
+ assertThat(isScheduled).isTrue();
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index 8fab197..1f6ac8d 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -54,6 +54,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
+import static org.robolectric.shadow.api.Shadow.extract;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.util.Collections.emptyList;
@@ -79,6 +80,7 @@
import android.net.Uri;
import android.os.DeadObjectException;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
@@ -101,6 +103,7 @@
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
+import com.android.server.testing.shadows.FrameworkShadowLooper;
import com.android.server.testing.shadows.ShadowBackupDataInput;
import com.android.server.testing.shadows.ShadowBackupDataOutput;
import com.android.server.testing.shadows.ShadowEventLog;
@@ -143,10 +146,11 @@
manifest = Config.NONE,
sdk = 26,
shadows = {
+ FrameworkShadowLooper.class,
ShadowBackupDataInput.class,
ShadowBackupDataOutput.class,
ShadowEventLog.class,
- ShadowQueuedWork.class
+ ShadowQueuedWork.class,
})
@SystemLoaderPackages({"com.android.server.backup", "android.app.backup"})
@SystemLoaderClasses({IBackupTransport.class, IBackupAgent.class, PackageInfo.class})
@@ -171,6 +175,7 @@
private File mDataDir;
private Application mApplication;
private ShadowApplication mShadowApplication;
+ private FrameworkShadowLooper mShadowMainLooper;
private Context mContext;
@Before
@@ -183,6 +188,8 @@
mShadowApplication = shadowOf(mApplication);
mContext = mApplication;
+ mShadowMainLooper = extract(Looper.getMainLooper());
+
File cacheDir = mApplication.getCacheDir();
// Corresponds to /data/backup
mBaseStateDir = new File(cacheDir, "base_state");
@@ -337,7 +344,7 @@
runTask(task);
- assertEventLogged(EventLogTags.BACKUP_START, mTransport.transportDirName);
+ assertEventLogged(EventLogTags.BACKUP_START, mTransport.transportName);
}
@Test
@@ -1571,11 +1578,10 @@
}
private void runTask(PerformBackupTask task) {
- Message message = mBackupHandler.obtainMessage(BackupHandler.MSG_BACKUP_RESTORE_STEP, task);
- mBackupHandler.sendMessage(message);
- while (mShadowBackupLooper.getScheduler().areAnyRunnable()) {
- mShadowBackupLooper.runToEndOfTasks();
- }
+ // Pretend we are not on the main-thread to prevent RemoteCall from complaining
+ mShadowMainLooper.setCurrentThread(false);
+ task.run();
+ mShadowMainLooper.reset();
assertTaskPostConditions();
}
@@ -1699,7 +1705,7 @@
String transportDirName,
boolean nonIncremental,
PackageData... packages) {
- ArrayList<BackupRequest> backupRequests =
+ ArrayList<BackupRequest> keyValueBackupRequests =
Stream.of(packages)
.map(packageData -> packageData.packageName)
.map(BackupRequest::new)
@@ -1713,7 +1719,7 @@
mBackupManagerService,
transportClient,
transportDirName,
- backupRequests,
+ keyValueBackupRequests,
mOldJournal,
mObserver,
mMonitor,
diff --git a/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java b/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java
new file mode 100644
index 0000000..aec207d
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.backup.remote;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import java.util.concurrent.CompletableFuture;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class FutureBackupCallbackTest {
+ @Test
+ public void testOperationComplete_completesFuture() throws Exception {
+ CompletableFuture<RemoteResult> future = new CompletableFuture<>();
+ FutureBackupCallback callback = new FutureBackupCallback(future);
+
+ callback.operationComplete(7);
+
+ assertThat(future.get()).isEqualTo(RemoteResult.successful(7));
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java b/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java
new file mode 100644
index 0000000..55db616
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.backup.remote;
+
+import static com.android.server.backup.testing.TestUtils.runToEndOfTasks;
+import static com.android.server.backup.testing.TestUtils.uncheck;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IBackupCallback;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.backup.testing.TestUtils.ThrowingRunnable;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class RemoteCallTest {
+ /** A {@link RemoteCallable} that calls the callback immediately. */
+ private final RemoteCallable<IBackupCallback> IMMEDIATE_CALLABLE =
+ callback -> callback.operationComplete(0);
+
+ @Mock private RemoteCallable<IBackupCallback> mCallable;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testCall_whenCancelledAndImmediateCallableAndTimeOut0_returnsCancel()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(true, IMMEDIATE_CALLABLE, 0);
+
+ RemoteResult result = runInWorkerThread(remoteCall::call);
+
+ assertThat(result).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ @Test
+ public void testCall_whenCancelledAndImmediateCallableAndTimeOut0_doesNotCallCallable()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(true, IMMEDIATE_CALLABLE, 0);
+
+ runInWorkerThread(remoteCall::call);
+
+ verify(mCallable, never()).call(any());
+ }
+
+ @Test
+ public void testCall_whenImmediateCallableAndTimeOut0AndCancelIsCalledBeforeCall_returnsCancel()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(IMMEDIATE_CALLABLE, 0);
+ remoteCall.cancel();
+
+ RemoteResult result = runInWorkerThread(remoteCall::call);
+
+ assertThat(result).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ @Test
+ public void
+ testCall_whenImmediateCallableAndTimeOut0AndCancelIsCalledBeforeCall_doesNotCallCallable()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(IMMEDIATE_CALLABLE, 0);
+ remoteCall.cancel();
+
+ runInWorkerThread(remoteCall::call);
+
+ verify(mCallable, never()).call(any());
+ }
+
+ @Test
+ public void testCall_whenImmediateCallableAndTimeOut0_returnsTimeOut() throws Exception {
+ RemoteCall remoteCall = new RemoteCall(IMMEDIATE_CALLABLE, 0);
+
+ RemoteResult result = runInWorkerThread(remoteCall::call);
+
+ assertThat(result).isEqualTo(RemoteResult.FAILED_TIMED_OUT);
+ }
+
+ @Test
+ public void testCall_whenTimeOut0_doesNotCallCallable() throws Exception {
+ RemoteCall remoteCall = new RemoteCall(mCallable, 0);
+
+ runInWorkerThread(remoteCall::call);
+
+ verify(mCallable, never()).call(any());
+ }
+
+ @Test
+ public void testCall_whenTimesOutBeforeCallbackIsCalled_returnsTimeOut() throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall =
+ new RemoteCall(
+ callback -> {
+ postDelayed(
+ Handler.getMain(), () -> callback.operationComplete(0), 1000);
+ scheduled.open();
+ },
+ 500);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ // Method runToEndOfTasks() will execute what was posted to the main handler, which is the
+ // completion of the callback and the time-out (that was scheduled by RemoteCall). But to be
+ // able to execute everything we have to ensure that runToEndOfTasks() is called *after*
+ // everything has been scheduled, that's why we use the condition variable scheduled, that
+ // is set to true (i.e. opened) when everything is scheduled, allowing us to run the tasks.
+ scheduled.block();
+ runToEndOfTasks(Looper.getMainLooper());
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_TIMED_OUT);
+ }
+
+ @Test
+ public void testCall_whenTimesOutBeforeCancelIsCalled_returnsTimeOut() throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall = new RemoteCall(callback -> scheduled.open(), 500);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ scheduled.block();
+ runToEndOfTasks(Looper.getMainLooper());
+ remoteCall.cancel();
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_TIMED_OUT);
+ }
+
+ @Test
+ public void testCall_whenCallbackIsCalledBeforeTimeOut_returnsSuccess() throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall =
+ new RemoteCall(
+ callback -> {
+ postDelayed(
+ Handler.getMain(), () -> callback.operationComplete(3), 500);
+ scheduled.open();
+ },
+ 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ scheduled.block();
+ runToEndOfTasks(Looper.getMainLooper());
+ assertThat(result.get()).isEqualTo(RemoteResult.successful(3));
+ }
+
+ @Test
+ public void testCall_whenCallbackIsCalledBeforeCancel_returnsSuccess() throws Exception {
+ CompletableFuture<IBackupCallback> callbackFuture = new CompletableFuture<>();
+ RemoteCall remoteCall = new RemoteCall(callbackFuture::complete, 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ // callbackFuture.get() will return when callable is executed (i.e. inside
+ // remoteCall.call()), at which point we can complete it.
+ IBackupCallback callback = callbackFuture.get();
+ callback.operationComplete(3);
+ remoteCall.cancel();
+ assertThat(result.get()).isEqualTo(RemoteResult.successful(3));
+ }
+
+ @Test
+ public void testCall_whenCancelIsCalledBeforeCallbackButAfterCall_returnsCancel()
+ throws Exception {
+ CompletableFuture<IBackupCallback> callbackFuture = new CompletableFuture<>();
+ RemoteCall remoteCall = new RemoteCall(callbackFuture::complete, 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ IBackupCallback callback = callbackFuture.get();
+ remoteCall.cancel();
+ callback.operationComplete(3);
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ @Test
+ public void testCall_whenCancelIsCalledBeforeTimeOutButAfterCall_returnsCancel()
+ throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall = new RemoteCall(callback -> scheduled.open(), 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ scheduled.block();
+ remoteCall.cancel();
+ runToEndOfTasks(Looper.getMainLooper());
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ private static <T> Future<T> runInWorkerThreadAsync(Callable<T> supplier) {
+ CompletableFuture<T> future = new CompletableFuture<>();
+ new Thread(() -> future.complete(uncheck(supplier)), "test-worker-thread").start();
+ return future;
+ }
+
+ private static <T> T runInWorkerThread(Callable<T> supplier) throws Exception {
+ return runInWorkerThreadAsync(supplier).get();
+ }
+
+ /** Unchecked version of {@link Handler#postDelayed(Runnable, long)}. */
+ private static void postDelayed(Handler handler, ThrowingRunnable runnable, long delayMillis) {
+ handler.postDelayed(() -> uncheck(runnable), delayMillis);
+ }
+
+ /** Unchecked version of {@link Handler#post(Runnable)}. */
+ private static void post(Handler handler, ThrowingRunnable runnable) {
+ handler.post(() -> uncheck(runnable));
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java b/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java
new file mode 100644
index 0000000..f1c4f27
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.backup.remote;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.expectThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class RemoteResultTest {
+ @Test
+ public void testSucceeded_whenSuccessfulResult_returnsTrue() {
+ RemoteResult result = RemoteResult.successful(3);
+
+ boolean succeeded = result.succeeded();
+
+ assertThat(succeeded).isTrue();
+ }
+
+ @Test
+ public void testSucceeded_whenFailedResults_returnsFalse() {
+ boolean timeOutSucceeded = RemoteResult.FAILED_TIMED_OUT.succeeded();
+ boolean cancelledSucceeded = RemoteResult.FAILED_CANCELLED.succeeded();
+ boolean threadInterruptedSucceeded = RemoteResult.FAILED_THREAD_INTERRUPTED.succeeded();
+
+ assertThat(timeOutSucceeded).isFalse();
+ assertThat(cancelledSucceeded).isFalse();
+ assertThat(threadInterruptedSucceeded).isFalse();
+ }
+
+ @Test
+ public void testGet_whenSuccessfulResult_returnsValue() {
+ RemoteResult result = RemoteResult.successful(7);
+
+ long value = result.get();
+
+ assertThat(value).isEqualTo(7);
+ }
+
+ @Test
+ public void testGet_whenFailedResult_throws() {
+ RemoteResult result = RemoteResult.FAILED_TIMED_OUT;
+
+ expectThrows(IllegalStateException.class, result::get);
+ }
+
+ @Test
+ public void testToString() {
+ assertThat(RemoteResult.successful(3).toString()).isEqualTo("RemoteResult{3}");
+ assertThat(RemoteResult.FAILED_TIMED_OUT.toString())
+ .isEqualTo("RemoteResult{FAILED_TIMED_OUT}");
+ assertThat(RemoteResult.FAILED_CANCELLED.toString())
+ .isEqualTo("RemoteResult{FAILED_CANCELLED}");
+ assertThat(RemoteResult.FAILED_THREAD_INTERRUPTED.toString())
+ .isEqualTo("RemoteResult{FAILED_THREAD_INTERRUPTED}");
+ }
+
+ @Test
+ public void testEquals() {
+ assertThat(RemoteResult.successful(3).equals(RemoteResult.successful(3))).isTrue();
+ assertThat(RemoteResult.successful(3).equals(RemoteResult.successful(7))).isFalse();
+ assertThat(RemoteResult.successful(-1).equals(RemoteResult.successful(1))).isFalse();
+ assertThat(RemoteResult.successful(Long.MAX_VALUE).equals(RemoteResult.successful(-1)))
+ .isFalse();
+ assertThat(RemoteResult.successful(3).equals(RemoteResult.FAILED_TIMED_OUT)).isFalse();
+ assertThat(RemoteResult.successful(3).equals("3")).isFalse();
+ assertThat(RemoteResult.successful(3).equals(null)).isFalse();
+ assertThat(RemoteResult.FAILED_TIMED_OUT.equals(RemoteResult.FAILED_TIMED_OUT)).isTrue();
+ assertThat(RemoteResult.FAILED_TIMED_OUT.equals(RemoteResult.FAILED_CANCELLED)).isFalse();
+ }
+
+ /** @see Object#hashCode() */
+ @Test
+ public void testHashCode() {
+ RemoteResult result3 = RemoteResult.successful(3);
+ assertThat(result3.hashCode()).isEqualTo(result3.hashCode());
+ assertThat(result3.hashCode()).isEqualTo(RemoteResult.successful(3).hashCode());
+ assertThat(RemoteResult.FAILED_TIMED_OUT.hashCode())
+ .isEqualTo(RemoteResult.FAILED_TIMED_OUT.hashCode());
+ assertThat(RemoteResult.FAILED_CANCELLED.hashCode())
+ .isEqualTo(RemoteResult.FAILED_CANCELLED.hashCode());
+ assertThat(RemoteResult.FAILED_THREAD_INTERRUPTED.hashCode())
+ .isEqualTo(RemoteResult.FAILED_THREAD_INTERRUPTED.hashCode());
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java b/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java
new file mode 100644
index 0000000..e0d3c0c
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.backup.remote;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IBackupManager;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class ServiceBackupCallbackTest {
+ @Test
+ public void testOperationComplete_callsBackupManagerOpComplete() throws Exception {
+ IBackupManager backupManager = mock(IBackupManager.class);
+ ServiceBackupCallback callback = new ServiceBackupCallback(backupManager, 0x68e);
+
+ callback.operationComplete(7);
+
+ verify(backupManager).opComplete(0x68e, 7);
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index 23d4ba4..084f27f 100644
--- a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -16,6 +16,8 @@
package com.android.server.backup.testing;
+import static com.android.server.backup.testing.TestUtils.runToEndOfTasks;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -46,8 +48,6 @@
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowBinder;
import org.robolectric.shadows.ShadowLog;
-import org.robolectric.shadows.ShadowLooper;
-import org.robolectric.shadows.ShadowSystemClock;
import java.io.File;
import java.lang.Thread.UncaughtExceptionHandler;
@@ -79,14 +79,7 @@
baseStateDir,
dataDir,
transportManager);
- ShadowLooper shadowBackupLooper = shadowOf(backupThread.getLooper());
- shadowBackupLooper.runToEndOfTasks();
- // Handler instances have their own clock, so advancing looper (with runToEndOfTasks())
- // above does NOT advance the handlers' clock, hence whenever a handler post messages with
- // specific time to the looper the time of those messages will be before the looper's time.
- // To fix this we advance SystemClock as well since that is from where the handlers read
- // time.
- ShadowSystemClock.setCurrentTimeMillis(shadowBackupLooper.getScheduler().getCurrentTime());
+ runToEndOfTasks(backupThread.getLooper());
return backupManagerService;
}
diff --git a/services/robotests/src/com/android/server/backup/testing/TestUtils.java b/services/robotests/src/com/android/server/backup/testing/TestUtils.java
index b657dd0..134cfd8 100644
--- a/services/robotests/src/com/android/server/backup/testing/TestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/TestUtils.java
@@ -18,15 +18,33 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.os.Looper;
+
import com.android.server.testing.shadows.ShadowEventLog;
import org.robolectric.shadows.ShadowLog;
+import org.robolectric.shadows.ShadowLooper;
+import org.robolectric.shadows.ShadowSystemClock;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.function.Predicate;
public class TestUtils {
+ /** Version of {@link ShadowLooper#runToEndOfTasks()} that also advances the system clock. */
+ public static void runToEndOfTasks(Looper looper) {
+ ShadowLooper shadowLooper = shadowOf(looper);
+ shadowLooper.runToEndOfTasks();
+ // Handler instances have their own clock, so advancing looper (with runToEndOfTasks())
+ // above does NOT advance the handlers' clock, hence whenever a handler post messages with
+ // specific time to the looper the time of those messages will be before the looper's time.
+ // To fix this we advance SystemClock as well since that is from where the handlers read
+ // time.
+ ShadowSystemClock.setCurrentTimeMillis(shadowLooper.getScheduler().getCurrentTime());
+ }
+
/** Reset logcat with {@link ShadowLog#reset()} before the test case. */
public static void assertLogcatAtMost(String tag, int level) {
assertThat(ShadowLog.getLogsForTag(tag).stream().allMatch(logItem -> logItem.type <= level))
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 5e7a2522..0dc5130 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -33,6 +33,7 @@
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
+import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -163,6 +164,7 @@
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
+ @Ignore("b/80297700")
@Test
public void handleSetSystemAudioMode_setOn_orignalOff() {
mMusicMute = true;
@@ -190,6 +192,7 @@
assertThat(mMusicMute).isFalse();
}
+ @Ignore("b/80297700")
@Test
public void handleSystemAudioModeRequest_turnOffByTv() {
assertThat(mMusicMute).isFalse();
@@ -215,6 +218,7 @@
assertThat(mMusicMute).isTrue();
}
+ @Ignore("b/80297700")
@Test
public void onStandbyAudioSystem_currentSystemAudioControlOn() {
// Set system audio control on first
@@ -298,6 +302,7 @@
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(message);
}
+ @Ignore("b/80297700")
@Test
public void terminateSystemAudioMode_systemAudioModeOn() {
mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(true);
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
index 1d37802..ef87f9d 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
@@ -55,6 +55,7 @@
import com.android.server.policy.keyguard.KeyguardServiceDelegate;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.WindowTestUtils.TestDisplayContent;
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Before;
@@ -123,7 +124,6 @@
mNavigationBar.attrs.gravity = Gravity.BOTTOM;
mPolicy.addWindow(mNavigationBar);
- mPolicy.mHasNavigationBar = true;
mPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;
}
@@ -245,12 +245,10 @@
policy[0].mAccessibilityManager = new AccessibilityManager(context,
mock(IAccessibilityManager.class), UserHandle.USER_CURRENT);
policy[0].mSystemGestures = mock(SystemGesturesPointerEventListener.class);
- policy[0].mNavigationBarCanMove = true;
- policy[0].mPortraitRotation = ROTATION_0;
- policy[0].mLandscapeRotation = ROTATION_90;
- policy[0].mUpsideDownRotation = ROTATION_180;
- policy[0].mSeascapeRotation = ROTATION_270;
- policy[0].onConfigurationChanged();
+
+ final TestDisplayContent displayContent = TestDisplayContent.create(context);
+ policy[0].setDefaultDisplay(displayContent);
+ policy[0].onConfigurationChanged(displayContent);
});
return policy[0];
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index f6599dc..e8d8022 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -42,6 +42,10 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
/**
* Tests for the {@link AppWindowToken} class.
*
@@ -162,6 +166,9 @@
sWm.mDisplayReady = true;
sWm.mDisplayEnabled = true;
+ final DisplayRotation spiedRotation = spy(mDisplayContent.getDisplayRotation());
+ mDisplayContent.setDisplayRotation(spiedRotation);
+
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
TYPE_BASE_APPLICATION);
attrs.setTitle("AppWindow");
@@ -169,20 +176,21 @@
mToken.addWindow(appWindow);
// Set initial orientation and update.
- performRotation(Surface.ROTATION_90);
+ performRotation(spiedRotation, Surface.ROTATION_90);
appWindow.resizeReported = false;
// Update the rotation to perform 180 degree rotation and check that resize was reported.
- performRotation(Surface.ROTATION_270);
+ performRotation(spiedRotation, Surface.ROTATION_270);
assertTrue(appWindow.resizeReported);
+
appWindow.removeImmediately();
}
- private void performRotation(int rotationToReport) {
- ((TestWindowManagerPolicy) sWm.mPolicy).rotationToReport = rotationToReport;
+ private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
+ doReturn(rotationToReport).when(spiedRotation).rotationForOrientation(anyInt(), anyInt());
sWm.updateRotation(false, false);
- // Simulate animator finishing orientation change
- sWm.mRoot.mOrientationChangeComplete = true;
+ // Prevent the next rotation from being deferred by animation.
+ sWm.mAnimator.setScreenRotationAnimationLocked(mDisplayContent.getDisplayId(), null);
sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
index a2ccee4..bfc99c8 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -255,16 +255,32 @@
* Asserts the top inset of {@param activity} is equal to {@param expected} waiting as needed.
*/
private void assertTopInsetEquals(Activity activity, int expected) throws Exception {
- waitFor(() -> getInsets(activity).getSystemWindowInsetTop() == expected);
+ waitForTopInsetEqual(activity, expected);
assertEquals(expected, getInsets(activity).getSystemWindowInsetTop());
}
+ private void waitForTopInsetEqual(Activity activity, int expected) {
+ waitFor(() -> getInsets(activity).getSystemWindowInsetTop() == expected);
+ }
+
/**
* Asserts the inset at {@param side} of {@param activity} is equal to {@param expected}
* waiting as needed.
*/
private void assertInsetGreaterOrEqual(Activity activity, int side, int expected)
throws Exception {
+ waitForInsetGreaterOrEqual(activity, side, expected);
+
+ final WindowInsets insets = getInsets(activity);
+ switch (side) {
+ case TOP: assertGreaterOrEqual(insets.getSystemWindowInsetTop(), expected); break;
+ case BOTTOM: assertGreaterOrEqual(insets.getSystemWindowInsetBottom(), expected); break;
+ case LEFT: assertGreaterOrEqual(insets.getSystemWindowInsetLeft(), expected); break;
+ case RIGHT: assertGreaterOrEqual(insets.getSystemWindowInsetRight(), expected); break;
+ }
+ }
+
+ private void waitForInsetGreaterOrEqual(Activity activity, int side, int expected) {
waitFor(() -> {
final WindowInsets insets = getInsets(activity);
switch (side) {
@@ -275,14 +291,6 @@
default: return true;
}
});
-
- final WindowInsets insets = getInsets(activity);
- switch (side) {
- case TOP: assertGreaterOrEqual(insets.getSystemWindowInsetTop(), expected); break;
- case BOTTOM: assertGreaterOrEqual(insets.getSystemWindowInsetBottom(), expected); break;
- case LEFT: assertGreaterOrEqual(insets.getSystemWindowInsetLeft(), expected); break;
- case RIGHT: assertGreaterOrEqual(insets.getSystemWindowInsetRight(), expected); break;
- }
}
/** Asserts that the first entry is greater than or equal to the second entry. */
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index e4f181b..735e284 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -31,7 +31,6 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.util.proto.ProtoOutputStream;
-import android.view.Display;
import android.view.DisplayCutout;
import android.view.IWindow;
import android.view.IWindowManager;
@@ -73,14 +72,7 @@
}
- @Override
- public boolean isDefaultOrientationForced() {
- return false;
- }
-
- @Override
- public void setInitialDisplaySize(Display display, int width, int height, int density) {
-
+ public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
}
@Override
@@ -389,22 +381,6 @@
public void onKeyguardOccludedChangedLw(boolean occluded) {
}
- @Override
- public int rotationForOrientationLw(int orientation, int lastRotation, boolean defaultDisplay) {
- return rotationToReport;
- }
-
- @Override
- public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
- return true;
- }
-
- @Override
- public void setRotationLw(int rotation) {
-
- }
-
- @Override
public void setSafeMode(boolean safeMode) {
}
@@ -440,11 +416,6 @@
}
@Override
- public void setCurrentOrientationLw(int newOrientation) {
-
- }
-
- @Override
public boolean performHapticFeedbackLw(WindowState win, int effectId,
boolean always) {
return false;
@@ -562,12 +533,13 @@
}
@Override
- public void onConfigurationChanged() {
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo) {
}
@Override
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
+ int newRotation) {
return false;
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 4864332..431d1a7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -121,13 +121,52 @@
mStubStack = new TaskStack(sWm, 0, null);
}
- public void assertRect(Rect rect, int left, int top, int right, int bottom) {
+ // Do not use this function directly in the tests below. Instead, use more explicit function
+ // such as assertFlame().
+ private void assertRect(Rect rect, int left, int top, int right, int bottom) {
assertEquals(left, rect.left);
assertEquals(top, rect.top);
assertEquals(right, rect.right);
assertEquals(bottom, rect.bottom);
}
+ private void assertContentInset(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.mContentInsets, left, top, right, bottom);
+ }
+
+ private void assertVisibleInset(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.mVisibleInsets, left, top, right, bottom);
+ }
+
+ private void assertStableInset(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.mStableInsets, left, top, right, bottom);
+ }
+
+ private void assertFrame(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.getFrameLw(), left, top, right, bottom);
+ }
+
+ private void assertContentFrame(WindowState w, Rect expectedRect) {
+ assertRect(w.getContentFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ expectedRect.bottom);
+ }
+
+ private void assertVisibleFrame(WindowState w, Rect expectedRect) {
+ assertRect(w.getVisibleFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ expectedRect.bottom);
+ }
+
+ private void assertStableFrame(WindowState w, Rect expectedRect) {
+ assertRect(w.getStableFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ expectedRect.bottom);
+ }
+
+ private void assertPolicyCrop(WindowStateWithTask w, int left, int top, int right, int bottom) {
+ Rect policyCrop = new Rect();
+ w.calculatePolicyCrop(policyCrop);
+ assertRect(policyCrop, left, top, right, bottom);
+ }
+
@Test
public void testLayoutInFullscreenTaskInsets() throws Exception {
Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
@@ -163,14 +202,13 @@
// and stable frames work the same way.
final WindowFrames windowFrames = new WindowFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(),0, 0, 1000, 1000);
- assertRect(w.mContentInsets, 0, topContentInset, 0, bottomContentInset);
- assertRect(w.mVisibleInsets, 0, topVisibleInset, 0, bottomVisibleInset);
- assertRect(w.mStableInsets, leftStableInset, 0, rightStableInset, 0);
- // The frames remain as passed in shrunk to the window frame
- assertTrue(cf.equals(w.getContentFrameLw()));
- assertTrue(vf.equals(w.getVisibleFrameLw()));
- assertTrue(sf.equals(w.getStableFrameLw()));
+ assertFrame(w, 0, 0, 1000, 1000);
+ assertContentInset(w, 0, topContentInset, 0, bottomContentInset);
+ assertVisibleInset(w, 0, topVisibleInset, 0, bottomVisibleInset);
+ assertStableInset(w, leftStableInset, 0, rightStableInset, 0);
+ assertContentFrame(w, cf);
+ assertVisibleFrame(w, vf);
+ assertStableFrame(w, sf);
// On the other hand getFrame() doesn't extend past cf we won't get any insets
w.mAttrs.x = 100;
w.mAttrs.y = 100;
@@ -178,12 +216,12 @@
w.mRequestedWidth = 100;
w.mRequestedHeight = 100;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 100, 100, 200, 200);
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, 100, 100, 200, 200);
+ assertContentInset(w, 0, 0, 0, 0);
// In this case the frames are shrunk to the window frame.
- assertTrue(w.getFrameLw().equals(w.getContentFrameLw()));
- assertTrue(w.getFrameLw().equals(w.getVisibleFrameLw()));
- assertTrue(w.getFrameLw().equals(w.getStableFrameLw()));
+ assertContentFrame(w, w.getFrameLw());
+ assertVisibleFrame(w, w.getFrameLw());
+ assertStableFrame(w, w.getFrameLw());
}
@Test
@@ -200,7 +238,7 @@
// so we expect it to fill the entire available frame.
final WindowFrames windowFrames = new WindowFrames(pf, pf, pf, pf, pf, pf, pf, pf);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 1000, 1000);
+ assertFrame(w, 0, 0, 1000, 1000);
// It can select various widths and heights within the bounds.
// Strangely the window attribute width is ignored for normal windows
@@ -210,14 +248,14 @@
w.computeFrameLw(windowFrames);
// Explicit width and height without requested width/height
// gets us nothing.
- assertRect(w.getFrameLw(), 0, 0, 0, 0);
+ assertFrame(w, 0, 0, 0, 0);
w.mRequestedWidth = 300;
w.mRequestedHeight = 300;
w.computeFrameLw(windowFrames);
// With requestedWidth/Height we can freely choose our size within the
// parent bounds.
- assertRect(w.getFrameLw(), 0, 0, 300, 300);
+ assertFrame(w, 0, 0, 300, 300);
// With FLAG_SCALED though, requestedWidth/height is used to control
// the unscaled surface size, and mAttrs.width/height becomes the
@@ -228,14 +266,14 @@
w.mAttrs.width = 100;
w.mAttrs.height = 100;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 100, 100);
+ assertFrame(w, 0, 0, 100, 100);
w.mAttrs.flags = 0;
// But sizes too large will be clipped to the containing frame
w.mRequestedWidth = 1200;
w.mRequestedHeight = 1200;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 1000, 1000);
+ assertFrame(w, 0, 0, 1000, 1000);
// Before they are clipped though windows will be shifted
w.mAttrs.x = 300;
@@ -243,7 +281,7 @@
w.mRequestedWidth = 1000;
w.mRequestedHeight = 1000;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 1000, 1000);
+ assertFrame(w, 0, 0, 1000, 1000);
// If there is room to move around in the parent frame the window will be shifted according
// to gravity.
@@ -253,16 +291,16 @@
w.mRequestedHeight = 300;
w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 700, 0, 1000, 300);
+ assertFrame(w, 700, 0, 1000, 300);
w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 700, 700, 1000, 1000);
+ assertFrame(w, 700, 700, 1000, 1000);
// Window specified x and y are interpreted as offsets in the opposite
// direction of gravity
w.mAttrs.x = 100;
w.mAttrs.y = 100;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 600, 600, 900, 900);
+ assertFrame(w, 600, 600, 900, 900);
}
@Test
@@ -286,24 +324,23 @@
w.computeFrameLw(windowFrames);
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
+ assertContentFrame(w, taskBounds);
+ assertContentInset(w, 0, 0, 0, 0);
pf.set(0, 0, logicalWidth, logicalHeight);
// We still produce insets against the containing frame the same way.
final int cfRight = logicalWidth / 2;
final int cfBottom = logicalHeight / 2;
final Rect cf = new Rect(0, 0, cfRight, cfBottom);
-
windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
int contentInsetRight = taskRight - cfRight;
int contentInsetBottom = taskBottom - cfBottom;
- assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
- taskBottom - contentInsetBottom);
+ assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
+ assertContentFrame(w, new Rect(taskLeft, taskTop, taskRight - contentInsetRight,
+ taskBottom - contentInsetBottom));
pf.set(0, 0, logicalWidth, logicalHeight);
// However if we set temp inset bounds, the insets will be computed
@@ -314,15 +351,14 @@
final int insetRight = insetLeft + (taskRight - taskLeft);
final int insetBottom = insetTop + (taskBottom - taskTop);
task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
-
windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
contentInsetRight = insetRight - cfRight;
contentInsetBottom = insetBottom - cfBottom;
- assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
- taskBottom - contentInsetBottom);
+ assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
+ assertContentFrame(w, new Rect(taskLeft, taskTop, taskRight - contentInsetRight,
+ taskBottom - contentInsetBottom));
}
@Test
@@ -344,20 +380,16 @@
final Rect vf = cf;
final Rect sf = vf;
// We use a decor content frame with insets to produce cropping.
- Rect dcf = cf;
-
- final Rect policyCrop = new Rect();
+ Rect dcf = new Rect(cf);
final WindowFrames windowFrames = new WindowFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
w.computeFrameLw(windowFrames);
- w.calculatePolicyCrop(policyCrop);
- assertRect(policyCrop, 0, cf.top, logicalWidth, cf.bottom);
+ assertPolicyCrop(w, 0, cf.top, logicalWidth, cf.bottom);
windowFrames.mDecorFrame.setEmpty();
// Likewise with no decor frame we would get no crop
w.computeFrameLw(windowFrames);
- w.calculatePolicyCrop(policyCrop);
- assertRect(policyCrop, 0, 0, logicalWidth, logicalHeight);
+ assertPolicyCrop(w, 0, 0, logicalWidth, logicalHeight);
// Now we set up a window which doesn't fill the entire decor frame.
// Normally it would be cropped to it's frame but in the case of docked resizing
@@ -372,16 +404,14 @@
w.mRequestedHeight = logicalHeight / 2;
w.computeFrameLw(windowFrames);
- w.calculatePolicyCrop(policyCrop);
// Normally the crop is shrunk from the decor frame
// to the computed window frame.
- assertRect(policyCrop, 0, 0, logicalWidth / 2, logicalHeight / 2);
+ assertPolicyCrop(w, 0, 0, logicalWidth / 2, logicalHeight / 2);
w.mDockedResizingForTest = true;
- w.calculatePolicyCrop(policyCrop);
// But if we are docked resizing it won't be, however we will still be
// shrunk to the decor frame and the display.
- assertRect(policyCrop, 0, 0,
+ assertPolicyCrop(w, 0, 0,
Math.min(pf.width(), displayInfo.logicalWidth),
Math.min(pf.height(), displayInfo.logicalHeight));
}
@@ -409,9 +439,9 @@
w.computeFrameLw(windowFrames);
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
+ assertContentFrame(w, taskBounds);
+ assertContentInset(w, 0, 0, 0, 0);
// Now simulate switch to fullscreen for letterboxed app.
final int xInset = logicalWidth / 10;
@@ -422,12 +452,11 @@
w.mAppToken.onOverrideConfigurationChanged(config);
pf.set(0, 0, logicalWidth, logicalHeight);
task.mFullscreenForTest = true;
-
windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertEquals(cf, w.getFrameLw());
- assertEquals(cf, w.getContentFrameLw());
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, cf.left, cf.top, cf.right, cf.bottom);
+ assertContentFrame(w, cf);
+ assertContentInset(w, 0, 0, 0, 0);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index a48a3b9..a1b1640 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -22,8 +22,10 @@
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
+import android.view.Display;
import android.view.IApplicationToken;
import android.view.IWindow;
+import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;
@@ -60,6 +62,37 @@
return service;
}
+ /** An extension of {@link DisplayContent} to gain package scoped access. */
+ public static class TestDisplayContent extends DisplayContent {
+
+ private TestDisplayContent(Display display, WindowManagerService service,
+ WallpaperController wallpaperController, DisplayWindowController controller) {
+ super(display, service, wallpaperController, controller);
+ }
+
+ /** Create a mocked default {@link DisplayContent}. */
+ public static TestDisplayContent create(Context context) {
+ final TestDisplayContent displayContent = mock(TestDisplayContent.class);
+ displayContent.isDefaultDisplay = true;
+
+ final DisplayPolicy displayPolicy = mock(DisplayPolicy.class);
+ when(displayPolicy.navigationBarCanMove()).thenReturn(true);
+ when(displayPolicy.hasNavigationBar()).thenReturn(true);
+
+ final DisplayRotation displayRotation = new DisplayRotation(
+ mock(WindowManagerService.class), displayContent, displayPolicy,
+ context, new Object());
+ displayRotation.mPortraitRotation = Surface.ROTATION_0;
+ displayRotation.mLandscapeRotation = Surface.ROTATION_90;
+ displayRotation.mUpsideDownRotation = Surface.ROTATION_180;
+ displayRotation.mSeascapeRotation = Surface.ROTATION_270;
+
+ when(displayContent.getDisplayRotation()).thenReturn(displayRotation);
+
+ return displayContent;
+ }
+ }
+
/**
* Creates a mock instance of {@link StackWindowController}.
*/
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 742ad65..f255d49 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -95,6 +95,7 @@
assertEquals(getUserSentiment(i), ranking.getUserSentiment());
assertEquals(getHidden(i), ranking.isSuspended());
assertActionsEqual(getSmartActions(key, i), ranking.getSmartActions());
+ assertEquals(getSmartReplies(key, i), ranking.getSmartReplies());
}
}
@@ -112,6 +113,7 @@
Bundle userSentiment = new Bundle();
Bundle mHidden = new Bundle();
Bundle smartActions = new Bundle();
+ Bundle smartReplies = new Bundle();
for (int i = 0; i < mKeys.length; i++) {
String key = mKeys[i];
@@ -130,12 +132,13 @@
userSentiment.putInt(key, getUserSentiment(i));
mHidden.putBoolean(key, getHidden(i));
smartActions.putParcelableArrayList(key, getSmartActions(key, i));
+ smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
}
NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
interceptedKeys.toArray(new String[0]), visibilityOverrides,
suppressedVisualEffects, importance, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
- smartActions);
+ smartActions, smartReplies);
return update;
}
@@ -216,6 +219,14 @@
return actions;
}
+ private ArrayList<CharSequence> getSmartReplies(String key, int index) {
+ ArrayList<CharSequence> choices = new ArrayList<>();
+ for (int i = 0; i < index; i++) {
+ choices.add("choice_" + key + "_" + i);
+ }
+ return choices;
+ }
+
private void assertActionsEqual(
List<Notification.Action> expecteds, List<Notification.Action> actuals) {
assertEquals(expecteds.size(), actuals.size());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 66285c3..0cbb1aa 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -111,6 +111,7 @@
import android.text.Html;
import android.util.ArrayMap;
import android.util.AtomicFile;
+import android.util.Log;
import com.android.internal.R;
import com.android.internal.statusbar.NotificationVisibility;
@@ -199,6 +200,7 @@
// Use a Testable subclass so we can simulate calls from the system without failing.
private static class TestableNotificationManagerService extends NotificationManagerService {
int countSystemChecks = 0;
+ boolean isSystemUid = true;
public TestableNotificationManagerService(Context context) {
super(context);
@@ -207,13 +209,13 @@
@Override
protected boolean isCallingUidSystem() {
countSystemChecks++;
- return true;
+ return isSystemUid;
}
@Override
protected boolean isCallerSystemOrPhone() {
countSystemChecks++;
- return true;
+ return isSystemUid;
}
@Override
@@ -651,6 +653,79 @@
assertNull(mService.getNotificationRecord(sbn.getKey()));
}
+ /**
+ * Confirm the system user on automotive devices can use car categories
+ */
+ @Test
+ public void testEnqueuedRestrictedNotifications_asSystem() throws Exception {
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(true);
+ List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
+ Notification.CATEGORY_CAR_WARNING,
+ Notification.CATEGORY_CAR_INFORMATION);
+ int id = 0;
+ for (String category: categories) {
+ final StatusBarNotification sbn =
+ generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
+ sbn.getNotification().category = category;
+ mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+ sbn.getId(), sbn.getNotification(), sbn.getUserId());
+ }
+ waitForIdle();
+ assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
+ }
+
+
+ /**
+ * Confirm restricted notification categories only apply to automotive.
+ */
+ @Test
+ public void testEnqueuedRestrictedNotifications_notAutomotive() throws Exception {
+ mService.isSystemUid = false;
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(false);
+ List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
+ Notification.CATEGORY_CAR_WARNING,
+ Notification.CATEGORY_CAR_INFORMATION);
+ int id = 0;
+ for (String category: categories) {
+ final StatusBarNotification sbn =
+ generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
+ sbn.getNotification().category = category;
+ mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+ sbn.getId(), sbn.getNotification(), sbn.getUserId());
+ }
+ waitForIdle();
+ assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
+ }
+
+ /**
+ * Confirm if a non-system user tries to use the car categories on a automotive device that
+ * they will get a security exception
+ */
+ @Test
+ public void testEnqueuedRestrictedNotifications_badUser() throws Exception {
+ mService.isSystemUid = false;
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(true);
+ List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
+ Notification.CATEGORY_CAR_WARNING,
+ Notification.CATEGORY_CAR_INFORMATION);
+ for (String category: categories) {
+ final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+ sbn.getNotification().category = category;
+ try {
+ mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+ sbn.getId(), sbn.getNotification(), sbn.getUserId());
+ fail("Calls from non system apps should not allow use of restricted categories");
+ } catch (SecurityException e) {
+ // pass
+ }
+ }
+ waitForIdle();
+ assertEquals(0, mBinderService.getActiveNotifications(PKG).length);
+ }
+
@Test
public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 22958d4..62fc9c4 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -843,6 +843,7 @@
public void onRemoteRttRequest(Connection c) {}
/** @hide */
public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {}
+ public void onConnectionTimeReset(Connection c) {}
}
/**
@@ -2372,6 +2373,16 @@
}
/**
+ * @hide
+ * Resets the cdma connection time.
+ */
+ public final void resetConnectionTime() {
+ for (Listener l : mListeners) {
+ l.onConnectionTimeReset(this);
+ }
+ }
+
+ /**
* Returns the connections or conferences with which this connection can be conferenced.
*/
public final List<Conferenceable> getConferenceables() {
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 2291090..61adcdd 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -1474,6 +1474,13 @@
mAdapter.onPhoneAccountChanged(id, pHandle);
}
}
+
+ public void onConnectionTimeReset(Connection c) {
+ String id = mIdByConnection.get(c);
+ if (id != null) {
+ mAdapter.resetConnectionTime(id);
+ }
+ }
};
/** {@inheritDoc} */
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index 0d319bb..520e7ed 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -255,6 +255,18 @@
}
/**
+ * Resets the cdma connection time.
+ */
+ void resetConnectionTime(String callId) {
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.resetConnectionTime(callId, Log.getExternalSession());
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /**
* Indicates that the call no longer exists. Can be used with either a call or a conference
* call.
*
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 3e1bf77..78d65e6 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -610,6 +610,11 @@
public void onConnectionServiceFocusReleased(Session.Info sessionInfo) {
mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_RELEASED).sendToTarget();
}
+
+ @Override
+ public void resetConnectionTime(String callId, Session.Info sessionInfo) {
+ // Do nothing
+ }
};
public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index bb4b483..9821dcb 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -466,6 +466,11 @@
Log.w(this, "onRemoteRttRequest called on a remote conference");
}
}
+
+ @Override
+ public void resetConnectionTime(String callId, Session.Info sessionInfo) {
+ // Do nothing
+ }
};
private final ConnectionServiceAdapterServant mServant =
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index be474bd..0157a58 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -121,4 +121,6 @@
in Session.Info sessionInfo);
void onConnectionServiceFocusReleased(in Session.Info sessionInfo);
+
+ void resetConnectionTime(String callIdi, in Session.Info sessionInfo);
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 9e23c5c..b2eb5e0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1553,7 +1553,8 @@
ITelephony telephony = getITelephony();
if (telephony == null)
return null;
- return telephony.getNeighboringCellInfo(mContext.getOpPackageName());
+ return telephony.getNeighboringCellInfo(mContext.getOpPackageName(),
+ mContext.getApplicationInfo().targetSdkVersion);
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
diff --git a/telephony/java/com/android/ims/internal/uce/common/CapInfo.java b/telephony/java/com/android/ims/internal/uce/common/CapInfo.java
index 56969a8..a9847ba 100644
--- a/telephony/java/com/android/ims/internal/uce/common/CapInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/common/CapInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.common;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -73,6 +74,7 @@
/**
* Constructor for the CapInfo class.
*/
+ @UnsupportedAppUsage
public CapInfo() {
};
@@ -80,6 +82,7 @@
/**
* Checks whether IM is supported.
*/
+ @UnsupportedAppUsage
public boolean isImSupported() {
return mImSupported;
}
@@ -87,6 +90,7 @@
/**
* Sets IM as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setImSupported(boolean imSupported) {
this.mImSupported = imSupported;
}
@@ -94,6 +98,7 @@
/**
* Checks whether FT Thumbnail is supported.
*/
+ @UnsupportedAppUsage
public boolean isFtThumbSupported() {
return mFtThumbSupported;
}
@@ -101,6 +106,7 @@
/**
* Sets FT thumbnail as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtThumbSupported(boolean ftThumbSupported) {
this.mFtThumbSupported = ftThumbSupported;
}
@@ -110,6 +116,7 @@
/**
* Checks whether FT Store and Forward is supported
*/
+ @UnsupportedAppUsage
public boolean isFtSnFSupported() {
return mFtSnFSupported;
}
@@ -117,6 +124,7 @@
/**
* Sets FT Store and Forward as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtSnFSupported(boolean ftSnFSupported) {
this.mFtSnFSupported = ftSnFSupported;
}
@@ -124,6 +132,7 @@
/**
* Checks whether File transfer HTTP is supported.
*/
+ @UnsupportedAppUsage
public boolean isFtHttpSupported() {
return mFtHttpSupported;
}
@@ -131,6 +140,7 @@
/**
* Sets File transfer HTTP as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtHttpSupported(boolean ftHttpSupported) {
this.mFtHttpSupported = ftHttpSupported;
}
@@ -138,6 +148,7 @@
/**
* Checks whether FT is supported.
*/
+ @UnsupportedAppUsage
public boolean isFtSupported() {
return mFtSupported;
}
@@ -145,6 +156,7 @@
/**
* Sets FT as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtSupported(boolean ftSupported) {
this.mFtSupported = ftSupported;
}
@@ -152,6 +164,7 @@
/**
* Checks whether IS is supported.
*/
+ @UnsupportedAppUsage
public boolean isIsSupported() {
return mIsSupported;
}
@@ -159,6 +172,7 @@
/**
* Sets IS as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setIsSupported(boolean isSupported) {
this.mIsSupported = isSupported;
}
@@ -166,6 +180,7 @@
/**
* Checks whether video sharing is supported during a CS call.
*/
+ @UnsupportedAppUsage
public boolean isVsDuringCSSupported() {
return mVsDuringCSSupported;
}
@@ -174,6 +189,7 @@
* Sets video sharing as supported or not supported during a CS
* call.
*/
+ @UnsupportedAppUsage
public void setVsDuringCSSupported(boolean vsDuringCSSupported) {
this.mVsDuringCSSupported = vsDuringCSSupported;
}
@@ -182,6 +198,7 @@
* Checks whether video sharing outside a voice call is
* supported.
*/
+ @UnsupportedAppUsage
public boolean isVsSupported() {
return mVsSupported;
}
@@ -189,6 +206,7 @@
/**
* Sets video sharing as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setVsSupported(boolean vsSupported) {
this.mVsSupported = vsSupported;
}
@@ -196,6 +214,7 @@
/**
* Checks whether social presence is supported.
*/
+ @UnsupportedAppUsage
public boolean isSpSupported() {
return mSpSupported;
}
@@ -203,6 +222,7 @@
/**
* Sets social presence as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setSpSupported(boolean spSupported) {
this.mSpSupported = spSupported;
}
@@ -211,6 +231,7 @@
* Checks whether capability discovery via presence is
* supported.
*/
+ @UnsupportedAppUsage
public boolean isCdViaPresenceSupported() {
return mCdViaPresenceSupported;
}
@@ -219,6 +240,7 @@
* Sets capability discovery via presence as supported or not
* supported.
*/
+ @UnsupportedAppUsage
public void setCdViaPresenceSupported(boolean cdViaPresenceSupported) {
this.mCdViaPresenceSupported = cdViaPresenceSupported;
}
@@ -226,6 +248,7 @@
/**
* Checks whether IP voice call is supported.
*/
+ @UnsupportedAppUsage
public boolean isIpVoiceSupported() {
return mIpVoiceSupported;
}
@@ -233,6 +256,7 @@
/**
* Sets IP voice call as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setIpVoiceSupported(boolean ipVoiceSupported) {
this.mIpVoiceSupported = ipVoiceSupported;
}
@@ -240,6 +264,7 @@
/**
* Checks whether IP video call is supported.
*/
+ @UnsupportedAppUsage
public boolean isIpVideoSupported() {
return mIpVideoSupported;
}
@@ -247,6 +272,7 @@
/**
* Sets IP video call as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setIpVideoSupported(boolean ipVideoSupported) {
this.mIpVideoSupported = ipVideoSupported;
}
@@ -255,6 +281,7 @@
* Checks whether Geo location Pull using File Transfer is
* supported.
*/
+ @UnsupportedAppUsage
public boolean isGeoPullFtSupported() {
return mGeoPullFtSupported;
}
@@ -263,6 +290,7 @@
* Sets Geo location Pull using File Transfer as supported or
* not supported.
*/
+ @UnsupportedAppUsage
public void setGeoPullFtSupported(boolean geoPullFtSupported) {
this.mGeoPullFtSupported = geoPullFtSupported;
}
@@ -270,6 +298,7 @@
/**
* Checks whether Geo Pull is supported.
*/
+ @UnsupportedAppUsage
public boolean isGeoPullSupported() {
return mGeoPullSupported;
}
@@ -277,6 +306,7 @@
/**
* Sets Geo Pull as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setGeoPullSupported(boolean geoPullSupported) {
this.mGeoPullSupported = geoPullSupported;
}
@@ -284,6 +314,7 @@
/**
* Checks whether Geo Push is supported.
*/
+ @UnsupportedAppUsage
public boolean isGeoPushSupported() {
return mGeoPushSupported;
}
@@ -291,6 +322,7 @@
/**
* Sets Geo Push as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setGeoPushSupported(boolean geoPushSupported) {
this.mGeoPushSupported = geoPushSupported;
}
@@ -298,6 +330,7 @@
/**
* Checks whether short messaging is supported.
*/
+ @UnsupportedAppUsage
public boolean isSmSupported() {
return mSmSupported;
}
@@ -305,6 +338,7 @@
/**
* Sets short messaging as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setSmSupported(boolean smSupported) {
this.mSmSupported = smSupported;
}
@@ -312,18 +346,22 @@
/**
* Checks whether store/forward and group chat are supported.
*/
+ @UnsupportedAppUsage
public boolean isFullSnFGroupChatSupported() {
return mFullSnFGroupChatSupported;
}
+ @UnsupportedAppUsage
public boolean isRcsIpVoiceCallSupported() {
return mRcsIpVoiceCallSupported;
}
+ @UnsupportedAppUsage
public boolean isRcsIpVideoCallSupported() {
return mRcsIpVideoCallSupported;
}
+ @UnsupportedAppUsage
public boolean isRcsIpVideoOnlyCallSupported() {
return mRcsIpVideoOnlyCallSupported;
}
@@ -331,16 +369,20 @@
/**
* Sets store/forward and group chat supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFullSnFGroupChatSupported(boolean fullSnFGroupChatSupported) {
this.mFullSnFGroupChatSupported = fullSnFGroupChatSupported;
}
+ @UnsupportedAppUsage
public void setRcsIpVoiceCallSupported(boolean rcsIpVoiceCallSupported) {
this.mRcsIpVoiceCallSupported = rcsIpVoiceCallSupported;
}
+ @UnsupportedAppUsage
public void setRcsIpVideoCallSupported(boolean rcsIpVideoCallSupported) {
this.mRcsIpVideoCallSupported = rcsIpVideoCallSupported;
}
+ @UnsupportedAppUsage
public void setRcsIpVideoOnlyCallSupported(boolean rcsIpVideoOnlyCallSupported) {
this.mRcsIpVideoOnlyCallSupported = rcsIpVideoOnlyCallSupported;
}
@@ -351,17 +393,20 @@
}
/** Sets the list of supported extensions. */
+ @UnsupportedAppUsage
public void setExts(String[] exts) {
this.mExts = exts;
}
/** Gets the time stamp for when to query again. */
+ @UnsupportedAppUsage
public long getCapTimestamp() {
return mCapTimestamp;
}
/** Sets the time stamp for when to query again. */
+ @UnsupportedAppUsage
public void setCapTimestamp(long capTimestamp) {
this.mCapTimestamp = capTimestamp;
}
diff --git a/telephony/java/com/android/ims/internal/uce/common/StatusCode.java b/telephony/java/com/android/ims/internal/uce/common/StatusCode.java
index ad9b669..3921cfb 100644
--- a/telephony/java/com/android/ims/internal/uce/common/StatusCode.java
+++ b/telephony/java/com/android/ims/internal/uce/common/StatusCode.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.common;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -71,12 +72,14 @@
* Constructor for the StatusCode class.
* @hide
*/
+ @UnsupportedAppUsage
public StatusCode() {}
/**
* Gets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public int getStatusCode() {
return mStatusCode;
}
@@ -85,6 +88,7 @@
* Sets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public void setStatusCode(int nStatusCode) {
this.mStatusCode = nStatusCode;
}
diff --git a/telephony/java/com/android/ims/internal/uce/common/UceLong.java b/telephony/java/com/android/ims/internal/uce/common/UceLong.java
index fd07fe8..7207899 100644
--- a/telephony/java/com/android/ims/internal/uce/common/UceLong.java
+++ b/telephony/java/com/android/ims/internal/uce/common/UceLong.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.common;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -32,6 +33,7 @@
* Constructor for the UceLong class.
* @hide
*/
+ @UnsupportedAppUsage
public UceLong() {
};
@@ -39,6 +41,7 @@
* Gets the long value.
* @hide
*/
+ @UnsupportedAppUsage
public long getUceLong() {
return mUceLong;
}
@@ -47,6 +50,7 @@
* Sets the long value.
* @hide
*/
+ @UnsupportedAppUsage
public void setUceLong(long uceLong) {
this.mUceLong = uceLong;
}
@@ -54,6 +58,7 @@
/** Get the client ID as integer value.
* @hide
*/
+ @UnsupportedAppUsage
public int getClientId() {
return mClientId;
}
@@ -62,6 +67,7 @@
* Set the client ID as integer value.
* @hide
*/
+ @UnsupportedAppUsage
public void setClientId(int nClientId) {
this.mClientId = nClientId;
}
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java b/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java
index c570f49..bcb9f2d 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java
@@ -15,6 +15,7 @@
*/
package com.android.ims.internal.uce.options;
+import android.annotation.UnsupportedAppUsage;
import com.android.ims.internal.uce.common.CapInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,10 +31,12 @@
return new OptionsCapInfo();
}
+ @UnsupportedAppUsage
public String getSdp() {
return mSdp;
}
+ @UnsupportedAppUsage
public void setSdp(String sdp) {
this.mSdp = sdp;
}
@@ -41,16 +44,19 @@
/**
* Constructor for the OptionsCapInfo class.
*/
+ @UnsupportedAppUsage
public OptionsCapInfo() {
mCapInfo = new CapInfo();
};
+ @UnsupportedAppUsage
public CapInfo getCapInfo() {
return mCapInfo;
}
/**
* Sets the CapInfo
*/
+ @UnsupportedAppUsage
public void setCapInfo(CapInfo capInfo) {
this.mCapInfo = capInfo;
}
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java
index 35f769c..14c64ac 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java
@@ -17,6 +17,7 @@
package com.android.ims.internal.uce.options;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -55,6 +56,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(int nCmdId) {
this.mCmdId = nCmdId;
}
@@ -63,6 +65,7 @@
* Constructor for the OptionsCDCmdId class.
* @hide
*/
+ @UnsupportedAppUsage
public OptionsCmdId(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java
index dab191c..4af3e6e 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java
@@ -19,6 +19,7 @@
import com.android.ims.internal.uce.common.StatusCode;
import com.android.ims.internal.uce.common.CapInfo;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,6 +42,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(OptionsCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -56,6 +58,7 @@
/**
Sets the user data.
@hide */
+ @UnsupportedAppUsage
public void setUserData(int userData) {
this.mUserData = userData;
}
@@ -72,6 +75,7 @@
* Sets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public void setStatus(StatusCode status) {
this.mStatus = status;
}
@@ -80,6 +84,7 @@
* Constructor for the OptionsCmdStatus class.
* @hide
*/
+ @UnsupportedAppUsage
public OptionsCmdStatus() {
mStatus = new StatusCode();
mCapInfo = new CapInfo();
@@ -96,6 +101,7 @@
* Sets the CapInfo
* @hide
*/
+ @UnsupportedAppUsage
public void setCapInfo(CapInfo capInfo) {
this.mCapInfo = capInfo;
}
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java b/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
index 0b9dd21..c5f333d 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.options;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,6 +42,7 @@
* Sets the Options command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(OptionsCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -57,6 +59,7 @@
* Sets the request ID
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -73,6 +76,7 @@
* Sets the SIP response code.
* @hide
*/
+ @UnsupportedAppUsage
public void setSipResponseCode(int sipResponseCode) {
this.mSipResponseCode = sipResponseCode;
}
@@ -89,6 +93,7 @@
* Sets the SIP response code reason phrase.
* @hide
*/
+ @UnsupportedAppUsage
public void setReasonPhrase(String reasonPhrase) {
this.mReasonPhrase = reasonPhrase;
}
@@ -105,6 +110,7 @@
* Sets the SIP retryAfter sec value
* @hide
*/
+ @UnsupportedAppUsage
public void setRetryAfter(int retryAfter) {
this.mRetryAfter = retryAfter;
}
@@ -113,6 +119,7 @@
* Constructor for the OptionsSipResponse class.
* @hide
*/
+ @UnsupportedAppUsage
public OptionsSipResponse() {
mCmdId = new OptionsCmdId();
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java
index 60fc226..745df5b 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java
@@ -18,6 +18,7 @@
import com.android.ims.internal.uce.common.CapInfo;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -26,12 +27,14 @@
public class PresCapInfo implements Parcelable {
private CapInfo mCapInfo;
+ @UnsupportedAppUsage
private String mContactUri = "";
/**
* Gets the UCE capability information.
* @hide
*/
+ @UnsupportedAppUsage
public CapInfo getCapInfo() {
return mCapInfo;
}
@@ -48,6 +51,7 @@
* Gets the contact URI.
* @hide
*/
+ @UnsupportedAppUsage
public String getContactUri() {
return mContactUri;
}
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java b/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java
index 395f3e8..41020ec 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -57,6 +58,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(int nCmdId) {
this.mCmdId = nCmdId;
}
@@ -66,6 +68,7 @@
* Constructor for the PresCmdId class.
* @hide
*/
+ @UnsupportedAppUsage
public PresCmdId(){};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java b/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java
index a5b498b..ff8069c 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java
@@ -18,6 +18,7 @@
import com.android.ims.internal.uce.common.StatusCode;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,6 +43,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(PresCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -58,6 +60,7 @@
* Sets the user data.
* @hide
*/
+ @UnsupportedAppUsage
public void setUserData(int userData) {
this.mUserData = userData;
}
@@ -73,6 +76,7 @@
* Sets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public void setStatus(StatusCode status) {
this.mStatus = status;
}
@@ -89,6 +93,7 @@
* Sets the request ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -97,6 +102,7 @@
* Constructor for the PresCmdStatus class.
* @hide
*/
+ @UnsupportedAppUsage
public PresCmdStatus() {
mStatus = new StatusCode();
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java b/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java
index 3e8531a..87193e3 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -65,6 +66,7 @@
* Sets the publish trigger type.
* @hide
*/
+ @UnsupportedAppUsage
public void setPublishTrigeerType(int nPublishTriggerType) {
this.mPublishTriggerType = nPublishTriggerType;
}
@@ -74,6 +76,7 @@
* Constructor for the PresPublishTriggerType class.
* @hide
*/
+ @UnsupportedAppUsage
public PresPublishTriggerType(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java
index a073a23..237c999 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,6 +39,7 @@
* Sets the Presence service resource instance information.
* @hide
*/
+ @UnsupportedAppUsage
public void setInstanceInfo(PresResInstanceInfo instanceInfo) {
this.mInstanceInfo = instanceInfo;
}
@@ -54,6 +56,7 @@
* Sets the resource URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setResUri(String resUri) {
this.mResUri = resUri;
}
@@ -70,6 +73,7 @@
* Sets the display name.
* @hide
*/
+ @UnsupportedAppUsage
public void setDisplayName(String displayName) {
this.mDisplayName = displayName;
}
@@ -79,6 +83,7 @@
* Constructor for the PresResInstanceInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresResInfo() {
mInstanceInfo = new PresResInstanceInfo();
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java
index 430cff1..29699ea 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Arrays;
@@ -59,6 +60,7 @@
* Sets the resource instance state.
* @hide
*/
+ @UnsupportedAppUsage
public void setResInstanceState(int nResInstanceState) {
this.mResInstanceState = nResInstanceState;
}
@@ -75,6 +77,7 @@
* Sets the resource ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setResId(String resourceId) {
this.mId = resourceId;
}
@@ -93,6 +96,7 @@
* code.
* @hide
*/
+ @UnsupportedAppUsage
public void setReason(String reason) {
this.mReason = reason;
}
@@ -109,6 +113,7 @@
* Sets the entity URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setPresentityUri(String presentityUri) {
this.mPresentityUri = presentityUri;
}
@@ -125,6 +130,7 @@
* Sets the tuple information.
* @hide
*/
+ @UnsupportedAppUsage
public void setTupleInfo(PresTupleInfo[] tupleInfo) {
this.mTupleInfoArray = new PresTupleInfo[tupleInfo.length];
this.mTupleInfoArray = tupleInfo;
@@ -135,6 +141,7 @@
* Constructor for the PresResInstanceInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresResInstanceInfo(){
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java
index 987dd77..ab46e4b 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -60,6 +61,7 @@
* Sets the URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setUri(String uri) {
this.mUri = uri;
}
@@ -76,6 +78,7 @@
* Sets the version.
* @hide
*/
+ @UnsupportedAppUsage
public void setVersion(int version) {
this.mVersion = version;
}
@@ -92,6 +95,7 @@
* Sets the RLMI state.
* @hide
*/
+ @UnsupportedAppUsage
public void setFullState(boolean fullState) {
this.mFullState = fullState;
}
@@ -108,6 +112,7 @@
* Sets the RLMI list name.
* @hide
*/
+ @UnsupportedAppUsage
public void setListName(String listName) {
this.mListName = listName;
}
@@ -124,6 +129,7 @@
* Sets the subscription request ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -140,6 +146,7 @@
* Sets the presence subscription state.
* @hide
*/
+ @UnsupportedAppUsage
public void setPresSubscriptionState(PresSubscriptionState presSubscriptionState) {
this.mPresSubscriptionState = presSubscriptionState;
}
@@ -156,6 +163,7 @@
* Sets the presence subscription expiration time.
* @hide
*/
+ @UnsupportedAppUsage
public void setSubscriptionExpireTime(int subscriptionExpireTime) {
this.mSubscriptionExpireTime = subscriptionExpireTime;
}
@@ -172,6 +180,7 @@
* Sets the presence subscription terminated reason.
* @hide
*/
+ @UnsupportedAppUsage
public void setSubscriptionTerminatedReason(String subscriptionTerminatedReason) {
this.mSubscriptionTerminatedReason = subscriptionTerminatedReason;
}
@@ -180,6 +189,7 @@
* Constructor for the PresTupleInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresRlmiInfo(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java
index f7b7264..83ba722 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -45,6 +46,7 @@
* Gets the media type.
* @hide
*/
+ @UnsupportedAppUsage
public int getMediaType() {
return mMediaCap;
}
@@ -61,6 +63,7 @@
* Gets the service ID.
* @hide
*/
+ @UnsupportedAppUsage
public String getServiceId() {
return mServiceID;
}
@@ -76,6 +79,7 @@
* Gets the service description.
* @hide
*/
+ @UnsupportedAppUsage
public String getServiceDesc() {
return mServiceDesc;
}
@@ -92,6 +96,7 @@
* Gets the service version.
* @hide
*/
+ @UnsupportedAppUsage
public String getServiceVer() {
return mServiceVer;
}
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java b/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java
index 456b443..5e42592 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +33,7 @@
* Gets the Presence command ID.
* @hide
*/
+ @UnsupportedAppUsage
public PresCmdId getCmdId() {
return mCmdId;
}
@@ -40,6 +42,7 @@
* Sets the Presence command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(PresCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -48,6 +51,7 @@
* Gets the request ID.
* @hide
*/
+ @UnsupportedAppUsage
public int getRequestId() {
return mRequestId;
}
@@ -56,6 +60,7 @@
* Sets the request ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -64,6 +69,7 @@
* Gets the SIP response code.
* @hide
*/
+ @UnsupportedAppUsage
public int getSipResponseCode() {
return mSipResponseCode;
}
@@ -72,6 +78,7 @@
* Sets the SIP response code.
* @hide
*/
+ @UnsupportedAppUsage
public void setSipResponseCode(int sipResponseCode) {
this.mSipResponseCode = sipResponseCode;
}
@@ -82,6 +89,7 @@
* code.
* @hide
*/
+ @UnsupportedAppUsage
public String getReasonPhrase() {
return mReasonPhrase;
}
@@ -90,6 +98,7 @@
* Sets the SIP response code reason phrase.
* @hide
*/
+ @UnsupportedAppUsage
public void setReasonPhrase(String reasonPhrase) {
this.mReasonPhrase = reasonPhrase;
}
@@ -98,6 +107,7 @@
* Gets the SIP retryAfter sec value.
* @hide
*/
+ @UnsupportedAppUsage
public int getRetryAfter() {
return mRetryAfter;
}
@@ -106,6 +116,7 @@
* Sets the SIP retryAfter sec value
* @hide
*/
+ @UnsupportedAppUsage
public void setRetryAfter(int retryAfter) {
this.mRetryAfter = retryAfter;
}
@@ -114,6 +125,7 @@
* Constructor for the PresSipResponse class.
* @hide
*/
+ @UnsupportedAppUsage
public PresSipResponse(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java b/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java
index 872bc23..bee928c 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -77,6 +78,7 @@
* Constructor for the PresSubscriptionState class.
* @hide
*/
+ @UnsupportedAppUsage
public PresSubscriptionState() { };
/**
@@ -92,6 +94,7 @@
* Sets the Presence subscription state.
* @hide
*/
+ @UnsupportedAppUsage
public void setPresSubscriptionState(int nPresSubscriptionState) {
this.mPresSubscriptionState = nPresSubscriptionState;
}
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
index e1867c5..7a47786 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -39,6 +40,7 @@
* Sets the feature tag.
* @hide
*/
+ @UnsupportedAppUsage
public void setFeatureTag(String featureTag) {
this.mFeatureTag = featureTag;
}
@@ -54,6 +56,7 @@
* Sets the contact URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setContactUri(String contactUri) {
this.mContactUri = contactUri;
}
@@ -70,6 +73,7 @@
* Sets the timestamp.
* @hide
*/
+ @UnsupportedAppUsage
public void setTimestamp(String timestamp) {
this.mTimestamp = timestamp;
}
@@ -78,6 +82,7 @@
* Constructor for the PresTupleInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresTupleInfo(){};
/** @hide */
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d850fbc..f9c3940 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -390,7 +390,7 @@
/**
* Returns the neighboring cell information of the device.
*/
- List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
+ List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg, int targetSdk);
int getCallState();
diff --git a/vr/java/com/google/vr/platform/DeviceInfo.java b/vr/java/com/google/vr/platform/DeviceInfo.java
index f6da66b..6a4617d 100644
--- a/vr/java/com/google/vr/platform/DeviceInfo.java
+++ b/vr/java/com/google/vr/platform/DeviceInfo.java
@@ -1,5 +1,6 @@
package com.google.vr.platform;
+import android.annotation.UnsupportedAppUsage;
import android.os.SystemProperties;
/**
@@ -13,6 +14,7 @@
/**
* Returns true if this device boots directly in VR mode.
*/
+ @UnsupportedAppUsage
public static boolean getVrBoot() {
return SystemProperties.getBoolean(VR_MODE_BOOT, false);
}
diff --git a/vr/java/com/google/vr/platform/Dvr.java b/vr/java/com/google/vr/platform/Dvr.java
index b07d634..41dcd87 100644
--- a/vr/java/com/google/vr/platform/Dvr.java
+++ b/vr/java/com/google/vr/platform/Dvr.java
@@ -1,5 +1,7 @@
package com.google.vr.platform;
+import android.annotation.UnsupportedAppUsage;
+
/**
* Class to load the dvr api.
* @hide
@@ -10,6 +12,7 @@
*
* @return A Long object describing the handle returned by dlopen.
*/
+ @UnsupportedAppUsage
public static Long loadLibrary() {
// Load a thin JNI library that runs dlopen on request.
System.loadLibrary("dvr_loader");
diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
index 2ea6e79..66297fc 100644
--- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
+++ b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
@@ -16,11 +16,12 @@
package android.net.wifi.hotspot2;
+import android.net.wifi.WifiManager;
import android.os.Handler;
/**
* Base class for provisioning callbacks. Should be extended by applications and set when calling
- * {@link WifiManager#startSubscriptionProvisiong(OsuProvider, ProvisioningCallback, Handler)}.
+ * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, ProvisioningCallback, Handler)}.
*
* @hide
*/
@@ -28,84 +29,101 @@
/**
* The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
*/
- public static final int OSU_FAILURE_AP_CONNECTION = 1;
+ public static final int OSU_FAILURE_AP_CONNECTION = 1;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for invalid server URL address.
*/
public static final int OSU_FAILURE_SERVER_URL_INVALID = 2;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to connection failure to the server.
*/
- public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
+ public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to invalid server certificate.
*/
- public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
+ public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to invalid service provider.
*/
- public static final int OSU_FAILURE_PROVIDER_VERIFICATION = 5;
+ public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5;
/**
- * The reason code for Provisioning Failure when a provisioning flow is aborted.
- * @hide
+ * The reason code for provisioning failure when a provisioning flow is aborted.
*/
public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6;
/**
- * The reason code for Provisioning Failure when a provisioning flow is aborted.
- * @hide
+ * The reason code for provisioning failure when a provisioning flow is not possible.
*/
public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The reason code for provisioning failure due to invalid server url.
*/
- public static final int OSU_STATUS_AP_CONNECTING = 1;
+ public static final int OSU_FAILURE_INVALID_SERVER_URL = 8;
/**
- * The status code for Provisioning flow to indicate connected to OSU AP
- * @hide
+ * The reason code for provisioning failure when a command received is not the expected command
+ * type.
*/
- public static final int OSU_STATUS_AP_CONNECTED = 2;
+ public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The reason code for provisioning failure when a SOAP message is not the expected message
+ * type.
*/
- public static final int OSU_STATUS_SERVER_CONNECTED = 3;
+ public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The reason code for provisioning failure when a SOAP message exchange fails.
*/
- public static final int OSU_STATUS_SERVER_VALIDATED = 4;
+ public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The status code for provisioning flow to indicate connecting to OSU AP
*/
- public static final int OSU_STATUS_PROVIDER_VERIFIED = 5;
+ public static final int OSU_STATUS_AP_CONNECTING = 1;
+
+ /**
+ * The status code for provisioning flow to indicate the OSU AP is connected.
+ */
+ public static final int OSU_STATUS_AP_CONNECTED = 2;
+
+ /**
+ * The status code for provisioning flow to indicate the server connection is completed.
+ */
+ public static final int OSU_STATUS_SERVER_CONNECTED = 3;
+
+ /**
+ * The status code for provisioning flow to indicate the server certificate is validated.
+ */
+ public static final int OSU_STATUS_SERVER_VALIDATED = 4;
+
+ /**
+ * The status code for provisioning flow to indicate the service provider is verified.
+ */
+ public static final int OSU_STATUS_SERVICE_PROVIDER_VERIFIED = 5;
+
+ /**
+ * The status code for provisioning flow to indicate starting the SOAP exchange.
+ */
+ public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6;
/**
* Provisioning status for OSU failure
+ *
* @param status indicates error condition
*/
public abstract void onProvisioningFailure(int status);
/**
* Provisioning status when OSU is in progress
+ *
* @param status indicates status of OSU flow
*/
public abstract void onProvisioningStatus(int status);