diff options
56 files changed, 1011 insertions, 225 deletions
diff --git a/api/current.txt b/api/current.txt index 65c4d87a4b84..dd71724bdeac 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6464,7 +6464,6 @@ package android.app.admin { method public int getLockTaskFeatures(android.content.ComponentName); method public java.lang.String[] getLockTaskPackages(android.content.ComponentName); method public java.lang.CharSequence getLongSupportMessage(android.content.ComponentName); - method public android.content.ComponentName getMandatoryBackupTransport(); method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName); method public long getMaximumTimeToLock(android.content.ComponentName); method public java.util.List<java.lang.String> getMeteredDataDisabledPackages(android.content.ComponentName); @@ -6571,7 +6570,6 @@ package android.app.admin { method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException; method public void setLogoutEnabled(android.content.ComponentName, boolean); method public void setLongSupportMessage(android.content.ComponentName, java.lang.CharSequence); - method public boolean setMandatoryBackupTransport(android.content.ComponentName, android.content.ComponentName); method public void setMasterVolumeMuted(android.content.ComponentName, boolean); method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int); method public void setMaximumTimeToLock(android.content.ComponentName, long); @@ -6732,7 +6730,6 @@ package android.app.admin { field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0 field public static final java.lang.String POLICY_DISABLE_CAMERA = "policy_disable_camera"; field public static final java.lang.String POLICY_DISABLE_SCREEN_CAPTURE = "policy_disable_screen_capture"; - field public static final java.lang.String POLICY_MANDATORY_BACKUPS = "policy_mandatory_backups"; field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 @@ -7400,7 +7397,7 @@ package android.app.usage { public static class NetworkStats.Bucket { ctor public NetworkStats.Bucket(); - method public int getDefaultNetwork(); + method public int getDefaultNetworkStatus(); method public long getEndTimeStamp(); method public int getMetered(); method public int getRoaming(); @@ -10956,7 +10953,7 @@ package android.content.pm { method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle); method public abstract void onPackagesAvailable(java.lang.String[], android.os.UserHandle, boolean); method public void onPackagesSuspended(java.lang.String[], android.os.UserHandle); - method public void onPackagesSuspended(java.lang.String[], android.os.Bundle, android.os.UserHandle); + method public void onPackagesSuspended(java.lang.String[], android.os.UserHandle, android.os.Bundle); method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean); method public void onPackagesUnsuspended(java.lang.String[], android.os.UserHandle); method public void onShortcutsChanged(java.lang.String, java.util.List<android.content.pm.ShortcutInfo>, android.os.UserHandle); diff --git a/api/system-current.txt b/api/system-current.txt index a559b7a27f59..308b03e119c8 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1030,7 +1030,7 @@ package android.content.pm { method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle); method public abstract int installExistingPackage(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract int installExistingPackage(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public boolean isPackageSuspended(java.lang.String); + method public boolean isPackageSuspended(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(android.content.Intent, int, android.os.UserHandle); method public abstract void registerDexModule(java.lang.String, android.content.pm.PackageManager.DexModuleRegisterCallback); method public abstract void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); @@ -4396,6 +4396,7 @@ package android.security.keystore.recovery { method public java.security.Key importKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException; method public deprecated void initRecoveryService(java.lang.String, byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; method public void initRecoveryService(java.lang.String, byte[], byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException; + method public static boolean isRecoverableKeyStoreEnabled(android.content.Context); method public void removeKey(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public void setRecoverySecretTypes(int[]) throws android.security.keystore.recovery.InternalRecoveryServiceException; method public deprecated void setRecoveryStatus(java.lang.String, java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.content.pm.PackageManager.NameNotFoundException; diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 73d1102dc090..4f068fe3df73 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -136,6 +136,7 @@ Landroid/app/ActivityThread$ServiceArgsData;->args:Landroid/content/Intent; Landroid/app/ActivityThread$ServiceArgsData;->token:Landroid/os/IBinder; Landroid/app/ActivityThread;->sPackageManager:Landroid/content/pm/IPackageManager; Landroid/app/ActivityThread;->startActivityNow(Landroid/app/Activity;Ljava/lang/String;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Landroid/os/IBinder;Landroid/os/Bundle;Landroid/app/Activity$NonConfigurationInstances;)Landroid/app/Activity; +Landroid/app/admin/DevicePolicyManager;->getProfileOwnerAsUser(I)Landroid/content/ComponentName; Landroid/app/admin/DevicePolicyManager;->getTrustAgentConfiguration(Landroid/content/ComponentName;Landroid/content/ComponentName;I)Ljava/util/List; Landroid/app/admin/DevicePolicyManager;->packageHasActiveAdmins(Ljava/lang/String;I)Z Landroid/app/admin/DevicePolicyManager;->setActiveAdmin(Landroid/content/ComponentName;ZI)V @@ -196,6 +197,7 @@ Landroid/app/AppOpsManager;->OP_PROJECT_MEDIA:I Landroid/app/AppOpsManager;->OP_READ_CONTACTS:I Landroid/app/AppOpsManager;->OP_READ_PHONE_STATE:I Landroid/app/AppOpsManager;->OP_READ_SMS:I +Landroid/app/AppOpsManager;->OP_RUN_IN_BACKGROUND:I Landroid/app/AppOpsManager;->OP_VIBRATE:I Landroid/app/AppOpsManager;->OP_WIFI_SCAN:I Landroid/app/AppOpsManager;->OP_WRITE_CONTACTS:I @@ -425,8 +427,17 @@ Landroid/bluetooth/BluetoothHeadset;->disconnectAudio()Z Landroid/bluetooth/BluetoothHeadset;->startScoUsingVirtualVoiceCall(Landroid/bluetooth/BluetoothDevice;)Z Landroid/bluetooth/BluetoothHeadset;->stopScoUsingVirtualVoiceCall(Landroid/bluetooth/BluetoothDevice;)Z Landroid/bluetooth/BluetoothMapClient;->sendMessage(Landroid/bluetooth/BluetoothDevice;[Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)Z +Landroid/bluetooth/BluetoothPan;->close()V +Landroid/bluetooth/BluetoothPan;->connect(Landroid/bluetooth/BluetoothDevice;)Z +Landroid/bluetooth/BluetoothPan;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z +Landroid/bluetooth/BluetoothPan;->doBind()Z +Landroid/bluetooth/BluetoothPan;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V +Landroid/bluetooth/BluetoothPan;->isEnabled()Z Landroid/bluetooth/BluetoothPan;->isTetheringOn()Z +Landroid/bluetooth/BluetoothPan;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z +Landroid/bluetooth/BluetoothPan;->log(Ljava/lang/String;)V Landroid/bluetooth/BluetoothPan;->setBluetoothTethering(Z)V +Landroid/bluetooth/BluetoothProfile;->PAN:I Landroid/bluetooth/BluetoothUuid;->RESERVED_UUIDS:[Landroid/os/ParcelUuid; Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String; Landroid/bluetooth/IBluetoothManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V @@ -499,6 +510,7 @@ Landroid/content/pm/ApplicationInfo;->scanPublicSourceDir:Ljava/lang/String; Landroid/content/pm/ApplicationInfo;->scanSourceDir:Ljava/lang/String; Landroid/content/pm/ApplicationInfo;->secondaryCpuAbi:Ljava/lang/String; Landroid/content/pm/ApplicationInfo;->secondaryNativeLibraryDir:Ljava/lang/String; +Landroid/content/pm/ApplicationInfo;->versionCode:I Landroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName; Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver; Landroid/content/pm/IPackageManager;->addPermissionAsync(Landroid/content/pm/PermissionInfo;)Z @@ -621,6 +633,7 @@ Landroid/content/res/ColorStateList;->mColors:[I Landroid/content/res/ColorStateList;->mDefaultColor:I Landroid/content/res/ColorStateList;->mFactory:Landroid/content/res/ColorStateList$ColorStateListFactory; Landroid/content/res/ColorStateList;->mStateSpecs:[[I +Landroid/content/res/ColorStateList;->onColorsChanged()V Landroid/content/res/CompatibilityInfo;->applicationScale:F Landroid/content/res/CompatibilityInfo;->DEFAULT_COMPATIBILITY_INFO:Landroid/content/res/CompatibilityInfo; Landroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable; @@ -689,6 +702,7 @@ Landroid/database/sqlite/SQLiteDatabaseConfiguration;->maxSqlCacheSize:I Landroid/database/sqlite/SQLiteDatabase;->CONFLICT_VALUES:[Ljava/lang/String; Landroid/database/sqlite/SQLiteDatabase;->mConfigurationLocked:Landroid/database/sqlite/SQLiteDatabaseConfiguration; Landroid/database/sqlite/SQLiteDatabase;->mConnectionPoolLocked:Landroid/database/sqlite/SQLiteConnectionPool; +Landroid/database/sqlite/SQLiteDatabase;->reopenReadWrite()V Landroid/database/sqlite/SQLiteDebug$PagerStats;->largestMemAlloc:I Landroid/database/sqlite/SQLiteDebug$PagerStats;->memoryUsed:I Landroid/database/sqlite/SQLiteDebug$PagerStats;->pageCacheOverflow:I @@ -736,6 +750,7 @@ Landroid/graphics/drawable/DrawableContainer;->mDrawableContainerState:Landroid/ Landroid/graphics/drawable/Drawable;->getOpticalInsets()Landroid/graphics/Insets; 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;->parseTintMode(ILandroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuff$Mode; Landroid/graphics/drawable/GradientDrawable$GradientState;->mAngle:I Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradientColors:[I Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradient:I @@ -748,12 +763,14 @@ Landroid/graphics/drawable/GradientDrawable$GradientState;->mPositions:[F Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadiusArray:[F Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadius: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;->mGradientState:Landroid/graphics/drawable/GradientDrawable$GradientState; Landroid/graphics/drawable/GradientDrawable;->mPadding:Landroid/graphics/Rect; Landroid/graphics/drawable/Icon;->getBitmap()Landroid/graphics/Bitmap; Landroid/graphics/drawable/Icon;->getDataBytes()[B @@ -763,9 +780,13 @@ Landroid/graphics/drawable/Icon;->getResources()Landroid/content/res/Resources; Landroid/graphics/drawable/Icon;->hasTint()Z 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;->mLayerState:Landroid/graphics/drawable/LayerDrawable$LayerState; Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState; Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;->mNinePatch:Landroid/graphics/NinePatch; +Landroid/graphics/drawable/RippleDrawable;->mState:Landroid/graphics/drawable/RippleDrawable$RippleState; +Landroid/graphics/drawable/RippleDrawable$RippleState;->mColor:Landroid/content/res/ColorStateList; Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I Landroid/graphics/drawable/StateListDrawable;->getStateCount()I Landroid/graphics/drawable/StateListDrawable;->getStateDrawable(I)Landroid/graphics/drawable/Drawable; @@ -785,6 +806,8 @@ Landroid/graphics/GraphicBuffer;->CREATOR:Landroid/os/Parcelable$Creator; Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V Landroid/graphics/GraphicBuffer;->mNativeObject:J Landroid/graphics/ImageDecoder;->postProcessAndRelease(Landroid/graphics/Canvas;)I +Landroid/graphics/Insets;->left:I +Landroid/graphics/Insets;->right:I Landroid/graphics/LinearGradient;->mColors:[I Landroid/graphics/Matrix;->native_instance:J Landroid/graphics/Movie;-><init>(J)V @@ -1477,6 +1500,7 @@ Landroid/os/storage/StorageManager;->findVolumeByUuid(Ljava/lang/String;)Landroi Landroid/os/storage/StorageManager;->getBestVolumeDescription(Landroid/os/storage/VolumeInfo;)Ljava/lang/String; Landroid/os/storage/StorageManager;->getDisks()Ljava/util/List; Landroid/os/storage/StorageManager;->getStorageBytesUntilLow(Ljava/io/File;)J +Landroid/os/storage/StorageManager;->getStorageFullBytes(Ljava/io/File;)J Landroid/os/storage/StorageManager;->getStorageLowBytes(Ljava/io/File;)J Landroid/os/storage/StorageManager;->getVolumeList(II)[Landroid/os/storage/StorageVolume; Landroid/os/storage/StorageManager;->getVolumeList()[Landroid/os/storage/StorageVolume; @@ -1496,8 +1520,10 @@ Landroid/os/storage/VolumeInfo;->getType()I Landroid/os/storage/VolumeInfo;->isPrimary()Z Landroid/os/storage/VolumeInfo;->isVisible()Z Landroid/os/StrictMode;->disableDeathOnFileUriExposure()V +Landroid/os/StrictMode;->enterCriticalSpan(Ljava/lang/String;)Landroid/os/StrictMode$Span; Landroid/os/StrictMode;->getThreadPolicyMask()I Landroid/os/StrictMode;->onBinderStrictModePolicyChange(I)V +Landroid/os/StrictMode$Span;->finish()V Landroid/os/StrictMode$ThreadPolicy$Builder;->penaltyListener(Landroid/os/StrictMode$OnThreadViolationListener;Ljava/util/concurrent/Executor;)Landroid/os/StrictMode$ThreadPolicy$Builder; Landroid/os/StrictMode;->violationsBeingTimed:Ljava/lang/ThreadLocal; Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V @@ -1631,6 +1657,7 @@ Landroid/provider/Browser;->sendString(Landroid/content/Context;Ljava/lang/Strin Landroid/provider/Browser;->updateVisitedHistory(Landroid/content/ContentResolver;Ljava/lang/String;Z)V Landroid/provider/CalendarContract$CalendarAlerts;->findNextAlarmTime(Landroid/content/ContentResolver;J)J Landroid/provider/CalendarContract$CalendarAlerts;->rescheduleMissedAlarms(Landroid/content/ContentResolver;Landroid/content/Context;Landroid/app/AlarmManager;)V +Landroid/provider/Downloads$Impl;->CONTENT_URI:Landroid/net/Uri; Landroid/provider/Settings$ContentProviderHolder;->mContentProvider:Landroid/content/IContentProvider; Landroid/provider/Settings$Global;->ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED:Ljava/lang/String; Landroid/provider/Settings$Global;->PACKAGE_VERIFIER_ENABLE:Ljava/lang/String; @@ -1868,6 +1895,7 @@ Landroid/service/media/MediaBrowserService;->KEY_MEDIA_ITEM:Ljava/lang/String; Landroid/service/media/MediaBrowserService$Result;->mFlags:I Landroid/service/notification/NotificationListenerService;->registerAsSystemService(Landroid/content/Context;Landroid/content/ComponentName;I)V Landroid/service/notification/NotificationListenerService;->unregisterAsSystemService()V +Landroid/service/notification/StatusBarNotification;->getUid()I Landroid/service/voice/AlwaysOnHotwordDetector$EventPayload;->getCaptureSession()Ljava/lang/Integer; Landroid/service/voice/VoiceInteractionService;->isKeyphraseAndLocaleSupportedForHotword(Ljava/lang/String;Ljava/util/Locale;)Z Landroid/service/vr/IVrManager;->getVr2dDisplayId()I @@ -1978,6 +2006,7 @@ Landroid/telephony/SubscriptionManager;->getDefaultVoiceSubscriptionInfo()Landro Landroid/telephony/SubscriptionManager;->getPhoneId(I)I Landroid/telephony/SubscriptionManager;->getSlotIndex(I)I Landroid/telephony/SubscriptionManager;->getSubId(I)[I +Landroid/telephony/SubscriptionManager;->setDefaultDataSubId(I)V Landroid/telephony/SubscriptionManager;->setDefaultSmsSubId(I)V Landroid/telephony/TelephonyManager;->from(Landroid/content/Context;)Landroid/telephony/TelephonyManager; Landroid/telephony/TelephonyManager;->getCallState(I)I @@ -2014,6 +2043,7 @@ Landroid/telephony/TelephonyManager;->isVolteAvailable()Z Landroid/telephony/TelephonyManager;->isWifiCallingAvailable()Z Landroid/telephony/TelephonyManager;->mSubscriptionManager:Landroid/telephony/SubscriptionManager; Landroid/text/AndroidBidi;->bidi(I[C[B)I +Landroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics; Landroid/text/DynamicLayout;-><init>(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZIIILandroid/text/TextUtils$TruncateAt;I)V Landroid/text/DynamicLayout;->sStaticLayout:Landroid/text/StaticLayout; Landroid/text/Html;->withinStyle(Ljava/lang/StringBuilder;Ljava/lang/CharSequence;II)V @@ -2079,6 +2109,7 @@ Landroid/text/TextLine;->mText:Ljava/lang/CharSequence; Landroid/text/TextLine;->obtain()Landroid/text/TextLine; Landroid/text/TextLine;->sCached:[Landroid/text/TextLine; Landroid/text/TextPaint;->setUnderlineText(IF)V +Landroid/text/TextUtils$TruncateAt;->END_SMALL:Landroid/text/TextUtils$TruncateAt; Landroid/transition/ChangeBounds;->BOTTOM_RIGHT_ONLY_PROPERTY:Landroid/util/Property; Landroid/transition/ChangeBounds;->POSITION_PROPERTY:Landroid/util/Property; Landroid/transition/TransitionManager;->sRunningTransitions:Ljava/lang/ThreadLocal; @@ -2092,6 +2123,7 @@ Landroid/util/Log;->wtf(ILjava/lang/String;Ljava/lang/String;Ljava/lang/Throwabl Landroid/util/LongSparseLongArray;->mKeys:[J Landroid/util/LongSparseLongArray;->mSize:I Landroid/util/LongSparseLongArray;->mValues:[J +Landroid/util/MathUtils;->constrain(III)I Landroid/util/NtpTrustedTime;->forceRefresh()Z Landroid/util/NtpTrustedTime;->getCachedNtpTime()J Landroid/util/NtpTrustedTime;->getCachedNtpTimeReference()J @@ -2100,6 +2132,7 @@ Landroid/util/NtpTrustedTime;->hasCache()Z Landroid/util/Pools$SimplePool;->mPool:[Ljava/lang/Object; Landroid/util/Pools$SynchronizedPool;->acquire()Ljava/lang/Object; Landroid/util/Pools$SynchronizedPool;-><init>(I)V +Landroid/util/Pools$SynchronizedPool;->release(Ljava/lang/Object;)Z Landroid/util/Rational;->mDenominator:I Landroid/util/Rational;->mNumerator:I Landroid/util/Singleton;->get()Ljava/lang/Object; @@ -2127,6 +2160,7 @@ Landroid/view/accessibility/AccessibilityRecord;->getSourceNodeId()J Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List; Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager; Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V +Landroid/view/animation/Animation;->detach()V Landroid/view/animation/Animation;->initializeInvalidateRegion(IIII)V Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener; Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V @@ -2171,10 +2205,12 @@ Landroid/view/inputmethod/InputMethodManager;->finishInputLocked()V Landroid/view/inputmethod/InputMethodManager;->focusIn(Landroid/view/View;)V Landroid/view/inputmethod/InputMethodManager;->focusOut(Landroid/view/View;)V Landroid/view/inputmethod/InputMethodManager;->getInputMethodWindowVisibleHeight()I +Landroid/view/inputmethod/InputMethodManager;->getInstance()Landroid/view/inputmethod/InputMethodManager; Landroid/view/inputmethod/InputMethodManager;->mCurId:Ljava/lang/String; Landroid/view/inputmethod/InputMethodManager;->mCurRootView:Landroid/view/View; Landroid/view/inputmethod/InputMethodManager;->mH:Landroid/view/inputmethod/InputMethodManager$H; Landroid/view/inputmethod/InputMethodManager;->mNextServedView:Landroid/view/View; +Landroid/view/inputmethod/InputMethodManager;->mServedInputConnectionWrapper:Landroid/view/inputmethod/InputMethodManager$ControlledInputConnectionWrapper; Landroid/view/inputmethod/InputMethodManager;->mServedView:Landroid/view/View; Landroid/view/inputmethod/InputMethodManager;->mService:Lcom/android/internal/view/IInputMethodManager; Landroid/view/inputmethod/InputMethodManager;->notifyUserAction()V @@ -2200,6 +2236,7 @@ Landroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;ILandro Landroid/view/KeyCharacterMap$FallbackAction;->keyCode:I Landroid/view/KeyCharacterMap$FallbackAction;->metaState:I Landroid/view/KeyCharacterMap;-><init>(J)V +Landroid/view/KeyEvent;->isConfirmKey(I)Z Landroid/view/KeyEvent;->mAction:I Landroid/view/KeyEvent;->mCharacters:Ljava/lang/String; Landroid/view/KeyEvent;->mDeviceId:I @@ -2252,6 +2289,9 @@ Landroid/view/RemoteAnimationTarget;->sourceContainerBounds:Landroid/graphics/Re Landroid/view/RemoteAnimationTarget;->taskId:I Landroid/view/RemoteAnimationTarget;->windowConfiguration:Landroid/app/WindowConfiguration; Landroid/view/RenderNodeAnimator;->callOnFinished(Landroid/view/RenderNodeAnimator;)V +Landroid/view/RenderNodeAnimator;-><init>(IF)V +Landroid/view/RenderNodeAnimator;->mapViewPropertyToRenderProperty(I)I +Landroid/view/RenderNodeAnimator;->setTarget(Landroid/view/View;)V Landroid/view/RenderNode;->discardDisplayList()V Landroid/view/RenderNode;->output()V Landroid/view/ScaleGestureDetector;->mListener:Landroid/view/ScaleGestureDetector$OnScaleGestureListener; @@ -2288,6 +2328,9 @@ Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;- Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(IILandroid/view/textclassifier/TextSelection;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionStarted(I)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; Landroid/view/textclassifier/TextClassificationManager;->getTextClassifier(I)Landroid/view/textclassifier/TextClassifier; +Landroid/view/textclassifier/TextClassifier;->classifyText(Ljava/lang/CharSequence;IILandroid/view/textclassifier/TextClassification$Options;)Landroid/view/textclassifier/TextClassification; +Landroid/view/textclassifier/TextClassifier;->generateLinks(Ljava/lang/CharSequence;Landroid/view/textclassifier/TextLinks$Options;)Landroid/view/textclassifier/TextLinks; +Landroid/view/textclassifier/TextClassifier;->suggestSelection(Ljava/lang/CharSequence;IILandroid/view/textclassifier/TextSelection$Options;)Landroid/view/textclassifier/TextSelection; Landroid/view/textservice/TextServicesManager;->isSpellCheckerEnabled()Z Landroid/view/TextureView;->destroyHardwareLayer()V Landroid/view/TextureView;->destroyHardwareResources()V @@ -2368,6 +2411,7 @@ Landroid/view/View$ListenerInfo;->mOnLongClickListener:Landroid/view/View$OnLong Landroid/view/View$ListenerInfo;->mOnTouchListener:Landroid/view/View$OnTouchListener; Landroid/view/View;->mAccessibilityDelegate:Landroid/view/View$AccessibilityDelegate; Landroid/view/View;->mAttachInfo:Landroid/view/View$AttachInfo; +Landroid/view/View;->mBackground:Landroid/graphics/drawable/Drawable; Landroid/view/View;->mBottom:I Landroid/view/View;->mContext:Landroid/content/Context; Landroid/view/View;->mDrawingCache:Landroid/graphics/Bitmap; @@ -2409,7 +2453,10 @@ Landroid/view/View;->resetResolvedTextAlignment()V Landroid/view/View;->resetResolvedTextDirection()V Landroid/view/View;->resetRtlProperties()V Landroid/view/ViewRootImpl;->detachFunctor(J)V +Landroid/view/ViewRootImpl;->dispatchInputEvent(Landroid/view/InputEvent;Landroid/view/InputEventReceiver;)V +Landroid/view/ViewRootImpl;->dispatchInputEvent(Landroid/view/InputEvent;)V Landroid/view/ViewRootImpl;->enqueueInputEvent(Landroid/view/InputEvent;)V +Landroid/view/ViewRootImpl;->getWindowFlags()I Landroid/view/ViewRootImpl;->invokeFunctor(JZ)V Landroid/view/ViewRootImpl;->mStopped:Z Landroid/view/ViewRootImpl;->mSurface:Landroid/view/Surface; @@ -2628,6 +2675,7 @@ Landroid/widget/MediaController;->mWindowManager:Landroid/view/WindowManager; Landroid/widget/NumberPicker;->mInputText:Landroid/widget/EditText; Landroid/widget/NumberPicker;->mSelectionDivider:Landroid/graphics/drawable/Drawable; Landroid/widget/NumberPicker;->mSelectorWheelPaint:Landroid/graphics/Paint; +Landroid/widget/OverScroller;->isScrollingInDirection(FF)Z Landroid/widget/OverScroller;->mScrollerY:Landroid/widget/OverScroller$SplineOverScroller; Landroid/widget/OverScroller$SplineOverScroller;->mCurrVelocity:F Landroid/widget/PopupMenu;->mPopup:Lcom/android/internal/view/menu/MenuPopupHelper; @@ -2655,6 +2703,7 @@ Landroid/widget/PopupWindow;->setEpicenterBounds(Landroid/graphics/Rect;)V Landroid/widget/PopupWindow;->setLayoutInScreenEnabled(Z)V Landroid/widget/PopupWindow;->setLayoutInsetDecor(Z)V Landroid/widget/PopupWindow;->setTouchModal(Z)V +Landroid/widget/PopupWindow;->showAtLocation(Landroid/os/IBinder;III)V Landroid/widget/ProgressBar;->mCurrentDrawable:Landroid/graphics/drawable/Drawable; Landroid/widget/ProgressBar;->mDuration:I Landroid/widget/ProgressBar;->mIndeterminate:Z @@ -3004,6 +3053,7 @@ Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I Lcom/android/internal/R$styleable;->DialogPreference:[I Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I Lcom/android/internal/R$styleable;->EdgeEffect:[I +Lcom/android/internal/R$styleable;->GridView:[I Lcom/android/internal/R$styleable;->IconMenuView:[I Lcom/android/internal/R$styleable;->ImageView:[I Lcom/android/internal/R$styleable;->ImageView_src:I @@ -3047,6 +3097,7 @@ Lcom/android/internal/R$styleable;->SyncAdapter_supportsUploading:I Lcom/android/internal/R$styleable;->SyncAdapter_userVisible:I Lcom/android/internal/R$styleable;->TabWidget:[I Lcom/android/internal/R$styleable;->TextAppearance:[I +Lcom/android/internal/R$styleable;->TextViewAppearance:[I Lcom/android/internal/R$styleable;->TextView_drawableBottom:I Lcom/android/internal/R$styleable;->TextView_drawableLeft:I Lcom/android/internal/R$styleable;->TextView_drawableRight:I @@ -3093,6 +3144,11 @@ Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBind Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I +Lcom/android/internal/telephony/SmsHeader;->concatRef:Lcom/android/internal/telephony/SmsHeader$ConcatRef; +Lcom/android/internal/telephony/SmsHeader$ConcatRef;->msgCount:I +Lcom/android/internal/telephony/SmsHeader$ConcatRef;->refNumber:I +Lcom/android/internal/telephony/SmsHeader$ConcatRef;->seqNumber:I +Lcom/android/internal/telephony/SmsMessageBase;->mUserDataHeader:Lcom/android/internal/telephony/SmsHeader; Lcom/android/internal/telephony/SmsRawData;->CREATOR:Landroid/os/Parcelable$Creator; Lcom/android/internal/telephony/SmsRawData;-><init>([B)V Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V @@ -3101,6 +3157,8 @@ Lcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;)V Lcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap; Lcom/android/internal/util/XmlUtils;->skipCurrentTag(Lorg/xmlpull/v1/XmlPullParser;)V Lcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/io/OutputStream;)V +Lcom/android/internal/view/IInputConnectionWrapper;->mInputConnection:Landroid/view/inputmethod/InputConnection; +Lcom/android/internal/view/IInputConnectionWrapper;->mLock:Ljava/lang/Object; Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager; Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList()Ljava/util/List; Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V @@ -3111,6 +3169,7 @@ Lcom/android/internal/view/menu/MenuBuilder;->setCurrentMenuInfo(Landroid/view/C Lcom/android/internal/view/menu/MenuBuilder;->setOptionalIconsVisible(Z)V Lcom/android/internal/view/menu/MenuItemImpl;->mIconResId:I Lcom/android/internal/view/menu/MenuItemImpl;->setMenuInfo(Landroid/view/ContextMenu$ContextMenuInfo;)V +Lcom/android/internal/view/menu/MenuPopupHelper;->mForceShowIcon:Z Lcom/android/internal/view/menu/MenuPopupHelper;->setForceShowIcon(Z)V Lcom/android/internal/view/menu/MenuView$ItemView;->getItemData()Lcom/android/internal/view/menu/MenuItemImpl; Lcom/android/okhttp/ConnectionPool;->keepAliveDurationNs:J diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt index b598296d3df0..76bf51013867 100644 --- a/config/hiddenapi-vendor-list.txt +++ b/config/hiddenapi-vendor-list.txt @@ -501,7 +501,6 @@ Landroid/telephony/SubscriptionManager;->isValidSlotIndex(I)Z Landroid/telephony/SubscriptionManager;->isValidSubscriptionId(I)Z Landroid/telephony/SubscriptionManager;->putPhoneIdAndSubIdExtra(Landroid/content/Intent;II)V Landroid/telephony/SubscriptionManager;->putPhoneIdAndSubIdExtra(Landroid/content/Intent;I)V -Landroid/telephony/SubscriptionManager;->setDefaultDataSubId(I)V Landroid/telephony/SubscriptionManager;->setDisplayName(Ljava/lang/String;IJ)I Landroid/telephony/SubscriptionManager;->setIconTint(II)I Landroid/telephony/TelephonyManager;->getIntAtIndex(Landroid/content/ContentResolver;Ljava/lang/String;I)I diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 2e93d88e0388..1084b425ea92 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2187,8 +2187,12 @@ public class ApplicationPackageManager extends PackageManager { /** @hide */ @Override - public boolean isPackageSuspended(String packageName) { - return isPackageSuspendedForUser(packageName, mContext.getUserId()); + public boolean isPackageSuspended(String packageName) throws NameNotFoundException { + try { + return isPackageSuspendedForUser(packageName, mContext.getUserId()); + } catch (IllegalArgumentException ie) { + throw new NameNotFoundException(packageName); + } } @Override diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 990147b2cf76..c491dccbbde1 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1169,6 +1169,7 @@ public class DevicePolicyManager { * Constant to indicate the feature of mandatory backups. Used as argument to * {@link #createAdminSupportIntent(String)}. * @see #setMandatoryBackupTransport(ComponentName, ComponentName) + * @hide */ public static final String POLICY_MANDATORY_BACKUPS = "policy_mandatory_backups"; @@ -6843,8 +6844,7 @@ public class DevicePolicyManager { * @param restriction Indicates for which feature the dialog should be displayed. Can be a * user restriction from {@link UserManager}, e.g. * {@link UserManager#DISALLOW_ADJUST_VOLUME}, or one of the constants - * {@link #POLICY_DISABLE_CAMERA}, {@link #POLICY_DISABLE_SCREEN_CAPTURE} or - * {@link #POLICY_MANDATORY_BACKUPS}. + * {@link #POLICY_DISABLE_CAMERA}, {@link #POLICY_DISABLE_SCREEN_CAPTURE}. * @return Intent An intent to be used to start the dialog-activity if the restriction is * set by an admin, or null if the restriction does not exist or no admin set it. */ @@ -8791,13 +8791,6 @@ public class DevicePolicyManager { * * <p> Backup service is off by default when device owner is present. * - * <p> If backups are made mandatory by specifying a non-null mandatory backup transport using - * the {@link DevicePolicyManager#setMandatoryBackupTransport} method, the backup service is - * automatically enabled. - * - * <p> If the backup service is disabled using this method after the mandatory backup transport - * has been set, the mandatory backup transport is cleared. - * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param enabled {@code true} to enable the backup service, {@code false} to disable it. * @throws SecurityException if {@code admin} is not a device owner. @@ -8835,6 +8828,8 @@ public class DevicePolicyManager { * <p>Only device owner can call this method. * <p>If backups were disabled and a non-null backup transport {@link ComponentName} is * specified, backups will be enabled. + * <p> If the backup service is disabled after the mandatory backup transport has been set, the + * mandatory backup transport is cleared. * * <p>NOTE: The method shouldn't be called on the main thread. * @@ -8842,6 +8837,7 @@ public class DevicePolicyManager { * @param backupTransportComponent The backup transport layer to be used for mandatory backups. * @return {@code true} if the backup transport was successfully set; {@code false} otherwise. * @throws SecurityException if {@code admin} is not a device owner. + * @hide */ @WorkerThread public boolean setMandatoryBackupTransport( @@ -8861,6 +8857,7 @@ public class DevicePolicyManager { * * @return a {@link ComponentName} of the backup transport layer to be used if backups are * mandatory or {@code null} if backups are not mandatory. + * @hide */ public ComponentName getMandatoryBackupTransport() { throwIfParentInstance("getMandatoryBackupTransport"); diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index d1c957b8fedc..39b9181b9b6e 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -148,10 +148,17 @@ public abstract class BackupAgent extends ContextWrapper { * Flag for {@link BackupDataOutput#getTransportFlags()} and * {@link FullBackupDataOutput#getTransportFlags()} only. * - * <p>The transport has client-side encryption enabled. i.e., the user's backup has been - * encrypted with a key known only to the device, and not to the remote storage solution. Even - * if an attacker had root access to the remote storage provider they should not be able to - * decrypt the user's backup data. + * <p>The transport has client-side encryption enabled. i.e., the user's backup is encrypted + * with a key known only to the device, and not to the remote storage solution where the backup + * data is stored. The key may be synced to a remote trusted hardware module if it has + * protections equivalent to those described in the + * <a href="https://developer.android.com/preview/features/security/ckv-whitepaper.html">Google + * Cloud Key Vault Service whitepaper</a>. Having direct access to the trusted hardware module + * must be insufficient to decrypt the user's backup data. + * + * <p>The backup data itself must be encrypted using an AES/GCM/NoPadding cipher. The key + * material must be randomly generated using {@link java.security.SecureRandom}, and must have + * at least 256 bits of entropy. */ public static final int FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED = 1; diff --git a/core/java/android/app/backup/BackupDataOutput.java b/core/java/android/app/backup/BackupDataOutput.java index 5a66f3407417..4f90cf7781e0 100644 --- a/core/java/android/app/backup/BackupDataOutput.java +++ b/core/java/android/app/backup/BackupDataOutput.java @@ -107,8 +107,12 @@ public class BackupDataOutput { /** * Returns flags with additional information about the backup transport. For supported flags see - * {@link android.app.backup.BackupAgent} + * {@link android.app.backup.BackupAgent}. * + * <p>Returns the same flags that {@link BackupTransport#getTransportFlags()} returns. + * + * @see BackupAgent#FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED + * @see BackupAgent#FLAG_DEVICE_TO_DEVICE_TRANSFER * @see FullBackupDataOutput#getTransportFlags() */ public int getTransportFlags() { diff --git a/core/java/android/app/backup/FullBackupDataOutput.java b/core/java/android/app/backup/FullBackupDataOutput.java index 18f428339941..f1d9dc6fa93c 100644 --- a/core/java/android/app/backup/FullBackupDataOutput.java +++ b/core/java/android/app/backup/FullBackupDataOutput.java @@ -26,8 +26,12 @@ public class FullBackupDataOutput { /** * Returns flags with additional information about the backup transport. For supported flags see - * {@link android.app.backup.BackupAgent} + * {@link android.app.backup.BackupAgent}. * + * <p>Returns the same flags that {@link BackupTransport#getTransportFlags()} returns. + * + * @see BackupAgent#FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED + * @see BackupAgent#FLAG_DEVICE_TO_DEVICE_TRANSFER * @see BackupDataOutput#getTransportFlags() */ public int getTransportFlags() { diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java index 7252f028d747..216a4a0987f5 100644 --- a/core/java/android/app/usage/NetworkStats.java +++ b/core/java/android/app/usage/NetworkStats.java @@ -237,20 +237,26 @@ public final class NetworkStats implements AutoCloseable { DEFAULT_NETWORK_YES }) @Retention(RetentionPolicy.SOURCE) - public @interface DefaultNetwork {} + public @interface DefaultNetworkStatus {} /** - * Combined usage for this network regardless of whether it was the active default network. + * Combined usage for this network regardless of default network status. */ public static final int DEFAULT_NETWORK_ALL = -1; /** - * Usage that occurs while this network is not the active default network. + * Usage that occurs while this network is not a default network. + * + * <p>This implies that the app responsible for this usage requested that it occur on a + * specific network different from the one(s) the system would have selected for it. */ public static final int DEFAULT_NETWORK_NO = 0x1; /** - * Usage that occurs while this network is the active default network. + * Usage that occurs while this network is a default network. + * + * <p>This implies that the app either did not select a specific network for this usage, + * or it selected a network that the system could have selected for app traffic. */ public static final int DEFAULT_NETWORK_YES = 0x2; @@ -262,7 +268,7 @@ public final class NetworkStats implements AutoCloseable { private int mUid; private int mTag; private int mState; - private int mDefaultNetwork; + private int mDefaultNetworkStatus; private int mMetered; private int mRoaming; private long mBeginTimeStamp; @@ -323,8 +329,9 @@ public final class NetworkStats implements AutoCloseable { return 0; } - private static @DefaultNetwork int convertDefaultNetwork(int defaultNetwork) { - switch (defaultNetwork) { + private static @DefaultNetworkStatus int convertDefaultNetworkStatus( + int defaultNetworkStatus) { + switch (defaultNetworkStatus) { case android.net.NetworkStats.DEFAULT_NETWORK_ALL : return DEFAULT_NETWORK_ALL; case android.net.NetworkStats.DEFAULT_NETWORK_NO: return DEFAULT_NETWORK_NO; case android.net.NetworkStats.DEFAULT_NETWORK_YES: return DEFAULT_NETWORK_YES; @@ -397,18 +404,15 @@ public final class NetworkStats implements AutoCloseable { } /** - * Default network state. One of the following values:<p/> + * Default network status. One of the following values:<p/> * <ul> * <li>{@link #DEFAULT_NETWORK_ALL}</li> * <li>{@link #DEFAULT_NETWORK_NO}</li> * <li>{@link #DEFAULT_NETWORK_YES}</li> * </ul> - * <p>Indicates whether the network usage occurred on the system default network for this - * type of traffic, or whether the application chose to send this traffic on a network that - * was not the one selected by the system. */ - public @DefaultNetwork int getDefaultNetwork() { - return mDefaultNetwork; + public @DefaultNetworkStatus int getDefaultNetworkStatus() { + return mDefaultNetworkStatus; } /** @@ -605,7 +609,7 @@ public final class NetworkStats implements AutoCloseable { bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid); bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag); bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set); - bucketOut.mDefaultNetwork = Bucket.convertDefaultNetwork( + bucketOut.mDefaultNetworkStatus = Bucket.convertDefaultNetworkStatus( mRecycledSummaryEntry.defaultNetwork); bucketOut.mMetered = Bucket.convertMetered(mRecycledSummaryEntry.metered); bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming); @@ -657,7 +661,7 @@ public final class NetworkStats implements AutoCloseable { bucketOut.mUid = Bucket.convertUid(getUid()); bucketOut.mTag = Bucket.convertTag(mTag); bucketOut.mState = mState; - bucketOut.mDefaultNetwork = Bucket.DEFAULT_NETWORK_ALL; + bucketOut.mDefaultNetworkStatus = Bucket.DEFAULT_NETWORK_ALL; bucketOut.mMetered = Bucket.METERED_ALL; bucketOut.mRoaming = Bucket.ROAMING_ALL; bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 01ee67158a93..f608fcb1a5df 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -40,6 +40,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import android.os.Process; import android.os.ResultReceiver; import android.os.ShellCommand; @@ -1814,8 +1815,12 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME"; /** - * Intent extra: A {@link Bundle} of extras for a package being suspended. Will be sent with - * {@link #ACTION_MY_PACKAGE_SUSPENDED}. + * Intent extra: A {@link Bundle} of extras for a package being suspended. Will be sent as an + * extra with {@link #ACTION_MY_PACKAGE_SUSPENDED}. + * + * <p>The contents of this {@link Bundle} are a contract between the suspended app and the + * suspending app, i.e. any app with the permission {@code android.permission.SUSPEND_APPS}. + * This is meant to enable the suspended app to better handle the state of being suspended. * * @see #ACTION_MY_PACKAGE_SUSPENDED * @see #ACTION_MY_PACKAGE_UNSUSPENDED @@ -2284,6 +2289,10 @@ public class Intent implements Parcelable, Cloneable { /** * Activity Action: Started to show more details about why an application was suspended. * + * <p>Whenever the system detects an activity launch for a suspended app, it shows a dialog to + * the user to inform them of the state and present them an affordance to start this activity + * action to show more details about the reason for suspension. + * * <p>Apps holding {@link android.Manifest.permission#SUSPEND_APPS} must declare an activity * handling this intent and protect it with * {@link android.Manifest.permission#SEND_SHOW_SUSPENDED_APP_DETAILS}. @@ -2293,6 +2302,8 @@ public class Intent implements Parcelable, Cloneable { * <p class="note">This is a protected intent that can only be sent * by the system. * + * @see PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle, + * PersistableBundle, String) * @see PackageManager#isPackageSuspended() * @see #ACTION_PACKAGES_SUSPENDED * diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 9aace2e7ba8d..8223363a2bc8 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -212,7 +212,7 @@ public class LauncherApps { * an applicaton. * * <p>Note: On devices running {@link android.os.Build.VERSION_CODES#P Android P} or higher, - * any apps that override {@link #onPackagesSuspended(String[], Bundle, UserHandle)} will + * any apps that override {@link #onPackagesSuspended(String[], UserHandle, Bundle)} will * not receive this callback. * * @param packageNames The names of the packages that have just been @@ -226,15 +226,20 @@ public class LauncherApps { * Indicates that one or more packages have been suspended. A device administrator or an app * with {@code android.permission.SUSPEND_APPS} can do this. * + * <p>A suspending app with the permission {@code android.permission.SUSPEND_APPS} can + * optionally provide a {@link Bundle} of extra information that it deems helpful for the + * launcher to handle the suspended state of these packages. The contents of this + * {@link Bundle} supposed to be a contract between the suspending app and the launcher. + * * @param packageNames The names of the packages that have just been suspended. - * @param launcherExtras A {@link Bundle} of extras for the launcher. * @param user the user for which the given packages were suspended. - * + * @param launcherExtras A {@link Bundle} of extras for the launcher, if provided to the + * system, {@code null} otherwise. * @see PackageManager#isPackageSuspended() * @see #getSuspendedPackageLauncherExtras(String, UserHandle) */ - public void onPackagesSuspended(String[] packageNames, @Nullable Bundle launcherExtras, - UserHandle user) { + public void onPackagesSuspended(String[] packageNames, UserHandle user, + @Nullable Bundle launcherExtras) { onPackagesSuspended(packageNames, user); } @@ -662,6 +667,9 @@ public class LauncherApps { * {@code PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle, * PersistableBundle, String)}. * + * <p>The contents of this {@link Bundle} are supposed to be a contract between the suspending + * app and the launcher. + * * <p>Note: This just returns whatever extras were provided to the system, <em>which might * even be {@code null}.</em> * @@ -670,7 +678,7 @@ public class LauncherApps { * @return A {@link Bundle} of launcher extras. Or {@code null} if the package is not currently * suspended. * - * @see Callback#onPackagesSuspended(String[], Bundle, UserHandle) + * @see Callback#onPackagesSuspended(String[], UserHandle, Bundle) * @see PackageManager#isPackageSuspended() */ public @Nullable Bundle getSuspendedPackageLauncherExtras(String packageName, UserHandle user) { @@ -1298,8 +1306,8 @@ public class LauncherApps { mCallback.onPackagesUnavailable(info.packageNames, info.user, info.replacing); break; case MSG_SUSPENDED: - mCallback.onPackagesSuspended(info.packageNames, info.launcherExtras, - info.user); + mCallback.onPackagesSuspended(info.packageNames, info.user, info.launcherExtras + ); break; case MSG_UNSUSPENDED: mCallback.onPackagesUnsuspended(info.packageNames, info.user); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 90fc8f8bd652..9d3b53f232d8 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -5571,7 +5571,8 @@ public abstract class PackageManager { * @param packageName The name of the package to get the suspended status of. * @param userId The user id. * @return {@code true} if the package is suspended or {@code false} if the package is not - * suspended or could not be found. + * suspended. + * @throws IllegalArgumentException if the package was not found. * @hide */ public abstract boolean isPackageSuspendedForUser(String packageName, int userId); @@ -5580,12 +5581,13 @@ public abstract class PackageManager { * Query if an app is currently suspended. * * @return {@code true} if the given package is suspended, {@code false} otherwise + * @throws NameNotFoundException if the package could not be found. * * @see #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle, String) * @hide */ @SystemApi - public boolean isPackageSuspended(String packageName) { + public boolean isPackageSuspended(String packageName) throws NameNotFoundException { throw new UnsupportedOperationException("isPackageSuspended not implemented"); } @@ -5616,11 +5618,16 @@ public abstract class PackageManager { } /** - * Returns any extra information supplied as {@code appExtras} to the system when the calling - * app was suspended. + * Returns a {@link Bundle} of extras that was meant to be sent to the calling app when it was + * suspended. An app with the permission {@code android.permission.SUSPEND_APPS} can supply this + * to the system at the time of suspending an app. * - * <p>Note: If no extras were supplied to the system, this method will return {@code null}, even - * when the calling app has been suspended.</p> + * <p>This is the same {@link Bundle} that is sent along with the broadcast + * {@link Intent#ACTION_MY_PACKAGE_SUSPENDED}, whenever the app is suspended. The contents of + * this {@link Bundle} are a contract between the suspended app and the suspending app. + * + * <p>Note: These extras are optional, so if no extras were supplied to the system, this method + * will return {@code null}, even when the calling app has been suspended. * * @return A {@link Bundle} containing the extras for the app, or {@code null} if the * package is not currently suspended. @@ -5628,6 +5635,7 @@ public abstract class PackageManager { * @see #isPackageSuspended() * @see Intent#ACTION_MY_PACKAGE_UNSUSPENDED * @see Intent#ACTION_MY_PACKAGE_SUSPENDED + * @see Intent#EXTRA_SUSPENDED_PACKAGE_EXTRAS */ public @Nullable Bundle getSuspendedPackageAppExtras() { throw new UnsupportedOperationException("getSuspendedPackageAppExtras not implemented"); diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 699e81bda7b7..a9d0911065f5 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -521,11 +521,6 @@ public abstract class PackageManagerInternal { public abstract @Nullable PackageParser.Package getPackage(@NonNull String packageName); /** - * Returns a {@link com.android.server.pm.PackageSetting} for a given package name. - */ - public abstract @Nullable Object getPackageSetting(String packageName); - - /** * Returns a list without a change observer. * * {@see #getPackageList(PackageListObserver)} diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java index f351c5afa579..b84843bf120d 100644 --- a/core/java/android/security/keystore/recovery/RecoveryController.java +++ b/core/java/android/security/keystore/recovery/RecoveryController.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.app.KeyguardManager; import android.app.PendingIntent; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; @@ -288,6 +289,18 @@ public class RecoveryController { } /** + * Checks whether the recoverable key store is currently available. + * + * <p>If it returns true, the device must currently be using a screen lock that is supported for + * use with the recoverable key store, i.e. AOSP PIN, pattern or password. + */ + @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) + public static boolean isRecoverableKeyStoreEnabled(@NonNull Context context) { + KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class); + return keyguardManager != null && keyguardManager.isDeviceSecure(); + } + + /** * @deprecated Use {@link #initRecoveryService(String, byte[], byte[])} instead. */ @Deprecated diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java index 66a9c6c01ca4..f59c0b5036bd 100644 --- a/core/java/android/view/DisplayCutout.java +++ b/core/java/android/view/DisplayCutout.java @@ -31,6 +31,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import android.util.PathParser; import android.util.proto.ProtoOutputStream; @@ -75,15 +76,19 @@ public final class DisplayCutout { false /* copyArguments */); + private static final Pair<Path, DisplayCutout> NULL_PAIR = new Pair<>(null, null); private static final Object CACHE_LOCK = new Object(); + @GuardedBy("CACHE_LOCK") private static String sCachedSpec; @GuardedBy("CACHE_LOCK") private static int sCachedDisplayWidth; @GuardedBy("CACHE_LOCK") + private static int sCachedDisplayHeight; + @GuardedBy("CACHE_LOCK") private static float sCachedDensity; @GuardedBy("CACHE_LOCK") - private static DisplayCutout sCachedCutout; + private static Pair<Path, DisplayCutout> sCachedCutout = NULL_PAIR; private final Rect mSafeInsets; private final Region mBounds; @@ -347,7 +352,7 @@ public final class DisplayCutout { } /** - * Creates an instance according to @android:string/config_mainBuiltInDisplayCutout. + * Creates the bounding path according to @android:string/config_mainBuiltInDisplayCutout. * * @hide */ @@ -357,6 +362,16 @@ public final class DisplayCutout { } /** + * Creates an instance according to @android:string/config_mainBuiltInDisplayCutout. + * + * @hide + */ + public static Path pathFromResources(Resources res, int displayWidth, int displayHeight) { + return pathAndDisplayCutoutFromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout), + displayWidth, displayHeight, res.getDisplayMetrics().density).first; + } + + /** * Creates an instance according to the supplied {@link android.util.PathParser.PathData} spec. * * @hide @@ -364,11 +379,17 @@ public final class DisplayCutout { @VisibleForTesting(visibility = PRIVATE) public static DisplayCutout fromSpec(String spec, int displayWidth, int displayHeight, float density) { + return pathAndDisplayCutoutFromSpec(spec, displayWidth, displayHeight, density).second; + } + + private static Pair<Path, DisplayCutout> pathAndDisplayCutoutFromSpec(String spec, + int displayWidth, int displayHeight, float density) { if (TextUtils.isEmpty(spec)) { - return null; + return NULL_PAIR; } synchronized (CACHE_LOCK) { if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth + && sCachedDisplayHeight == displayHeight && sCachedDensity == density) { return sCachedCutout; } @@ -398,7 +419,7 @@ public final class DisplayCutout { p = PathParser.createPathFromPathData(spec); } catch (Throwable e) { Log.wtf(TAG, "Could not inflate cutout: ", e); - return null; + return NULL_PAIR; } final Matrix m = new Matrix(); @@ -414,7 +435,7 @@ public final class DisplayCutout { bottomPath = PathParser.createPathFromPathData(bottomSpec); } catch (Throwable e) { Log.wtf(TAG, "Could not inflate bottom cutout: ", e); - return null; + return NULL_PAIR; } // Keep top transform m.postTranslate(0, displayHeight); @@ -422,10 +443,11 @@ public final class DisplayCutout { p.addPath(bottomPath); } - final DisplayCutout result = fromBounds(p); + final Pair<Path, DisplayCutout> result = new Pair<>(p, fromBounds(p)); synchronized (CACHE_LOCK) { sCachedSpec = spec; sCachedDisplayWidth = displayWidth; + sCachedDisplayHeight = displayHeight; sCachedDensity = density; sCachedCutout = result; } diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 95a83da3fad5..7946e9e2f63d 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -201,6 +201,7 @@ import java.util.List; * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> + * <li>{@link #getContentChangeTypes()} - The type of state changes.</li> * <li>{@link #getSource()} - The source info (for registered clients).</li> * <li>{@link #getClassName()} - The class name of the source.</li> * <li>{@link #getPackageName()} - The package name of the source.</li> @@ -863,16 +864,17 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par } /** - * Gets the bit mask of change types signaled by an - * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. A single event may represent - * multiple change types. + * Gets the bit mask of change types signaled by a + * {@link #TYPE_WINDOW_CONTENT_CHANGED} event or {@link #TYPE_WINDOW_STATE_CHANGED}. A single + * event may represent multiple change types. * * @return The bit mask of change types. One or more of: * <ul> - * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION} - * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE} - * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_TEXT} - * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED} + * <li>{@link #CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION} + * <li>{@link #CONTENT_CHANGE_TYPE_SUBTREE} + * <li>{@link #CONTENT_CHANGE_TYPE_TEXT} + * <li>{@link #CONTENT_CHANGE_TYPE_PANE_TITLE} + * <li>{@link #CONTENT_CHANGE_TYPE_UNDEFINED} * </ul> */ @ContentChangeTypes @@ -891,6 +893,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par } case CONTENT_CHANGE_TYPE_SUBTREE: return "CONTENT_CHANGE_TYPE_SUBTREE"; case CONTENT_CHANGE_TYPE_TEXT: return "CONTENT_CHANGE_TYPE_TEXT"; + case CONTENT_CHANGE_TYPE_PANE_TITLE: return "CONTENT_CHANGE_TYPE_PANE_TITLE"; case CONTENT_CHANGE_TYPE_UNDEFINED: return "CONTENT_CHANGE_TYPE_UNDEFINED"; default: return Integer.toHexString(type); } @@ -1324,7 +1327,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par } if (!DEBUG_CONCISE_TOSTRING || mWindowChangeTypes != 0) { builder.append("; WindowChangeTypes: ").append( - contentChangeTypesToString(mWindowChangeTypes)); + windowChangeTypesToString(mWindowChangeTypes)); } super.appendTo(builder); if (DEBUG || DEBUG_CONCISE_TOSTRING) { diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java index f80625f0f82f..96016b44c081 100644 --- a/core/java/android/view/textclassifier/TextClassification.java +++ b/core/java/android/view/textclassifier/TextClassification.java @@ -375,13 +375,13 @@ public final class TextClassification implements Parcelable { */ public static final class Builder { - @NonNull private String mText; @NonNull private List<RemoteAction> mActions = new ArrayList<>(); @NonNull private final Map<String, Float> mEntityConfidence = new ArrayMap<>(); - @Nullable Drawable mLegacyIcon; - @Nullable String mLegacyLabel; - @Nullable Intent mLegacyIntent; - @Nullable OnClickListener mLegacyOnClickListener; + @Nullable private String mText; + @Nullable private Drawable mLegacyIcon; + @Nullable private String mLegacyLabel; + @Nullable private Intent mLegacyIntent; + @Nullable private OnClickListener mLegacyOnClickListener; @Nullable private String mId; /** diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java index 3d503e2ab70b..851b2c9be29b 100644 --- a/core/java/android/view/textclassifier/TextLinks.java +++ b/core/java/android/view/textclassifier/TextLinks.java @@ -339,7 +339,7 @@ public final class TextLinks implements Parcelable { /** * @return The config representing the set of entities to look for - * @see #setEntityConfig(TextClassifier.EntityConfig) + * @see Builder#setEntityConfig(TextClassifier.EntityConfig) */ @Nullable public TextClassifier.EntityConfig getEntityConfig() { diff --git a/core/java/android/webkit/TracingConfig.java b/core/java/android/webkit/TracingConfig.java index d95ca61dff3f..20801684d672 100644 --- a/core/java/android/webkit/TracingConfig.java +++ b/core/java/android/webkit/TracingConfig.java @@ -54,37 +54,37 @@ public class TracingConfig { /** * Predefined set of categories typically useful for analyzing WebViews. - * Typically includes android_webview and Java. + * Typically includes "android_webview" and "Java" categories. */ public static final int CATEGORIES_ANDROID_WEBVIEW = 1 << 1; /** * Predefined set of categories typically useful for web developers. - * Typically includes blink, compositor, renderer.scheduler and v8 categories. + * Typically includes "blink", "compositor", "renderer.scheduler" and "v8" categories. */ public static final int CATEGORIES_WEB_DEVELOPER = 1 << 2; /** * Predefined set of categories for analyzing input latency issues. - * Typically includes input, renderer.scheduler categories. + * Typically includes "input", "renderer.scheduler" categories. */ public static final int CATEGORIES_INPUT_LATENCY = 1 << 3; /** * Predefined set of categories for analyzing rendering issues. - * Typically includes blink, compositor and gpu categories. + * Typically includes "blink", "compositor" and "gpu" categories. */ public static final int CATEGORIES_RENDERING = 1 << 4; /** * Predefined set of categories for analyzing javascript and rendering issues. - * Typically includes blink, compositor, gpu, renderer.scheduler and v8 categories. + * Typically includes "blink", "compositor", "gpu", "renderer.scheduler" and "v8" categories. */ public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 1 << 5; /** * Predefined set of categories for studying difficult rendering performance problems. - * Typically includes blink, compositor, gpu, renderer.scheduler, v8 and + * Typically includes "blink", "compositor", "gpu", "renderer.scheduler", "v8" and * some other compositor categories which are disabled by default. */ public static final int CATEGORIES_FRAME_VIEWER = 1 << 6; @@ -123,7 +123,9 @@ public class TracingConfig { } /** - * Returns a bitmask of the predefined categories values of this configuration. + * Returns a bitmask of the predefined category sets of this configuration. + * + * @return Bitmask of predefined category sets. */ @PredefinedCategories public int getPredefinedCategories() { @@ -133,7 +135,7 @@ public class TracingConfig { /** * Returns the list of included custom category patterns for this configuration. * - * @return empty list if no custom category patterns are specified. + * @return Empty list if no custom category patterns are specified. */ @NonNull public List<String> getCustomIncludedCategories() { @@ -142,6 +144,8 @@ public class TracingConfig { /** * Returns the tracing mode of this configuration. + * + * @return The tracing mode of this configuration. */ @TracingMode public int getTracingMode() { @@ -150,28 +154,37 @@ public class TracingConfig { /** * Builder used to create {@link TracingConfig} objects. - * + * <p> * Examples: - * new TracingConfig.Builder().build() - * -- creates a configuration with default options: {@link #CATEGORIES_NONE}, - * {@link #RECORD_UNTIL_FULL}. - * new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER).build() - * -- records trace events from the "web developer" predefined category sets. - * new TracingConfig.Builder().addCategories(CATEGORIES_RENDERING, - * CATEGORIES_INPUT_LATENCY).build() - * -- records trace events from the "rendering" and "input latency" predefined - * category sets. - * new TracingConfig.Builder().addCategories("browser").build() - * -- records only the trace events from the "browser" category. - * new TracingConfig.Builder().addCategories("blink*","renderer*").build() - * -- records only the trace events matching the "blink*" and "renderer*" patterns - * (e.g. "blink.animations", "renderer_host" and "renderer.scheduler" categories). - * new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER) + * <pre class="prettyprint"> + * // Create a configuration with default options: {@link #CATEGORIES_NONE}, + * // {@link #RECORD_CONTINUOUSLY}. + * <code>new TracingConfig.Builder().build()</code> + * + * // Record trace events from the "web developer" predefined category sets. + * // Uses a ring buffer (the default {@link #RECORD_CONTINUOUSLY} mode) for + * // internal storage during tracing. + * <code>new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER).build()</code> + * + * // Record trace events from the "rendering" and "input latency" predefined + * // category sets. + * <code>new TracingConfig.Builder().addCategories(CATEGORIES_RENDERING, + * CATEGORIES_INPUT_LATENCY).build()</code> + * + * // Record only the trace events from the "browser" category. + * <code>new TracingConfig.Builder().addCategories("browser").build()</code> + * + * // Record only the trace events matching the "blink*" and "renderer*" patterns + * // (e.g. "blink.animations", "renderer_host" and "renderer.scheduler" categories). + * <code>new TracingConfig.Builder().addCategories("blink*","renderer*").build()</code> + * + * // Record events from the "web developer" predefined category set and events from + * // the "disabled-by-default-v8.gc" category to understand where garbage collection + * // is being triggered. Uses a limited size buffer for internal storage during tracing. + * <code>new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER) * .addCategories("disabled-by-default-v8.gc") - * .setTracingMode(RECORD_CONTINUOUSLY).build() - * -- records events from the "web developer" predefined category set and events from - * the "disabled-by-default-v8.gc" category to understand where garbage collection - * is being triggered. Uses a ring buffer for internal storage during tracing. + * .setTracingMode(RECORD_UNTIL_FULL).build()</code> + * </pre> */ public static class Builder { private @PredefinedCategories int mPredefinedCategories = CATEGORIES_NONE; @@ -185,6 +198,8 @@ public class TracingConfig { /** * Build {@link TracingConfig} using the current settings. + * + * @return The {@link TracingConfig} with the current settings. */ public TracingConfig build() { return new TracingConfig(mPredefinedCategories, mCustomIncludedCategories, @@ -192,16 +207,15 @@ public class TracingConfig { } /** - * Adds categories from a predefined set of categories to be included in the trace output. + * Adds predefined sets of categories to be included in the trace output. + * + * A predefined category set can be one of {@link #CATEGORIES_NONE}, + * {@link #CATEGORIES_ALL}, {@link #CATEGORIES_ANDROID_WEBVIEW}, + * {@link #CATEGORIES_WEB_DEVELOPER}, {@link #CATEGORIES_INPUT_LATENCY}, + * {@link #CATEGORIES_RENDERING}, {@link #CATEGORIES_JAVASCRIPT_AND_RENDERING} or + * {@link #CATEGORIES_FRAME_VIEWER}. * - * @param predefinedCategories list or bitmask of predefined category sets to use: - * {@link #CATEGORIES_NONE}, {@link #CATEGORIES_ALL}, - * {@link #CATEGORIES_ANDROID_WEBVIEW}, - * {@link #CATEGORIES_WEB_DEVELOPER}, - * {@link #CATEGORIES_INPUT_LATENCY}, - * {@link #CATEGORIES_RENDERING}, - * {@link #CATEGORIES_JAVASCRIPT_AND_RENDERING} or - * {@link #CATEGORIES_FRAME_VIEWER}. + * @param predefinedCategories A list or bitmask of predefined category sets. * @return The builder to facilitate chaining. */ public Builder addCategories(@PredefinedCategories int... predefinedCategories) { @@ -215,11 +229,11 @@ public class TracingConfig { * Adds custom categories to be included in trace output. * * Note that the categories are defined by the currently-in-use version of WebView. They - * live in chromium code and are not part of the Android API. See + * live in chromium code and are not part of the Android API. * See <a href="https://www.chromium.org/developers/how-tos/trace-event-profiling-tool"> * chromium documentation on tracing</a> for more details. * - * @param categories a list of category patterns. A category pattern can contain wilcards, + * @param categories A list of category patterns. A category pattern can contain wildcards, * e.g. "blink*" or full category name e.g. "renderer.scheduler". * @return The builder to facilitate chaining. */ @@ -235,7 +249,7 @@ public class TracingConfig { * * Same as {@link #addCategories(String...)} but allows to pass a Collection as a parameter. * - * @param categories a list of category patters. + * @param categories A list of category patterns. * @return The builder to facilitate chaining. */ public Builder addCategories(Collection<String> categories) { @@ -245,8 +259,9 @@ public class TracingConfig { /** * Sets the tracing mode for this configuration. + * When tracingMode is not set explicitly, the default is {@link #RECORD_CONTINUOUSLY}. * - * @param tracingMode tracing mode to use, one of {@link #RECORD_UNTIL_FULL} or + * @param tracingMode The tracing mode to use, one of {@link #RECORD_UNTIL_FULL} or * {@link #RECORD_CONTINUOUSLY}. * @return The builder to facilitate chaining. */ diff --git a/core/java/android/webkit/TracingController.java b/core/java/android/webkit/TracingController.java index 50068f5abfb2..05c0304e042c 100644 --- a/core/java/android/webkit/TracingController.java +++ b/core/java/android/webkit/TracingController.java @@ -35,9 +35,9 @@ import java.util.concurrent.Executor; * Example usage: * <pre class="prettyprint"> * TracingController tracingController = TracingController.getInstance(); - * tracingController.start(new TraceConfig.Builder() + * tracingController.start(new TracingConfig.Builder() * .addCategories(CATEGORIES_WEB_DEVELOPER).build()); - * [..] + * ... * tracingController.stop(new FileOutputStream("trace.json"), * Executors.newSingleThreadExecutor()); * </pre></p> @@ -49,7 +49,7 @@ public abstract class TracingController { * only one TracingController instance for all WebView instances, * however this restriction may be relaxed in a future Android release. * - * @return the default TracingController instance + * @return The default TracingController instance. */ @NonNull public static TracingController getInstance() { @@ -65,8 +65,10 @@ public abstract class TracingController { * using an internal buffer and flushed to the outputStream when * {@link #stop(OutputStream, Executor)} is called. * - * @param tracingConfig configuration options to use for tracing - * @throws IllegalStateException if the system is already tracing. + * @param tracingConfig Configuration options to use for tracing. + * @throws IllegalStateException If the system is already tracing. + * @throws IllegalArgumentException If the configuration is invalid (e.g. + * invalid category pattern or invalid tracing mode). */ public abstract void start(@NonNull TracingConfig tracingConfig); @@ -77,17 +79,22 @@ public abstract class TracingController { * in chunks by invoking {@link java.io.OutputStream#write(byte[])}. On completion * the {@link java.io.OutputStream#close()} method is called. * - * @param outputStream the output steam the tracing data will be sent to. If null + * @param outputStream The output stream the tracing data will be sent to. If null * the tracing data will be discarded. - * @param executor the {@link java.util.concurrent.Executor} on which the - * outputStream #write and #close methods will be invoked. - * @return false if the system was not tracing at the time of the call, true - * otherwise. + * @param executor The {@link java.util.concurrent.Executor} on which the + * outputStream {@link java.io.OutputStream#write(byte[])} and + * {@link java.io.OutputStream#close()} methods will be invoked. + * @return False if the WebView framework was not tracing at the time of the call, + * true otherwise. */ public abstract boolean stop(@Nullable OutputStream outputStream, @NonNull @CallbackExecutor Executor executor); - /** True if the system is tracing */ + /** + * Returns whether the WebView framework is tracing. + * + * @return True if tracing is enabled. + */ public abstract boolean isTracing(); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 24f2fbf7f132..2b7221a1eb55 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -64,6 +64,8 @@ interface IStatusBarService in NotificationVisibility[] noLongerVisibleKeys); void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded); void onNotificationDirectReplied(String key); + void onNotificationSmartRepliesAdded(in String key, in int replyCount); + void onNotificationSmartReplySent(in String key, in int replyIndex); void onNotificationSettingsViewed(String key); void setSystemUiVisibility(int vis, int mask, String cause); diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java index 6e9401d7c7a0..6ee74cb9a742 100644 --- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java +++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java @@ -208,6 +208,12 @@ public class DisplayCutoutTest { } @Test + public void fromSpec_wontCacheIfScreenHeightChanges() { + DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 4000, 1f); + assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached))); + } + + @Test public void fromSpec_wontCacheIfDensityChanges() { DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 2f); assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached))); diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml index 22867df76aea..72d9bce687ab 100644 --- a/data/fonts/fonts.xml +++ b/data/fonts/fonts.xml @@ -111,6 +111,8 @@ <family lang="und-Ethi"> <font weight="400" style="normal">NotoSansEthiopic-Regular.ttf</font> <font weight="700" style="normal">NotoSansEthiopic-Bold.ttf</font> + <font weight="400" style="normal" fallbackFor="serif">NotoSerifEthiopic-Regular.otf</font> + <font weight="700" style="normal" fallbackFor="serif">NotoSerifEthiopic-Bold.otf</font> </family> <family lang="und-Hebr"> <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font> @@ -167,6 +169,8 @@ <family lang="und-Guru" variant="elegant"> <font weight="400" style="normal">NotoSansGurmukhi-Regular.ttf</font> <font weight="700" style="normal">NotoSansGurmukhi-Bold.ttf</font> + <font weight="400" style="normal" fallbackFor="serif">NotoSerifGurmukhi-Regular.otf</font> + <font weight="700" style="normal" fallbackFor="serif">NotoSerifGurmukhi-Bold.otf</font> </family> <family lang="und-Guru" variant="compact"> <font weight="400" style="normal">NotoSansGurmukhiUI-Regular.ttf</font> @@ -231,9 +235,15 @@ <font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font> </family> - <family lang="und-Sinh"> + <family lang="und-Sinh" variant="elegant"> <font weight="400" style="normal">NotoSansSinhala-Regular.ttf</font> <font weight="700" style="normal">NotoSansSinhala-Bold.ttf</font> + <font weight="400" style="normal" fallbackFor="serif">NotoSerifSinhala-Regular.otf</font> + <font weight="700" style="normal" fallbackFor="serif">NotoSerifSinhala-Bold.otf</font> + </family> + <family lang="und-Sinh" variant="compact"> + <font weight="400" style="normal">NotoSansSinhalaUI-Regular.otf</font> + <font weight="700" style="normal">NotoSansSinhalaUI-Bold.otf</font> </family> <family lang="und-Khmr" variant="elegant"> <font weight="100" style="normal">NotoSansKhmer-VF.ttf @@ -272,7 +282,9 @@ <axis tag="wdth" stylevalue="100.0" /> <axis tag="wght" stylevalue="190.0" /> </font> - </family> + <font weight="400" style="normal" fallbackFor="serif">NotoSerifKhmer-Regular.otf</font> + <font weight="700" style="normal" fallbackFor="serif">NotoSerifKhmer-Bold.otf</font> + </family> <family lang="und-Khmr" variant="compact"> <font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font> @@ -290,6 +302,8 @@ <family lang="und-Mymr" variant="elegant"> <font weight="400" style="normal">NotoSansMyanmar-Regular.ttf</font> <font weight="700" style="normal">NotoSansMyanmar-Bold.ttf</font> + <font weight="400" style="normal" fallbackFor="serif">NotoSerifMyanmar-Regular.otf</font> + <font weight="700" style="normal" fallbackFor="serif">NotoSerifMyanmar-Bold.otf</font> </family> <family lang="und-Mymr" variant="compact"> <font weight="400" style="normal">NotoSansMyanmarUI-Regular.ttf</font> @@ -303,6 +317,9 @@ <font weight="400" style="normal">NotoSansCham-Regular.ttf</font> <font weight="700" style="normal">NotoSansCham-Bold.ttf</font> </family> + <family lang="und-Ahom"> + <font weight="400" style="normal">NotoSansAhom-Regular.otf</font> + </family> <family lang="und-Adlm"> <font weight="400" style="normal">NotoSansAdlam-Regular.ttf</font> </family> @@ -354,6 +371,9 @@ <family lang="und-Egyp"> <font weight="400" style="normal">NotoSansEgyptianHieroglyphs-Regular.ttf</font> </family> + <family lang="und-Elba"> + <font weight="400" style="normal">NotoSansElbasan-Regular.otf</font> + </family> <family lang="und-Glag"> <font weight="400" style="normal">NotoSansGlagolitic-Regular.ttf</font> </family> @@ -538,4 +558,64 @@ <family lang="und-Phag"> <font weight="400" style="normal">NotoSansPhagsPa-Regular.ttf</font> </family> + <family lang="und-Hluw"> + <font weight="400" style="normal">NotoSansAnatolianHieroglyphs-Regular.otf</font> + </family> + <family lang="und-Bass"> + <font weight="400" style="normal">NotoSansBassaVah-Regular.otf</font> + </family> + <family lang="und-Bhks"> + <font weight="400" style="normal">NotoSansBhaiksuki-Regular.otf</font> + </family> + <family lang="und-Hatr"> + <font weight="400" style="normal">NotoSansHatran-Regular.otf</font> + </family> + <family lang="und-Lina"> + <font weight="400" style="normal">NotoSansLinearA-Regular.otf</font> + </family> + <family lang="und-Mani"> + <font weight="400" style="normal">NotoSansManichaean-Regular.otf</font> + </family> + <family lang="und-Marc"> + <font weight="400" style="normal">NotoSansMarchen-Regular.otf</font> + </family> + <family lang="und-Merc"> + <font weight="400" style="normal">NotoSansMeroitic-Regular.otf</font> + </family> + <family lang="und-Plrd"> + <font weight="400" style="normal">NotoSansMiao-Regular.otf</font> + </family> + <family lang="und-Mroo"> + <font weight="400" style="normal">NotoSansMro-Regular.otf</font> + </family> + <family lang="und-Mult"> + <font weight="400" style="normal">NotoSansMultani-Regular.otf</font> + </family> + <family lang="und-Nbat"> + <font weight="400" style="normal">NotoSansNabataean-Regular.otf</font> + </family> + <family lang="und-Newa"> + <font weight="400" style="normal">NotoSansNewa-Regular.otf</font> + </family> + <family lang="und-Narb"> + <font weight="400" style="normal">NotoSansOldNorthArabian-Regular.otf</font> + </family> + <family lang="und-Perm"> + <font weight="400" style="normal">NotoSansOldPermic-Regular.otf</font> + </family> + <family lang="und-Hmng"> + <font weight="400" style="normal">NotoSansPahawhHmong-Regular.otf</font> + </family> + <family lang="und-Palm"> + <font weight="400" style="normal">NotoSansPalmyrene-Regular.otf</font> + </family> + <family lang="und-Pauc"> + <font weight="400" style="normal">NotoSansPauCinHau-Regular.otf</font> + </family> + <family lang="und-Shrd"> + <font weight="400" style="normal">NotoSansSharada-Regular.otf</font> + </family> + <family lang="und-Sora"> + <font weight="400" style="normal">NotoSansSoraSompeng-Regular.otf</font> + </family> </familyset> diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index aeef2158b20f..fdb7499bfe3d 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -63,6 +63,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -4786,6 +4787,21 @@ public class AudioManager { } /** + * Add {@link MicrophoneInfo} by device information while filtering certain types. + */ + private void addMicrophonesFromAudioDeviceInfo(ArrayList<MicrophoneInfo> microphones, + HashSet<Integer> filterTypes) { + AudioDeviceInfo[] devices = getDevicesStatic(GET_DEVICES_INPUTS); + for (AudioDeviceInfo device : devices) { + if (filterTypes.contains(device.getType())) { + continue; + } + MicrophoneInfo microphone = microphoneInfoFromAudioDeviceInfo(device); + microphones.add(microphone); + } + } + + /** * Returns a list of {@link MicrophoneInfo} that corresponds to the characteristics * of all available microphones. The list is empty when no microphones are available * on the device. An error during the query will result in an IOException being thrown. @@ -4796,21 +4812,17 @@ public class AudioManager { public List<MicrophoneInfo> getMicrophones() throws IOException { ArrayList<MicrophoneInfo> microphones = new ArrayList<MicrophoneInfo>(); int status = AudioSystem.getMicrophones(microphones); + HashSet<Integer> filterTypes = new HashSet<>(); + filterTypes.add(AudioDeviceInfo.TYPE_TELEPHONY); if (status != AudioManager.SUCCESS) { - // fail and bail! + // fail and populate microphones with unknown characteristics by device information. Log.e(TAG, "getMicrophones failed:" + status); - return new ArrayList<MicrophoneInfo>(); // Always return a list. + addMicrophonesFromAudioDeviceInfo(microphones, filterTypes); + return microphones; } setPortIdForMicrophones(microphones); - AudioDeviceInfo[] devices = getDevicesStatic(GET_DEVICES_INPUTS); - for (AudioDeviceInfo device : devices) { - if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_MIC || - device.getType() == AudioDeviceInfo.TYPE_TELEPHONY) { - continue; - } - MicrophoneInfo microphone = microphoneInfoFromAudioDeviceInfo(device); - microphones.add(microphone); - } + filterTypes.add(AudioDeviceInfo.TYPE_BUILTIN_MIC); + addMicrophonesFromAudioDeviceInfo(microphones, filterTypes); return microphones; } diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index 4f0dccb8a088..6b35dd4cc379 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -1628,7 +1628,6 @@ public class AudioRecord implements AudioRouting int status = native_get_active_microphones(activeMicrophones); if (status != AudioManager.SUCCESS) { Log.e(TAG, "getActiveMicrophones failed:" + status); - return new ArrayList<MicrophoneInfo>(); } AudioManager.setPortIdForMicrophones(activeMicrophones); diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 90b6bff63874..82d64f300850 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -1434,7 +1434,6 @@ public class MediaRecorder implements AudioRouting int status = native_getActiveMicrophones(activeMicrophones); if (status != AudioManager.SUCCESS) { Log.e(TAG, "getActiveMicrophones failed:" + status); - return new ArrayList<MicrophoneInfo>(); } AudioManager.setPortIdForMicrophones(activeMicrophones); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java index 4a6df5051679..bab59f1f1c32 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java @@ -29,5 +29,5 @@ public interface BluetoothCallback { void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState); void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state); void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile); - void onProfileAudioStateChanged(int bluetoothProfile, int state); + void onAudioModeChanged(); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index b74b2cd03a52..06fe4de4b9b6 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -27,6 +27,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.telephony.TelephonyManager; import android.util.Log; import com.android.settingslib.R; @@ -119,6 +120,12 @@ public class BluetoothEventManager { addHandler(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED, new ActiveDeviceChangedHandler()); + // Headset state changed broadcasts + addHandler(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED, + new AudioModeChangedHandler()); + addHandler(TelephonyManager.ACTION_PHONE_STATE_CHANGED, + new AudioModeChangedHandler()); + mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler); mContext.registerReceiver(mProfileBroadcastReceiver, mProfileIntentFilter, null, mReceiverHandler); } @@ -456,4 +463,25 @@ public class BluetoothEventManager { } } } + + private class AudioModeChangedHandler implements Handler { + + @Override + public void onReceive(Context context, Intent intent, BluetoothDevice device) { + final String action = intent.getAction(); + if (action == null) { + Log.w(TAG, "AudioModeChangedHandler() action is null"); + return; + } + dispatchAudioModeChanged(); + } + } + + private void dispatchAudioModeChanged() { + synchronized (mCallbacks) { + for (BluetoothCallback callback : mCallbacks) { + callback.onAudioModeChanged(); + } + } + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java new file mode 100644 index 000000000000..d1e37f6e945b --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java @@ -0,0 +1,81 @@ +/* + * 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 com.android.settingslib.bluetooth; + +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothHeadset; +import android.content.Context; +import android.content.Intent; + +import android.telephony.TelephonyManager; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class BluetoothEventManagerTest { + + @Mock + private LocalBluetoothAdapter mLocalAdapter; + @Mock + private CachedBluetoothDeviceManager mCachedDeviceManager; + @Mock + private BluetoothCallback mBluetoothCallback; + + private Context mContext; + private Intent mIntent; + private BluetoothEventManager mBluetoothEventManager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + + mBluetoothEventManager = new BluetoothEventManager(mLocalAdapter, + mCachedDeviceManager, mContext); + } + + /** + * Intent ACTION_AUDIO_STATE_CHANGED should dispatch to callback. + */ + @Test + public void intentWithExtraState_audioStateChangedShouldDispatchToRegisterCallback() { + mBluetoothEventManager.registerCallback(mBluetoothCallback); + mIntent = new Intent(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); + + mContext.sendBroadcast(mIntent); + + verify(mBluetoothCallback).onAudioModeChanged(); + } + + /** + * Intent ACTION_PHONE_STATE_CHANGED should dispatch to callback. + */ + @Test + public void intentWithExtraState_phoneStateChangedShouldDispatchToRegisterCallback() { + mBluetoothEventManager.registerCallback(mBluetoothCallback); + mIntent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + + mContext.sendBroadcast(mIntent); + + verify(mBluetoothCallback).onAudioModeChanged(); + } +} diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 313f73f8d634..f72868431d43 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -253,6 +253,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { && !RESTORE_FROM_HIGHER_SDK_INT_SUPPORTED_KEYS.contains(key)) { Log.w(TAG, "Not restoring unrecognized key '" + key + "' from future version " + appVersionCode); + data.skipEntityData(); continue; } diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml index ef18725ce7e3..f424171286f0 100644 --- a/packages/SystemUI/res/layout/qs_footer_impl.xml +++ b/packages/SystemUI/res/layout/qs_footer_impl.xml @@ -38,9 +38,7 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="1dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" + android:layout_marginStart="16dp" android:layout_gravity="center_vertical" android:gravity="end" > @@ -48,18 +46,17 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical|start" - android:layout_margin="15dp" + android:layout_marginEnd="8dp" android:visibility="gone" layout="@layout/mobile_signal_group" /> <com.android.keyguard.CarrierText android:id="@+id/qs_carrier_text" android:layout_width="0dp" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:layout_weight="1" - android:layout_marginStart="8dp" + android:layout_gravity="center_vertical|start" android:layout_marginEnd="32dp" - android:gravity="center_vertical|start" android:ellipsize="marquee" android:textAppearance="@style/TextAppearance.QS.TileLabel" android:textColor="?android:attr/textColorPrimary" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index ceff6e04d0d2..90095317c8ad 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -375,7 +375,7 @@ <dimen name="qs_header_alarm_icon_size">18dp</dimen> <dimen name="qs_header_alarm_text_margin_start">6dp</dimen> <dimen name="qs_footer_padding_start">16dp</dimen> - <dimen name="qs_footer_padding_end">24dp</dimen> + <dimen name="qs_footer_padding_end">16dp</dimen> <dimen name="qs_footer_icon_size">16dp</dimen> <dimen name="qs_notif_collapsed_space">64dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index a0fa69e61f20..e54b083ecdf4 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -14,6 +14,10 @@ package com.android.systemui; +import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_180; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; @@ -21,12 +25,14 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static com.android.systemui.tuner.TunablePadding.FLAG_START; import static com.android.systemui.tuner.TunablePadding.FLAG_END; +import android.annotation.Dimension; import android.app.Fragment; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; @@ -41,6 +47,7 @@ import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.Surface; import android.view.View; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; @@ -359,6 +366,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { if (!mBoundingPath.isEmpty()) { mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.FILL); + mPaint.setAntiAlias(true); canvas.drawPath(mBoundingPath, mPaint); } } @@ -388,7 +396,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { if (hasCutout()) { mBounds.set(mInfo.displayCutout.getBounds()); localBounds(mBoundingRect); - mInfo.displayCutout.getBounds().getBoundaryPath(mBoundingPath); + updateBoundingPath(); invalidate(); newVisible = VISIBLE; } else { @@ -400,6 +408,44 @@ public class ScreenDecorations extends SystemUI implements Tunable { } } + private void updateBoundingPath() { + int lw = mInfo.logicalWidth; + int lh = mInfo.logicalHeight; + + boolean flipped = mInfo.rotation == ROTATION_90 || mInfo.rotation == ROTATION_270; + + int dw = flipped ? lh : lw; + int dh = flipped ? lw : lh; + + mBoundingPath.set(DisplayCutout.pathFromResources(getResources(), lw, lh)); + Matrix m = new Matrix(); + transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m); + mBoundingPath.transform(m); + } + + private static void transformPhysicalToLogicalCoordinates(@Surface.Rotation int rotation, + @Dimension int physicalWidth, @Dimension int physicalHeight, Matrix out) { + switch (rotation) { + case ROTATION_0: + out.reset(); + break; + case ROTATION_90: + out.setRotate(270); + out.postTranslate(0, physicalWidth); + break; + case ROTATION_180: + out.setRotate(180); + out.postTranslate(physicalWidth, physicalHeight); + break; + case ROTATION_270: + out.setRotate(90); + out.postTranslate(physicalHeight, 0); + break; + default: + throw new IllegalArgumentException("Unknown rotation: " + rotation); + } + } + private boolean hasCutout() { final DisplayCutout displayCutout = mInfo.displayCutout; if (displayCutout == null) { diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index c01cafaaa9b8..52d458cee987 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -42,6 +42,7 @@ import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.ScrimView; +import com.android.systemui.statusbar.SmartReplyLogger; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBouncer; @@ -146,5 +147,6 @@ public class SystemUIFactory { () -> new NotificationViewHierarchyManager(context)); providers.put(NotificationEntryManager.class, () -> new NotificationEntryManager(context)); providers.put(KeyguardDismissUtil.class, KeyguardDismissUtil::new); + providers.put(SmartReplyLogger.class, () -> new SmartReplyLogger(context)); } } diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java index 94641054f548..ebd15f559239 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java +++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java @@ -613,7 +613,7 @@ public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeCha int bluetoothProfile) { } @Override - public void onProfileAudioStateChanged(int bluetoothProfile, int state) { } + public void onAudioModeChanged() { } } private final class BluetoothErrorListener implements Utils.ErrorListener { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 29c2edc22f4c..4256cd63dc4b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -80,7 +80,7 @@ public class NotificationContentView extends FrameLayout { private RemoteInputView mHeadsUpRemoteInput; private SmartReplyConstants mSmartReplyConstants; - private SmartReplyView mExpandedSmartReplyView; + private SmartReplyLogger mSmartReplyLogger; private NotificationViewWrapper mContractedWrapper; private NotificationViewWrapper mExpandedWrapper; @@ -153,6 +153,7 @@ public class NotificationContentView extends FrameLayout { super(context, attrs); mHybridGroupManager = new HybridGroupManager(getContext(), this); mSmartReplyConstants = Dependency.get(SmartReplyConstants.class); + mSmartReplyLogger = Dependency.get(SmartReplyLogger.class); initView(); } @@ -1243,7 +1244,7 @@ public class NotificationContentView extends FrameLayout { } applyRemoteInput(entry, hasRemoteInput); - applySmartReplyView(remoteInputWithChoices, pendingIntentWithChoices); + applySmartReplyView(remoteInputWithChoices, pendingIntentWithChoices, entry); } private void applyRemoteInput(NotificationData.Entry entry, boolean hasRemoteInput) { @@ -1344,13 +1345,21 @@ public class NotificationContentView extends FrameLayout { return null; } - private void applySmartReplyView(RemoteInput remoteInput, PendingIntent pendingIntent) { - mExpandedSmartReplyView = mExpandedChild == null ? - null : applySmartReplyView(mExpandedChild, remoteInput, pendingIntent); + private void applySmartReplyView(RemoteInput remoteInput, PendingIntent pendingIntent, + NotificationData.Entry entry) { + if (mExpandedChild != null) { + SmartReplyView view = + applySmartReplyView(mExpandedChild, remoteInput, pendingIntent, entry); + if (view != null && remoteInput != null && remoteInput.getChoices() != null + && remoteInput.getChoices().length > 0) { + mSmartReplyLogger.smartRepliesAdded(entry, remoteInput.getChoices().length); + } + } } private SmartReplyView applySmartReplyView( - View view, RemoteInput remoteInput, PendingIntent pendingIntent) { + View view, RemoteInput remoteInput, PendingIntent pendingIntent, + NotificationData.Entry entry) { View smartReplyContainerCandidate = view.findViewById( com.android.internal.R.id.smart_reply_container); if (!(smartReplyContainerCandidate instanceof LinearLayout)) { @@ -1372,7 +1381,8 @@ public class NotificationContentView extends FrameLayout { } } if (smartReplyView != null) { - smartReplyView.setRepliesFromRemoteInput(remoteInput, pendingIntent); + smartReplyView.setRepliesFromRemoteInput(remoteInput, pendingIntent, + mSmartReplyLogger, entry); smartReplyContainer.setVisibility(View.VISIBLE); } return smartReplyView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyLogger.java new file mode 100644 index 000000000000..75dd77d8ec3a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyLogger.java @@ -0,0 +1,52 @@ +/* + * 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.statusbar; + +import android.content.Context; +import android.os.RemoteException; +import android.os.ServiceManager; +import com.android.internal.statusbar.IStatusBarService; + +/** + * Handles reporting when smart replies are added to a notification + * and clicked upon. + */ +public class SmartReplyLogger { + protected IStatusBarService mBarService; + + public SmartReplyLogger(Context context) { + mBarService = IStatusBarService.Stub.asInterface( + ServiceManager.getService(Context.STATUS_BAR_SERVICE)); + } + + public void smartReplySent(NotificationData.Entry entry, int replyIndex) { + try { + mBarService.onNotificationSmartReplySent(entry.notification.getKey(), + replyIndex); + } catch (RemoteException e) { + // Nothing to do, system going down + } + } + + public void smartRepliesAdded(final NotificationData.Entry entry, int replyCount) { + try { + mBarService.onNotificationSmartRepliesAdded(entry.notification.getKey(), + replyCount); + } catch (RemoteException e) { + // Nothing to do, system going down + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 58f8baa6ef5b..ca6d5968a43c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -103,6 +103,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; import java.util.Locale; +import java.util.Optional; /** * Fragment containing the NavigationBarFragment. Contains logic for what happens @@ -1109,8 +1110,11 @@ public class NavigationBarFragment extends Fragment implements Callbacks { public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { // Only hide the icon if the top task changes its requestedOrientation // Launcher can alter its requestedOrientation while it's not on top, don't hide on this - final boolean top = ActivityManagerWrapper.getInstance().getRunningTask().id == taskId; - if (top) setRotateSuggestionButtonState(false); + Optional.ofNullable(ActivityManagerWrapper.getInstance()) + .map(ActivityManagerWrapper::getRunningTask) + .ifPresent(a -> { + if (a.id == taskId) setRotateSuggestionButtonState(false); + }); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java index 94db95a6f33c..cd17cfcd0e9f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java @@ -280,7 +280,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {} @Override - public void onProfileAudioStateChanged(int bluetoothProfile, int state) {} + public void onAudioModeChanged() {} private ActuallyCachedState getCachedState(CachedBluetoothDevice device) { ActuallyCachedState state = mCachedState.get(device); 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 74b39268fc2d..4c79ee32f8e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java @@ -23,6 +23,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardHostView.OnDismissAction; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.statusbar.NotificationData; +import com.android.systemui.statusbar.SmartReplyLogger; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import java.text.BreakIterator; @@ -109,14 +111,16 @@ public class SmartReplyView extends ViewGroup { Math.max(getChildCount(), 1), DECREASING_MEASURED_WIDTH_WITHOUT_PADDING_COMPARATOR); } - public void setRepliesFromRemoteInput(RemoteInput remoteInput, PendingIntent pendingIntent) { + public void setRepliesFromRemoteInput(RemoteInput remoteInput, PendingIntent pendingIntent, + SmartReplyLogger smartReplyLogger, NotificationData.Entry entry) { removeAllViews(); if (remoteInput != null && pendingIntent != null) { CharSequence[] choices = remoteInput.getChoices(); if (choices != null) { - for (CharSequence choice : choices) { + for (int i = 0; i < choices.length; ++i) { Button replyButton = inflateReplyButton( - getContext(), this, choice, remoteInput, pendingIntent); + getContext(), this, i, choices[i], remoteInput, pendingIntent, + smartReplyLogger, entry); addView(replyButton); } } @@ -130,8 +134,9 @@ public class SmartReplyView extends ViewGroup { } @VisibleForTesting - Button inflateReplyButton(Context context, ViewGroup root, CharSequence choice, - RemoteInput remoteInput, PendingIntent pendingIntent) { + Button inflateReplyButton(Context context, ViewGroup root, int replyIndex, + CharSequence choice, RemoteInput remoteInput, PendingIntent pendingIntent, + SmartReplyLogger smartReplyLogger, NotificationData.Entry entry) { Button b = (Button) LayoutInflater.from(context).inflate( R.layout.smart_reply_button, root, false); b.setText(choice); @@ -147,6 +152,7 @@ public class SmartReplyView extends ViewGroup { } catch (PendingIntent.CanceledException e) { Log.w(TAG, "Unable to send smart reply", e); } + smartReplyLogger.smartReplySent(entry, replyIndex); return false; // do not defer }; 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 56882c654b33..2bb810665f3a 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 @@ -22,11 +22,16 @@ import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + import android.app.PendingIntent; import android.app.RemoteInput; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; +import android.service.notification.StatusBarNotification; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -38,6 +43,8 @@ import android.widget.LinearLayout; import com.android.keyguard.KeyguardHostView.OnDismissAction; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.NotificationData; +import com.android.systemui.statusbar.SmartReplyLogger; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import java.util.concurrent.atomic.AtomicReference; @@ -46,6 +53,8 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @@ -66,8 +75,12 @@ public class SmartReplyViewTest extends SysuiTestCase { private int mDoubleLinePaddingHorizontal; private int mSpacing; + @Mock private SmartReplyLogger mLogger; + private NotificationData.Entry mEntry; + @Before public void setUp() { + MockitoAnnotations.initMocks(this); mReceiver = new BlockingQueueIntentReceiver(); mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION)); mDependency.get(KeyguardDismissUtil.class).setDismissHandler( @@ -82,6 +95,10 @@ public class SmartReplyViewTest extends SysuiTestCase { mDoubleLinePaddingHorizontal = res.getDimensionPixelSize( R.dimen.smart_reply_button_padding_horizontal_double_line); mSpacing = res.getDimensionPixelSize(R.dimen.smart_reply_button_spacing); + + StatusBarNotification notification = mock(StatusBarNotification.class); + when(notification.getKey()).thenReturn("akey"); + mEntry = new NotificationData.Entry(notification); } @After @@ -138,6 +155,13 @@ public class SmartReplyViewTest extends SysuiTestCase { } @Test + public void testSendSmartReply_LoggerCall() { + setRepliesFromRemoteInput(TEST_CHOICES); + mView.getChildAt(2).performClick(); + verify(mLogger).smartReplySent(mEntry, 2); + } + + @Test public void testMeasure_empty() { mView.measure(WIDTH_SPEC, HEIGHT_SPEC); assertEquals(500, mView.getMeasuredWidthAndState()); @@ -316,7 +340,7 @@ public class SmartReplyViewTest extends SysuiTestCase { 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); + mView.setRepliesFromRemoteInput(input, pendingIntent, mLogger, mEntry); } /** Builds a {@link ViewGroup} whose measures and layout mirror a {@link SmartReplyView}. */ @@ -343,8 +367,9 @@ public class SmartReplyViewTest extends SysuiTestCase { } Button previous = null; - for (CharSequence choice : choices) { - Button current = mView.inflateReplyButton(mContext, mView, choice, null, null); + for (int i = 0; i < choices.length; ++i) { + Button current = mView.inflateReplyButton(mContext, mView, i, choices[i], + null, null, null, null); current.setPadding(paddingHorizontal, current.getPaddingTop(), paddingHorizontal, current.getPaddingBottom()); if (previous != null) { diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index f27cca6bf366..97224087b69d 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -5618,6 +5618,24 @@ message MetricsEvent { // OS: P SETTINGS_AUTO_BRIGHTNESS = 1381; + // OPEN: Smart replies in a notification seen at least once + // CATEGORY: NOTIFICATION + // PACKAGE: App that posted the notification + // SUBTYPE: Number of smart replies. + // OS: P + SMART_REPLY_VISIBLE = 1382; + + // ACTION: Smart reply in a notification clicked. + // CATEGORY: NOTIFICATION + // PACKAGE: App that posted the notification + // SUBTYPE: Index of smart reply clicked. + // OS: P + SMART_REPLY_ACTION = 1383; + + // Tagged data for SMART_REPLY_VISIBLE. Count of number of smart replies. + // OS: P + NOTIFICATION_SMART_REPLY_COUNT = 1384; + // ---- End P Constants, all P constants go above this line ---- // Add new aosp constants above this line. // END OF AOSP CONSTANTS diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 4ce157fde648..767deb98379a 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1198,10 +1198,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } boolean isFocusable() { - if (inSplitScreenPrimaryWindowingMode() && mStackSupervisor.mIsDockMinimized) { - return false; - } - return getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable(); + return mStackSupervisor.isFocusable(this, isAlwaysFocusable()); } boolean isResizeable() { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 1e9edd9a1b44..6d4ac8f99651 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1077,13 +1077,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } boolean isFocusable() { - if (getWindowConfiguration().canReceiveKeys()) { - return true; - } - // The stack isn't focusable. See if its top activity is focusable to force focus on the - // stack. final ActivityRecord r = topRunningActivityLocked(); - return r != null && r.isFocusable(); + return mStackSupervisor.isFocusable(this, r != null && r.isFocusable()); } final boolean isAttached() { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 731a44d35cf2..cbf30bdd0cbb 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -667,6 +667,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return mFocusedStack; } + boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) { + if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) { + return false; + } + + return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable; + } + ActivityStack getLastStack() { return mLastFocusedStack; } diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index f74daf2be38b..f7439b9a0d05 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -42,7 +42,7 @@ import java.util.Arrays; */ public abstract class BrightnessMappingStrategy { private static final String TAG = "BrightnessMappingStrategy"; - private static final boolean DEBUG = false; + private static final boolean DEBUG = true; private static final float LUX_GRAD_SMOOTHING = 0.25f; private static final float MAX_GRAD = 1.0f; @@ -352,9 +352,9 @@ public abstract class BrightnessMappingStrategy { // current^gamma = desired => gamma = log[current](desired) gamma = MathUtils.log(desiredBrightness) / MathUtils.log(currentBrightness); // max^-adjustment = gamma => adjustment = -log[max](gamma) - adjustment = -MathUtils.constrain( - MathUtils.log(gamma) / MathUtils.log(maxGamma), -1, 1); + adjustment = -MathUtils.log(gamma) / MathUtils.log(maxGamma); } + adjustment = MathUtils.constrain(adjustment, -1, +1); if (DEBUG) { Slog.d(TAG, "inferAutoBrightnessAdjustment: " + maxGamma + "^" + -adjustment + "=" + MathUtils.pow(maxGamma, -adjustment) + " == " + gamma); diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java index 36bc0962f65b..b61a27ac6c6d 100644 --- a/services/core/java/com/android/server/notification/NotificationDelegate.java +++ b/services/core/java/com/android/server/notification/NotificationDelegate.java @@ -40,4 +40,6 @@ public interface NotificationDelegate { void onNotificationExpansionChanged(String key, boolean userAction, boolean expanded); void onNotificationDirectReplied(String key); void onNotificationSettingsViewed(String key); + void onNotificationSmartRepliesAdded(String key, int replyCount); + void onNotificationSmartReplySent(String key, int replyIndex); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 7e04d3337e68..7254acf3438e 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -121,6 +121,7 @@ import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManagerInternal; import android.media.IRingtonePlayer; +import android.metrics.LogMaker; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -395,6 +396,8 @@ public class NotificationManagerService extends SystemService { private GroupHelper mGroupHelper; private boolean mIsTelevision; + private MetricsLogger mMetricsLogger; + private static class Archive { final int mBufferSize; final ArrayDeque<StatusBarNotification> mBuffer; @@ -801,6 +804,18 @@ public class NotificationManagerService extends SystemService { // Report to usage stats that notification was made visible if (DBG) Slog.d(TAG, "Marking notification as visible " + nv.key); reportSeen(r); + + // If the newly visible notification has smart replies + // then log that the user has seen them. + if (r.getNumSmartRepliesAdded() > 0 + && !r.hasSeenSmartReplies()) { + r.setSeenSmartReplies(true); + LogMaker logMaker = r.getLogMaker() + .setCategory(MetricsEvent.SMART_REPLY_VISIBLE) + .addTaggedData(MetricsEvent.NOTIFICATION_SMART_REPLY_COUNT, + r.getNumSmartRepliesAdded()); + mMetricsLogger.write(logMaker); + } } r.setVisibility(true, nv.rank); nv.recycle(); @@ -855,6 +870,31 @@ public class NotificationManagerService extends SystemService { } @Override + public void onNotificationSmartRepliesAdded(String key, int replyCount) { + synchronized (mNotificationLock) { + NotificationRecord r = mNotificationsByKey.get(key); + if (r != null) { + r.setNumSmartRepliesAdded(replyCount); + } + } + } + + @Override + public void onNotificationSmartReplySent(String key, int replyIndex) { + synchronized (mNotificationLock) { + NotificationRecord r = mNotificationsByKey.get(key); + if (r != null) { + LogMaker logMaker = r.getLogMaker() + .setCategory(MetricsEvent.SMART_REPLY_ACTION) + .setSubtype(replyIndex); + mMetricsLogger.write(logMaker); + // Treat clicking on a smart reply as a user interaction. + reportUserInteraction(r); + } + } + } + + @Override public void onNotificationSettingsViewed(String key) { synchronized (mNotificationLock) { NotificationRecord r = mNotificationsByKey.get(key); @@ -1349,6 +1389,7 @@ public class NotificationManagerService extends SystemService { extractorNames = new String[0]; } mUsageStats = usageStats; + mMetricsLogger = new MetricsLogger(); mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper()); mConditionProviders = conditionProviders; mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper(), mConditionProviders); @@ -3956,9 +3997,14 @@ public class NotificationManagerService extends SystemService { + ", notificationUid=" + notificationUid + ", notification=" + notification; Log.e(TAG, noChannelStr); - doChannelWarningToast("Developer warning for package \"" + pkg + "\"\n" + - "Failed to post notification on channel \"" + channelId + "\"\n" + - "See log for more details"); + boolean appNotificationsOff = mRankingHelper.getImportance(pkg, notificationUid) + == NotificationManager.IMPORTANCE_NONE; + + if (!appNotificationsOff) { + doChannelWarningToast("Developer warning for package \"" + pkg + "\"\n" + + "Failed to post notification on channel \"" + channelId + "\"\n" + + "See log for more details"); + } return; } diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index c88708551662..9bd3e529cb29 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -149,6 +149,8 @@ public final class NotificationRecord { private final NotificationStats mStats; private int mUserSentiment; private boolean mIsInterruptive; + private int mNumberOfSmartRepliesAdded; + private boolean mHasSeenSmartReplies; @VisibleForTesting public NotificationRecord(Context context, StatusBarNotification sbn, @@ -962,6 +964,22 @@ public final class NotificationRecord { mStats.setViewedSettings(); } + public void setNumSmartRepliesAdded(int noReplies) { + mNumberOfSmartRepliesAdded = noReplies; + } + + public int getNumSmartRepliesAdded() { + return mNumberOfSmartRepliesAdded; + } + + public boolean hasSeenSmartReplies() { + return mHasSeenSmartReplies; + } + + public void setSeenSmartReplies(boolean hasSeenSmartReplies) { + mHasSeenSmartReplies = hasSeenSmartReplies; + } + public Set<Uri> getNotificationUris() { Notification notification = getNotification(); Set<Uri> uris = new ArraySet<>(); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f2d812e8a38f..22654507d179 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -5304,7 +5304,7 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mPackages) { final String[] packageNames = getPackagesForUid(uid); final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0) - ? mSettings.getPackageLPr(packageNames[0]).getPackage() + ? mPackages.get(packageNames[0]) : null; return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid()); } @@ -8070,6 +8070,7 @@ public class PackageManagerService extends IPackageManager.Stub callingUid = mIsolatedOwners.get(callingUid); } final PackageSetting ps = mSettings.mPackages.get(packageName); + PackageParser.Package pkg = mPackages.get(packageName); final boolean returnAllowed = ps != null && (isCallerSameApp(packageName, callingUid) @@ -8140,7 +8141,7 @@ public class PackageManagerService extends IPackageManager.Stub } private boolean isCallerSameApp(String packageName, int uid) { - PackageParser.Package pkg = mSettings.getPackageLPr(packageName).getPackage(); + PackageParser.Package pkg = mPackages.get(packageName); return pkg != null && UserHandle.getAppId(uid) == pkg.applicationInfo.uid; } @@ -10181,20 +10182,10 @@ public class PackageManagerService extends IPackageManager.Stub // The signature has changed, but this package is in the system // image... let's recover! pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails; - // However... if this package is part of a shared user, but it - // doesn't match the signature of the shared user, let's fail. - // What this means is that you can't change the signatures - // associated with an overall shared user, which doesn't seem all - // that unreasonable. + // If the system app is part of a shared user we allow that shared user to change + // signatures as well in part as part of an OTA. if (signatureCheckPs.sharedUser != null) { - if (compareSignatures( - signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures, - pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) { - throw new PackageManagerException( - INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, - "Signature mismatch for shared user: " - + pkgSetting.sharedUser); - } + signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails; } // File a report about this. String msg = "System package " + pkg.packageName @@ -14135,9 +14126,6 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, false /* checkShell */, "isPackageSuspendedForUser for user " + userId); - if (getPackageUid(packageName, 0, userId) != callingUid) { - mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, null); - } synchronized (mPackages) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) { @@ -23610,13 +23598,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } @Override - public Object getPackageSetting(String packageName) { - synchronized (mPackages) { - return mSettings.getPackageLPr(packageName); - } - } - - @Override public PackageList getPackageList(PackageListObserver observer) { synchronized (mPackages) { final int N = mPackages.size(); diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 065133b01b6d..f5b52fc486ea 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -212,11 +212,12 @@ public class PermissionManagerService { return PackageManager.PERMISSION_DENIED; } - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(pkgName); - if (ps != null && ps.getPackage() != null) { - if (mPackageManagerInt.filterAppAccess(ps.getPackage(), callingUid, userId)) { + final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName); + if (pkg != null && pkg.mExtras != null) { + if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { return PackageManager.PERMISSION_DENIED; } + final PackageSetting ps = (PackageSetting) pkg.mExtras; final boolean instantApp = ps.getInstantApp(userId); final PermissionsState permissionsState = ps.getPermissionsState(); if (permissionsState.hasPermission(permName, userId)) { diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 2db80394236a..36fa868ba0e4 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -1096,6 +1096,30 @@ public class StatusBarManagerService extends IStatusBarService.Stub { } @Override + public void onNotificationSmartRepliesAdded(String key, int replyCount) + throws RemoteException { + enforceStatusBarService(); + long identity = Binder.clearCallingIdentity(); + try { + mNotificationDelegate.onNotificationSmartRepliesAdded(key, replyCount); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void onNotificationSmartReplySent(String key, int replyIndex) + throws RemoteException { + enforceStatusBarService(); + long identity = Binder.clearCallingIdentity(); + try { + mNotificationDelegate.onNotificationSmartReplySent(key, replyIndex); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override public void onNotificationSettingsViewed(String key) throws RemoteException { enforceStatusBarService(); long identity = Binder.clearCallingIdentity(); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java index 9663a1b58686..08b8af289bd8 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java @@ -23,6 +23,9 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; +import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; +import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -287,4 +290,43 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { // Verify that the stack was removed. assertEquals(originalStackCount, defaultDisplay.getChildCount()); } + + @Test + public void testFocusability() throws Exception { + final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack( + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); + final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true) + .setStack(stack).build(); + + // Under split screen primary we should be focusable when not minimized + mService.mStackSupervisor.setDockedStackMinimized(false); + assertTrue(stack.isFocusable()); + assertTrue(activity.isFocusable()); + + // Under split screen primary we should not be focusable when minimized + mService.mStackSupervisor.setDockedStackMinimized(true); + assertFalse(stack.isFocusable()); + assertFalse(activity.isFocusable()); + + final ActivityStack pinnedStack = mService.mStackSupervisor.getDefaultDisplay().createStack( + WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */); + final ActivityRecord pinnedActivity = new ActivityBuilder(mService).setCreateTask(true) + .setStack(pinnedStack).build(); + + // We should not be focusable when in pinned mode + assertFalse(pinnedStack.isFocusable()); + assertFalse(pinnedActivity.isFocusable()); + + // Add flag forcing focusability. + pinnedActivity.info.flags |= FLAG_ALWAYS_FOCUSABLE; + + // We should not be focusable when in pinned mode + assertTrue(pinnedStack.isFocusable()); + assertTrue(pinnedActivity.isFocusable()); + + // Without the overridding activity, stack should not be focusable. + pinnedStack.removeTask(pinnedActivity.getTask(), "testFocusability", + REMOVE_TASK_MODE_DESTROYING); + assertFalse(pinnedStack.isFocusable()); + } } diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java index fb25cf3f01e0..284d443bbcf9 100644 --- a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java +++ b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java @@ -32,7 +32,9 @@ import android.hardware.display.BrightnessConfiguration; import android.os.PowerManager; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.util.MathUtils; import android.util.Spline; +import android.util.Slog; import org.junit.Test; import org.junit.runner.RunWith; @@ -91,6 +93,29 @@ public class BrightnessMappingStrategyTest { private static final float[] EMPTY_FLOAT_ARRAY = new float[0]; private static final int[] EMPTY_INT_ARRAY = new int[0]; + private static final float MAXIMUM_GAMMA = 3.0f; + private static final int[] GAMMA_CORRECTION_LUX = { + 0, + 100, + 1000, + 2500, + 4000, + 4900, + 5000 + }; + private static final float[] GAMMA_CORRECTION_NITS = { + 1.0f, + 10.55f, + 96.5f, + 239.75f, + 383.0f, + 468.95f, + 478.5f, + }; + private static final Spline GAMMA_CORRECTION_SPLINE = Spline.createSpline( + new float[] { 0.0f, 100.0f, 1000.0f, 2500.0f, 4000.0f, 4900.0f, 5000.0f }, + new float[] { 0.035f, 0.035f, 0.221f, 0.523f, 0.797f, 0.980f, 1.0f }); + @Test public void testSimpleStrategyMappingAtControlPoints() { Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT); @@ -325,7 +350,7 @@ public class BrightnessMappingStrategyTest { } // Now set the middle of the lux range to something just above the minimum. - final float minBrightness = strategy.getBrightness(LUX_LEVELS[0]); + float minBrightness = strategy.getBrightness(LUX_LEVELS[0]); strategy.addUserDataPoint(LUX_LEVELS[idx], minBrightness + 0.01f); // Then make sure the curve is still monotonic. @@ -340,7 +365,8 @@ public class BrightnessMappingStrategyTest { // And that the lowest lux level still gives the absolute minimum brightness. This should // be true assuming that there are more than two lux levels in the curve since we picked a // brightness just barely above the minimum for the middle of the curve. - assertEquals(minBrightness, strategy.getBrightness(LUX_LEVELS[0]), 0.001 /*tolerance*/); + minBrightness = (float) MathUtils.pow(minBrightness, MAXIMUM_GAMMA); // Gamma correction. + assertEquals(minBrightness, strategy.getBrightness(LUX_LEVELS[0]), 0.01 /*tolerance*/); } private static float[] toFloatArray(int[] vals) { @@ -396,6 +422,9 @@ public class BrightnessMappingStrategyTest { when(mockResources.getInteger( com.android.internal.R.integer.config_screenBrightnessSettingMaximum)) .thenReturn(255); + when(mockResources.getFraction( + com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma, 1, 1)) + .thenReturn(MAXIMUM_GAMMA); return mockResources; } @@ -419,4 +448,121 @@ public class BrightnessMappingStrategyTest { return mockArray; } + // Gamma correction tests. + // x0 = 100 y0 = ~0.01 + // x1 = 1000 y1 = ~0.20 + // x2 = 2500 y2 = ~0.50 + // x3 = 4000 y3 = ~0.80 + // x4 = 4900 y4 = ~0.99 + + @Test + public void testGammaCorrectionLowChangeAtCenter() { + // If we set a user data point at (x2, y2^0.5), i.e. gamma = 0.5, it should bump the rest + // of the spline accordingly. + final int x1 = 1000; + final int x2 = 2500; + final int x3 = 4000; + final float y1 = GAMMA_CORRECTION_SPLINE.interpolate(x1); + final float y2 = GAMMA_CORRECTION_SPLINE.interpolate(x2); + final float y3 = GAMMA_CORRECTION_SPLINE.interpolate(x3); + Resources resources = createResources(GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS, + DISPLAY_LEVELS_NITS, DISPLAY_LEVELS_BACKLIGHT); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources); + // Let's start with a sanity check: + assertEquals(y1, strategy.getBrightness(x1), 0.01f /* tolerance */); + assertEquals(y2, strategy.getBrightness(x2), 0.01f /* tolerance */); + assertEquals(y3, strategy.getBrightness(x3), 0.01f /* tolerance */); + // OK, let's roll: + float gamma = 0.5f; + strategy.addUserDataPoint(x2, (float) MathUtils.pow(y2, gamma)); + assertEquals(MathUtils.pow(y1, gamma), strategy.getBrightness(x1), 0.01f /* tolerance */); + assertEquals(MathUtils.pow(y2, gamma), strategy.getBrightness(x2), 0.01f /* tolerance */); + assertEquals(MathUtils.pow(y3, gamma), strategy.getBrightness(x3), 0.01f /* tolerance */); + // The adjustment should be +0.63 (manual calculation). + assertEquals(+0.63f, strategy.getAutoBrightnessAdjustment(), 0.01f /* tolerance */); + } + + @Test + public void testGammaCorrectionHighChangeAtCenter() { + // This time we set a user data point at (x2, y2^0.25), i.e. gamma = 0.3 (the minimum), + // which should bump the rest of the spline accordingly, and further correct x2 to hit + // y2^0.25 (not y2^0.3). + final int x1 = 1000; + final int x2 = 2500; + final int x3 = 4000; + final float y1 = GAMMA_CORRECTION_SPLINE.interpolate(x1); + final float y2 = GAMMA_CORRECTION_SPLINE.interpolate(x2); + final float y3 = GAMMA_CORRECTION_SPLINE.interpolate(x3); + Resources resources = createResources(GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS, + DISPLAY_LEVELS_NITS, DISPLAY_LEVELS_BACKLIGHT); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources); + // Sanity check: + assertEquals(y1, strategy.getBrightness(x1), 0.01f /* tolerance */); + assertEquals(y2, strategy.getBrightness(x2), 0.01f /* tolerance */); + assertEquals(y3, strategy.getBrightness(x3), 0.01f /* tolerance */); + // Let's roll: + float gamma = 0.25f; + final float minGamma = 1.0f / MAXIMUM_GAMMA; + strategy.addUserDataPoint(x2, (float) MathUtils.pow(y2, gamma)); + assertEquals(MathUtils.pow(y1, minGamma), strategy.getBrightness(x1), + 0.01f /* tolerance */); + assertEquals(MathUtils.pow(y2, gamma), strategy.getBrightness(x2), + 0.01f /* tolerance */); + assertEquals(MathUtils.pow(y3, minGamma), strategy.getBrightness(x3), + 0.01f /* tolerance */); + // The adjustment should be +1.0 (maximum adjustment). + assertEquals(+1.0f, strategy.getAutoBrightnessAdjustment(), 0.01f /* tolerance */); + } + + @Test + public void testGammaCorrectionExtremeChangeAtCenter() { + // Extreme changes (e.g. setting brightness to 0.0 or 1.0) can't be gamma corrected, so we + // just make sure the adjustment reflects the change. + Resources resources = createResources(GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS, + DISPLAY_LEVELS_NITS, DISPLAY_LEVELS_BACKLIGHT); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources); + assertEquals(0.0f, strategy.getAutoBrightnessAdjustment(), 0.01f /* tolerance */); + strategy.addUserDataPoint(2500, 1.0f); + assertEquals(+1.0f, strategy.getAutoBrightnessAdjustment(), 0.01f /* tolerance */); + strategy.addUserDataPoint(2500, 0.0f); + assertEquals(-1.0f, strategy.getAutoBrightnessAdjustment(), 0.01f /* tolerance */); + } + + @Test + public void testGammaCorrectionChangeAtEdges() { + // The algorithm behaves differently at the edges, because gamma correction there tends to + // be extreme. If we add a user data point at (x0, y0+0.3), the adjustment should be + // 0.3*2 = 0.6, resulting in a gamma of 3**-0.6 = ~0.52. + final int x0 = 100; + final int x2 = 2500; + final int x4 = 4900; + final float y0 = GAMMA_CORRECTION_SPLINE.interpolate(x0); + final float y2 = GAMMA_CORRECTION_SPLINE.interpolate(x2); + final float y4 = GAMMA_CORRECTION_SPLINE.interpolate(x4); + Resources resources = createResources(GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS, + DISPLAY_LEVELS_NITS, DISPLAY_LEVELS_BACKLIGHT); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources); + // Sanity, as per tradition: + assertEquals(y0, strategy.getBrightness(x0), 0.01f /* tolerance */); + assertEquals(y2, strategy.getBrightness(x2), 0.01f /* tolerance */); + assertEquals(y4, strategy.getBrightness(x4), 0.01f /* tolerance */); + // Rollin': + float increase = 0.3f; + float adjustment = increase * 2; + float gamma = (float) MathUtils.pow(MAXIMUM_GAMMA, -adjustment); + strategy.addUserDataPoint(x0, y0 + increase); + assertEquals(y0 + increase, strategy.getBrightness(x0), 0.01f /* tolerance */); + assertEquals(MathUtils.pow(y2, gamma), strategy.getBrightness(x2), 0.01f /* tolerance */); + assertEquals(MathUtils.pow(y4, gamma), strategy.getBrightness(x4), 0.01f /* tolerance */); + assertEquals(adjustment, strategy.getAutoBrightnessAdjustment(), 0.01f /* tolerance */); + // Similarly, if we set a user data point at (x4, 1.0), the adjustment should be (1-y4)*2. + increase = 1.0f - y4; + adjustment = increase * 2; + gamma = (float) MathUtils.pow(MAXIMUM_GAMMA, -adjustment); + strategy.addUserDataPoint(x4, 1.0f); + assertEquals(MathUtils.pow(y0, gamma), strategy.getBrightness(x0), 0.01f /* tolerance */); + assertEquals(MathUtils.pow(y2, gamma), strategy.getBrightness(x2), 0.01f /* tolerance */); + assertEquals(1.0f, strategy.getBrightness(x4), 0.01f /* tolerance */); + assertEquals(adjustment, strategy.getAutoBrightnessAdjustment(), 0.01f /* tolerance */); + } } diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java index 084f7e531858..c5cd0a3f6a2a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java @@ -242,7 +242,7 @@ public class SuspendPackagesTest { } @Test - public void testIsPackageSuspended() { + public void testIsPackageSuspended() throws Exception { suspendTestPackage(null, null, null); assertTrue("isPackageSuspended is false", mPackageManager.isPackageSuspended(TEST_APP_PACKAGE_NAME)); @@ -370,8 +370,8 @@ public class SuspendPackagesTest { } @Override - public void onPackagesSuspended(String[] packageNames, Bundle launcherExtras, - UserHandle user) { + public void onPackagesSuspended(String[] packageNames, UserHandle user, + Bundle launcherExtras) { final StringBuilder errorString = new StringBuilder(); if (!Arrays.equals(packageNames, PACKAGES_TO_SUSPEND)) { errorString.append("Received unexpected packageNames in onPackagesSuspended:"); |