diff options
111 files changed, 2003 insertions, 370 deletions
diff --git a/api/current.txt b/api/current.txt index 2572cd3d0dfd..423e0ae6df69 100644 --- a/api/current.txt +++ b/api/current.txt @@ -27627,6 +27627,7 @@ package android.net.http { public class X509TrustManagerExtensions { ctor public X509TrustManagerExtensions(javax.net.ssl.X509TrustManager) throws java.lang.IllegalArgumentException; method public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, java.lang.String) throws java.security.cert.CertificateException; + method public boolean isSameTrustConfiguration(java.lang.String, java.lang.String); method public boolean isUserAddedCertificate(java.security.cert.X509Certificate); } @@ -42405,7 +42406,7 @@ package android.telephony { } public final class SubscriptionPlan implements android.os.Parcelable { - method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator(); + method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator(); method public int describeContents(); method public int getDataLimitBehavior(); method public long getDataLimitBytes(); @@ -42427,9 +42428,7 @@ package android.telephony { public static class SubscriptionPlan.Builder { method public android.telephony.SubscriptionPlan build(); method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime); - method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime); - method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime); - method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime); + method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period); method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int); method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence); diff --git a/api/system-current.txt b/api/system-current.txt index 76a71cd7c44e..6186a5571bad 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1255,6 +1255,7 @@ package android.hardware.display { method public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration(); method public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents(); method public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration(); + method public android.util.Pair<float[], float[]> getMinimumBrightnessCurve(); method public android.graphics.Point getStableDisplaySize(); method public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration); method public void setSaturationLevel(float); @@ -5191,7 +5192,7 @@ package android.telephony { } public final class SubscriptionPlan implements android.os.Parcelable { - method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator(); + method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator(); method public int describeContents(); method public int getDataLimitBehavior(); method public long getDataLimitBytes(); @@ -5213,9 +5214,10 @@ package android.telephony { public static class SubscriptionPlan.Builder { method public android.telephony.SubscriptionPlan build(); method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime); - method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime); - method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime); - method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime); + method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period); + method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime); + method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime); + method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime); method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int); method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence); diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index a40ea0857b70..73d1102dc090 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -153,6 +153,8 @@ Landroid/app/AlarmManager;->mService:Landroid/app/IAlarmManager; Landroid/app/AlarmManager;->WINDOW_EXACT:J Landroid/app/AlarmManager;->WINDOW_HEURISTIC:J Landroid/app/AlertDialog$Builder;->P:Lcom/android/internal/app/AlertController$AlertParams; +Landroid/app/AlertDialog$Builder;->setRecycleOnMeasureEnabled(Z)Landroid/app/AlertDialog$Builder; +Landroid/app/AlertDialog$Builder;->setView(Landroid/view/View;IIII)Landroid/app/AlertDialog$Builder; Landroid/app/AlertDialog;->mAlert:Lcom/android/internal/app/AlertController; Landroid/app/AppGlobals;->getInitialApplication()Landroid/app/Application; Landroid/app/AppGlobals;->getInitialPackage()Ljava/lang/String; @@ -207,6 +209,7 @@ Landroid/app/backup/BackupDataInputStream;->key:Ljava/lang/String; Landroid/app/backup/BackupDataOutput;->mBackupWriter:J Landroid/app/backup/BackupHelperDispatcher$Header;->chunkSize:I Landroid/app/backup/BackupHelperDispatcher$Header;->keyPrefix:Ljava/lang/String; +Landroid/app/backup/FileBackupHelperBase;->writeNewStateDescription(Landroid/os/ParcelFileDescriptor;)V Landroid/app/backup/FullBackup;->backupToTar(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/backup/FullBackupDataOutput;)I Landroid/app/backup/FullBackupDataOutput;->addSize(J)V Landroid/app/backup/FullBackupDataOutput;-><init>(Landroid/os/ParcelFileDescriptor;)V @@ -260,6 +263,7 @@ Landroid/app/IActivityManager;->moveTaskToFront(IILandroid/os/Bundle;)V Landroid/app/IActivityManager;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V Landroid/app/IActivityManager;->requestBugReport(I)V Landroid/app/IActivityManager;->resumeAppSwitches()V +Landroid/app/IActivityManager;->setActivityController(Landroid/app/IActivityController;Z)V Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V Landroid/app/IActivityManager;->setTaskResizeable(II)V Landroid/app/IActivityManager;->stopService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;I)I @@ -329,6 +333,7 @@ Landroid/app/NativeActivity;->showIme(I)V Landroid/app/Notification$Builder;->mActions:Ljava/util/ArrayList; Landroid/app/Notification$Builder;->makePublicContentView()Landroid/widget/RemoteViews; Landroid/app/Notification$Builder;->setChannel(Ljava/lang/String;)Landroid/app/Notification$Builder; +Landroid/app/Notification;-><init>(Landroid/content/Context;ILjava/lang/CharSequence;JLjava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/content/Intent;)V Landroid/app/Notification;->isGroupSummary()Z Landroid/app/NotificationManager;->getService()Landroid/app/INotificationManager; Landroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V @@ -374,6 +379,7 @@ Landroid/app/TimePickerDialog;->mTimePicker:Landroid/widget/TimePicker; Landroid/app/trust/ITrustManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/app/usage/UsageStatsManager;->mService:Landroid/app/usage/IUsageStatsManager; Landroid/app/usage/UsageStats;->mLastEvent:I +Landroid/app/usage/UsageStats;->mLaunchCount:I Landroid/app/usage/UsageStats;->mTotalTimeInForeground:J Landroid/app/Vr2dDisplayProperties$Builder;->build()Landroid/app/Vr2dDisplayProperties; Landroid/app/Vr2dDisplayProperties$Builder;-><init>()V @@ -414,6 +420,10 @@ Landroid/bluetooth/BluetoothGattDescriptor;->mInstance:I Landroid/bluetooth/BluetoothGatt;->mAuthRetryState:I Landroid/bluetooth/BluetoothGatt;->refresh()Z Landroid/bluetooth/BluetoothHeadset;->close()V +Landroid/bluetooth/BluetoothHeadset;->connectAudio()Z +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;->isTetheringOn()Z Landroid/bluetooth/BluetoothPan;->setBluetoothTethering(Z)V @@ -450,6 +460,7 @@ Landroid/content/ContentResolver;->mContext:Landroid/content/Context; Landroid/content/ContentResolver;->mPackageName:Ljava/lang/String; Landroid/content/ContentResolver;->releaseProvider(Landroid/content/IContentProvider;)Z Landroid/content/ContentResolver;->releaseUnstableProvider(Landroid/content/IContentProvider;)Z +Landroid/content/ContentResolver;->takePersistableUriPermission(Ljava/lang/String;Landroid/net/Uri;I)V Landroid/content/ContentResolver;->unstableProviderDied(Landroid/content/IContentProvider;)V Landroid/content/ContentValues;-><init>(Ljava/util/HashMap;)V Landroid/content/ContentValues;->mValues:Ljava/util/HashMap; @@ -475,6 +486,7 @@ Landroid/content/Intent;->ACTION_ALARM_CHANGED:Ljava/lang/String; Landroid/content/IntentFilter;->mActions:Ljava/util/ArrayList; Landroid/content/Intent;->mExtras:Landroid/os/Bundle; Landroid/content/Intent;->putExtra(Ljava/lang/String;Landroid/os/IBinder;)Landroid/content/Intent; +Landroid/content/Intent;->toInsecureString()Ljava/lang/String; Landroid/content/pm/ActivityInfo;->resizeMode:I Landroid/content/pm/ActivityInfo;->supportsPictureInPicture()Z Landroid/content/pm/ApplicationInfo;->enabledSetting:I @@ -515,6 +527,7 @@ Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/content/pm/LauncherActivityInfo;->mActivityInfo:Landroid/content/pm/ActivityInfo; Landroid/content/pm/LauncherApps;->mPm:Landroid/content/pm/PackageManager; Landroid/content/pm/LauncherApps;->startShortcut(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Rect;Landroid/os/Bundle;I)V +Landroid/content/pm/PackageInfo;->INSTALL_LOCATION_UNSPECIFIED:I Landroid/content/pm/PackageItemInfo;->setForceSafeLabels(Z)V Landroid/content/pm/PackageManager;->buildRequestPermissionsIntent([Ljava/lang/String;)Landroid/content/Intent; Landroid/content/pm/PackageManager;->freeStorageAndNotify(JLandroid/content/pm/IPackageDataObserver;)V @@ -584,6 +597,7 @@ Landroid/content/res/AssetFileDescriptor;->mLength:J Landroid/content/res/AssetFileDescriptor;->mStartOffset:J Landroid/content/res/AssetManager;->addAssetPathAsSharedLibrary(Ljava/lang/String;)I Landroid/content/res/AssetManager;->addAssetPath(Ljava/lang/String;)I +Landroid/content/res/AssetManager;->applyStyle(JIILandroid/content/res/XmlBlock$Parser;[IJJ)V Landroid/content/res/AssetManager;->getAssignedPackageIdentifiers()Landroid/util/SparseArray; Landroid/content/res/AssetManager;->getResourceBagText(II)Ljava/lang/CharSequence; Landroid/content/res/AssetManager;->getResourceEntryName(I)Ljava/lang/String; @@ -599,12 +613,14 @@ Landroid/content/res/AssetManager;->openNonAsset(ILjava/lang/String;)Ljava/io/In Landroid/content/res/AssetManager;->openNonAsset(Ljava/lang/String;I)Ljava/io/InputStream; Landroid/content/res/AssetManager;->openNonAsset(Ljava/lang/String;)Ljava/io/InputStream; Landroid/content/res/AssetManager;->resolveAttrs(JII[I[I[I[I)Z +Landroid/content/res/AssetManager;->retrieveAttributes(Landroid/content/res/XmlBlock$Parser;[I[I[I)Z Landroid/content/res/AssetManager;->setConfiguration(IILjava/lang/String;IIIIIIIIIIIIIII)V Landroid/content/res/ColorStateList$ColorStateListFactory;-><init>(Landroid/content/res/ColorStateList;)V Landroid/content/res/ColorStateList;->getColors()[I 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/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; @@ -747,6 +763,7 @@ 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;->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/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I @@ -778,6 +795,7 @@ Landroid/graphics/Picture;->mNativePicture:J Landroid/graphics/PixelXorXfermode;-><init>(I)V Landroid/graphics/PorterDuffColorFilter;->setColor(I)V Landroid/graphics/PorterDuffColorFilter;->setMode(Landroid/graphics/PorterDuff$Mode;)V +Landroid/graphics/Rect;->scale(F)V Landroid/graphics/Region;-><init>(JI)V Landroid/graphics/Region;->mNativeRegion:J Landroid/graphics/SurfaceTexture;->mFrameAvailableListener:J @@ -1051,11 +1069,13 @@ Landroid/media/MediaCodec$CodecException;-><init>(IILjava/lang/String;)V Landroid/media/MediaCodec;->getBuffers(Z)[Ljava/nio/ByteBuffer; Landroid/media/MediaCodec;->releaseOutputBuffer(IZZJ)V Landroid/media/MediaFile;->FIRST_AUDIO_FILE_TYPE:I +Landroid/media/MediaFile;->getFileTypeForMimeType(Ljava/lang/String;)I Landroid/media/MediaFile;->getFileType(Ljava/lang/String;)Landroid/media/MediaFile$MediaFileType; Landroid/media/MediaFile;->getMimeTypeForFile(Ljava/lang/String;)Ljava/lang/String; Landroid/media/MediaFile;-><init>()V Landroid/media/MediaFile;->isAudioFileType(I)Z Landroid/media/MediaFile;->isImageFileType(I)Z +Landroid/media/MediaFile;->isPlayListFileType(I)Z Landroid/media/MediaFile;->isVideoFileType(I)Z Landroid/media/MediaFile;->LAST_AUDIO_FILE_TYPE:I Landroid/media/MediaFile$MediaFileType;->fileType:I @@ -1072,6 +1092,7 @@ Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;[Ljava/lang/String; Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;Ljava/util/List;)V Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;)V Landroid/media/MediaPlayer;->setRetransmitEndpoint(Ljava/net/InetSocketAddress;)V +Landroid/media/MediaRecorder;->setParameter(Ljava/lang/String;)V Landroid/media/MediaRouter$RouteInfo;->getStatusCode()I Landroid/media/MediaRouter$RouteInfo;->STATUS_CONNECTING:I Landroid/media/MediaRouter;->selectRouteInt(ILandroid/media/MediaRouter$RouteInfo;Z)V @@ -1142,8 +1163,10 @@ Landroid/net/ConnectivityManager;->getTetheredIfaces()[Ljava/lang/String; Landroid/net/ConnectivityManager;->isNetworkSupported(I)Z Landroid/net/ConnectivityManager;->isNetworkTypeMobile(I)Z Landroid/net/ConnectivityManager;->mService:Landroid/net/IConnectivityManager; +Landroid/net/ConnectivityManager;->registerNetworkFactory(Landroid/os/Messenger;Ljava/lang/String;)V Landroid/net/ConnectivityManager;->requestRouteToHostAddress(ILjava/net/InetAddress;)Z Landroid/net/ConnectivityManager;->requestRouteToHost(II)Z +Landroid/net/ConnectivityManager;->setBackgroundDataSetting(Z)V Landroid/net/ConnectivityManager;->TYPE_MOBILE_CBS:I Landroid/net/ConnectivityManager;->TYPE_MOBILE_EMERGENCY:I Landroid/net/ConnectivityManager;->TYPE_MOBILE_FOTA:I @@ -1285,6 +1308,7 @@ Landroid/nfc/NfcAdapter;->setNdefPushMessageCallback(Landroid/nfc/NfcAdapter$Cre Landroid/opengl/GLSurfaceView$EglHelper;->mEglContext:Ljavax/microedition/khronos/egl/EGLContext; Landroid/opengl/GLSurfaceView$GLThread;->mEglHelper:Landroid/opengl/GLSurfaceView$EglHelper; Landroid/opengl/GLSurfaceView;->mGLThread:Landroid/opengl/GLSurfaceView$GLThread; +Landroid/opengl/GLSurfaceView;->mRenderer:Landroid/opengl/GLSurfaceView$Renderer; Landroid/os/AsyncTask;->mFuture:Ljava/util/concurrent/FutureTask; Landroid/os/AsyncTask;->mStatus:Landroid/os/AsyncTask$Status; Landroid/os/AsyncTask;->mTaskInvoked:Ljava/util/concurrent/atomic/AtomicBoolean; @@ -1293,6 +1317,7 @@ Landroid/os/AsyncTask;->sDefaultExecutor:Ljava/util/concurrent/Executor; Landroid/os/AsyncTask;->setDefaultExecutor(Ljava/util/concurrent/Executor;)V Landroid/os/BatteryStats$Counter;->getCountLocked(I)I Landroid/os/BatteryStats;->getUidStats()Landroid/util/SparseArray; +Landroid/os/BatteryStats$HistoryItem;->CMD_UPDATE:B Landroid/os/BatteryStats$HistoryItem;->states2:I Landroid/os/BatteryStats;->NUM_DATA_CONNECTION_TYPES:I Landroid/os/BatteryStats;->startIteratingHistoryLocked()Z @@ -1904,6 +1929,7 @@ Landroid/system/OsConstants;->UNIX_PATH_MAX:I Landroid/system/OsConstants;->XATTR_CREATE:I Landroid/system/OsConstants;->XATTR_REPLACE:I Landroid/system/StructTimeval;->fromMillis(J)Landroid/system/StructTimeval; +Landroid/telecom/AudioState;->isMuted:Z Landroid/telecom/TelecomManager;->EXTRA_IS_HANDOVER:Ljava/lang/String; Landroid/telecom/TelecomManager;->getUserSelectedOutgoingPhoneAccount()Landroid/telecom/PhoneAccountHandle; Landroid/telecom/TelecomManager;->setUserSelectedOutgoingPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V @@ -1938,6 +1964,8 @@ Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_GREAT:I Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_MODERATE:I Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_NONE_OR_UNKNOWN:I Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_POOR:I +Landroid/telephony/SmsManager;->sendMultipartTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/util/ArrayList;IZI)V +Landroid/telephony/SmsManager;->sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;IZI)V Landroid/telephony/SmsMessage;->getSubId()I Landroid/telephony/SmsMessage;->mWrappedSmsMessage:Lcom/android/internal/telephony/SmsMessageBase; Landroid/telephony/SubscriptionManager;->getActiveSubscriptionIdList()[I @@ -2032,6 +2060,7 @@ Landroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;III)V Landroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V Landroid/text/SpannableStringInternal;->START:I Landroid/text/SpanSet;->spans:[Ljava/lang/Object; +Landroid/text/StaticLayout;->getHeight(Z)I Landroid/text/StaticLayout;-><init>(Ljava/lang/CharSequence;IILandroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZLandroid/text/TextUtils$TruncateAt;II)V Landroid/text/StaticLayout$LineBreaks;->ascents:[F Landroid/text/StaticLayout$LineBreaks;->breaks:[I @@ -2091,18 +2120,21 @@ Landroid/view/accessibility/AccessibilityManager;->mIsHighTextContrastEnabled:Z Landroid/view/accessibility/AccessibilityManager;->sInstance:Landroid/view/accessibility/AccessibilityManager; Landroid/view/accessibility/AccessibilityManager;->sInstanceSync:Ljava/lang/Object; Landroid/view/accessibility/AccessibilityNodeInfo;->isSealed()Z +Landroid/view/accessibility/AccessibilityNodeInfo;->mChildNodeIds:Landroid/util/LongArray; Landroid/view/accessibility/AccessibilityNodeInfo;->refresh(Landroid/os/Bundle;Z)Z Landroid/view/accessibility/AccessibilityNodeInfo;->setSealed(Z)V 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;->initializeInvalidateRegion(IIII)V Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener; Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/view/Choreographer$CallbackQueue;->addCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)V Landroid/view/Choreographer;->doFrame(JI)V Landroid/view/Choreographer;->getFrameTime()J Landroid/view/Choreographer;->mCallbackQueues:[Landroid/view/Choreographer$CallbackQueue; +Landroid/view/Choreographer;->mFrameIntervalNanos:J Landroid/view/Choreographer;->mLastFrameTimeNanos:J Landroid/view/Choreographer;->mLock:Ljava/lang/Object; Landroid/view/Choreographer;->scheduleVsyncLocked()V @@ -2238,10 +2270,13 @@ Landroid/view/Surface;-><init>(J)V Landroid/view/Surface;->mLock:Ljava/lang/Object; Landroid/view/Surface;->mNativeObject:J Landroid/view/SurfaceSession;->mNativeClient:J +Landroid/view/Surface;->transferFrom(Landroid/view/Surface;)V +Landroid/view/SurfaceView;->isFixedSize()Z Landroid/view/SurfaceView;->mCallbacks:Ljava/util/ArrayList; Landroid/view/SurfaceView;->mFormat:I Landroid/view/SurfaceView;->mRequestedFormat:I Landroid/view/SurfaceView;->mSurfaceHolder:Landroid/view/SurfaceHolder; +Landroid/view/SurfaceView;->setFrame(IIII)Z Landroid/view/SurfaceView;->surfacePositionLost_uiRtSync(J)V Landroid/view/SurfaceView;->updateSurfacePosition_renderWorker(JIIII)V Landroid/view/textclassifier/logging/SmartSelectionEventTracker;-><init>(Landroid/content/Context;I)V @@ -2286,6 +2321,7 @@ Landroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V Landroid/view/View;->dispatchDetachedFromWindow()V Landroid/view/View;->fitsSystemWindows()Z Landroid/view/View;->getAccessibilityDelegate()Landroid/view/View$AccessibilityDelegate; +Landroid/view/View;->getAccessibilityViewId()I Landroid/view/View;->getBoundsOnScreen(Landroid/graphics/Rect;)V Landroid/view/View;->getHorizontalScrollFactor()F Landroid/view/View;->getInverseMatrix()Landroid/graphics/Matrix; @@ -2311,6 +2347,7 @@ Landroid/view/ViewGroup;->mGroupFlags:I Landroid/view/ViewGroup;->mOnHierarchyChangeListener:Landroid/view/ViewGroup$OnHierarchyChangeListener; Landroid/view/ViewGroup;->mPersistentDrawingCache:I Landroid/view/ViewGroup;->offsetChildrenTopAndBottom(I)V +Landroid/view/ViewGroup;->onChildVisibilityChanged(Landroid/view/View;II)V Landroid/view/ViewGroup;->resetResolvedDrawables()V Landroid/view/ViewGroup;->resetResolvedLayoutDirection()V Landroid/view/ViewGroup;->resetResolvedPadding()V @@ -2321,6 +2358,7 @@ Landroid/view/View;->includeForAccessibility()Z Landroid/view/View;->initializeScrollbars(Landroid/content/res/TypedArray;)V Landroid/view/View;->internalSetPadding(IIII)V Landroid/view/View;->isPaddingResolved()Z +Landroid/view/View;->isRootNamespace()Z Landroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z Landroid/view/View;->isVisibleToUser()Z Landroid/view/View$ListenerInfo;-><init>()V @@ -2343,6 +2381,7 @@ Landroid/view/View;->mPaddingLeft:I Landroid/view/View;->mPaddingRight:I Landroid/view/View;->mPaddingTop:I Landroid/view/View;->mParent:Landroid/view/ViewParent; +Landroid/view/View;->mPrivateFlags2:I Landroid/view/View;->mPrivateFlags3:I Landroid/view/View;->mPrivateFlags:I Landroid/view/View;->mRecreateDisplayList:Z @@ -2423,8 +2462,31 @@ Landroid/view/Window;->mCallback:Landroid/view/Window$Callback; Landroid/view/Window;->mContext:Landroid/content/Context; Landroid/view/Window;->mHardwareAccelerated:Z Landroid/view/Window;->mWindowStyle:Landroid/content/res/TypedArray; +Landroid/webkit/CacheManager;->cacheDisabled()Z +Landroid/webkit/CacheManager$CacheResult;->getContentDisposition()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getContentLength()J +Landroid/webkit/CacheManager$CacheResult;->getEncoding()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getETag()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getExpires()J +Landroid/webkit/CacheManager$CacheResult;->getExpiresString()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getHttpStatusCode()I +Landroid/webkit/CacheManager$CacheResult;->getInputStream()Ljava/io/InputStream; +Landroid/webkit/CacheManager$CacheResult;->getLastModified()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getLocalPath()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getLocation()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getMimeType()Ljava/lang/String; +Landroid/webkit/CacheManager$CacheResult;->getOutputStream()Ljava/io/OutputStream; +Landroid/webkit/CacheManager$CacheResult;-><init>()V +Landroid/webkit/CacheManager$CacheResult;->setEncoding(Ljava/lang/String;)V +Landroid/webkit/CacheManager$CacheResult;->setInputStream(Ljava/io/InputStream;)V +Landroid/webkit/CacheManager;->endCacheTransaction()Z +Landroid/webkit/CacheManager;->getCacheFileBaseDir()Ljava/io/File; +Landroid/webkit/CacheManager;->getCacheFile(Ljava/lang/String;Ljava/util/Map;)Landroid/webkit/CacheManager$CacheResult; +Landroid/webkit/CacheManager;->saveCacheFile(Ljava/lang/String;Landroid/webkit/CacheManager$CacheResult;)V +Landroid/webkit/CacheManager;->startCacheTransaction()Z Landroid/webkit/IWebViewUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/webkit/WebResourceResponse;->mImmutable:Z +Landroid/webkit/WebSettings$TextSize;->value:I Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler; Landroid/webkit/WebViewClient;->onUnhandledInputEvent(Landroid/webkit/WebView;Landroid/view/InputEvent;)V Landroid/webkit/WebView;->debugDump()V @@ -2435,11 +2497,13 @@ Landroid/webkit/WebViewFactory;->getProvider()Landroid/webkit/WebViewFactoryProv Landroid/webkit/WebViewFactory;->getWebViewContextAndSetProvider()Landroid/content/Context; Landroid/webkit/WebViewFactory;->sPackageInfo:Landroid/content/pm/PackageInfo; Landroid/webkit/WebViewFactory;->sProviderInstance:Landroid/webkit/WebViewFactoryProvider; +Landroid/webkit/WebView;->getContentWidth()I Landroid/webkit/WebView;->getTouchIconUrl()Ljava/lang/String; Landroid/webkit/WebView;->getVisibleTitleHeight()I Landroid/webkit/WebView;->isPaused()Z Landroid/webkit/WebView;->mProvider:Landroid/webkit/WebViewProvider; Landroid/webkit/WebView;->notifyFindDialogDismissed()V +Landroid/webkit/WebView;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V Landroid/webkit/WebView;->restorePicture(Landroid/os/Bundle;Ljava/io/File;)Z Landroid/webkit/WebView;->savePicture(Landroid/os/Bundle;Ljava/io/File;)Z Landroid/webkit/WebView;->sEnforceThreadChecking:Z @@ -2454,6 +2518,7 @@ Landroid/widget/AbsListView;->mEdgeGlowTop:Landroid/widget/EdgeEffect; Landroid/widget/AbsListView;->mFastScroll:Landroid/widget/FastScroller; Landroid/widget/AbsListView;->mFlingRunnable:Landroid/widget/AbsListView$FlingRunnable; Landroid/widget/AbsListView;->mIsChildViewEnabled:Z +Landroid/widget/AbsListView;->mLayoutMode:I Landroid/widget/AbsListView;->mMaximumVelocity:I Landroid/widget/AbsListView;->mMotionPosition:I Landroid/widget/AbsListView;->mOnScrollListener:Landroid/widget/AbsListView$OnScrollListener; @@ -2483,6 +2548,8 @@ Landroid/widget/ActivityChooserModel;->get(Landroid/content/Context;Ljava/lang/S Landroid/widget/ActivityChooserView;->setExpandActivityOverflowButtonDrawable(Landroid/graphics/drawable/Drawable;)V Landroid/widget/AdapterView;->mDataChanged:Z Landroid/widget/AdapterView;->mFirstPosition:I +Landroid/widget/AdapterView;->mNextSelectedPosition:I +Landroid/widget/AdapterView;->mNextSelectedRowId:J Landroid/widget/AdapterView;->mOldSelectedPosition:I Landroid/widget/AdapterView;->setNextSelectedPositionInt(I)V Landroid/widget/AdapterView;->setSelectedPositionInt(I)V @@ -2492,6 +2559,7 @@ Landroid/widget/AutoCompleteTextView;->ensureImeVisible(Z)V Landroid/widget/AutoCompleteTextView;->mPopup:Landroid/widget/ListPopupWindow; Landroid/widget/AutoCompleteTextView;->setDropDownAlwaysVisible(Z)V Landroid/widget/AutoCompleteTextView;->setForceIgnoreOutsideTouch(Z)V +Landroid/widget/BaseAdapter;->mDataSetObservable:Landroid/database/DataSetObservable; Landroid/widget/CompoundButton;->mButtonDrawable:Landroid/graphics/drawable/Drawable; Landroid/widget/CompoundButton;->mOnCheckedChangeListener:Landroid/widget/CompoundButton$OnCheckedChangeListener; Landroid/widget/CursorAdapter;->mChangeObserver:Landroid/widget/CursorAdapter$ChangeObserver; @@ -2741,6 +2809,10 @@ Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setContactUri(Ljava/lang/ Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setFeatureTag(Ljava/lang/String;)V Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setTimestamp(Ljava/lang/String;)V Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V +Lcom/android/internal/app/AlertController;->mCustomTitleView:Landroid/view/View; +Lcom/android/internal/app/AlertController;->mForceInverseBackground:Z +Lcom/android/internal/app/AlertController;->mTitle:Ljava/lang/CharSequence; +Lcom/android/internal/app/AlertController;->mView:Landroid/view/View; Lcom/android/internal/app/AlertController$RecycleListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V Lcom/android/internal/app/IAppOpsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IAppOpsService; Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I @@ -3211,6 +3283,7 @@ Ljava/lang/ref/ReferenceQueue;->add(Ljava/lang/ref/Reference;)V Ljava/lang/ref/Reference;->referent:Ljava/lang/Object; Ljava/lang/Runtime;->loadLibrary(Ljava/lang/String;Ljava/lang/ClassLoader;)V Ljava/lang/Runtime;->load(Ljava/lang/String;Ljava/lang/ClassLoader;)V +Ljava/lang/Runtime;->mLibPaths:[Ljava/lang/String; Ljava/lang/Runtime;->nativeLoad(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String; Ljava/lang/Short;->value:S Ljava/lang/String;-><init>(II[C)V @@ -3232,7 +3305,9 @@ Ljava/lang/Thread;-><init>(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V Ljava/lang/Thread;->lock:Ljava/lang/Object; Ljava/lang/Thread;->name:Ljava/lang/String; Ljava/lang/Thread;->nativePeer:J +Ljava/lang/Thread;->parkBlocker:Ljava/lang/Object; Ljava/lang/Thread;->priority:I +Ljava/lang/Thread;->threadLocals:Ljava/lang/ThreadLocal$ThreadLocalMap; Ljava/lang/Throwable;->backtrace:Ljava/lang/Object; Ljava/lang/Throwable;->cause:Ljava/lang/Throwable; Ljava/lang/Throwable;->detailMessage:Ljava/lang/String; @@ -3264,7 +3339,10 @@ Ljava/net/Socket;->getFileDescriptor$()Ljava/io/FileDescriptor; Ljava/net/Socket;->impl:Ljava/net/SocketImpl; Ljava/net/SocketImpl;->serverSocket:Ljava/net/ServerSocket; Ljava/net/SocketImpl;->socket:Ljava/net/Socket; +Ljava/net/URI;->fragment:Ljava/lang/String; Ljava/net/URI;->host:Ljava/lang/String; +Ljava/net/URI;->port:I +Ljava/net/URI;->string:Ljava/lang/String; Ljava/net/URL;->handler:Ljava/net/URLStreamHandler; Ljava/net/URL;->handlers:Ljava/util/Hashtable; Ljava/nio/Buffer;->address:J @@ -3285,6 +3363,9 @@ Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V Ljava/text/DateFormat;->is24Hour:Ljava/lang/Boolean; Ljava/time/Duration;->toSeconds()Ljava/math/BigDecimal; Ljava/time/OffsetDateTime;-><init>(Ljava/time/LocalDateTime;Ljava/time/ZoneOffset;)V +Ljava/util/ArrayDeque;->elements:[Ljava/lang/Object; +Ljava/util/ArrayDeque;->head:I +Ljava/util/ArrayDeque;->tail:I Ljava/util/ArrayList;->elementData:[Ljava/lang/Object; Ljava/util/ArrayList;->size:I Ljava/util/ArrayList$SubList;->parent:Ljava/util/AbstractList; @@ -3297,22 +3378,37 @@ Ljava/util/Collections$SynchronizedCollection;->c:Ljava/util/Collection; Ljava/util/Collections$SynchronizedMap;->m:Ljava/util/Map; Ljava/util/Collections$UnmodifiableCollection;->c:Ljava/util/Collection; Ljava/util/Collections$UnmodifiableMap;->m:Ljava/util/Map; +Ljava/util/concurrent/atomic/AtomicInteger;->value:I Ljava/util/concurrent/ConcurrentHashMap$BaseIterator;->hasMoreElements()Z +Ljava/util/concurrent/CopyOnWriteArraySet;->al:Ljava/util/concurrent/CopyOnWriteArrayList; Ljava/util/concurrent/Executors$RunnableAdapter;->task:Ljava/lang/Runnable; Ljava/util/concurrent/FutureTask;->callable:Ljava/util/concurrent/Callable; Ljava/util/concurrent/FutureTask;->EXCEPTIONAL:I Ljava/util/concurrent/FutureTask;->outcome:Ljava/lang/Object; Ljava/util/concurrent/FutureTask;->state:I +Ljava/util/concurrent/LinkedBlockingDeque;->first:Ljava/util/concurrent/LinkedBlockingDeque$Node; +Ljava/util/concurrent/LinkedBlockingDeque;->lock:Ljava/util/concurrent/locks/ReentrantLock; Ljava/util/concurrent/LinkedBlockingQueue;->capacity:I +Ljava/util/concurrent/LinkedBlockingQueue;->head:Ljava/util/concurrent/LinkedBlockingQueue$Node; +Ljava/util/concurrent/LinkedBlockingQueue;->putLock:Ljava/util/concurrent/locks/ReentrantLock; +Ljava/util/concurrent/LinkedBlockingQueue;->takeLock:Ljava/util/concurrent/locks/ReentrantLock; +Ljava/util/concurrent/ThreadPoolExecutor;->allowCoreThreadTimeOut:Z Ljava/util/EnumMap;->keyType:Ljava/lang/Class; Ljava/util/EnumSet;->elementType:Ljava/lang/Class; Ljava/util/HashMap$HashIterator;->hasNext()Z +Ljava/util/HashMap;->modCount:I +Ljava/util/HashMap;->table:[Ljava/util/HashMap$Node; +Ljava/util/HashSet;->map:Ljava/util/HashMap; Ljava/util/jar/JarFile;->manifest:Ljava/util/jar/Manifest; Ljava/util/LinkedHashMap;->eldest()Ljava/util/Map$Entry; Ljava/util/LinkedHashMap$LinkedHashIterator;->hasNext()Z +Ljava/util/LinkedList;->size:I Ljava/util/Locale;->createConstant(Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale; +Ljava/util/PriorityQueue;->modCount:I +Ljava/util/PriorityQueue;->size:I Ljava/util/Random;->seedUniquifier()J Ljava/util/regex/Matcher;->appendPos:I +Ljava/util/Vector;->elementData(I)Ljava/lang/Object; Ljava/util/zip/Deflater;->buf:[B Ljava/util/zip/Deflater;->finished:Z Ljava/util/zip/Deflater;->finish:Z diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 5113fd0cc368..757fc643d9a3 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1338,6 +1338,32 @@ public class NotificationManager { return false; } + /** + * @hide + */ + public static int toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress) { + return toggleEffects(currentEffects, SCREEN_OFF_SUPPRESSED_EFFECTS, suppress); + } + + /** + * @hide + */ + public static int toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress) { + return toggleEffects(currentEffects, SCREEN_ON_SUPPRESSED_EFFECTS, suppress); + } + + private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) { + for (int i = 0; i < effects.length; i++) { + final int effect = effects[i]; + if (suppress) { + currentEffects |= effect; + } else { + currentEffects &= ~effect; + } + } + return currentEffects; + } + public static String suppressedEffectsToString(int effects) { if (effects <= 0) return ""; final StringBuilder sb = new StringBuilder(); diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 37360bad73c7..49cc498cffa2 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -37,6 +37,7 @@ import android.util.SparseArray; import android.widget.RemoteViews; import android.widget.RemoteViews.OnClickHandler; +import com.android.internal.R; import com.android.internal.appwidget.IAppWidgetHost; import com.android.internal.appwidget.IAppWidgetService; @@ -171,8 +172,9 @@ public class AppWidgetHost { return; } sServiceInitialized = true; - if (!context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_APP_WIDGETS)) { + PackageManager packageManager = context.getPackageManager(); + if (!packageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS) + && !context.getResources().getBoolean(R.bool.config_enableAppWidgetService)) { return; } IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE); diff --git a/core/java/android/content/QuickViewConstants.java b/core/java/android/content/QuickViewConstants.java index a25513de3d47..132d43f2e143 100644 --- a/core/java/android/content/QuickViewConstants.java +++ b/core/java/android/content/QuickViewConstants.java @@ -45,8 +45,8 @@ public class QuickViewConstants { * Feature to delete an individual document. Quick viewer implementations must use * Storage Access Framework to both verify delete permission and to delete content. * - * @see DocumentsContract#Document#FLAG_SUPPORTS_DELETE - * @see DocumentsContract#deleteDocument(ContentResolver resolver, Uri documentUri) + * @see DocumentsContract.Document#FLAG_SUPPORTS_DELETE + * @see DocumentsContract#deleteDocument(ContentResolver, Uri) */ public static final String FEATURE_DELETE = "android:delete"; diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 49b1efd08c91..c5a39f4c4502 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; @@ -1166,7 +1167,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface HiddenApiEnforcementPolicy {} - private boolean isValidHiddenApiEnforcementPolicy(int policy) { + /** @hide */ + public static boolean isValidHiddenApiEnforcementPolicy(int policy) { return policy >= HIDDEN_API_ENFORCEMENT_DEFAULT && policy <= HIDDEN_API_ENFORCEMENT_MAX; } @@ -1686,13 +1688,17 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * @hide */ public @HiddenApiEnforcementPolicy int getHiddenApiEnforcementPolicy() { + if (isAllowedToUseHiddenApis()) { + return HIDDEN_API_ENFORCEMENT_NONE; + } if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) { return mHiddenApiPolicy; } - if (isAllowedToUseHiddenApis()) { - return HIDDEN_API_ENFORCEMENT_NONE; + if (targetSdkVersion <= Build.VERSION_CODES.O_MR1) { + return HIDDEN_API_ENFORCEMENT_BLACK; + } else { + return HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK; } - return HIDDEN_API_ENFORCEMENT_BLACK; } /** @@ -1706,6 +1712,31 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } /** + * Updates the hidden API enforcement policy for this app from the given values, if appropriate. + * + * This will have no effect if this app is not subject to hidden API enforcement, i.e. if it + * is on the package whitelist. + * + * @param policyPreP configured policy for pre-P apps, or {@link + * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured. + * @param policyP configured policy for apps targeting P or later, or {@link + * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured. + * @hide + */ + public void maybeUpdateHiddenApiEnforcementPolicy( + @HiddenApiEnforcementPolicy int policyPreP, @HiddenApiEnforcementPolicy int policyP) { + if (isPackageWhitelistedForHiddenApis()) { + return; + } + if (targetSdkVersion <= Build.VERSION_CODES.O_MR1) { + setHiddenApiEnforcementPolicy(policyPreP); + } else if (targetSdkVersion > Build.VERSION_CODES.O_MR1) { + setHiddenApiEnforcementPolicy(policyP); + } + + } + + /** * @hide */ public void setVersionCode(long newVersionCode) { diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 33e77d288ee1..34e3d8b5c2c8 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -6131,7 +6131,9 @@ public abstract class PackageManager { * signed. This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES} * since it takes into account the possibility of signing certificate rotation, except in the * case of packages that are signed by multiple certificates, for which signing certificate - * rotation is not supported. + * rotation is not supported. This method is analogous to using {@code getPackageInfo} with + * {@code GET_SIGNING_CERTIFICATES} and then searching through the resulting {@code + * signingCertificateHistory} field to see if the desired certificate is present. * * @param packageName package whose signing certificates to check * @param certificate signing certificate for which to search @@ -6145,13 +6147,19 @@ public abstract class PackageManager { } /** - * Searches the set of signing certificates by which the given uid has proven to have been - * signed. This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES} + * Searches the set of signing certificates by which the package(s) for the given uid has proven + * to have been signed. For multiple packages sharing the same uid, this will return the + * signing certificates found in the signing history of the "newest" package, where "newest" + * indicates the package with the newest signing certificate in the shared uid group. This + * method should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES} * since it takes into account the possibility of signing certificate rotation, except in the * case of packages that are signed by multiple certificates, for which signing certificate - * rotation is not supported. + * rotation is not supported. This method is analogous to using {@code getPackagesForUid} + * followed by {@code getPackageInfo} with {@code GET_SIGNING_CERTIFICATES}, selecting the + * {@code PackageInfo} of the newest-signed bpackage , and finally searching through the + * resulting {@code signingCertificateHistory} field to see if the desired certificate is there. * - * @param uid package whose signing certificates to check + * @param uid uid whose signing certificates to check * @param certificate signing certificate for which to search * @param type representation of the {@code certificate} * @return true if this package was or is signed by exactly the certificate {@code certificate} diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index a9d0911065f5..699e81bda7b7 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -521,6 +521,11 @@ 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/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java index 67e97bfd3d62..6d9ba778d09a 100644 --- a/core/java/android/hardware/display/BrightnessConfiguration.java +++ b/core/java/android/hardware/display/BrightnessConfiguration.java @@ -86,7 +86,9 @@ public final class BrightnessConfiguration implements Parcelable { sb.append("(").append(mLux[i]).append(", ").append(mNits[i]).append(")"); } sb.append("], '"); - sb.append(mDescription); + if (mDescription != null) { + sb.append(mDescription); + } sb.append("'}"); return sb.toString(); } @@ -96,7 +98,9 @@ public final class BrightnessConfiguration implements Parcelable { int result = 1; result = result * 31 + Arrays.hashCode(mLux); result = result * 31 + Arrays.hashCode(mNits); - result = result * 31 + mDescription.hashCode(); + if (mDescription != null) { + result = result * 31 + mDescription.hashCode(); + } return result; } diff --git a/core/java/android/hardware/display/Curve.aidl b/core/java/android/hardware/display/Curve.aidl new file mode 100644 index 000000000000..796493ef1189 --- /dev/null +++ b/core/java/android/hardware/display/Curve.aidl @@ -0,0 +1,19 @@ +/* + * 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 android.hardware.display; + +parcelable Curve; diff --git a/core/java/android/hardware/display/Curve.java b/core/java/android/hardware/display/Curve.java new file mode 100644 index 000000000000..ac28fdd634ac --- /dev/null +++ b/core/java/android/hardware/display/Curve.java @@ -0,0 +1,62 @@ +/* + * 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 android.hardware.display; + +import android.os.Parcel; +import android.os.Parcelable; + +/** @hide */ +public final class Curve implements Parcelable { + private final float[] mX; + private final float[] mY; + + public Curve(float[] x, float[] y) { + mX = x; + mY = y; + } + + public float[] getX() { + return mX; + } + + public float[] getY() { + return mY; + } + + public static final Creator<Curve> CREATOR = new Creator<Curve>() { + public Curve createFromParcel(Parcel in) { + float[] x = in.createFloatArray(); + float[] y = in.createFloatArray(); + return new Curve(x, y); + } + + public Curve[] newArray(int size) { + return new Curve[size]; + } + }; + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeFloatArray(mX); + out.writeFloatArray(mY); + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index efb9517adc00..b182fa2e8ad3 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -28,6 +28,7 @@ import android.content.Context; import android.graphics.Point; import android.media.projection.MediaProjection; import android.os.Handler; +import android.util.Pair; import android.util.SparseArray; import android.view.Display; import android.view.Surface; @@ -748,6 +749,22 @@ public final class DisplayManager { } /** + * Returns the minimum brightness curve, which guarantess that any brightness curve that dips + * below it is rejected by the system. + * This prevent auto-brightness from setting the screen so dark as to prevent the user from + * resetting or disabling it, and maps lux to the absolute minimum nits that are still readable + * in that ambient brightness. + * + * @return The minimum brightness curve (as lux values and their corresponding nits values). + * + * @hide + */ + @SystemApi + public Pair<float[], float[]> getMinimumBrightnessCurve() { + return mGlobal.getMinimumBrightnessCurve(); + } + + /** * Listens for changes in available display devices. */ public interface DisplayListener { diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 2d0ef2f23432..d968a3e942bb 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -31,6 +31,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import android.view.Display; import android.view.DisplayAdjustments; @@ -563,6 +564,24 @@ public final class DisplayManagerGlobal { } /** + * Returns the minimum brightness curve, which guarantess that any brightness curve that dips + * below it is rejected by the system. + * This prevent auto-brightness from setting the screen so dark as to prevent the user from + * resetting or disabling it, and maps lux to the absolute minimum nits that are still readable + * in that ambient brightness. + * + * @return The minimum brightness curve (as lux values and their corresponding nits values). + */ + public Pair<float[], float[]> getMinimumBrightnessCurve() { + try { + Curve curve = mDm.getMinimumBrightnessCurve(); + return Pair.create(curve.getX(), curve.getY()); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + + /** * Retrieves ambient brightness stats. */ public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() { diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index b77de748a987..b57599724ad5 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -19,6 +19,7 @@ package android.hardware.display; import android.content.pm.ParceledListSlice; import android.graphics.Point; import android.hardware.display.BrightnessConfiguration; +import android.hardware.display.Curve; import android.hardware.display.IDisplayManagerCallback; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.WifiDisplay; @@ -112,4 +113,7 @@ interface IDisplayManager { // Temporarily sets the auto brightness adjustment factor. void setTemporaryAutoBrightnessAdjustment(float adjustment); + + // Get the minimum brightness curve. + Curve getMinimumBrightnessCurve(); } diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index 1a28732e874e..e84c85ee8edb 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -19,7 +19,7 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; import android.util.BackupUtils; -import android.util.Pair; +import android.util.Range; import android.util.RecurrenceRule; import com.android.internal.util.Preconditions; @@ -136,7 +136,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { return 0; } - public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() { + public Iterator<Range<ZonedDateTime>> cycleIterator() { return cycleRule.cycleIterator(); } diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index bf6b7e09f529..6546c391799b 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -31,6 +31,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.util.DebugUtils; import android.util.Pair; +import android.util.Range; import com.google.android.collect.Sets; @@ -258,8 +259,21 @@ public class NetworkPolicyManager { } /** {@hide} */ + @Deprecated public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) { - return policy.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator(); + return new Iterator<Pair<ZonedDateTime, ZonedDateTime>>() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public Pair<ZonedDateTime, ZonedDateTime> next() { + final Range<ZonedDateTime> r = it.next(); + return Pair.create(r.getLower(), r.getUpper()); + } + }; } /** diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java index b00cb482e73e..321f9718ee8e 100644 --- a/core/java/android/net/NetworkState.java +++ b/core/java/android/net/NetworkState.java @@ -26,6 +26,8 @@ import android.util.Slog; * @hide */ public class NetworkState implements Parcelable { + private static final boolean SANITY_CHECK_ROAMING = false; + public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null); public final NetworkInfo networkInfo; @@ -47,7 +49,7 @@ public class NetworkState implements Parcelable { // This object is an atomic view of a network, so the various components // should always agree on roaming state. - if (networkInfo != null && networkCapabilities != null) { + if (SANITY_CHECK_ROAMING && networkInfo != null && networkCapabilities != null) { if (networkInfo.isRoaming() == networkCapabilities .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) { Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java index e0fa63a5977d..f9b6dfce32ff 100644 --- a/core/java/android/net/http/X509TrustManagerExtensions.java +++ b/core/java/android/net/http/X509TrustManagerExtensions.java @@ -21,7 +21,6 @@ import android.security.net.config.UserCertificateSource; import com.android.org.conscrypt.TrustManagerImpl; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.cert.CertificateException; @@ -133,8 +132,6 @@ public class X509TrustManagerExtensions { /** * Returns {@code true} if the TrustManager uses the same trust configuration for the provided * hostnames. - * - * @hide */ @SystemApi public boolean isSameTrustConfiguration(String hostname1, String hostname2) { diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java index 911410744bd6..d493ccebf531 100644 --- a/core/java/android/os/storage/DiskInfo.java +++ b/core/java/android/os/storage/DiskInfo.java @@ -17,6 +17,7 @@ package android.os.storage; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; @@ -93,7 +94,7 @@ public class DiskInfo implements Parcelable { return true; } - public String getDescription() { + public @Nullable String getDescription() { final Resources res = Resources.getSystem(); if ((flags & FLAG_SD) != 0) { if (isInteresting(label)) { @@ -112,6 +113,17 @@ public class DiskInfo implements Parcelable { } } + public @Nullable String getShortDescription() { + final Resources res = Resources.getSystem(); + if (isSd()) { + return res.getString(com.android.internal.R.string.storage_sd_card); + } else if (isUsb()) { + return res.getString(com.android.internal.R.string.storage_usb_drive); + } else { + return null; + } + } + public boolean isAdoptable() { return (flags & FLAG_ADOPTABLE) != 0; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 50d73ce749a2..c7c2c1597ba8 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1179,6 +1179,23 @@ public final class Settings { public static final String ACTION_ZEN_MODE_SETTINGS = "android.settings.ZEN_MODE_SETTINGS"; /** + * Activity Action: Show Zen Mode visual effects configuration settings. + * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ZEN_MODE_BLOCKED_EFFECTS_SETTINGS = + "android.settings.ZEN_MODE_BLOCKED_EFFECTS_SETTINGS"; + + /** + * Activity Action: Show Zen Mode onboarding activity. + * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ZEN_MODE_ONBOARDING = "android.settings.ZEN_MODE_ONBOARDING"; + + /** * Activity Action: Show Zen Mode (aka Do Not Disturb) priority configuration settings. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) @@ -3113,6 +3130,9 @@ public final class Settings { */ public static final String DISPLAY_COLOR_MODE = "display_color_mode"; + private static final Validator DISPLAY_COLOR_MODE_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 2); + /** * The amount of time in milliseconds before the device goes to sleep or begins * to dream after a period of inactivity. This value is also known as the @@ -4092,6 +4112,7 @@ public final class Settings { SHOW_BATTERY_PERCENT, NOTIFICATION_VIBRATION_INTENSITY, HAPTIC_FEEDBACK_INTENSITY, + DISPLAY_COLOR_MODE }; /** @@ -4204,6 +4225,7 @@ public final class Settings { PRIVATE_SETTINGS.add(LOCK_TO_APP_ENABLED); PRIVATE_SETTINGS.add(EGG_MODE); PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT); + PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE); } /** @@ -4225,6 +4247,7 @@ public final class Settings { VALIDATORS.put(NEXT_ALARM_FORMATTED, NEXT_ALARM_FORMATTED_VALIDATOR); VALIDATORS.put(FONT_SCALE, FONT_SCALE_VALIDATOR); VALIDATORS.put(DIM_SCREEN, DIM_SCREEN_VALIDATOR); + VALIDATORS.put(DISPLAY_COLOR_MODE, DISPLAY_COLOR_MODE_VALIDATOR); VALIDATORS.put(SCREEN_OFF_TIMEOUT, SCREEN_OFF_TIMEOUT_VALIDATOR); VALIDATORS.put(SCREEN_BRIGHTNESS_FOR_VR, SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR); VALIDATORS.put(SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_VALIDATOR); @@ -11117,6 +11140,14 @@ public final class Settings { public static final String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities"; /** + * If nonzero, all system error dialogs will be hidden. For example, the + * crash and ANR dialogs will not be shown, and the system will just proceed + * as if they had been accepted by the user. + * @hide + */ + public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs"; + + /** * Use Dock audio output for media: * 0 = disabled * 1 = enabled @@ -11735,6 +11766,29 @@ public final class Settings { "hidden_api_blacklist_exemptions"; /** + * Hidden API enforcement policy for apps targeting SDK versions prior to the latest + * version. + * + * Values correspond to @{@link + * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy} + * + * @hide + */ + public static final String HIDDEN_API_POLICY_PRE_P_APPS = + "hidden_api_policy_pre_p_apps"; + + /** + * Hidden API enforcement policy for apps targeting the current SDK version. + * + * Values correspond to @{@link + * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy} + * + * @hide + */ + public static final String HIDDEN_API_POLICY_P_APPS = + "hidden_api_policy_p_apps"; + + /** * Timeout for a single {@link android.media.soundtrigger.SoundTriggerDetectionService} * operation (in ms). * diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java index ad3b4b6d6343..de86a66aeb8f 100644 --- a/core/java/android/text/format/Formatter.java +++ b/core/java/android/text/format/Formatter.java @@ -40,6 +40,10 @@ public final class Formatter { public static final int FLAG_SHORTER = 1 << 0; /** {@hide} */ public static final int FLAG_CALCULATE_ROUNDED = 1 << 1; + /** {@hide} */ + public static final int FLAG_SI_UNITS = 1 << 2; + /** {@hide} */ + public static final int FLAG_IEC_UNITS = 1 << 3; /** {@hide} */ public static class BytesResult { @@ -90,7 +94,7 @@ public final class Formatter { if (context == null) { return ""; } - final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0); + final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SI_UNITS); return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix, res.value, res.units)); } @@ -103,41 +107,43 @@ public final class Formatter { if (context == null) { return ""; } - final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER); + final BytesResult res = formatBytes(context.getResources(), sizeBytes, + FLAG_SI_UNITS | FLAG_SHORTER); return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix, res.value, res.units)); } /** {@hide} */ public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) { + final int unit = ((flags & FLAG_IEC_UNITS) != 0) ? 1024 : 1000; final boolean isNegative = (sizeBytes < 0); float result = isNegative ? -sizeBytes : sizeBytes; int suffix = com.android.internal.R.string.byteShort; long mult = 1; if (result > 900) { suffix = com.android.internal.R.string.kilobyteShort; - mult = 1000; - result = result / 1000; + mult = unit; + result = result / unit; } if (result > 900) { suffix = com.android.internal.R.string.megabyteShort; - mult *= 1000; - result = result / 1000; + mult *= unit; + result = result / unit; } if (result > 900) { suffix = com.android.internal.R.string.gigabyteShort; - mult *= 1000; - result = result / 1000; + mult *= unit; + result = result / unit; } if (result > 900) { suffix = com.android.internal.R.string.terabyteShort; - mult *= 1000; - result = result / 1000; + mult *= unit; + result = result / unit; } if (result > 900) { suffix = com.android.internal.R.string.petabyteShort; - mult *= 1000; - result = result / 1000; + mult *= unit; + result = result / unit; } // Note we calculate the rounded long by ourselves, but still let String.format() // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java index 9f115eba442c..975ad488bf54 100644 --- a/core/java/android/util/RecurrenceRule.java +++ b/core/java/android/util/RecurrenceRule.java @@ -158,7 +158,7 @@ public class RecurrenceRule implements Parcelable { && period.getDays() == 0; } - public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() { + public Iterator<Range<ZonedDateTime>> cycleIterator() { if (period != null) { return new RecurringIterator(); } else { @@ -166,7 +166,7 @@ public class RecurrenceRule implements Parcelable { } } - private class NonrecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> { + private class NonrecurringIterator implements Iterator<Range<ZonedDateTime>> { boolean hasNext; public NonrecurringIterator() { @@ -179,13 +179,13 @@ public class RecurrenceRule implements Parcelable { } @Override - public Pair<ZonedDateTime, ZonedDateTime> next() { + public Range<ZonedDateTime> next() { hasNext = false; - return new Pair<>(start, end); + return new Range<>(start, end); } } - private class RecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> { + private class RecurringIterator implements Iterator<Range<ZonedDateTime>> { int i; ZonedDateTime cycleStart; ZonedDateTime cycleEnd; @@ -231,12 +231,12 @@ public class RecurrenceRule implements Parcelable { } @Override - public Pair<ZonedDateTime, ZonedDateTime> next() { + public Range<ZonedDateTime> next() { if (LOGD) Log.d(TAG, "Cycle " + i + " from " + cycleStart + " to " + cycleEnd); - Pair<ZonedDateTime, ZonedDateTime> p = new Pair<>(cycleStart, cycleEnd); + Range<ZonedDateTime> r = new Range<>(cycleStart, cycleEnd); i--; updateCycle(); - return p; + return r; } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index da15506ecac8..c5ab2e6887b1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -487,6 +487,7 @@ <protected-broadcast android:name="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" /> <protected-broadcast android:name="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" /> <protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" /> + <protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_PLANS_CHANGED" /> <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" /> <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" /> diff --git a/core/res/res/drawable/ic_zen_24dp.xml b/core/res/res/drawable/ic_zen_24dp.xml new file mode 100644 index 000000000000..790bfb97c60c --- /dev/null +++ b/core/res/res/drawable/ic_zen_24dp.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:viewportHeight="24.0" + android:viewportWidth="24.0" + android:height="24dp" + android:width="24dp" > + + <path + android:fillColor="?android:attr/colorControlActivated" + android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4 11H8c-.55 0-1-.45-1-1s.45-1 1-1h8c.55 0 1 .45 1 1s-.45 1-1 1z" /> + +</vector>
\ No newline at end of file diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index aceba0879368..fe34d98ec163 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2154,9 +2154,6 @@ Corresponds to <code>LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES</code>. --> <enum name="shortEdges" value="1" /> - <!-- Use <code>shortEdges</code> instead. This is temporarily here to unblock pushing - the SDK until all usages have been migrated to <code>shortEdges</code> --> - <enum name="always" value="1" /> <!-- <p> The window is never allowed to overlap with the <code>DisplayCutout</code> area. <p> diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml index 70485111d208..0fe80a154f7a 100644 --- a/core/res/res/values/colors_device_defaults.xml +++ b/core/res/res/values/colors_device_defaults.xml @@ -38,4 +38,8 @@ <color name="background_device_default_light">@color/background_material_light</color> <color name="background_floating_device_default_dark">@color/background_floating_material_dark</color> <color name="background_floating_device_default_light">@color/background_floating_material_light</color> + + <!-- Error color --> + <color name="error_color_device_default_dark">@color/error_color_material_dark</color> + <color name="error_color_device_default_light">@color/error_color_material_light</color> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 4ce89c9b0022..fc030ca3d316 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1289,6 +1289,32 @@ in darkness (although they may not be visible in a bright room). --> <integer name="config_screenBrightnessDark">1</integer> + <!-- Array of lux values to define the minimum brightness curve, which guarantees that any + brightness curve that dips below it is rejected by the system. + This prevents auto-brightness from setting the screen so dark as to prevent the user from + resetting or disabling it. + + The values must be non-negative and strictly increasing, and correspond to the values in + the config_minimumBrightnessCurveNits array. --> + <array name="config_minimumBrightnessCurveLux"> + <item>0.0</item> + <item>2000.0</item> + <item>4000.0</item> + </array> + + <!-- Array of nits values to define the minimum brightness curve, which guarantees that any + brightness curve that dips below it is rejected by the system. + This should map lux to the absolute minimum nits that are still readable in that ambient + brightness. + + The values must be non-negative and non-decreasing, and correspond to the values in the + config_minimumBrightnessCurveLux array. --> + <array name="config_minimumBrightnessCurveNits"> + <item>0.0</item> + <item>50.0</item> + <item>90.0</item> + </array> + <!-- Array of light sensor lux values to define our levels for auto backlight brightness support. The N entries of this array define N + 1 control points as follows: (1-based arrays) diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 715be5b47d1c..1798d45e29b3 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4943,9 +4943,9 @@ <!-- Title for the notification channel notifying user of do not disturb system changes (i.e. Do Not Disturb has changed). [CHAR LIMIT=NONE] --> <string name="notification_channel_do_not_disturb">Do Not Disturb</string> <!-- Title of notification indicating do not disturb visual interruption settings have changed when upgrading to P --> - <string name="zen_upgrade_notification_visd_title">Do Not Disturb is hiding notifications to help you focus</string> + <string name="zen_upgrade_notification_visd_title">New: Do Not Disturb is hiding notifications</string> <!-- Content of notification indicating users can tap on the notification to go to dnd behavior settings --> - <string name="zen_upgrade_notification_visd_content">This is new behavior. Tap to change.</string> + <string name="zen_upgrade_notification_visd_content">Tap to learn more and change.</string> <!-- Title of notification indicating do not disturb settings have changed when upgrading to P --> <string name="zen_upgrade_notification_title">Do Not Disturb has changed</string> <!-- Content of notification indicating users can tap on the notification to go to dnd behavior settings --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index ce7f1ff29ede..b6f0b709e9e3 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1810,6 +1810,8 @@ <java-symbol type="array" name="config_dynamicHysteresisBrightLevels" /> <java-symbol type="array" name="config_dynamicHysteresisDarkLevels" /> <java-symbol type="array" name="config_dynamicHysteresisLuxLevels" /> + <java-symbol type="array" name="config_minimumBrightnessCurveLux" /> + <java-symbol type="array" name="config_minimumBrightnessCurveNits" /> <java-symbol type="array" name="config_protectedNetworks" /> <java-symbol type="array" name="config_statusBarIcons" /> <java-symbol type="array" name="config_tether_bluetooth_regexs" /> @@ -2547,6 +2549,7 @@ <java-symbol type="drawable" name="ic_settings_24dp" /> <java-symbol type="drawable" name="ic_storage_48dp" /> <java-symbol type="drawable" name="ic_usb_48dp" /> + <java-symbol type="drawable" name="ic_zen_24dp" /> <!-- Floating toolbar --> <java-symbol type="id" name="floating_toolbar_menu_item_image" /> diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml index fd6cc9509ec9..92b2f3341ddd 100644 --- a/core/res/res/values/themes_device_defaults.xml +++ b/core/res/res/values/themes_device_defaults.xml @@ -210,6 +210,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> </style> @@ -221,6 +222,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -248,6 +250,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -277,6 +280,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -305,6 +309,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -348,6 +353,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -368,6 +374,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -394,6 +401,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -421,6 +429,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -464,6 +473,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -492,6 +502,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -518,6 +529,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -546,6 +558,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -573,6 +586,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -600,6 +614,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -627,6 +642,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -654,6 +670,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -685,6 +702,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Text styles --> <item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item> @@ -706,6 +724,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -731,6 +750,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -908,6 +928,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> </style> <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an @@ -917,6 +938,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -943,6 +965,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -970,6 +993,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -999,6 +1023,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1027,6 +1052,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1072,6 +1098,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Progress bar attributes --> <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item> @@ -1091,6 +1118,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1120,6 +1148,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1150,6 +1179,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1181,6 +1211,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> </style> <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. --> @@ -1194,6 +1225,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> </style> <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller @@ -1206,6 +1238,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1237,6 +1270,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1266,6 +1300,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1294,6 +1329,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1321,6 +1357,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1346,6 +1383,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1371,6 +1409,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1404,6 +1443,7 @@ easier. <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item> <item name="colorSecondary">@color/secondary_device_default_settings_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <item name="colorEdgeEffect">@android:color/black</item> <!-- Add white nav bar with divider that matches material --> @@ -1438,6 +1478,7 @@ easier. <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item> <item name="colorSecondary">@color/secondary_device_default_settings_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <item name="colorControlNormal">?attr/textColorPrimary</item> <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item> @@ -1465,6 +1506,7 @@ easier. <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item> <item name="colorSecondary">@color/secondary_device_default_settings_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item> <!-- Progress bar attributes --> @@ -1482,6 +1524,7 @@ easier. <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item> <item name="colorSecondary">@color/secondary_device_default_settings</item> <item name="colorAccent">@color/accent_device_default_dark</item> + <item name="colorError">@color/error_color_device_default_dark</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1511,6 +1554,7 @@ easier. <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item> <item name="colorSecondary">@color/secondary_device_default_settings</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1540,6 +1584,7 @@ easier. <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item> <item name="colorSecondary">@color/secondary_device_default_settings</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1569,6 +1614,7 @@ easier. <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item> <item name="colorSecondary">@color/secondary_device_default_settings</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Dialog attributes --> <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> @@ -1617,6 +1663,7 @@ easier. <item name="colorPrimary">@color/primary_device_default_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item> <item name="colorAccent">@color/accent_device_default_light</item> + <item name="colorError">@color/error_color_device_default_light</item> <!-- Progress bar attributes --> <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item> diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml index 7b5ad9a42d00..68ef34b279e6 100644 --- a/core/tests/coretests/AndroidTest.xml +++ b/core/tests/coretests/AndroidTest.xml @@ -25,5 +25,6 @@ <option name="test-tag" value="FrameworksCoreTests" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.coretests" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java index bad0d258a54c..5ef30a828cf7 100644 --- a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java +++ b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java @@ -41,7 +41,7 @@ public class BrightnessConfigurationTest { }; private static final float[] NITS_LEVELS = { - 0.5f, + 1f, 90f, 100f, }; diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index cb3509c33ce6..a5941b26b9d3 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -60,7 +60,6 @@ public class SettingsBackupTest { Settings.System.ALARM_ALERT, // backup candidate? Settings.System.ALARM_ALERT_CACHE, // internal cache Settings.System.APPEND_FOR_LAST_AUDIBLE, // suffix deprecated since API 2 - Settings.System.DISPLAY_COLOR_MODE, // bug? Settings.System.EGG_MODE, // I am the lolrus Settings.System.END_BUTTON_BEHAVIOR, // bug? Settings.System @@ -247,6 +246,9 @@ public class SettingsBackupTest { Settings.Global.HDMI_CONTROL_ENABLED, Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, + Settings.Global.HIDDEN_API_POLICY_P_APPS, + Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS, + Settings.Global.HIDE_ERROR_DIALOGS, Settings.Global.HTTP_PROXY, HYBRID_SYSUI_BATTERY_WARNING_FLAGS, Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY, diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java index 04d2dad4e224..c02d97ce98a0 100644 --- a/core/tests/coretests/src/android/text/format/FormatterTest.java +++ b/core/tests/coretests/src/android/text/format/FormatterTest.java @@ -16,12 +16,14 @@ package android.text.format; +import static android.text.format.Formatter.FLAG_IEC_UNITS; +import static android.text.format.Formatter.FLAG_SI_UNITS; + import static org.junit.Assert.assertEquals; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import android.icu.util.MeasureUnit; import android.platform.test.annotations.Presubmit; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -34,7 +36,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.util.Locale; -import java.util.Set; @Presubmit @SmallTest @@ -104,6 +105,27 @@ public class FormatterTest { checkFormatBytes(9123000, false, "9,12", 9120000); } + @Test + public void testFormatBytesSi() { + setLocale(Locale.US); + + checkFormatBytes(1_000, FLAG_SI_UNITS, "1.00", 1_000); + checkFormatBytes(1_024, FLAG_SI_UNITS, "1.02", 1_020); + checkFormatBytes(1_500, FLAG_SI_UNITS, "1.50", 1_500); + checkFormatBytes(12_582_912L, FLAG_SI_UNITS, "12.58", 12_580_000L); + } + + @Test + public void testFormatBytesIec() { + setLocale(Locale.US); + + checkFormatBytes(1_000, FLAG_IEC_UNITS, "0.98", 1_003); + checkFormatBytes(1_024, FLAG_IEC_UNITS, "1.00", 1_024); + checkFormatBytes(1_500, FLAG_IEC_UNITS, "1.46", 1_495); + checkFormatBytes(12_500_000L, FLAG_IEC_UNITS, "11.92", 12_499_025L); + checkFormatBytes(12_582_912L, FLAG_IEC_UNITS, "12.00", 12_582_912L); + } + private static final long SECOND = 1000; private static final long MINUTE = 60 * SECOND; private static final long HOUR = 60 * MINUTE; @@ -195,8 +217,14 @@ public class FormatterTest { private void checkFormatBytes(long bytes, boolean useShort, String expectedString, long expectedRounded) { + checkFormatBytes(bytes, (useShort ? Formatter.FLAG_SHORTER : 0), + expectedString, expectedRounded); + } + + private void checkFormatBytes(long bytes, int flags, + String expectedString, long expectedRounded) { BytesResult r = Formatter.formatBytes(mContext.getResources(), bytes, - Formatter.FLAG_CALCULATE_ROUNDED | (useShort ? Formatter.FLAG_SHORTER : 0)); + Formatter.FLAG_CALCULATE_ROUNDED | flags); assertEquals(expectedString, r.value); assertEquals(expectedRounded, r.roundedBytes); } diff --git a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java index 42b6048b533a..39d492d65415 100644 --- a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java +++ b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java @@ -57,13 +57,13 @@ public class RecurrenceRuleTest extends TestCase { assertTrue(r.isMonthly()); - final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); assertTrue(it.hasNext()); - assertEquals(Pair.create( + assertEquals(new Range<>( ZonedDateTime.parse("2015-11-14T00:00:00.00Z"), ZonedDateTime.parse("2015-12-14T00:00:00.00Z")), it.next()); assertTrue(it.hasNext()); - assertEquals(Pair.create( + assertEquals(new Range<>( ZonedDateTime.parse("2015-10-14T00:00:00.00Z"), ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next()); } @@ -77,13 +77,13 @@ public class RecurrenceRuleTest extends TestCase { assertFalse(r.isMonthly()); - final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); assertTrue(it.hasNext()); - assertEquals(Pair.create( + assertEquals(new Range<>( ZonedDateTime.parse("2010-11-17T00:11:00.00Z"), ZonedDateTime.parse("2010-11-20T00:11:00.00Z")), it.next()); assertTrue(it.hasNext()); - assertEquals(Pair.create( + assertEquals(new Range<>( ZonedDateTime.parse("2010-11-14T00:11:00.00Z"), ZonedDateTime.parse("2010-11-17T00:11:00.00Z")), it.next()); assertFalse(it.hasNext()); @@ -98,9 +98,9 @@ public class RecurrenceRuleTest extends TestCase { assertFalse(r.isMonthly()); - final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); assertTrue(it.hasNext()); - assertEquals(Pair.create( + assertEquals(new Range<>( ZonedDateTime.parse("2010-11-14T00:11:00.000Z"), ZonedDateTime.parse("2010-11-20T00:11:00.000Z")), it.next()); assertFalse(it.hasNext()); @@ -112,7 +112,7 @@ public class RecurrenceRuleTest extends TestCase { assertFalse(r.isMonthly()); - final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); assertFalse(it.hasNext()); } @@ -122,22 +122,22 @@ public class RecurrenceRuleTest extends TestCase { ZonedDateTime.parse("2030-01-31T00:00:00.000Z"), Period.ofMonths(1)); - final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = r.cycleIterator(); ZonedDateTime lastStart = null; int months = 0; while (it.hasNext()) { - final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next(); + final Range<ZonedDateTime> cycle = it.next(); // Make sure cycle has reasonable length - final long length = cycle.second.toEpochSecond() - cycle.first.toEpochSecond(); + final long length = cycle.getUpper().toEpochSecond() - cycle.getLower().toEpochSecond(); assertTrue(cycle + " must be more than 4 weeks", length >= 2419200); assertTrue(cycle + " must be less than 5 weeks", length <= 3024000); // Make sure we have no gaps if (lastStart != null) { - assertEquals(lastStart, cycle.second); + assertEquals(lastStart, cycle.getUpper()); } - lastStart = cycle.first; + lastStart = cycle.getLower(); months++; } diff --git a/core/tests/privacytests/AndroidTest.xml b/core/tests/privacytests/AndroidTest.xml index 8098c1497865..a3e785cbf246 100644 --- a/core/tests/privacytests/AndroidTest.xml +++ b/core/tests/privacytests/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.coretests.privacy" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/core/tests/utiltests/AndroidTest.xml b/core/tests/utiltests/AndroidTest.xml index 270d7731a974..f32acb43afe4 100644 --- a/core/tests/utiltests/AndroidTest.xml +++ b/core/tests/utiltests/AndroidTest.xml @@ -25,5 +25,6 @@ <option name="test-tag" value="FrameworksUtilTests" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.utiltests" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 985a7569a92c..7d4e6f83ab0c 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -456,6 +456,22 @@ status_t ResStringPool::setTo(const void* data, size_t size, bool copyData) uninit(); + // The chunk must be at least the size of the string pool header. + if (size < sizeof(ResStringPool_header)) { + LOG_ALWAYS_FATAL("Bad string block: data size %zu is too small to be a string block", size); + return (mError=BAD_TYPE); + } + + // The data is at least as big as a ResChunk_header, so we can safely validate the other + // header fields. + // `data + size` is safe because the source of `size` comes from the kernel/filesystem. + if (validate_chunk(reinterpret_cast<const ResChunk_header*>(data), sizeof(ResStringPool_header), + reinterpret_cast<const uint8_t*>(data) + size, + "ResStringPool_header") != NO_ERROR) { + LOG_ALWAYS_FATAL("Bad string block: malformed block dimensions"); + return (mError=BAD_TYPE); + } + const bool notDeviceEndian = htods(0xf0) != 0xf0; if (copyData || notDeviceEndian) { @@ -467,6 +483,8 @@ status_t ResStringPool::setTo(const void* data, size_t size, bool copyData) data = mOwnedData; } + // The size has been checked, so it is safe to read the data in the ResStringPool_header + // data structure. mHeader = (const ResStringPool_header*)data; if (notDeviceEndian) { diff --git a/location/tests/locationtests/AndroidTest.xml b/location/tests/locationtests/AndroidTest.xml index 0c5b7cca5ae5..bb6547bec0f7 100644 --- a/location/tests/locationtests/AndroidTest.xml +++ b/location/tests/locationtests/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.locationtests" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 0458931566f4..9152ff2e99f7 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -250,9 +250,10 @@ public final class AudioAttributes implements Parcelable { SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, SUPPRESSIBLE_MEDIA); SUPPRESSIBLE_USAGES.put(USAGE_GAME, SUPPRESSIBLE_MEDIA); SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANT, SUPPRESSIBLE_MEDIA); + /** default volume assignment is STREAM_MUSIC, handle unknown usage as media */ + SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN, SUPPRESSIBLE_MEDIA); SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION_SIGNALLING, SUPPRESSIBLE_SYSTEM); SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_SONIFICATION, SUPPRESSIBLE_SYSTEM); - SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN, SUPPRESSIBLE_SYSTEM); } /** @@ -1057,8 +1058,7 @@ public final class AudioAttributes implements Parcelable { case USAGE_ASSISTANCE_ACCESSIBILITY: return AudioSystem.STREAM_ACCESSIBILITY; case USAGE_UNKNOWN: - return fromGetVolumeControlStream ? - AudioManager.USE_DEFAULT_STREAM_TYPE : AudioSystem.STREAM_MUSIC; + return AudioSystem.STREAM_MUSIC; default: if (fromGetVolumeControlStream) { throw new IllegalArgumentException("Unknown usage value " + aa.getUsage() + diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp index b4ca88cd2bcf..ed2afdd84a7c 100644 --- a/media/jni/soundpool/SoundPool.cpp +++ b/media/jni/soundpool/SoundPool.cpp @@ -809,7 +809,11 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV mAudioTrack = newTrack; ALOGV("using new track %p for sample %d", newTrack.get(), sample->sampleID()); } - newTrack->setVolume(leftVolume, rightVolume); + if (mMuted) { + newTrack->setVolume(0.0f, 0.0f); + } else { + newTrack->setVolume(leftVolume, rightVolume); + } newTrack->setLoop(0, frameCount, loop); mPos = 0; mSample = sample; diff --git a/packages/MtpDocumentsProvider/tests/AndroidTest.xml b/packages/MtpDocumentsProvider/tests/AndroidTest.xml index 940d36465dba..f84131c22915 100644 --- a/packages/MtpDocumentsProvider/tests/AndroidTest.xml +++ b/packages/MtpDocumentsProvider/tests/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.InstrumentationTest" > <option name="package" value="com.android.mtp.tests" /> <option name="runner" value="com.android.mtp.TestResultInstrumentation" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml index 15dd64beb4cf..d21a2e49c634 100644 --- a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml +++ b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml @@ -25,5 +25,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.printspooler.outofprocess.tests" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/SettingsLib/tests/integ/AndroidTest.xml b/packages/SettingsLib/tests/integ/AndroidTest.xml index 96621ebebd71..d7ee618207a8 100644 --- a/packages/SettingsLib/tests/integ/AndroidTest.xml +++ b/packages/SettingsLib/tests/integ/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.settingslib" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml index 3a1568954aaf..46b8f94f23a3 100644 --- a/packages/SettingsProvider/test/AndroidTest.xml +++ b/packages/SettingsProvider/test/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.providers.setting.test" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/Shell/tests/AndroidTest.xml b/packages/Shell/tests/AndroidTest.xml index bd37712c854c..e592d82bfaf7 100644 --- a/packages/Shell/tests/AndroidTest.xml +++ b/packages/Shell/tests/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.shell.tests" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/SystemUI/res/layout/car_left_navigation_bar.xml index 18301a83defd..02be45788761 100644 --- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml +++ b/packages/SystemUI/res/layout/car_left_navigation_bar.xml @@ -40,7 +40,7 @@ android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" - systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end" + systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" android:src="@drawable/car_ic_overview" android:background="?android:attr/selectableItemBackground" android:paddingTop="30dp" diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml index a65ff1693797..708f5955f306 100644 --- a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml +++ b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml @@ -40,7 +40,7 @@ android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" - systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end" + systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" android:src="@drawable/car_ic_overview" android:background="?android:attr/selectableItemBackground" android:paddingTop="30dp" diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml index 9ff16a23b10e..d568d0d3c179 100644 --- a/packages/SystemUI/res/layout/car_navigation_bar.xml +++ b/packages/SystemUI/res/layout/car_navigation_bar.xml @@ -38,7 +38,7 @@ android:id="@+id/home" android:layout_height="match_parent" android:layout_width="wrap_content" - systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end" + systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" android:src="@drawable/car_ic_overview" android:background="?android:attr/selectableItemBackground" android:paddingLeft="30dp" diff --git a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml index b0488ae6382b..4ba6c06d80a1 100644 --- a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml +++ b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml @@ -38,7 +38,7 @@ android:id="@+id/home" android:layout_height="match_parent" android:layout_width="wrap_content" - systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end" + systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" android:src="@drawable/car_ic_overview" android:background="?android:attr/selectableItemBackground" android:paddingLeft="30dp" diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar.xml b/packages/SystemUI/res/layout/car_right_navigation_bar.xml index 99bd23cd4889..91ba02622e9a 100644 --- a/packages/SystemUI/res/layout/car_right_navigation_bar.xml +++ b/packages/SystemUI/res/layout/car_right_navigation_bar.xml @@ -40,7 +40,7 @@ android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" - systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end" + systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" android:src="@drawable/car_ic_overview" android:background="?android:attr/selectableItemBackground" android:paddingTop="30dp" diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml index a65ff1693797..708f5955f306 100644 --- a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml +++ b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml @@ -40,7 +40,7 @@ android:id="@+id/home" android:layout_height="wrap_content" android:layout_width="match_parent" - systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end" + systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" android:src="@drawable/car_ic_overview" android:background="?android:attr/selectableItemBackground" android:paddingTop="30dp" diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml index e4ea08edbc89..b5d48b4636a8 100644 --- a/packages/SystemUI/res/layout/remote_input.xml +++ b/packages/SystemUI/res/layout/remote_input.xml @@ -51,12 +51,10 @@ <ImageButton android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:layout_gravity="center" android:paddingStart="12dp" android:paddingEnd="24dp" - android:paddingTop="16dp" - android:paddingBottom="16dp" android:id="@+id/remote_input_send" android:src="@drawable/ic_send" android:contentDescription="@*android:string/ime_action_send" diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index 0e92c60ab823..d45c427d3082 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -98,5 +98,8 @@ <item type="id" name="status_bar_view_state_tag" /> <item type="id" name="display_cutout" /> + + <!-- Optional cancel button on Keyguard --> + <item type="id" name="cancel_button"/> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java index 20d14188e456..78b1b26140d5 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java @@ -15,10 +15,13 @@ */ package com.android.systemui.shared.recents.model; +import static android.content.pm.PackageManager.MATCH_ANY_USER; + import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; @@ -108,10 +111,12 @@ public abstract class IconLoader { } if (desc.getIconResource() != 0) { try { - Context packageContext = mContext.createPackageContextAsUser( - taskKey.getPackageName(), 0, UserHandle.of(userId)); - return createBadgedDrawable(packageContext.getDrawable(desc.getIconResource()), - userId, desc); + PackageManager pm = mContext.getPackageManager(); + ApplicationInfo appInfo = pm.getApplicationInfo(taskKey.getPackageName(), + MATCH_ANY_USER); + Resources res = pm.getResourcesForApplication(appInfo); + return createBadgedDrawable(res.getDrawable(desc.getIconResource(), null), userId, + desc); } catch (Resources.NotFoundException|PackageManager.NameNotFoundException e) { Log.e(TAG, "Could not find icon drawable from resource", e); } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java index 6fa7db3f2cdb..32e4bbf4cd50 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java @@ -18,23 +18,24 @@ package com.android.systemui.shared.system; import android.app.AppGlobals; import android.content.ComponentName; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.RemoteException; -import java.util.ArrayList; import java.util.List; public class PackageManagerWrapper { - private static final String TAG = "PackageManagerWrapper"; - private static final PackageManagerWrapper sInstance = new PackageManagerWrapper(); private static final IPackageManager mIPackageManager = AppGlobals.getPackageManager(); + public static final String ACTION_PREFERRED_ACTIVITY_CHANGED = + Intent.ACTION_PREFERRED_ACTIVITY_CHANGED; + public static PackageManagerWrapper getInstance() { return sInstance; } @@ -53,40 +54,15 @@ public class PackageManagerWrapper { } /** - * @return true if the packageName belongs to the current preferred home app on the device. - * - * If will also return false if there are multiple home apps and the user has not picked any - * preferred home, in which case the user would see a disambiguation screen on going to home. + * Report the set of 'Home' activity candidates, plus (if any) which of them + * is the current "always use this one" setting. */ - public boolean isDefaultHomeActivity(String packageName) { - List<ResolveInfo> allHomeCandidates = new ArrayList<>(); - ComponentName home; + public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { try { - home = mIPackageManager.getHomeActivities(allHomeCandidates); + return mIPackageManager.getHomeActivities(allHomeCandidates); } catch (RemoteException e) { e.printStackTrace(); - return false; - } - - if (home != null && packageName.equals(home.getPackageName())) { - return true; - } - - // Find the launcher with the highest priority and return that component if there are no - // other home activity with the same priority. - int lastPriority = Integer.MIN_VALUE; - ComponentName lastComponent = null; - final int size = allHomeCandidates.size(); - for (int i = 0; i < size; i++) { - final ResolveInfo ri = allHomeCandidates.get(i); - if (ri.priority > lastPriority) { - lastComponent = ri.activityInfo.getComponentName(); - lastPriority = ri.priority; - } else if (ri.priority == lastPriority) { - // Two components found with same priority. - lastComponent = null; - } + return null; } - return lastComponent != null && packageName.equals(lastComponent.getPackageName()); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java index c1cff9e8f735..adb246013d5d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java @@ -107,6 +107,13 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { new View[]{ null, mEcaView, null }}; + + View cancelBtn = findViewById(R.id.cancel_button); + if (cancelBtn != null) { + cancelBtn.setOnClickListener(view -> { + mCallback.reset(); + }); + } } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 75c52d8ead65..7cc37c476e31 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -205,6 +205,13 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView } }); + View cancelBtn = findViewById(R.id.cancel_button); + if (cancelBtn != null) { + cancelBtn.setOnClickListener(view -> { + mCallback.reset(); + }); + } + // If there's more than one IME, enable the IME switcher button updateSwitchImeButton(); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java index 651831eea517..174dcaba0759 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java @@ -157,6 +157,13 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit if (button != null) { button.setCallback(this); } + + View cancelBtn = findViewById(R.id.cancel_button); + if (cancelBtn != null) { + cancelBtn.setOnClickListener(view -> { + mCallback.reset(); + }); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 0ba26e94ce1e..c01cafaaa9b8 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -25,6 +25,7 @@ import android.view.ViewGroup; import com.android.internal.logging.MetricsLogger; import com.android.internal.widget.LockPatternUtils; +import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.Dependency.DependencyProvider; import com.android.systemui.classifier.FalsingManager; @@ -101,12 +102,13 @@ public class SystemUIFactory { dismissCallbackRegistry, FalsingManager.getInstance(context)); } - public ScrimController createScrimController(LightBarController lightBarController, - ScrimView scrimBehind, ScrimView scrimInFront, LockscreenWallpaper lockscreenWallpaper, + public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront, + LockscreenWallpaper lockscreenWallpaper, Consumer<Float> scrimBehindAlphaListener, + Consumer<GradientColors> scrimInFrontColorListener, Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters, AlarmManager alarmManager) { - return new ScrimController(lightBarController, scrimBehind, scrimInFront, - scrimVisibleListener, dozeParameters, alarmManager); + return new ScrimController(scrimBehind, scrimInFront, scrimBehindAlphaListener, + scrimInFrontColorListener, scrimVisibleListener, dozeParameters, alarmManager); } public NotificationIconAreaController createNotificationIconAreaController(Context context, diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 71614634cd00..101c79013571 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -16,17 +16,19 @@ package com.android.systemui.qs; +import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS; + import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.widget.FrameLayout; -import com.android.settingslib.Utils; import com.android.systemui.R; +import com.android.systemui.SysUiServiceProvider; import com.android.systemui.qs.customize.QSCustomizer; +import com.android.systemui.statusbar.CommandQueue; /** * Wrapper view with background which contains {@link QSPanel} and {@link BaseStatusBarHeader} @@ -48,6 +50,7 @@ public class QSContainerImpl extends FrameLayout { private View mStatusBarBackground; private int mSideMargins; + private boolean mQsDisabled; public QSContainerImpl(Context context, AttributeSet attrs) { super(context, attrs); @@ -96,6 +99,16 @@ public class QSContainerImpl extends FrameLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (mQsDisabled) { + // Only show the status bar contents in QQS header when QS is disabled. + mHeader.measure(widthMeasureSpec, heightMeasureSpec); + LayoutParams layoutParams = (LayoutParams) mHeader.getLayoutParams(); + int height = layoutParams.topMargin + layoutParams.bottomMargin + + mHeader.getMeasuredHeight(); + super.onMeasure( + widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); + return; + } // Since we control our own bottom, be whatever size we want. // Otherwise the QSPanel ends up with 0 height when the window is only the // size of the status bar. @@ -121,6 +134,15 @@ public class QSContainerImpl extends FrameLayout { updateExpansion(); } + public void disable(int state1, int state2, boolean animate) { + final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0; + if (disabled == mQsDisabled) return; + mQsDisabled = disabled; + mBackgroundGradient.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE); + mQSPanel.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE); + mQSFooter.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE); + } + private void updateResources() { LayoutParams layoutParams = (LayoutParams) mQSPanel.getLayoutParams(); layoutParams.topMargin = mContext.getResources().getDimensionPixelSize( diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java index 3f3cea2eaa17..6c7eda7c89d1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java @@ -69,4 +69,6 @@ public interface QSFooter { */ @Nullable View getExpandView(); + + default void disable(int state1, int state2, boolean animate) {} } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index 0fa659748f5d..cf549fa634f5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -47,10 +47,8 @@ import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.R.dimen; -import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.qs.TouchAnimator.Builder; -import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.MultiUserSwitch; import com.android.systemui.statusbar.phone.SettingsButton; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -62,8 +60,7 @@ import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChange import com.android.systemui.tuner.TunerService; public class QSFooterImpl extends FrameLayout implements QSFooter, - OnClickListener, OnUserInfoChangedListener, EmergencyListener, - SignalCallback, CommandQueue.Callbacks { + OnClickListener, OnUserInfoChangedListener, EmergencyListener, SignalCallback { private ActivityStarter mActivityStarter; private UserInfoController mUserInfoController; @@ -211,16 +208,9 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, } @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this); - } - - @Override @VisibleForTesting public void onDetachedFromWindow() { setListening(false); - SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this); super.onDetachedFromWindow(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 018a63560429..cb068e3b5372 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -14,9 +14,12 @@ package com.android.systemui.qs; +import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.app.Fragment; +import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; @@ -35,12 +38,14 @@ import android.widget.FrameLayout.LayoutParams; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.R.id; +import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qs.customize.QSCustomizer; +import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; import com.android.systemui.statusbar.stack.StackStateAnimator; -public class QSFragment extends Fragment implements QS { +public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks { private static final String TAG = "QS"; private static final boolean DEBUG = false; private static final String EXTRA_EXPANDED = "expanded"; @@ -65,6 +70,7 @@ public class QSFragment extends Fragment implements QS { private int mLayoutDirection; private QSFooter mFooter; private float mLastQSExpansion = -1; + private boolean mQsDisabled; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @@ -176,6 +182,17 @@ public class QSFragment extends Fragment implements QS { } } + @Override + public void disable(int state1, int state2, boolean animate) { + final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0; + if (disabled == mQsDisabled) return; + mQsDisabled = disabled; + mContainer.disable(state1, state2, animate); + mHeader.disable(state1, state2, animate); + mFooter.disable(state1, state2, animate); + updateQsState(); + } + private void updateQsState() { final boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating; @@ -189,6 +206,9 @@ public class QSFragment extends Fragment implements QS { mFooter.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating) ? View.VISIBLE : View.INVISIBLE); + if (mQsDisabled) { + mFooter.setVisibility(View.GONE); + } mFooter.setExpanded((mKeyguardShowing && !mHeaderAnimating) || (mQsExpanded && !mStackScrollerOverscrolling)); mQSPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE); @@ -258,6 +278,12 @@ public class QSFragment extends Fragment implements QS { mHeader.setListening(listening); mFooter.setListening(listening); mQSPanel.setListening(mListening && mQsExpanded); + if (listening) { + SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this); + } else { + SysUiServiceProvider.getComponent(getContext(), CommandQueue.class) + .removeCallbacks(this); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 70bfad1033e7..e2af90d6bbce 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -68,7 +68,7 @@ import java.util.Locale; * battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner * contents. */ -public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue.Callbacks, +public class QuickStatusBarHeader extends RelativeLayout implements View.OnClickListener, NextAlarmController.NextAlarmChangeCallback { private static final String TAG = "QuickStatusBarHeader"; private static final boolean DEBUG = false; @@ -249,8 +249,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue com.android.internal.R.dimen.quick_qs_offset_height); mSystemIconsView.setLayoutParams(mSystemIconsView.getLayoutParams()); - getLayoutParams().height = - resources.getDimensionPixelSize(com.android.internal.R.dimen.quick_qs_total_height); + getLayoutParams().height = resources.getDimensionPixelSize(mQsDisabled + ? com.android.internal.R.dimen.quick_qs_offset_height + : com.android.internal.R.dimen.quick_qs_total_height); setLayoutParams(getLayoutParams()); updateStatusIconAlphaAnimator(); @@ -320,20 +321,18 @@ public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue TOOLTIP_NOT_YET_SHOWN_COUNT); } - @Override public void disable(int state1, int state2, boolean animate) { final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0; if (disabled == mQsDisabled) return; mQsDisabled = disabled; mHeaderQsPanel.setDisabledByPolicy(disabled); - final int rawHeight = (int) getResources().getDimension( - com.android.internal.R.dimen.quick_qs_total_height); - getLayoutParams().height = disabled ? (rawHeight - mHeaderQsPanel.getHeight()) : rawHeight; + mHeaderTextContainerView.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE); + mQuickQsStatusIcons.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE); + updateResources(); } @Override public void onAttachedToWindow() { - SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this); Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager); requestApplyInsets(); } @@ -354,7 +353,6 @@ public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue @VisibleForTesting public void onDetachedFromWindow() { setListening(false); - SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this); Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager); super.onDetachedFromWindow(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java index 75bc95588244..30e9afd8ea04 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java @@ -21,7 +21,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import android.annotation.TargetApi; import android.app.ActivityManager; -import android.content.ComponentName; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -62,6 +61,7 @@ public class RecentsOnboarding { private static final String TAG = "RecentsOnboarding"; private static final boolean RESET_PREFS_FOR_DEBUG = false; + private static final boolean ONBOARDING_ENABLED = false; private static final long SHOW_DELAY_MS = 500; private static final long SHOW_HIDE_DURATION_MS = 300; // Don't show the onboarding until the user has launched this number of apps. @@ -184,6 +184,9 @@ public class RecentsOnboarding { } public void onConnectedToLauncher() { + if (!ONBOARDING_ENABLED) { + return; + } boolean alreadySeenRecentsOnboarding = Prefs.getBoolean(mContext, Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false); if (!mTaskListenerRegistered && !alreadySeenRecentsOnboarding) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index b81e9af4f692..29c2edc22f4c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -26,6 +26,7 @@ import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; +import android.view.MotionEvent; import android.view.NotificationHeaderView; import android.view.View; import android.view.ViewGroup; @@ -1631,6 +1632,42 @@ public class NotificationContentView extends FrameLayout { return null; } + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + float y = ev.getY(); + // We still want to distribute touch events to the remote input even if it's outside the + // view boundary. We're therefore manually dispatching these events to the remote view + RemoteInputView riv = getRemoteInputForView(getViewForVisibleType(mVisibleType)); + if (riv != null && riv.getVisibility() == VISIBLE) { + int inputStart = mUnrestrictedContentHeight - riv.getHeight(); + if (y <= mUnrestrictedContentHeight && y >= inputStart) { + ev.offsetLocation(0, -inputStart); + return riv.dispatchTouchEvent(ev); + } + } + return super.dispatchTouchEvent(ev); + } + + /** + * Overridden to make sure touches to the reply action bar actually go through to this view + */ + @Override + public boolean pointInView(float localX, float localY, float slop) { + float top = mClipTopAmount; + float bottom = mUnrestrictedContentHeight; + return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) && + localY < (bottom + slop); + } + + private RemoteInputView getRemoteInputForView(View child) { + if (child == mExpandedChild) { + return mExpandedRemoteInput; + } else if (child == mHeadsUpChild) { + return mHeadsUpRemoteInput; + } + return null; + } + public int getExpandHeight() { int viewType = VISIBLE_TYPE_EXPANDED; if (mExpandedChild == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java index a93be00ba080..6238526a521f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java @@ -308,15 +308,15 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G minimize.setVisibility(GONE); } - // Set up app settings link + // Set up app settings link (i.e. Customize) TextView settingsLinkView = findViewById(R.id.app_settings); Intent settingsIntent = getAppSettingsIntent(mPm, mPkg, mSingleNotificationChannel, mSbn.getId(), mSbn.getTag()); - if (settingsIntent != null + if (!mIsForBlockingHelper + && settingsIntent != null && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) { settingsLinkView.setVisibility(VISIBLE); - settingsLinkView.setText(mContext.getString(R.string.notification_app_settings, - mSbn.getNotification().getSettingsText())); + settingsLinkView.setText(mContext.getString(R.string.notification_app_settings)); settingsLinkView.setOnClickListener((View view) -> { mAppSettingsClickListener.onClick(view, settingsIntent); }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java index e248db4b2a06..ec243fe98710 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java @@ -24,8 +24,8 @@ public class CarNavigationButton extends com.android.keyguard.AlphaOptimizedImag private String mLongIntent; private boolean mBroadcastIntent; private boolean mSelected = false; - private float mSelectedAlpha; - private float mUnselectedAlpha; + private float mSelectedAlpha = 1f; + private float mUnselectedAlpha = 1f; private int mSelectedIconResourceId; private int mIconResourceId; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 2c335a3ad7ce..cc143bb848cf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -111,7 +111,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo private final Context mContext; protected final ScrimView mScrimBehind; protected final ScrimView mScrimInFront; - private final LightBarController mLightBarController; private final UnlockMethodCache mUnlockMethodCache; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final DozeParameters mDozeParameters; @@ -145,6 +144,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo private int mCurrentBehindTint; private boolean mWallpaperVisibilityTimedOut; private int mScrimsVisibility; + private final Consumer<GradientColors> mScrimInFrontColorListener; + private final Consumer<Float> mScrimBehindAlphaListener; private final Consumer<Integer> mScrimVisibleListener; private boolean mBlankScreen; private boolean mScreenBlankingCallbackCalled; @@ -161,17 +162,20 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo private boolean mWakeLockHeld; private boolean mKeyguardOccluded; - public ScrimController(LightBarController lightBarController, ScrimView scrimBehind, - ScrimView scrimInFront, Consumer<Integer> scrimVisibleListener, - DozeParameters dozeParameters, AlarmManager alarmManager) { + public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, + Consumer<Float> scrimBehindAlphaListener, + Consumer<GradientColors> scrimInFrontColorListener, + Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters, + AlarmManager alarmManager) { mScrimBehind = scrimBehind; mScrimInFront = scrimInFront; + mScrimBehindAlphaListener = scrimBehindAlphaListener; + mScrimInFrontColorListener = scrimInFrontColorListener; mScrimVisibleListener = scrimVisibleListener; mContext = scrimBehind.getContext(); mUnlockMethodCache = UnlockMethodCache.getInstance(mContext); mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer(); mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); - mLightBarController = lightBarController; mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha); mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout, "hide_aod_wallpaper", new Handler()); @@ -370,6 +374,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo setOrAdaptCurrentAnimation(mScrimBehind); setOrAdaptCurrentAnimation(mScrimInFront); + + mScrimBehindAlphaListener.accept(mScrimBehind.getViewAlpha()); } } @@ -478,7 +484,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo float minOpacity = ColorUtils.calculateMinimumBackgroundAlpha(textColor, mainColor, 4.5f /* minimumContrast */) / 255f; mScrimBehindAlpha = Math.max(mScrimBehindAlphaResValue, minOpacity); - mLightBarController.setScrimColor(mScrimInFront.getColors()); + mScrimInFrontColorListener.accept(mScrimInFront.getColors()); } // We want to override the back scrim opacity for the AOD state @@ -705,9 +711,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo } } - // TODO factor mLightBarController out of this class if (scrim == mScrimBehind) { - mLightBarController.setScrimAlpha(alpha); + mScrimBehindAlphaListener.accept(alpha); } final boolean wantsAlphaUpdate = alpha != currentAlpha; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 9c5cf3069eef..0072dc07d535 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -916,8 +916,14 @@ public class StatusBar extends SystemUI implements DemoMode, ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind); ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front); - mScrimController = SystemUIFactory.getInstance().createScrimController(mLightBarController, + mScrimController = SystemUIFactory.getInstance().createScrimController( scrimBehind, scrimInFront, mLockscreenWallpaper, + scrimBehindAlpha -> { + mLightBarController.setScrimAlpha(scrimBehindAlpha); + }, + scrimInFrontColor -> { + mLightBarController.setScrimColor(scrimInFrontColor); + }, scrimsVisible -> { if (mStatusBarWindowManager != null) { mStatusBarWindowManager.setScrimsVisibility(scrimsVisible); @@ -1428,13 +1434,13 @@ public class StatusBar extends SystemUI implements DemoMode, } public void addQsTile(ComponentName tile) { - if (mQSPanel.getHost() != null) { + if (mQSPanel != null && mQSPanel.getHost() != null) { mQSPanel.getHost().addTile(tile); } } public void remQsTile(ComponentName tile) { - if (mQSPanel.getHost() != null) { + if (mQSPanel != null && mQSPanel.getHost() != null) { mQSPanel.getHost().removeTile(tile); } } @@ -4998,6 +5004,14 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) { + RemoteInputController controller = mRemoteInputManager.getController(); + if (controller.isRemoteInputActive(row.getEntry()) + && !TextUtils.isEmpty(row.getActiveRemoteInputText())) { + // We have an active remote input typed and the user clicked on the notification. + // this was probably unintentional, so we're closing the edit text instead. + controller.closeRemoteInputs(); + return; + } Notification notification = sbn.getNotification(); final PendingIntent intent = notification.contentIntent != null ? notification.contentIntent @@ -5061,12 +5075,7 @@ public class StatusBar extends SystemUI implements DemoMode, Intent fillInIntent = null; Entry entry = row.getEntry(); CharSequence remoteInputText = null; - RemoteInputController controller = mRemoteInputManager.getController(); - if (controller.isRemoteInputActive(entry)) { - remoteInputText = row.getActiveRemoteInputText(); - } - if (TextUtils.isEmpty(remoteInputText) - && !TextUtils.isEmpty(entry.remoteInputText)) { + if (!TextUtils.isEmpty(entry.remoteInputText)) { remoteInputText = entry.remoteInputText; } if (!TextUtils.isEmpty(remoteInputText) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index baeaaadf419f..9aa804484716 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -16,9 +16,6 @@ package com.android.systemui.statusbar.policy; -import libcore.icu.LocaleData; - -import android.app.ActivityManager; import android.app.StatusBarManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -46,6 +43,7 @@ import com.android.systemui.Dependency; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; @@ -53,6 +51,8 @@ import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; +import libcore.icu.LocaleData; + import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Locale; @@ -66,6 +66,9 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C public static final String CLOCK_SECONDS = "clock_seconds"; + private final CurrentUserTracker mCurrentUserTracker; + private int mCurrentUserId; + private boolean mClockVisibleByPolicy = true; private boolean mClockVisibleByUser = true; @@ -117,6 +120,12 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C } finally { a.recycle(); } + mCurrentUserTracker = new CurrentUserTracker(context) { + @Override + public void onUserSwitched(int newUserId) { + mCurrentUserId = newUserId; + } + }; } @Override @@ -141,6 +150,8 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C if (mShowDark) { Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this); } + mCurrentUserTracker.startTracking(); + mCurrentUserId = mCurrentUserTracker.getCurrentUserId(); } // NOTE: It's safe to do these after registering the receiver since the receiver always runs @@ -166,6 +177,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C if (mShowDark) { Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this); } + mCurrentUserTracker.stopTracking(); } } @@ -302,7 +314,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C private final CharSequence getSmallTime() { Context context = getContext(); - boolean is24 = DateFormat.is24HourFormat(context, ActivityManager.getCurrentUser()); + boolean is24 = DateFormat.is24HourFormat(context, mCurrentUserId); LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); final char MAGIC1 = '\uEF00'; @@ -392,8 +404,7 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C } else if (hhmm != null && hhmm.length() == 4) { int hh = Integer.parseInt(hhmm.substring(0, 2)); int mm = Integer.parseInt(hhmm.substring(2)); - boolean is24 = DateFormat.is24HourFormat( - getContext(), ActivityManager.getCurrentUser()); + boolean is24 = DateFormat.is24HourFormat(getContext(), mCurrentUserId); if (is24) { mCalendar.set(Calendar.HOUR_OF_DAY, hh); } else { diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml index 53839a9bf56b..fc353a1945a6 100644 --- a/packages/SystemUI/tests/AndroidTest.xml +++ b/packages/SystemUI/tests/AndroidTest.xml @@ -24,5 +24,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.systemui.tests" /> <option name="runner" value="android.testing.TestableInstrumentation" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java index d86e947cdfcc..658ac73153ab 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java @@ -696,6 +696,29 @@ public class NotificationInfoTest extends SysuiTestCase { assertEquals(GONE, settingsLink.getVisibility()); } + @Test + public void testBindHeader_noSettingsLinkWhenIsForBlockingHelper() throws Exception { + final String settingsText = "work chats"; + final ResolveInfo ri = new ResolveInfo(); + ri.activityInfo = new ActivityInfo(); + ri.activityInfo.packageName = TEST_PACKAGE_NAME; + ri.activityInfo.name = "something"; + List<ResolveInfo> ris = new ArrayList<>(); + ris.add(ri); + when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris); + mNotificationChannel.setImportance(IMPORTANCE_LOW); + Notification n = new Notification.Builder(mContext, mNotificationChannel.getId()) + .setSettingsText(settingsText).build(); + StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, + 0, null, 0, 0, n, UserHandle.CURRENT, null, 0); + + mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, + TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, false, true, + true); + final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings); + assertEquals(GONE, settingsLink.getVisibility()); + } + @Test public void testWillBeRemovedReturnsFalseBeforeBind() throws Exception { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 82129a196f93..0416232673ba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -42,6 +42,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; +import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.ScrimView; @@ -65,9 +66,12 @@ public class ScrimControllerTest extends SysuiTestCase { private SynchronousScrimController mScrimController; private ScrimView mScrimBehind; private ScrimView mScrimInFront; + private Consumer<Float> mScrimBehindAlphaCallback; + private Consumer<GradientColors> mScrimInFrontColorCallback; private Consumer<Integer> mScrimVisibilityCallback; + private float mScrimBehindAlpha; + private GradientColors mScrimInFrontColor; private int mScrimVisibility; - private LightBarController mLightBarController; private DozeParameters mDozeParamenters; private WakeLock mWakeLock; private boolean mAlwaysOnEnabled; @@ -75,19 +79,20 @@ public class ScrimControllerTest extends SysuiTestCase { @Before public void setup() { - mLightBarController = mock(LightBarController.class); mScrimBehind = spy(new ScrimView(getContext())); mScrimInFront = new ScrimView(getContext()); mWakeLock = mock(WakeLock.class); mAlarmManager = mock(AlarmManager.class); mAlwaysOnEnabled = true; + mScrimBehindAlphaCallback = (Float alpha) -> mScrimBehindAlpha = alpha; + mScrimInFrontColorCallback = (GradientColors color) -> mScrimInFrontColor = color; mScrimVisibilityCallback = (Integer visible) -> mScrimVisibility = visible; mDozeParamenters = mock(DozeParameters.class); when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled); when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true); - mScrimController = new SynchronousScrimController(mLightBarController, mScrimBehind, - mScrimInFront, mScrimVisibilityCallback, mDozeParamenters, - mAlarmManager); + mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront, + mScrimBehindAlphaCallback, mScrimInFrontColorCallback, mScrimVisibilityCallback, + mDozeParamenters, mAlarmManager); } @Test @@ -206,6 +211,28 @@ public class ScrimControllerTest extends SysuiTestCase { } @Test + public void panelExpansion() { + mScrimController.setPanelExpansion(0f); + mScrimController.setPanelExpansion(0.5f); + mScrimController.transitionTo(ScrimState.UNLOCKED); + mScrimController.finishAnimationsImmediately(); + + reset(mScrimBehind); + mScrimController.setPanelExpansion(0f); + mScrimController.setPanelExpansion(1.0f); + mScrimController.onPreDraw(); + + Assert.assertEquals("Scrim alpha should change after setPanelExpansion", + mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f); + + mScrimController.setPanelExpansion(0f); + mScrimController.onPreDraw(); + + Assert.assertEquals("Scrim alpha should change after setPanelExpansion", + mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f); + } + + @Test public void panelExpansionAffectsAlpha() { mScrimController.setPanelExpansion(0f); mScrimController.setPanelExpansion(0.5f); @@ -531,11 +558,12 @@ public class ScrimControllerTest extends SysuiTestCase { private boolean mAnimationCancelled; boolean mOnPreDrawCalled; - SynchronousScrimController(LightBarController lightBarController, - ScrimView scrimBehind, ScrimView scrimInFront, + SynchronousScrimController(ScrimView scrimBehind, ScrimView scrimInFront, + Consumer<Float> scrimBehindAlphaListener, + Consumer<GradientColors> scrimInFrontColorListener, Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters, AlarmManager alarmManager) { - super(lightBarController, scrimBehind, scrimInFront, + super(scrimBehind, scrimInFront, scrimBehindAlphaListener, scrimInFrontColorListener, scrimVisibleListener, dozeParameters, alarmManager); mHandler = new FakeHandler(Looper.myLooper()); } diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index b6ac3fb36284..446c0a1d11b1 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -4779,7 +4779,7 @@ message MetricsEvent { // CATEGORY: SETTINGS ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK = 1210; - // FIELD - Manually selected mobile network + // Not used anymore. FIELD_MOBILE_NETWORK = 1211; // OPEN: Settings > Network & Internet > Mobile network > Access Point Names @@ -5583,6 +5583,36 @@ message MetricsEvent { // OS: P SETTINGS_GESTURE_SWIPE_UP = 1374; + // OPEN: Settings > Storage > Dialog to format a storage volume + // CATEGORY: SETTINGS + // OS: P + DIALOG_VOLUME_FORMAT = 1375; + + // OPEN: DND onboarding activity > screen on checkbox + // CATEGORY: SETTINGS + // OS: P + ACTION_ZEN_ONBOARDING_SCREEN_ON = 1376; + + // OPEN: DND onboarding activity > screen off checkbox + // CATEGORY: SETTINGS + // OS: P + ACTION_ZEN_ONBOARDING_SCREEN_OFF = 1377; + + // OPEN: DND onboarding activity > Ok button + // CATEGORY: SETTINGS + // OS: P + ACTION_ZEN_ONBOARDING_OK = 1378; + + // OPEN: DND onboarding activity > Settings link + // CATEGORY: SETTINGS + // OS: P + ACTION_ZEN_ONBOARDING_SETTINGS = 1379; + + // OPEN: DND onboarding activity + // CATEGORY: SETTINGS + // OS: P + SETTINGS_ZEN_ONBOARDING = 1380; + // ---- 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/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 59cb13562764..6463bed639a9 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -52,6 +52,8 @@ import android.database.ContentObserver; import android.net.ConnectivityManager; import android.net.ConnectivityManager.PacketKeepalive; import android.net.IConnectivityManager; +import android.net.IIpConnectivityMetrics; +import android.net.INetdEventCallback; import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; import android.net.INetworkPolicyManager; @@ -140,6 +142,7 @@ import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.DataConnectionStats; import com.android.server.connectivity.DnsManager; import com.android.server.connectivity.DnsManager.PrivateDnsConfig; +import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; import com.android.server.connectivity.IpConnectivityMetrics; import com.android.server.connectivity.KeepaliveTracker; import com.android.server.connectivity.LingerMonitor; @@ -155,6 +158,7 @@ import com.android.server.connectivity.PermissionMonitor; import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Vpn; import com.android.server.connectivity.tethering.TetheringDependencies; +import com.android.server.net.BaseNetdEventCallback; import com.android.server.net.BaseNetworkObserver; import com.android.server.net.LockdownVpnTracker; import com.android.server.net.NetworkPolicyManagerInternal; @@ -256,6 +260,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private INetworkStatsService mStatsService; private INetworkPolicyManager mPolicyManager; private NetworkPolicyManagerInternal mPolicyManagerInternal; + private IIpConnectivityMetrics mIpConnectivityMetrics; private String mCurrentTcpBufferSizes; @@ -414,6 +419,9 @@ public class ConnectivityService extends IConnectivityManager.Stub // Handle changes in Private DNS settings. private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37; + // Handle private DNS validation status updates. + private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38; + private static String eventName(int what) { return sMagicDecoderRing.get(what, Integer.toString(what)); } @@ -1553,6 +1561,41 @@ public class ConnectivityService extends IConnectivityManager.Stub return true; } + @VisibleForTesting + protected final INetdEventCallback mNetdEventCallback = new BaseNetdEventCallback() { + @Override + public void onPrivateDnsValidationEvent(int netId, String ipAddress, + String hostname, boolean validated) { + try { + mHandler.sendMessage(mHandler.obtainMessage( + EVENT_PRIVATE_DNS_VALIDATION_UPDATE, + new PrivateDnsValidationUpdate(netId, + InetAddress.parseNumericAddress(ipAddress), + hostname, validated))); + } catch (IllegalArgumentException e) { + loge("Error parsing ip address in validation event"); + } + } + }; + + @VisibleForTesting + protected void registerNetdEventCallback() { + mIpConnectivityMetrics = + (IIpConnectivityMetrics) IIpConnectivityMetrics.Stub.asInterface( + ServiceManager.getService(IpConnectivityLog.SERVICE_NAME)); + if (mIpConnectivityMetrics == null) { + Slog.wtf(TAG, "Missing IIpConnectivityMetrics"); + } + + try { + mIpConnectivityMetrics.addNetdEventCallback( + INetdEventCallback.CALLBACK_CALLER_CONNECTIVITY_SERVICE, + mNetdEventCallback); + } catch (Exception e) { + loge("Error registering netd callback: " + e); + } + } + private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() { @Override public void onUidRulesChanged(int uid, int uidRules) { @@ -1738,6 +1781,7 @@ public class ConnectivityService extends IConnectivityManager.Stub void systemReady() { loadGlobalProxy(); + registerNetdEventCallback(); synchronized (this) { mSystemReady = true; @@ -2288,6 +2332,9 @@ public class ConnectivityService extends IConnectivityManager.Stub for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { handlePerNetworkPrivateDnsConfig(nai, cfg); + if (networkRequiresValidation(nai)) { + handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); + } } } @@ -2312,6 +2359,15 @@ public class ConnectivityService extends IConnectivityManager.Stub updateDnses(nai.linkProperties, null, nai.network.netId); } + private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) { + NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId); + if (nai == null) { + return; + } + mDnsManager.updatePrivateDnsValidation(update); + handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); + } + private void updateLingerState(NetworkAgentInfo nai, long now) { // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm. // 2. If the network was lingering and there are now requests, unlinger it. @@ -3002,6 +3058,10 @@ public class ConnectivityService extends IConnectivityManager.Stub case EVENT_PRIVATE_DNS_SETTINGS_CHANGED: handlePrivateDnsSettingsChanged(); break; + case EVENT_PRIVATE_DNS_VALIDATION_UPDATE: + handlePrivateDnsValidationUpdate( + (PrivateDnsValidationUpdate) msg.obj); + break; } } } @@ -4575,6 +4635,11 @@ public class ConnectivityService extends IConnectivityManager.Stub updateRoutes(newLp, oldLp, netId); updateDnses(newLp, oldLp, netId); + // Make sure LinkProperties represents the latest private DNS status. + // This does not need to be done before updateDnses because the + // LinkProperties are not the source of the private DNS configuration. + // updateDnses will fetch the private DNS configuration from DnsManager. + mDnsManager.updatePrivateDnsStatus(netId, newLp); // Start or stop clat accordingly to network state. networkAgent.updateClat(mNetd); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 75bad46a5cfc..04d54e1dcb8d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -52,6 +52,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; +import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT; import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; @@ -118,6 +119,7 @@ import static android.provider.Settings.Global.DEBUG_APP; import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; +import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS; import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS; import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER; import static android.provider.Settings.System.FONT_SCALE; @@ -1282,17 +1284,24 @@ public class ActivityManagerService extends IActivityManager.Stub private final class FontScaleSettingObserver extends ContentObserver { private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE); + private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS); public FontScaleSettingObserver() { super(mHandler); ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL); + resolver.registerContentObserver(mHideErrorDialogsUri, false, this, + UserHandle.USER_ALL); } @Override public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { if (mFontScaleUri.equals(uri)) { updateFontScaleIfNeeded(userId); + } else if (mHideErrorDialogsUri.equals(uri)) { + synchronized (ActivityManagerService.this) { + updateShouldShowDialogsLocked(getGlobalConfiguration()); + } } } } @@ -1949,7 +1958,7 @@ public class ActivityManagerService extends IActivityManager.Stub final ActivityManagerConstants mConstants; // Encapsulates the global setting "hidden_api_blacklist_exemptions" - final HiddenApiBlacklist mHiddenApiBlacklist; + final HiddenApiSettings mHiddenApiBlacklist; PackageManagerInternal mPackageManagerInt; @@ -2884,17 +2893,19 @@ public class ActivityManagerService extends IActivityManager.Stub } /** - * Encapsulates the global setting "hidden_api_blacklist_exemptions", including tracking the - * latest value via a content observer. + * Encapsulates global settings related to hidden API enforcement behaviour, including tracking + * the latest value via a content observer. */ - static class HiddenApiBlacklist extends ContentObserver { + static class HiddenApiSettings extends ContentObserver { private final Context mContext; private boolean mBlacklistDisabled; private String mExemptionsStr; private List<String> mExemptions = Collections.emptyList(); + @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT; + @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT; - public HiddenApiBlacklist(Handler handler, Context context) { + public HiddenApiSettings(Handler handler, Context context) { super(handler); mContext = context; } @@ -2904,6 +2915,14 @@ public class ActivityManagerService extends IActivityManager.Stub Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS), false, this); + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS), + false, + this); + mContext.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS), + false, + this); update(); } @@ -2923,13 +2942,32 @@ public class ActivityManagerService extends IActivityManager.Stub } zygoteProcess.setApiBlacklistExemptions(mExemptions); } + mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS); + mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS); + } + private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) { + int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey, + ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT); + if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) { + return policy; + } else { + return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT; + } } boolean isDisabled() { return mBlacklistDisabled; } + @HiddenApiEnforcementPolicy int getPolicyForPrePApps() { + return mPolicyPreP; + } + + @HiddenApiEnforcementPolicy int getPolicyForPApps() { + return mPolicyP; + } + public void onChange(boolean selfChange) { update(); } @@ -3102,7 +3140,7 @@ public class ActivityManagerService extends IActivityManager.Stub } }; - mHiddenApiBlacklist = new HiddenApiBlacklist(mHandler, mContext); + mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext); Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); @@ -4218,6 +4256,9 @@ public class ActivityManagerService extends IActivityManager.Stub } if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) { + app.info.maybeUpdateHiddenApiEnforcementPolicy( + mHiddenApiBlacklist.getPolicyForPrePApps(), + mHiddenApiBlacklist.getPolicyForPApps()); @HiddenApiEnforcementPolicy int policy = app.info.getHiddenApiEnforcementPolicy(); int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT); @@ -22449,7 +22490,7 @@ public class ActivityManagerService extends IActivityManager.Stub mUserController.getCurrentUserId()); // TODO: If our config changes, should we auto dismiss any currently showing dialogs? - mShowDialogs = shouldShowDialogs(mTempConfig); + updateShouldShowDialogsLocked(mTempConfig); AttributeCache ac = AttributeCache.instance(); if (ac != null) { @@ -22704,7 +22745,7 @@ public class ActivityManagerService extends IActivityManager.Stub * A thought: SystemUI might also want to get told about this, the Power * dialog / global actions also might want different behaviors. */ - private static boolean shouldShowDialogs(Configuration config) { + private void updateShouldShowDialogsLocked(Configuration config) { final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH && config.navigation == Configuration.NAVIGATION_NONAV); @@ -22713,7 +22754,9 @@ public class ActivityManagerService extends IActivityManager.Stub && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER) && modeType != Configuration.UI_MODE_TYPE_TELEVISION && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET); - return inputMethodExists && uiModeSupportsDialogs; + final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(), + HIDE_ERROR_DIALOGS, 0) != 0; + mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet; } @Override diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java index 365c43666cc2..2b988d30f4bb 100644 --- a/services/core/java/com/android/server/am/RecentTasks.java +++ b/services/core/java/com/android/server/am/RecentTasks.java @@ -534,8 +534,8 @@ class RecentTasks { final TaskRecord tr = mTasks.get(i); final String taskPackageName = tr.getBaseIntent().getComponent().getPackageName(); - if (tr.userId != userId) return; - if (!taskPackageName.equals(packageName)) return; + if (tr.userId != userId) continue; + if (!taskPackageName.equals(packageName)) continue; mService.mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS, "remove-package-task"); diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index a2943346e074..b6e414a2f84d 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -1184,11 +1184,6 @@ class UserController implements Handler.Callback { Slog.w(TAG, "No user info for user #" + targetUserId); return false; } - if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mInjector.getContext())) { - Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId - + " when device is in demo mode"); - return false; - } if (!targetUserInfo.supportsSwitchTo()) { Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported"); return false; diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java index 2a361a02d7d2..7aaac06024e7 100644 --- a/services/core/java/com/android/server/connectivity/DnsManager.java +++ b/services/core/java/com/android/server/connectivity/DnsManager.java @@ -37,10 +37,10 @@ import android.net.Uri; import android.net.dns.ResolvUtil; import android.os.Binder; import android.os.INetworkManagementService; -import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; +import android.util.Pair; import android.util.Slog; import com.android.server.connectivity.MockableSystemProperties; @@ -50,8 +50,12 @@ import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; +import java.util.Set; import java.util.StringJoiner; @@ -110,6 +114,7 @@ import java.util.StringJoiner; */ public class DnsManager { private static final String TAG = DnsManager.class.getSimpleName(); + private static final PrivateDnsConfig PRIVATE_DNS_OFF = new PrivateDnsConfig(); /* Defaults for resolver parameters. */ private static final int DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS = 1800; @@ -183,11 +188,89 @@ public class DnsManager { }; } + public static class PrivateDnsValidationUpdate { + final public int netId; + final public InetAddress ipAddress; + final public String hostname; + final public boolean validated; + + public PrivateDnsValidationUpdate(int netId, InetAddress ipAddress, + String hostname, boolean validated) { + this.netId = netId; + this.ipAddress = ipAddress; + this.hostname = hostname; + this.validated = validated; + } + } + + private static class PrivateDnsValidationStatuses { + enum ValidationStatus { + IN_PROGRESS, + FAILED, + SUCCEEDED + } + + // Validation statuses of <hostname, ipAddress> pairs for a single netId + private Map<Pair<String, InetAddress>, ValidationStatus> mValidationMap; + + private PrivateDnsValidationStatuses() { + mValidationMap = new HashMap<>(); + } + + private boolean hasValidatedServer() { + for (ValidationStatus status : mValidationMap.values()) { + if (status == ValidationStatus.SUCCEEDED) { + return true; + } + } + return false; + } + + private void updateTrackedDnses(String[] ipAddresses, String hostname) { + Set<Pair<String, InetAddress>> latestDnses = new HashSet<>(); + for (String ipAddress : ipAddresses) { + try { + latestDnses.add(new Pair(hostname, + InetAddress.parseNumericAddress(ipAddress))); + } catch (IllegalArgumentException e) {} + } + // Remove <hostname, ipAddress> pairs that should not be tracked. + for (Iterator<Map.Entry<Pair<String, InetAddress>, ValidationStatus>> it = + mValidationMap.entrySet().iterator(); it.hasNext(); ) { + Map.Entry<Pair<String, InetAddress>, ValidationStatus> entry = it.next(); + if (!latestDnses.contains(entry.getKey())) { + it.remove(); + } + } + // Add new <hostname, ipAddress> pairs that should be tracked. + for (Pair<String, InetAddress> p : latestDnses) { + if (!mValidationMap.containsKey(p)) { + mValidationMap.put(p, ValidationStatus.IN_PROGRESS); + } + } + } + + private void updateStatus(PrivateDnsValidationUpdate update) { + Pair<String, InetAddress> p = new Pair(update.hostname, + update.ipAddress); + if (!mValidationMap.containsKey(p)) { + return; + } + if (update.validated) { + mValidationMap.put(p, ValidationStatus.SUCCEEDED); + } else { + mValidationMap.put(p, ValidationStatus.FAILED); + } + } + } + private final Context mContext; private final ContentResolver mContentResolver; private final INetworkManagementService mNMS; private final MockableSystemProperties mSystemProperties; + // TODO: Replace these Maps with SparseArrays. private final Map<Integer, PrivateDnsConfig> mPrivateDnsMap; + private final Map<Integer, PrivateDnsValidationStatuses> mPrivateDnsValidationMap; private int mNumDnsEntries; private int mSampleValidity; @@ -203,6 +286,7 @@ public class DnsManager { mNMS = nms; mSystemProperties = sp; mPrivateDnsMap = new HashMap<>(); + mPrivateDnsValidationMap = new HashMap<>(); // TODO: Create and register ContentObservers to track every setting // used herein, posting messages to respond to changes. @@ -214,6 +298,7 @@ public class DnsManager { public void removeNetwork(Network network) { mPrivateDnsMap.remove(network.netId); + mPrivateDnsValidationMap.remove(network.netId); } public PrivateDnsConfig updatePrivateDns(Network network, PrivateDnsConfig cfg) { @@ -223,6 +308,40 @@ public class DnsManager { : mPrivateDnsMap.remove(network.netId); } + public void updatePrivateDnsStatus(int netId, LinkProperties lp) { + // Use the PrivateDnsConfig data pushed to this class instance + // from ConnectivityService. + final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId, + PRIVATE_DNS_OFF); + + final boolean useTls = privateDnsCfg.useTls; + final boolean strictMode = privateDnsCfg.inStrictMode(); + final String tlsHostname = strictMode ? privateDnsCfg.hostname : ""; + + if (strictMode) { + lp.setUsePrivateDns(true); + lp.setPrivateDnsServerName(tlsHostname); + } else if (useTls) { + // We are in opportunistic mode. Private DNS should be used if there + // is a known DNS-over-TLS validated server. + boolean validated = mPrivateDnsValidationMap.containsKey(netId) && + mPrivateDnsValidationMap.get(netId).hasValidatedServer(); + lp.setUsePrivateDns(validated); + lp.setPrivateDnsServerName(null); + } else { + // Private DNS is disabled. + lp.setUsePrivateDns(false); + lp.setPrivateDnsServerName(null); + } + } + + public void updatePrivateDnsValidation(PrivateDnsValidationUpdate update) { + final PrivateDnsValidationStatuses statuses = + mPrivateDnsValidationMap.get(update.netId); + if (statuses == null) return; + statuses.updateStatus(update); + } + public void setDnsConfigurationForNetwork( int netId, LinkProperties lp, boolean isDefaultNetwork) { final String[] assignedServers = NetworkUtils.makeStrings(lp.getDnsServers()); @@ -238,10 +357,11 @@ public class DnsManager { // // At this time we do not attempt to enable Private DNS on non-Internet // networks like IMS. - final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.get(netId); + final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId, + PRIVATE_DNS_OFF); - final boolean useTls = (privateDnsCfg != null) && privateDnsCfg.useTls; - final boolean strictMode = (privateDnsCfg != null) && privateDnsCfg.inStrictMode(); + final boolean useTls = privateDnsCfg.useTls; + final boolean strictMode = privateDnsCfg.inStrictMode(); final String tlsHostname = strictMode ? privateDnsCfg.hostname : ""; final String[] tlsServers = strictMode ? NetworkUtils.makeStrings( @@ -251,6 +371,17 @@ public class DnsManager { : useTls ? assignedServers // Opportunistic : new String[0]; // Off + // Prepare to track the validation status of the DNS servers in the + // resolver config when private DNS is in opportunistic or strict mode. + if (useTls) { + if (!mPrivateDnsValidationMap.containsKey(netId)) { + mPrivateDnsValidationMap.put(netId, new PrivateDnsValidationStatuses()); + } + mPrivateDnsValidationMap.get(netId).updateTrackedDnses(tlsServers, tlsHostname); + } else { + mPrivateDnsValidationMap.remove(netId); + } + Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %s, %s, %s)", netId, Arrays.toString(assignedServers), Arrays.toString(domainStrs), Arrays.toString(params), tlsHostname, Arrays.toString(tlsServers))); diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java index 3868ea6a1056..906a6a3dd1cc 100644 --- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java +++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java @@ -57,6 +57,7 @@ import android.provider.Settings; import android.telephony.TelephonyManager; import android.util.DebugUtils; import android.util.Pair; +import android.util.Range; import android.util.Slog; import com.android.internal.R; @@ -266,9 +267,9 @@ public class MultipathPolicyTracker { } private long getRemainingDailyBudget(long limitBytes, - Pair<ZonedDateTime, ZonedDateTime> cycle) { - final long start = cycle.first.toInstant().toEpochMilli(); - final long end = cycle.second.toInstant().toEpochMilli(); + Range<ZonedDateTime> cycle) { + final long start = cycle.getLower().toInstant().toEpochMilli(); + final long end = cycle.getUpper().toInstant().toEpochMilli(); final long totalBytes = getNetworkTotalBytes(start, end); final long remainingBytes = totalBytes == -1 ? 0 : Math.max(0, limitBytes - totalBytes); // 1 + ((end - now - 1) / millisInDay with integers is equivalent to: @@ -389,7 +390,7 @@ public class MultipathPolicyTracker { private static boolean hasActiveCycle(NetworkPolicy policy) { return policy.hasCycle() && policy.lastLimitSnooze < - policy.cycleIterator().next().first.toInstant().toEpochMilli(); + policy.cycleIterator().next().getLower().toInstant().toEpochMilli(); } // Only ever updated on the handler thread. Accessed from other binder threads to retrieve diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index bfd34ac9ae05..f403953f892d 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -222,6 +222,9 @@ class AutomaticBrightnessController { } public int getAutomaticScreenBrightness() { + if (!mAmbientLuxValid) { + return -1; + } if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) { return (int) (mScreenAutoBrightness * mDozeScaleFactor); } @@ -346,6 +349,7 @@ class AutomaticBrightnessController { pw.println(" mLightSensorEnabled=" + mLightSensorEnabled); pw.println(" mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime)); pw.println(" mAmbientLux=" + mAmbientLux); + pw.println(" mAmbientLuxValid=" + mAmbientLuxValid); pw.println(" mAmbientLightHorizon=" + mAmbientLightHorizon); pw.println(" mBrighteningLuxThreshold=" + mBrighteningLuxThreshold); pw.println(" mDarkeningLuxThreshold=" + mDarkeningLuxThreshold); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 93e0bd5b45c5..0f531a8063ce 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -36,11 +36,13 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Point; import android.hardware.SensorManager; import android.hardware.display.AmbientBrightnessDayStats; import android.hardware.display.BrightnessChangeEvent; import android.hardware.display.BrightnessConfiguration; +import android.hardware.display.Curve; import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayViewport; @@ -72,8 +74,10 @@ import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; import android.util.IntArray; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; +import android.util.Spline; import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; @@ -276,6 +280,11 @@ public final class DisplayManagerService extends SystemService { private final Injector mInjector; + // The minimum brightness curve, which guarantess that any brightness curve that dips below it + // is rejected by the system. + private final Curve mMinimumBrightnessCurve; + private final Spline mMinimumBrightnessSpline; + public DisplayManagerService(Context context) { this(context, new Injector()); } @@ -289,8 +298,15 @@ public final class DisplayManagerService extends SystemService { mUiHandler = UiThread.getHandler(); mDisplayAdapterListener = new DisplayAdapterListener(); mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); + Resources resources = mContext.getResources(); mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); + float[] lux = getFloatArray(resources.obtainTypedArray( + com.android.internal.R.array.config_minimumBrightnessCurveLux)); + float[] nits = getFloatArray(resources.obtainTypedArray( + com.android.internal.R.array.config_minimumBrightnessCurveNits)); + mMinimumBrightnessCurve = new Curve(lux, nits); + mMinimumBrightnessSpline = Spline.createSpline(lux, nits); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); @@ -1032,9 +1048,15 @@ public final class DisplayManagerService extends SystemService { } } + @VisibleForTesting + Curve getMinimumBrightnessCurveInternal() { + return mMinimumBrightnessCurve; + } + private void setBrightnessConfigurationForUserInternal( @Nullable BrightnessConfiguration c, @UserIdInt int userId, @Nullable String packageName) { + validateBrightnessConfiguration(c); final int userSerial = getUserManager().getUserSerialNumber(userId); synchronized (mSyncRoot) { try { @@ -1049,6 +1071,28 @@ public final class DisplayManagerService extends SystemService { } } + @VisibleForTesting + void validateBrightnessConfiguration(BrightnessConfiguration config) { + if (config == null) { + return; + } + if (isBrightnessConfigurationTooDark(config)) { + throw new IllegalArgumentException("brightness curve is too dark"); + } + } + + private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) { + Pair<float[], float[]> curve = config.getCurve(); + float[] lux = curve.first; + float[] nits = curve.second; + for (int i = 0; i < lux.length; i++) { + if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) { + return true; + } + } + return false; + } + private void loadBrightnessConfiguration() { synchronized (mSyncRoot) { final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId); @@ -1369,6 +1413,16 @@ public final class DisplayManagerService extends SystemService { } } + private static float[] getFloatArray(TypedArray array) { + int length = array.length(); + float[] floatArray = new float[length]; + for (int i = 0; i < length; i++) { + floatArray[i] = array.getFloat(i, Float.NaN); + } + array.recycle(); + return floatArray; + } + /** * This is the object that everything in the display manager locks on. * We make it an inner class within the {@link DisplayManagerService} to so that it is @@ -1999,6 +2053,16 @@ public final class DisplayManagerService extends SystemService { } } + @Override // Binder call + public Curve getMinimumBrightnessCurve() { + final long token = Binder.clearCallingIdentity(); + try { + return getMinimumBrightnessCurveInternal(); + } finally { + Binder.restoreCallingIdentity(token); + } + } + void setBrightness(int brightness) { Settings.System.putIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT); diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java index 88b2a3685088..0700ab35df1b 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java @@ -534,17 +534,33 @@ public class SyntheticPasswordManager { private void destroyWeaverSlot(long handle, int userId) { int slot = loadWeaverSlot(handle, userId); + destroyState(WEAVER_SLOT_NAME, handle, userId); if (slot != INVALID_WEAVER_SLOT) { - try { - weaverEnroll(slot, null, null); - } catch (RemoteException e) { - Log.w(TAG, "Failed to destroy slot", e); + Set<Integer> usedSlots = getUsedWeaverSlots(); + if (!usedSlots.contains(slot)) { + Log.i(TAG, "Destroy weaver slot " + slot + " for user " + userId); + try { + weaverEnroll(slot, null, null); + } catch (RemoteException e) { + Log.w(TAG, "Failed to destroy slot", e); + } + } else { + Log.w(TAG, "Skip destroying reused weaver slot " + slot + " for user " + userId); } } - destroyState(WEAVER_SLOT_NAME, handle, userId); } - private int getNextAvailableWeaverSlot() { + /** + * Return the set of weaver slots that are currently in use by all users on the device. + * <p> + * <em>Note:</em> Users who are in the process of being deleted are not tracked here + * (due to them being marked as partial in UserManager so not visible from + * {@link UserManager#getUsers}). As a result their weaver slots will not be considered + * taken and can be reused by new users. Care should be taken when cleaning up the + * deleted user in {@link #removeUser}, to prevent a reused slot from being erased + * unintentionally. + */ + private Set<Integer> getUsedWeaverSlots() { Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers( WEAVER_SLOT_NAME); HashSet<Integer> slots = new HashSet<>(); @@ -554,8 +570,13 @@ public class SyntheticPasswordManager { slots.add(slot); } } + return slots; + } + + private int getNextAvailableWeaverSlot() { + Set<Integer> usedSlots = getUsedWeaverSlots(); for (int i = 0; i < mWeaverConfig.slots; i++) { - if (!slots.contains(i)) { + if (!usedSlots.contains(i)) { return i; } } @@ -592,6 +613,7 @@ public class SyntheticPasswordManager { if (isWeaverAvailable()) { // Weaver based user password int weaverSlot = getNextAvailableWeaverSlot(); + Log.i(TAG, "Weaver enroll password to slot " + weaverSlot + " for user " + userId); byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken), null); if (weaverSecret == null) { Log.e(TAG, "Fail to enroll user password under weaver " + userId); @@ -749,6 +771,7 @@ public class SyntheticPasswordManager { if (isWeaverAvailable()) { int slot = getNextAvailableWeaverSlot(); try { + Log.i(TAG, "Weaver enroll token to slot " + slot + " for user " + userId); weaverEnroll(slot, null, tokenData.weaverSecret); } catch (RemoteException e) { Log.e(TAG, "Failed to enroll weaver secret when activating token", e); diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 1782ae5293d0..8e7737312676 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -39,6 +39,7 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; @@ -195,6 +196,7 @@ import android.util.AtomicFile; import android.util.DataUnit; import android.util.Log; import android.util.Pair; +import android.util.Range; import android.util.RecurrenceRule; import android.util.Slog; import android.util.SparseArray; @@ -503,6 +505,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mNetworkPoliciesSecondLock") private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray(); + /** Map from network ID to last observed roaming state */ + @GuardedBy("mNetworkPoliciesSecondLock") + private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray(); + /** Map from netId to subId as of last update */ @GuardedBy("mNetworkPoliciesSecondLock") private final SparseIntArray mNetIdToSubId = new SparseIntArray(); @@ -1018,6 +1024,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } }; + private static boolean updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue, + Network network) { + final boolean lastValue = lastValues.get(network.netId, false); + final boolean changed = (lastValue != newValue) || lastValues.indexOfKey(network.netId) < 0; + if (changed) { + lastValues.put(network.netId, newValue); + } + return changed; + } + private final NetworkCallback mNetworkCallback = new NetworkCallback() { @Override public void onCapabilitiesChanged(Network network, @@ -1025,13 +1041,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (network == null || networkCapabilities == null) return; synchronized (mNetworkPoliciesSecondLock) { - final boolean oldMetered = mNetworkMetered.get(network.netId, false); final boolean newMetered = !networkCapabilities .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); + final boolean meteredChanged = updateCapabilityChange( + mNetworkMetered, newMetered, network); + + final boolean newRoaming = !networkCapabilities + .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); + final boolean roamingChanged = updateCapabilityChange( + mNetworkRoaming, newRoaming, network); - if ((oldMetered != newMetered) || mNetworkMetered.indexOfKey(network.netId) < 0) { + if (meteredChanged || roamingChanged) { mLogger.meterednessChanged(network.netId, newMetered); - mNetworkMetered.put(network.netId, newMetered); updateNetworkRulesNL(); } } @@ -1770,18 +1791,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long quotaBytes; final long limitBytes = plan.getDataLimitBytes(); - if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) { + if (!state.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)) { + // Clamp to 0 when roaming + quotaBytes = 0; + } else if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) { quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN; } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) { // Unlimited data; let's use 20MiB/day (600MiB/month) quotaBytes = quotaUnlimited; } else { // Limited data; let's only use 10% of remaining budget - final Pair<ZonedDateTime, ZonedDateTime> cycle = plan.cycleIterator().next(); - final long start = cycle.first.toInstant().toEpochMilli(); - final long end = cycle.second.toInstant().toEpochMilli(); + final Range<ZonedDateTime> cycle = plan.cycleIterator().next(); + final long start = cycle.getLower().toInstant().toEpochMilli(); + final long end = cycle.getUpper().toInstant().toEpochMilli(); final Instant now = mClock.instant(); - final long startOfDay = ZonedDateTime.ofInstant(now, cycle.first.getZone()) + final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone()) .truncatedTo(ChronoUnit.DAYS) .toInstant().toEpochMilli(); final long totalBytes = getTotalBytes( diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java index 2ef754e2ba6a..ab525237db5c 100644 --- a/services/core/java/com/android/server/net/NetworkStatsCollection.java +++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java @@ -47,7 +47,7 @@ import android.util.ArrayMap; import android.util.AtomicFile; import android.util.IntArray; import android.util.MathUtils; -import android.util.Pair; +import android.util.Range; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -266,11 +266,11 @@ public class NetworkStatsCollection implements FileRotator.Reader { long collectEnd = end; if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) { - final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = augmentPlan.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = augmentPlan.cycleIterator(); while (it.hasNext()) { - final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next(); - final long cycleStart = cycle.first.toInstant().toEpochMilli(); - final long cycleEnd = cycle.second.toInstant().toEpochMilli(); + final Range<ZonedDateTime> cycle = it.next(); + final long cycleStart = cycle.getLower().toInstant().toEpochMilli(); + final long cycleEnd = cycle.getUpper().toInstant().toEpochMilli(); if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) { augmentStart = cycleStart; collectStart = Long.min(collectStart, augmentStart); diff --git a/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java index 17c5868a53f7..766d8ca8a47c 100644 --- a/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java +++ b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java @@ -91,7 +91,7 @@ class NetworkWatchlistShellCommand extends ShellCommand { final long ident = Binder.clearCallingIdentity(); try { // Reset last report time - if (!WatchlistConfig.getInstance().isConfigSecure()) { + if (WatchlistConfig.getInstance().isConfigSecure()) { pw.println("Error: Cannot force generate report under production config"); return -1; } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 586abc16fe34..156f70259938 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -32,6 +32,7 @@ import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.database.ContentObserver; +import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManagerInternal; @@ -1198,8 +1199,6 @@ public class ZenModeHelper { @VisibleForTesting protected Notification createZenUpgradeNotification() { - Intent intent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); final Bundle extras = new Bundle(); extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, mContext.getResources().getString(R.string.global_action_settings)); @@ -1210,15 +1209,20 @@ public class ZenModeHelper { title = R.string.zen_upgrade_notification_visd_title; content = R.string.zen_upgrade_notification_visd_content; } + Intent onboardingIntent = new Intent(Settings.ZEN_MODE_ONBOARDING); + onboardingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); return new Notification.Builder(mContext, SystemNotificationChannels.DO_NOT_DISTURB) + .setAutoCancel(true) .setSmallIcon(R.drawable.ic_settings_24dp) + .setLargeIcon(Icon.createWithResource(mContext, R.drawable.ic_zen_24dp)) .setContentTitle(mContext.getResources().getString(title)) .setContentText(mContext.getResources().getString(content)) + .setContentIntent(PendingIntent.getActivity(mContext, 0, onboardingIntent, + PendingIntent.FLAG_UPDATE_CURRENT)) .setAutoCancel(true) .setLocalOnly(true) .addExtras(extras) .setStyle(new Notification.BigTextStyle()) - .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0, null)) .build(); } diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java index bc9fa4b7e32b..dbf0940fb4f5 100644 --- a/services/core/java/com/android/server/pm/InstantAppResolver.java +++ b/services/core/java/com/android/server/pm/InstantAppResolver.java @@ -256,8 +256,6 @@ public abstract class InstantAppResolver { int flags = origIntent.getFlags(); final Intent intent = new Intent(); intent.setFlags(flags - | Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); if (token != null) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 26d4037b4656..5b45cbe1f658 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -5305,7 +5305,7 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mPackages) { final String[] packageNames = getPackagesForUid(uid); final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0) - ? mPackages.get(packageNames[0]) + ? mSettings.getPackageLPr(packageNames[0]).getPackage() : null; return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid()); } @@ -8071,7 +8071,6 @@ 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) @@ -8142,7 +8141,7 @@ public class PackageManagerService extends IPackageManager.Stub } private boolean isCallerSameApp(String packageName, int uid) { - PackageParser.Package pkg = mPackages.get(packageName); + PackageParser.Package pkg = mSettings.getPackageLPr(packageName).getPackage(); return pkg != null && UserHandle.getAppId(uid) == pkg.applicationInfo.uid; } @@ -23625,6 +23624,13 @@ 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 f5b52fc486ea..065133b01b6d 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -212,12 +212,11 @@ public class PermissionManagerService { return PackageManager.PERMISSION_DENIED; } - final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName); - if (pkg != null && pkg.mExtras != null) { - if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) { + final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(pkgName); + if (ps != null && ps.getPackage() != null) { + if (mPackageManagerInt.filterAppAccess(ps.getPackage(), 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/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index 1575694dc825..165a409028d6 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -113,63 +113,73 @@ public class AppWindowContainerController mListener.onWindowsGone(); }; - private final Runnable mAddStartingWindow = () -> { - final StartingData startingData; - final AppWindowToken container; + private final Runnable mAddStartingWindow = new Runnable() { - synchronized (mWindowMap) { - if (mContainer == null) { - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to" - + " add starting window"); - return; - } - startingData = mContainer.startingData; - container = mContainer; - } + @Override + public void run() { + final StartingData startingData; + final AppWindowToken container; + + synchronized (mWindowMap) { + if (mContainer == null) { + if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to" + + " add starting window"); + return; + } - if (startingData == null) { - // Animation has been canceled... do nothing. - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "startingData was nulled out before handling" - + " mAddStartingWindow: " + mContainer); - return; - } + // There can only be one adding request, silly caller! + mService.mAnimationHandler.removeCallbacks(this); - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting " - + this + ": startingData=" + container.startingData); + startingData = mContainer.startingData; + container = mContainer; + } - StartingSurface surface = null; - try { - surface = startingData.createStartingSurface(container); - } catch (Exception e) { - Slog.w(TAG_WM, "Exception when adding starting window", e); - } - if (surface != null) { - boolean abort = false; - synchronized(mWindowMap) { - // If the window was successfully added, then - // we need to remove it. - if (container.removed || container.startingData == null) { - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, - "Aborted starting " + container - + ": removed=" + container.removed - + " startingData=" + container.startingData); - container.startingWindow = null; - container.startingData = null; - abort = true; - } else { - container.startingSurface = surface; - } - if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG_WM, - "Added starting " + mContainer - + ": startingWindow=" - + container.startingWindow + " startingView=" - + container.startingSurface); + if (startingData == null) { + // Animation has been canceled... do nothing. + if (DEBUG_STARTING_WINDOW) + Slog.v(TAG_WM, "startingData was nulled out before handling" + + " mAddStartingWindow: " + mContainer); + return; } - if (abort) { - surface.remove(); + + if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting " + + AppWindowContainerController.this + ": startingData=" + + container.startingData); + + StartingSurface surface = null; + try { + surface = startingData.createStartingSurface(container); + } catch (Exception e) { + Slog.w(TAG_WM, "Exception when adding starting window", e); + } + if (surface != null) { + boolean abort = false; + synchronized (mWindowMap) { + // If the window was successfully added, then + // we need to remove it. + if (container.removed || container.startingData == null) { + if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, + "Aborted starting " + container + + ": removed=" + container.removed + + " startingData=" + container.startingData); + container.startingWindow = null; + container.startingData = null; + abort = true; + } else { + container.startingSurface = surface; + } + if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG_WM, + "Added starting " + mContainer + + ": startingWindow=" + + container.startingWindow + " startingView=" + + container.startingSurface); + } + if (abort) { + surface.remove(); + } + } else if (DEBUG_STARTING_WINDOW) { + Slog.v(TAG_WM, "Surface returned was null: " + mContainer); } - } else if (DEBUG_STARTING_WINDOW) { - Slog.v(TAG_WM, "Surface returned was null: " + mContainer); } }; @@ -558,8 +568,10 @@ public class AppWindowContainerController // Note: we really want to do sendMessageAtFrontOfQueue() because we // want to process the message ASAP, before any other queued // messages. - if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING"); - mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow); + if (!mService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) { + if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING"); + mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow); + } } private boolean createSnapshot(TaskSnapshot snapshot) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index fa7eff261409..2b5620c1bbb0 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1243,6 +1243,10 @@ public class WindowManagerService extends IWindowManager.Stub Slog.w(TAG_WM, "Attempted to add window with exiting application token " + token + ". Aborting."); return WindowManagerGlobal.ADD_APP_EXITING; + } else if (type == TYPE_APPLICATION_STARTING && atoken.startingWindow != null) { + Slog.w(TAG_WM, "Attempted to add starting window to token with already existing" + + " starting window"); + return WindowManagerGlobal.ADD_DUPLICATE_ADD; } } else if (rootType == TYPE_INPUT_METHOD) { if (token.windowType != TYPE_INPUT_METHOD) { @@ -1930,7 +1934,15 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.setOpaqueLocked(false); } - boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0; + final int oldVisibility = win.mViewVisibility; + + // If the window is becoming visible, visibleOrAdding may change which may in turn + // change the IME target. + final boolean becameVisible = + (oldVisibility == View.INVISIBLE || oldVisibility == View.GONE) + && viewVisibility == View.VISIBLE; + boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0 + || becameVisible; final boolean isDefaultDisplay = win.isDefaultDisplay(); boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) @@ -1946,7 +1958,6 @@ public class WindowManagerService extends IWindowManager.Stub win.mRelayoutCalled = true; win.mInRelayout = true; - final int oldVisibility = win.mViewVisibility; win.mViewVisibility = viewVisibility; if (DEBUG_SCREEN_ON) { RuntimeException stack = new RuntimeException(); diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml index 0ec16b523a1b..8f989df23b1b 100644 --- a/services/tests/servicestests/AndroidTest.xml +++ b/services/tests/servicestests/AndroidTest.xml @@ -28,5 +28,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.servicestests" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index d908b8e29146..cecc94b92d87 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -18,6 +18,7 @@ package com.android.server; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_WIFI; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; @@ -30,6 +31,7 @@ import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.TAG_ALL; import static android.net.NetworkTemplate.buildTemplateMobileAll; +import static android.net.NetworkTemplate.buildTemplateWifi; import static android.net.TrafficStats.MB_IN_BYTES; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED; @@ -43,6 +45,7 @@ import static android.text.format.Time.TIMEZONE_UTC; import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS; import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH; +import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN; import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT; import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED; import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID; @@ -65,6 +68,7 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -121,7 +125,7 @@ import android.text.TextUtils; import android.text.format.Time; import android.util.DataUnit; import android.util.Log; -import android.util.Pair; +import android.util.Range; import android.util.RecurrenceRule; import com.android.internal.telephony.PhoneConstants; @@ -201,7 +205,8 @@ public class NetworkPolicyManagerServiceTest { private static final int TEST_SUB_ID = 42; private static final int TEST_NET_ID = 24; - private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi(TEST_SSID); + private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID); + private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI); /** * Path on assets where files used by {@link NetPolicyXml} are located. @@ -221,6 +226,7 @@ public class NetworkPolicyManagerServiceTest { private @Mock IActivityManager mActivityManager; private @Mock INetworkManagementService mNetworkManager; private @Mock IConnectivityManager mConnManager; + private @Mock ConnectivityManager mConnectivityManager; private @Mock NotificationManager mNotifManager; private @Mock PackageManager mPackageManager; private @Mock IPackageManager mIpm; @@ -228,6 +234,9 @@ public class NetworkPolicyManagerServiceTest { private @Mock CarrierConfigManager mCarrierConfigManager; private @Mock TelephonyManager mTelephonyManager; + private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor = + ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class); + private ActivityManagerInternal mActivityManagerInternal; private NetworkStatsManagerInternal mStatsService; @@ -331,6 +340,8 @@ public class NetworkPolicyManagerServiceTest { return mTelephonyManager; case Context.NOTIFICATION_SERVICE: return mNotifManager; + case Context.CONNECTIVITY_SERVICE: + return mConnectivityManager; default: return super.getSystemService(name); } @@ -394,6 +405,8 @@ public class NetworkPolicyManagerServiceTest { .thenReturn(buildApplicationInfo(PKG_NAME_C)); when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true); when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true); + doNothing().when(mConnectivityManager) + .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture()); // Prepare NPMS. mService.systemReady(mService.networkScoreAndNetworkManagementServiceReady()); @@ -821,11 +834,11 @@ public class NetworkPolicyManagerServiceTest { private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) { RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime), ZoneId.systemDefault()); - final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = policy.cycleIterator(); + final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator(); while (it.hasNext()) { - final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next(); - if (cycle.first.toInstant().toEpochMilli() < currentTime) { - return cycle.first.toInstant().toEpochMilli(); + final Range<ZonedDateTime> cycle = it.next(); + if (cycle.getLower().toInstant().toEpochMilli() < currentTime) { + return cycle.getLower().toInstant().toEpochMilli(); } } throw new IllegalStateException( @@ -835,7 +848,7 @@ public class NetworkPolicyManagerServiceTest { private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) { RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime), ZoneId.systemDefault()); - return policy.cycleIterator().next().second.toInstant().toEpochMilli(); + return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli(); } @Test @@ -1015,10 +1028,8 @@ public class NetworkPolicyManagerServiceTest { mService.updateNetworks(); // Define simple data plan - final SubscriptionPlan plan = SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z")) - .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED) - .build(); + final SubscriptionPlan plan = buildMonthlyDataPlan( + ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800)); mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan }, mServiceContext.getOpPackageName()); @@ -1122,10 +1133,8 @@ public class NetworkPolicyManagerServiceTest { mService.updateNetworks(); // Define simple data plan which gives us effectively 60MB/day - final SubscriptionPlan plan = SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z")) - .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED) - .build(); + final SubscriptionPlan plan = buildMonthlyDataPlan( + ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800)); mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan }, mServiceContext.getOpPackageName()); @@ -1497,21 +1506,13 @@ public class NetworkPolicyManagerServiceTest { final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1)); final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0); when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong())) - .thenAnswer(new Answer<Long>() { - @Override - public Long answer(InvocationOnMock invocation) throws Throwable { - final NetworkStatsHistory.Entry entry = history.getValues( - invocation.getArgument(1), invocation.getArgument(2), null); - return entry.rxBytes + entry.txBytes; - } + .thenAnswer(invocation -> { + final NetworkStatsHistory.Entry entry = history.getValues( + invocation.getArgument(1), invocation.getArgument(2), null); + return entry.rxBytes + entry.txBytes; }); when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong())) - .thenAnswer(new Answer<NetworkStats>() { - @Override - public NetworkStats answer(InvocationOnMock invocation) throws Throwable { - return stats; - } - }); + .thenReturn(stats); // Get active mobile network in place expectMobileDefaults(); @@ -1535,17 +1536,18 @@ public class NetworkPolicyManagerServiceTest { mService.updateNetworks(); // No quotas - assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS)); - assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH)); + assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN, + internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS)); + assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN, + internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH)); } // Limited data plan { - final SubscriptionPlan plan = SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z")) - .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED) - .build(); - mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan }, + final SubscriptionPlan plan = buildMonthlyDataPlan( + ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), + DataUnit.MEGABYTES.toBytes(1800)); + mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan}, mServiceContext.getOpPackageName()); reset(mTelephonyManager, mNetworkManager, mNotifManager); @@ -1561,13 +1563,45 @@ public class NetworkPolicyManagerServiceTest { internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH)); } + // Limited data plan, over quota + { + final SubscriptionPlan plan = buildMonthlyDataPlan( + ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), + DataUnit.MEGABYTES.toBytes(100)); + mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan}, + mServiceContext.getOpPackageName()); + + reset(mTelephonyManager, mNetworkManager, mNotifManager); + expectMobileDefaults(); + + mService.updateNetworks(); + + assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS)); + assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH)); + } + + // Roaming + { + final SubscriptionPlan plan = buildMonthlyDataPlan( + ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED); + mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan}, + mServiceContext.getOpPackageName()); + + reset(mTelephonyManager, mNetworkManager, mNotifManager); + expectMobileDefaults(); + expectNetworkState(true /* roaming */); + + mService.updateNetworks(); + + assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS)); + assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH)); + } + // Unlimited data plan { - final SubscriptionPlan plan = SubscriptionPlan.Builder - .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z")) - .setDataLimit(BYTES_UNLIMITED, LIMIT_BEHAVIOR_DISABLED) - .build(); - mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan }, + final SubscriptionPlan plan = buildMonthlyDataPlan( + ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED); + mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan}, mServiceContext.getOpPackageName()); reset(mTelephonyManager, mNetworkManager, mNotifManager); @@ -1580,9 +1614,27 @@ public class NetworkPolicyManagerServiceTest { internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS)); assertEquals(DataUnit.MEBIBYTES.toBytes(10), internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH)); + + // Capabilities change to roaming + final ConnectivityManager.NetworkCallback callback = mNetworkCallbackCaptor.getValue(); + assertNotNull(callback); + expectNetworkState(true /* roaming */); + callback.onCapabilitiesChanged( + new Network(TEST_NET_ID), + buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */)); + + assertEquals(0, internal.getSubscriptionOpportunisticQuota( + new Network(TEST_NET_ID), NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH)); } } + private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) { + return SubscriptionPlan.Builder + .createRecurringMonthly(start) + .setDataLimit(limitBytes, LIMIT_BEHAVIOR_DISABLED) + .build(); + } + private ApplicationInfo buildApplicationInfo(String label) { final ApplicationInfo ai = new ApplicationInfo(); ai.nonLocalizedLabel = label; @@ -1602,9 +1654,12 @@ public class NetworkPolicyManagerServiceTest { return lp; } - private NetworkCapabilities buildNetworkCapabilities(int subId) { + private NetworkCapabilities buildNetworkCapabilities(int subId, boolean roaming) { final NetworkCapabilities nc = new NetworkCapabilities(); nc.addTransportType(TRANSPORT_CELLULAR); + if (!roaming) { + nc.addCapability(NET_CAPABILITY_NOT_ROAMING); + } nc.setNetworkSpecifier(new StringNetworkSpecifier(String.valueOf(subId))); return nc; } @@ -1658,18 +1713,22 @@ public class NetworkPolicyManagerServiceTest { hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED); } - private void expectMobileDefaults() throws Exception { - when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn( - new int[] { TEST_SUB_ID }); - when(mTelephonyManager.getSubscriberId(TEST_SUB_ID)).thenReturn(TEST_IMSI); + private void expectNetworkState(boolean roaming) throws Exception { when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] { new NetworkState(buildNetworkInfo(), buildLinkProperties(TEST_IFACE), - buildNetworkCapabilities(TEST_SUB_ID), + buildNetworkCapabilities(TEST_SUB_ID, roaming), new Network(TEST_NET_ID), TEST_IMSI, null) }); } + private void expectMobileDefaults() throws Exception { + when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn( + new int[] { TEST_SUB_ID }); + when(mTelephonyManager.getSubscriberId(TEST_SUB_ID)).thenReturn(TEST_IMSI); + expectNetworkState(false /* roaming */); + } + private void verifyAdvisePersistThreshold() throws Exception { verify(mStatsService).advisePersistThreshold(anyLong()); } diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java index 1192114109a9..592f7b16470f 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java @@ -39,6 +39,7 @@ import static org.mockito.Mockito.spy; import static java.lang.Integer.MAX_VALUE; +import android.annotation.TestApi; import android.app.ActivityManager; import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager.RunningTaskInfo; @@ -594,6 +595,23 @@ public class RecentTasksTest extends ActivityTestsBase { } @Test + public void testRemovePackageByName() throws Exception { + // Add a number of tasks with the same package name + mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".Task1").build()); + mRecentTasks.add(createTaskBuilder("com.android.pkg2", ".Task2").build()); + mRecentTasks.add(createTaskBuilder("com.android.pkg3", ".Task3").build()); + mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".Task4").build()); + mRecentTasks.removeTasksByPackageName("com.android.pkg1", TEST_USER_0_ID); + + final ArrayList<TaskRecord> tasks = mRecentTasks.getRawTasks(); + for (int i = 0; i < tasks.size(); i++) { + if (tasks.get(i).intent.getComponent().getPackageName().equals("com.android.pkg1")) { + fail("Expected com.android.pkg1 tasks to be removed"); + } + } + } + + @Test public void testNotRecentsComponent_denyApiAccess() throws Exception { doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(), anyInt(), anyInt()); @@ -694,8 +712,12 @@ public class RecentTasksTest extends ActivityTestsBase { } private TaskBuilder createTaskBuilder(String className) { + return createTaskBuilder(mContext.getPackageName(), className); + } + + private TaskBuilder createTaskBuilder(String packageName, String className) { return new TaskBuilder(mService.mStackSupervisor) - .setComponent(new ComponentName(mContext.getPackageName(), className)) + .setComponent(new ComponentName(packageName, className)) .setStack(mStack) .setTaskId(LAST_TASK_ID++) .setUserId(TEST_USER_0_ID); diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index 2f2afd71706c..ceee60c017e5 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -17,12 +17,15 @@ package com.android.server.display; import android.content.Context; +import android.hardware.display.BrightnessConfiguration; +import android.hardware.display.Curve; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayViewport; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.input.InputManagerInternal; import android.os.Handler; import android.os.IBinder; +import android.os.UserHandle; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.view.SurfaceControl; @@ -226,6 +229,62 @@ public class DisplayManagerServiceTest extends AndroidTestCase { + " virtual display adapter"); } + /** + * Tests that an exception is raised for too dark a brightness configuration. + */ + public void testTooDarkBrightnessConfigurationThrowException() { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal(); + float[] lux = minimumBrightnessCurve.getX(); + float[] minimumNits = minimumBrightnessCurve.getY(); + float[] nits = new float[minimumNits.length]; + // For every control point, assert that making it slightly lower than the minimum throws an + // exception. + for (int i = 0; i < nits.length; i++) { + for (int j = 0; j < nits.length; j++) { + nits[j] = minimumNits[j]; + if (j == i) { + nits[j] -= 0.1f; + } + if (nits[j] < 0) { + nits[j] = 0; + } + } + BrightnessConfiguration config = + new BrightnessConfiguration.Builder(lux, nits).build(); + Exception thrown = null; + try { + displayManager.validateBrightnessConfiguration(config); + } catch (IllegalArgumentException e) { + thrown = e; + } + assertNotNull("Building too dark a brightness configuration must throw an exception"); + } + } + + /** + * Tests that no exception is raised for not too dark a brightness configuration. + */ + public void testBrightEnoughBrightnessConfigurationDoesNotThrowException() { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal(); + float[] lux = minimumBrightnessCurve.getX(); + float[] nits = minimumBrightnessCurve.getY(); + BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits).build(); + displayManager.validateBrightnessConfiguration(config); + } + + /** + * Tests that null brightness configurations are alright. + */ + public void testNullBrightnessConfiguration() { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + displayManager.validateBrightnessConfiguration(null); + } + private void registerDefaultDisplays(DisplayManagerService displayManager) { Handler handler = displayManager.getDisplayHandler(); // Would prefer to call displayManager.onStart() directly here but it performs binderService diff --git a/services/tests/uiservicestests/AndroidTest.xml b/services/tests/uiservicestests/AndroidTest.xml index d3b9d4a72ab8..11e8f090a8fa 100644 --- a/services/tests/uiservicestests/AndroidTest.xml +++ b/services/tests/uiservicestests/AndroidTest.xml @@ -24,5 +24,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.tests.uiservices" /> <option name="runner" value="android.testing.TestableInstrumentation" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 3acc2773afb5..d02a983c2c9d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -201,12 +201,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { AudioAttributes.USAGE_MEDIA); verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, AudioAttributes.USAGE_GAME); + verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, + AudioAttributes.USAGE_UNKNOWN); // Alarms only will silence system noises (but not vibrations) verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO); - verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, - AudioAttributes.USAGE_UNKNOWN); } @Test diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 754fe687344a..a9389bea2452 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -477,6 +477,9 @@ public class SubscriptionManager { * <p> * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription * the user is interested in. + * <p> + * Receivers should protect themselves by checking that the sender holds the + * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @SystemApi @@ -1719,6 +1722,8 @@ public class SubscriptionManager { * </ul> * * @param subId the subscriber this relationship applies to + * @throws SecurityException if the caller doesn't meet the requirements + * outlined above. */ @SystemApi public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) { @@ -1744,10 +1749,13 @@ public class SubscriptionManager { * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. * </ul> * - * @param subId the subscriber this relationship applies to + * @param subId the subscriber this relationship applies to. An empty list + * may be sent to clear any existing plans. * @param plans the list of plans. The first plan is always the primary and * most important plan. Any additional plans are secondary and * may not be displayed or used by decision making logic. + * @throws SecurityException if the caller doesn't meet the requirements + * outlined above. */ @SystemApi public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) { @@ -1788,6 +1796,8 @@ public class SubscriptionManager { * be automatically cleared, or {@code 0} to leave in the * requested state until explicitly cleared, or the next reboot, * whichever happens first. + * @throws SecurityException if the caller doesn't meet the requirements + * outlined above. */ @SystemApi public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @@ -1822,6 +1832,8 @@ public class SubscriptionManager { * be automatically cleared, or {@code 0} to leave in the * requested state until explicitly cleared, or the next reboot, * whichever happens first. + * @throws SecurityException if the caller doesn't meet the requirements + * outlined above. */ @SystemApi public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java index 4ffb70ba04a8..ef2a364f5a34 100644 --- a/telephony/java/android/telephony/SubscriptionPlan.java +++ b/telephony/java/android/telephony/SubscriptionPlan.java @@ -24,7 +24,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import android.util.Pair; +import android.util.Range; import android.util.RecurrenceRule; import com.android.internal.util.Preconditions; @@ -209,7 +209,7 @@ public final class SubscriptionPlan implements Parcelable { * any recurrence rules. The iterator starts from the currently active cycle * and walks backwards through time. */ - public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() { + public Iterator<Range<ZonedDateTime>> cycleIterator() { return cycleRule.cycleIterator(); } @@ -227,6 +227,9 @@ public final class SubscriptionPlan implements Parcelable { /** * Start defining a {@link SubscriptionPlan} that covers a very specific * window of time, and never automatically recurs. + * + * @param start The exact time at which the plan starts. + * @param end The exact time at which the plan ends. */ public static Builder createNonrecurring(ZonedDateTime start, ZonedDateTime end) { if (!end.isAfter(start)) { @@ -237,28 +240,40 @@ public final class SubscriptionPlan implements Parcelable { } /** - * Start defining a {@link SubscriptionPlan} that will recur - * automatically every month. It will always recur on the same day of a - * particular month. When a particular month ends before the defined - * recurrence day, the plan will recur on the last instant of that - * month. + * Start defining a {@link SubscriptionPlan} that starts at a specific + * time, and automatically recurs after each specific period of time, + * repeating indefinitely. + * <p> + * When the given period is set to exactly one month, the plan will + * always recur on the day of the month defined by + * {@link ZonedDateTime#getDayOfMonth()}. When a particular month ends + * before this day, the plan will recur on the last possible instant of + * that month. + * + * @param start The exact time at which the plan starts. + * @param period The period after which the plan automatically recurs. */ + public static Builder createRecurring(ZonedDateTime start, Period period) { + return new Builder(start, null, period); + } + + /** {@hide} */ + @SystemApi + @Deprecated public static Builder createRecurringMonthly(ZonedDateTime start) { return new Builder(start, null, Period.ofMonths(1)); } - /** - * Start defining a {@link SubscriptionPlan} that will recur - * automatically every week. - */ + /** {@hide} */ + @SystemApi + @Deprecated public static Builder createRecurringWeekly(ZonedDateTime start) { return new Builder(start, null, Period.ofDays(7)); } - /** - * Start defining a {@link SubscriptionPlan} that will recur - * automatically every day. - */ + /** {@hide} */ + @SystemApi + @Deprecated public static Builder createRecurringDaily(ZonedDateTime start) { return new Builder(start, null, Period.ofDays(1)); } diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java index 2f52c0ac2d99..dfb6e2cef42f 100644 --- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java +++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java @@ -77,6 +77,11 @@ public final class ImsFeatureConfiguration implements Parcelable { result = 31 * result + featureType; return result; } + + @Override + public String toString() { + return "{s=" + slotId + ", f=" + featureType + "}"; + } } /** diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 03fc84d87b05..7e8b2de4bc2a 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -829,6 +829,16 @@ interface ITelephony { boolean isResolvingImsBinding(); /** + * @return true if the ImsService to bind to for the slot id specified was set, false otherwise. + */ + boolean setImsService(int slotId, boolean isCarrierImsService, String packageName); + + /** + * @return the package name of the carrier/device ImsService associated with this slot. + */ + String getImsService(int slotId, boolean isCarrierImsService); + + /** * Set the network selection mode to automatic. * * @param subId the id of the subscription to update. diff --git a/tests/DexLoggerIntegrationTests/AndroidTest.xml b/tests/DexLoggerIntegrationTests/AndroidTest.xml index 8ed19f893476..fb1bef6da08a 100644 --- a/tests/DexLoggerIntegrationTests/AndroidTest.xml +++ b/tests/DexLoggerIntegrationTests/AndroidTest.xml @@ -25,5 +25,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest"> <option name="package" value="com.android.frameworks.dexloggertest"/> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/tests/UsbTests/AndroidTest.xml b/tests/UsbTests/AndroidTest.xml index 0b623fbf2015..4affad39b4eb 100644 --- a/tests/UsbTests/AndroidTest.xml +++ b/tests/UsbTests/AndroidTest.xml @@ -25,5 +25,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest"> <option name="package" value="com.android.server.usb"/> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/> + <option name="hidden-api-checks" value="false"/> </test> -</configuration>
\ No newline at end of file +</configuration> diff --git a/tests/net/AndroidTest.xml b/tests/net/AndroidTest.xml index f8ecc6b80cce..6e020a3daa2b 100644 --- a/tests/net/AndroidTest.xml +++ b/tests/net/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.tests.net" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index b0e11c4e8b48..482d6e1fdb31 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -161,6 +161,7 @@ import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -879,6 +880,10 @@ public class ConnectivityServiceTest { return mMetricsService; } + @Override + protected void registerNetdEventCallback() { + } + public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() { return mLastCreatedNetworkMonitor; } @@ -3777,6 +3782,11 @@ public class ConnectivityServiceTest { // The default on Android is opportunistic mode ("Automatic"). setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); + final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); + final NetworkRequest cellRequest = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_CELLULAR).build(); + mCm.requestNetwork(cellRequest, cellNetworkCallback); + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); waitForIdle(); // CS tells netd about the empty DNS config for this network. @@ -3812,6 +3822,14 @@ public class ConnectivityServiceTest { assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); reset(mNetworkManagementService); + cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent); + cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, + mCellNetworkAgent); + CallbackInfo cbi = cellNetworkCallback.expectCallback( + CallbackState.LINK_PROPERTIES, mCellNetworkAgent); + cellNetworkCallback.assertNoCallback(); + assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive()); + assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName()); setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork( @@ -3821,6 +3839,7 @@ public class ConnectivityServiceTest { assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); reset(mNetworkManagementService); + cellNetworkCallback.assertNoCallback(); setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( @@ -3833,8 +3852,112 @@ public class ConnectivityServiceTest { assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); reset(mNetworkManagementService); + cellNetworkCallback.assertNoCallback(); - // Can't test strict mode without properly mocking out the DNS lookups. + setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); + // Can't test dns configuration for strict mode without properly mocking + // out the DNS lookups, but can test that LinkProperties is updated. + cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, + mCellNetworkAgent); + cellNetworkCallback.assertNoCallback(); + assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive()); + assertEquals("strict.example.com", ((LinkProperties)cbi.arg).getPrivateDnsServerName()); + } + + @Test + public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception { + // The default on Android is opportunistic mode ("Automatic"). + setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); + + final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); + final NetworkRequest cellRequest = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_CELLULAR).build(); + mCm.requestNetwork(cellRequest, cellNetworkCallback); + + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + waitForIdle(); + LinkProperties lp = new LinkProperties(); + mCellNetworkAgent.sendLinkProperties(lp); + mCellNetworkAgent.connect(false); + waitForIdle(); + cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent); + cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, + mCellNetworkAgent); + CallbackInfo cbi = cellNetworkCallback.expectCallback( + CallbackState.LINK_PROPERTIES, mCellNetworkAgent); + cellNetworkCallback.assertNoCallback(); + assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive()); + assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName()); + Set<InetAddress> dnsServers = new HashSet<>(); + checkDnsServers(cbi.arg, dnsServers); + + // Send a validation event for a server that is not part of the current + // resolver config. The validation event should be ignored. + mService.mNetdEventCallback.onPrivateDnsValidationEvent( + mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", true); + cellNetworkCallback.assertNoCallback(); + + // Add a dns server to the LinkProperties. + LinkProperties lp2 = new LinkProperties(lp); + lp2.addDnsServer(InetAddress.getByName("145.100.185.16")); + mCellNetworkAgent.sendLinkProperties(lp2); + cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, + mCellNetworkAgent); + cellNetworkCallback.assertNoCallback(); + assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive()); + assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName()); + dnsServers.add(InetAddress.getByName("145.100.185.16")); + checkDnsServers(cbi.arg, dnsServers); + + // Send a validation event containing a hostname that is not part of + // the current resolver config. The validation event should be ignored. + mService.mNetdEventCallback.onPrivateDnsValidationEvent( + mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", true); + cellNetworkCallback.assertNoCallback(); + + // Send a validation event where validation failed. + mService.mNetdEventCallback.onPrivateDnsValidationEvent( + mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false); + cellNetworkCallback.assertNoCallback(); + + // Send a validation event where validation succeeded for a server in + // the current resolver config. A LinkProperties callback with updated + // private dns fields should be sent. + mService.mNetdEventCallback.onPrivateDnsValidationEvent( + mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true); + cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, + mCellNetworkAgent); + cellNetworkCallback.assertNoCallback(); + assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive()); + assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName()); + checkDnsServers(cbi.arg, dnsServers); + + // The private dns fields in LinkProperties should be preserved when + // the network agent sends unrelated changes. + LinkProperties lp3 = new LinkProperties(lp2); + lp3.setMtu(1300); + mCellNetworkAgent.sendLinkProperties(lp3); + cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, + mCellNetworkAgent); + cellNetworkCallback.assertNoCallback(); + assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive()); + assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName()); + checkDnsServers(cbi.arg, dnsServers); + assertEquals(1300, ((LinkProperties)cbi.arg).getMtu()); + + // Removing the only validated server should affect the private dns + // fields in LinkProperties. + LinkProperties lp4 = new LinkProperties(lp3); + lp4.removeDnsServer(InetAddress.getByName("145.100.185.16")); + mCellNetworkAgent.sendLinkProperties(lp4); + cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, + mCellNetworkAgent); + cellNetworkCallback.assertNoCallback(); + assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive()); + assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName()); + dnsServers.remove(InetAddress.getByName("145.100.185.16")); + checkDnsServers(cbi.arg, dnsServers); + assertEquals(1300, ((LinkProperties)cbi.arg).getMtu()); } private void checkDirectlyConnectedRoutes(Object callbackObj, @@ -3854,6 +3977,13 @@ public class ConnectivityServiceTest { assertTrue(observedRoutes.containsAll(expectedRoutes)); } + private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) { + assertTrue(callbackObj instanceof LinkProperties); + LinkProperties lp = (LinkProperties) callbackObj; + assertEquals(dnsServers.size(), lp.getDnsServers().size()); + assertTrue(lp.getDnsServers().containsAll(dnsServers)); + } + private static <T> void assertEmpty(T[] ts) { int length = ts.length; assertEquals("expected empty array, but length was " + length, 0, length); diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java new file mode 100644 index 000000000000..bcd8bf3df7ce --- /dev/null +++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.connectivity; + +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.net.LinkProperties; +import android.net.Network; +import android.os.INetworkManagementService; +import android.provider.Settings; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.test.mock.MockContentResolver; + +import com.android.internal.util.test.FakeSettingsProvider; +import com.android.server.connectivity.MockableSystemProperties; + +import java.net.InetAddress; + +import org.junit.runner.RunWith; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Tests for {@link DnsManager}. + * + * Build, install and run with: + * runtest frameworks-net -c com.android.server.connectivity.DnsManagerTest + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class DnsManagerTest { + static final int TEST_NETID = 100; + static final int TEST_NETID_ALTERNATE = 101; + static final int TEST_NETID_UNTRACKED = 102; + final boolean IS_DEFAULT = true; + final boolean NOT_DEFAULT = false; + + DnsManager mDnsManager; + MockContentResolver mContentResolver; + + @Mock Context mCtx; + @Mock INetworkManagementService mNMService; + @Mock MockableSystemProperties mSystemProperties; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContentResolver = new MockContentResolver(); + mContentResolver.addProvider(Settings.AUTHORITY, + new FakeSettingsProvider()); + when(mCtx.getContentResolver()).thenReturn(mContentResolver); + mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties); + + // Clear the private DNS settings + Settings.Global.putString(mContentResolver, + Settings.Global.PRIVATE_DNS_MODE, ""); + Settings.Global.putString(mContentResolver, + Settings.Global.PRIVATE_DNS_SPECIFIER, ""); + } + + @Test + public void testTrackedValidationUpdates() throws Exception { + mDnsManager.updatePrivateDns(new Network(TEST_NETID), + mDnsManager.getPrivateDnsConfig()); + mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE), + mDnsManager.getPrivateDnsConfig()); + LinkProperties lp = new LinkProperties(); + lp.addDnsServer(InetAddress.getByName("3.3.3.3")); + lp.addDnsServer(InetAddress.getByName("4.4.4.4")); + + // Send a validation event that is tracked on the alternate netId + mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); + mDnsManager.setDnsConfigurationForNetwork(TEST_NETID_ALTERNATE, lp, NOT_DEFAULT); + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE, + InetAddress.parseNumericAddress("4.4.4.4"), "", true)); + LinkProperties fixedLp = new LinkProperties(lp); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); + assertFalse(fixedLp.isPrivateDnsActive()); + assertNull(fixedLp.getPrivateDnsServerName()); + fixedLp = new LinkProperties(lp); + mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp); + assertTrue(fixedLp.isPrivateDnsActive()); + assertNull(fixedLp.getPrivateDnsServerName()); + + // Switch to strict mode + Settings.Global.putString(mContentResolver, + Settings.Global.PRIVATE_DNS_MODE, + PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); + Settings.Global.putString(mContentResolver, + Settings.Global.PRIVATE_DNS_SPECIFIER, "strictmode.com"); + mDnsManager.updatePrivateDns(new Network(TEST_NETID), + mDnsManager.getPrivateDnsConfig()); + mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); + fixedLp = new LinkProperties(lp); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); + assertTrue(fixedLp.isPrivateDnsActive()); + assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName()); + fixedLp = new LinkProperties(lp); + } + + @Test + public void testIgnoreUntrackedValidationUpdates() throws Exception { + // The PrivateDnsConfig map is empty, so no validation events will + // be tracked. + LinkProperties lp = new LinkProperties(); + lp.addDnsServer(InetAddress.getByName("3.3.3.3")); + mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, + InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); + assertFalse(lp.isPrivateDnsActive()); + assertNull(lp.getPrivateDnsServerName()); + + // Validation event has untracked netId + mDnsManager.updatePrivateDns(new Network(TEST_NETID), + mDnsManager.getPrivateDnsConfig()); + mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED, + InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); + assertFalse(lp.isPrivateDnsActive()); + assertNull(lp.getPrivateDnsServerName()); + + // Validation event has untracked ipAddress + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, + InetAddress.parseNumericAddress("4.4.4.4"), "", true)); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); + assertFalse(lp.isPrivateDnsActive()); + assertNull(lp.getPrivateDnsServerName()); + + // Validation event has untracked hostname + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, + InetAddress.parseNumericAddress("3.3.3.3"), "hostname", + true)); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); + assertFalse(lp.isPrivateDnsActive()); + assertNull(lp.getPrivateDnsServerName()); + + // Validation event failed + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, + InetAddress.parseNumericAddress("3.3.3.3"), "", false)); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); + assertFalse(lp.isPrivateDnsActive()); + assertNull(lp.getPrivateDnsServerName()); + + // Network removed + mDnsManager.removeNetwork(new Network(TEST_NETID)); + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, + InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); + assertFalse(lp.isPrivateDnsActive()); + assertNull(lp.getPrivateDnsServerName()); + + // Turn private DNS mode off + Settings.Global.putString(mContentResolver, + Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF); + mDnsManager.updatePrivateDns(new Network(TEST_NETID), + mDnsManager.getPrivateDnsConfig()); + mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); + mDnsManager.updatePrivateDnsValidation( + new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, + InetAddress.parseNumericAddress("3.3.3.3"), "", true)); + mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); + assertFalse(lp.isPrivateDnsActive()); + assertNull(lp.getPrivateDnsServerName()); + } +} diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml index 764eb2b94327..45c7a1708d20 100644 --- a/wifi/tests/AndroidTest.xml +++ b/wifi/tests/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.net.wifi.test" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> |