Merge "Update mobile data QS tile subtext." into pi-dev
diff --git a/api/current.txt b/api/current.txt
index 2572cd3..423e0ae 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27627,6 +27627,7 @@
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 @@
}
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 @@
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 76a71cd..6186a55 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1255,6 +1255,7 @@
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 @@
}
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 @@
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 a40ea08..73d1102 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -153,6 +153,8 @@
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/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;->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/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/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/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;->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/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/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;->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(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;->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/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;->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/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;->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/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;->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;->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_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;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;->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;->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;->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;->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;->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;->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;->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;->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;->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/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;->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;->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/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;->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;->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/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$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 5113fd0..757fc64 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1338,6 +1338,32 @@
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 37360ba..49cc498 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -37,6 +37,7 @@
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 @@
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 a25513d..132d43f 100644
--- a/core/java/android/content/QuickViewConstants.java
+++ b/core/java/android/content/QuickViewConstants.java
@@ -45,8 +45,8 @@
* 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 49b1efd..c5a39f4 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -26,6 +26,7 @@
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 @@
@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 @@
* @hide
*/
public @HiddenApiEnforcementPolicy int getHiddenApiEnforcementPolicy() {
- if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) {
- return mHiddenApiPolicy;
- }
if (isAllowedToUseHiddenApis()) {
return HIDDEN_API_ENFORCEMENT_NONE;
}
- return HIDDEN_API_ENFORCEMENT_BLACK;
+ if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) {
+ return mHiddenApiPolicy;
+ }
+ if (targetSdkVersion <= Build.VERSION_CODES.O_MR1) {
+ return HIDDEN_API_ENFORCEMENT_BLACK;
+ } else {
+ return HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK;
+ }
}
/**
@@ -1706,6 +1712,31 @@
}
/**
+ * 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 33e77d2..34e3d8b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6131,7 +6131,9 @@
* 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 @@
}
/**
- * 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 a9d0911..699e81b 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -521,6 +521,11 @@
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 67e97bf..6d9ba77 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -86,7 +86,9 @@
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 @@
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 0000000..796493e
--- /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 0000000..ac28fdd
--- /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 efb9517..b182fa2 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -28,6 +28,7 @@
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 @@
}
/**
+ * 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 2d0ef2f..d968a3e 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -31,6 +31,7 @@
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 @@
}
/**
+ * 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 b77de748..b575997 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -19,6 +19,7 @@
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 @@
// 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 1a28732..e84c85e 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -19,7 +19,7 @@
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 @@
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 bf6b7e0..6546c39 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -31,6 +31,7 @@
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 @@
}
/** {@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 b00cb48..321f971 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -26,6 +26,8 @@
* @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 @@
// 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 e0fa63a..f9b6dfc 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -21,7 +21,6 @@
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 @@
/**
* 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 9114107..d493cce 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 @@
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 @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 50d73ce..c7c2c15 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1179,6 +1179,23 @@
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 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 @@
SHOW_BATTERY_PERCENT,
NOTIFICATION_VIBRATION_INTENSITY,
HAPTIC_FEEDBACK_INTENSITY,
+ DISPLAY_COLOR_MODE
};
/**
@@ -4204,6 +4225,7 @@
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 @@
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 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 @@
"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 ad3b4b6..de86a66 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -40,6 +40,10 @@
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 @@
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 @@
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 9f115eb..975ad48 100644
--- a/core/java/android/util/RecurrenceRule.java
+++ b/core/java/android/util/RecurrenceRule.java
@@ -158,7 +158,7 @@
&& 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 @@
}
}
- private class NonrecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
+ private class NonrecurringIterator implements Iterator<Range<ZonedDateTime>> {
boolean hasNext;
public NonrecurringIterator() {
@@ -179,13 +179,13 @@
}
@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 @@
}
@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 da15506..c5ab2e6 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 0000000..790bfb9
--- /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 aceba08..fe34d98 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 7048511..0fe80a1 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 4ce89c9..fc030ca 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 715be5b..1798d45 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 ce7f1ff..b6f0b70 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 fd6cc95..92b2f33 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -210,6 +210,7 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 @@
<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 7b5ad9a..68ef34b 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 bad0d25..5ef30a8 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 @@
};
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 cb3509c..a5941b2 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -60,7 +60,6 @@
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 @@
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 04d2dad..c02d97c 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.runner.RunWith;
import java.util.Locale;
-import java.util.Set;
@Presubmit
@SmallTest
@@ -104,6 +105,27 @@
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 @@
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 42b6048..39d492d 100644
--- a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
+++ b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
@@ -57,13 +57,13 @@
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 @@
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 @@
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 @@
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 @@
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 8098c14..a3e785c 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 270d773..f32acb4 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 985a756..7d4e6f8 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -456,6 +456,22 @@
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 @@
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 0c5b7cc..bb6547b 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 0458931..9152ff2 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -250,9 +250,10 @@
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 @@
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 b4ca88c..ed2afdd 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -809,7 +809,11 @@
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 940d364..f84131c 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 15dd64b..d21a2e4 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 96621eb..d7ee618 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 3a156895..46b8f94 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 bd37712c..e592d82 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 18301a8..02be457 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 a65ff16..708f595 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 9ff16a2..d568d0d 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 b0488ae..4ba6c06 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 99bd23c..91ba026 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 a65ff16..708f595 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 e4ea08e..b5d48b4 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 0e92c60..d45c427 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 20d1418..78b1b2614 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 @@
}
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 6fa7db3..32e4bbf 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 @@
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 @@
}
/**
- * @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;
+ return null;
}
-
- 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 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 c1cff9e..adb2460 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -107,6 +107,13 @@
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 75c52d8..7cc37c4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -205,6 +205,13 @@
}
});
+ 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 651831e..174dcab 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -157,6 +157,13 @@
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 0ba26e9..c01cafa 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -25,6 +25,7 @@
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 @@
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 7161463..101c790 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 @@
private View mStatusBarBackground;
private int mSideMargins;
+ private boolean mQsDisabled;
public QSContainerImpl(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -96,6 +99,16 @@
@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 @@
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 3f3cea2..6c7eda7 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 @@
*/
@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 0fa6597..cf549fa 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.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.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 @@
}
@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 018a635..cb068e3 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 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 @@
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 @@
}
}
+ @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 @@
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 @@
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 70bfad1..e2af90d 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 @@
* 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 @@
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 @@
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 @@
@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 75bc9558..30e9afd8 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 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 @@
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 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 b81e9af..29c2edc 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.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 @@
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 a93be00..6238526 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 @@
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 e248db4..ec243fe 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 @@
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 2c335a3..cc143bb 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 @@
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 @@
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 @@
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 @@
setOrAdaptCurrentAnimation(mScrimBehind);
setOrAdaptCurrentAnimation(mScrimInFront);
+
+ mScrimBehindAlphaListener.accept(mScrimBehind.getViewAlpha());
}
}
@@ -478,7 +484,7 @@
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 @@
}
}
- // 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 9c5cf306..0072dc0 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 @@
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 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 @@
@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 @@
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 baeaaad..9aa8044 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.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.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 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 @@
} finally {
a.recycle();
}
+ mCurrentUserTracker = new CurrentUserTracker(context) {
+ @Override
+ public void onUserSwitched(int newUserId) {
+ mCurrentUserId = newUserId;
+ }
+ };
}
@Override
@@ -141,6 +150,8 @@
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 @@
if (mShowDark) {
Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
}
+ mCurrentUserTracker.stopTracking();
}
}
@@ -302,7 +314,7 @@
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 @@
} 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 53839a9b..fc353a1 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 d86e947..658ac73 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 @@
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 82129a1..0416232 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.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 @@
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 @@
@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 @@
}
@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 @@
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 b6ac3fb..446c0a1 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4779,7 +4779,7 @@
// 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 @@
// 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 59cb135..6463bed 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.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.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.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 @@
private INetworkStatsService mStatsService;
private INetworkPolicyManager mPolicyManager;
private NetworkPolicyManagerInternal mPolicyManagerInternal;
+ private IIpConnectivityMetrics mIpConnectivityMetrics;
private String mCurrentTcpBufferSizes;
@@ -414,6 +419,9 @@
// 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 @@
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 @@
void systemReady() {
loadGlobalProxy();
+ registerNetdEventCallback();
synchronized (this) {
mSystemReady = true;
@@ -2288,6 +2332,9 @@
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
handlePerNetworkPrivateDnsConfig(nai, cfg);
+ if (networkRequiresValidation(nai)) {
+ handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
+ }
}
}
@@ -2312,6 +2359,15 @@
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 @@
case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
handlePrivateDnsSettingsChanged();
break;
+ case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
+ handlePrivateDnsValidationUpdate(
+ (PrivateDnsValidationUpdate) msg.obj);
+ break;
}
}
}
@@ -4575,6 +4635,11 @@
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 75bad46..04d54e1 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.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.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 @@
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 @@
final ActivityManagerConstants mConstants;
// Encapsulates the global setting "hidden_api_blacklist_exemptions"
- final HiddenApiBlacklist mHiddenApiBlacklist;
+ final HiddenApiSettings mHiddenApiBlacklist;
PackageManagerInternal mPackageManagerInt;
@@ -2884,17 +2893,19 @@
}
/**
- * 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 @@
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 @@
}
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 @@
}
};
- mHiddenApiBlacklist = new HiddenApiBlacklist(mHandler, mContext);
+ mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
@@ -4218,6 +4256,9 @@
}
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 @@
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 @@
* 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 @@
&& !(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 365c436..2b988d3 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 @@
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 a294334..b6e414a2 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 @@
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 2a361a0..7aaac06 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.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.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 @@
*/
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 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 @@
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 void removeNetwork(Network network) {
mPrivateDnsMap.remove(network.netId);
+ mPrivateDnsValidationMap.remove(network.netId);
}
public PrivateDnsConfig updatePrivateDns(Network network, PrivateDnsConfig cfg) {
@@ -223,6 +308,40 @@
: 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 @@
//
// 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 @@
: 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 3868ea6..906a6a3 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.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 @@
}
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 @@
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 bfd34ac..f403953 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 @@
}
public int getAutomaticScreenBrightness() {
+ if (!mAmbientLuxValid) {
+ return -1;
+ }
if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) {
return (int) (mScreenAutoBrightness * mDozeScaleFactor);
}
@@ -346,6 +349,7 @@
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 93e0bd5..0f531a8 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.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.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 @@
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 @@
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 @@
}
}
+ @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 @@
}
}
+ @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 @@
}
}
+ 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 @@
}
}
+ @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 88b2a36..0700ab3 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 @@
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 @@
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 @@
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 @@
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 1782ae5..8e77373 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_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.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 @@
@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 @@
}
};
+ 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 @@
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);
- if ((oldMetered != newMetered) || mNetworkMetered.indexOfKey(network.netId) < 0) {
+ final boolean newRoaming = !networkCapabilities
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
+ final boolean roamingChanged = updateCapabilityChange(
+ mNetworkRoaming, newRoaming, network);
+
+ if (meteredChanged || roamingChanged) {
mLogger.meterednessChanged(network.netId, newMetered);
- mNetworkMetered.put(network.netId, newMetered);
updateNetworkRulesNL();
}
}
@@ -1770,18 +1791,21 @@
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 2ef754e..ab52523 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.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 @@
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 17c5868..766d8ca 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 @@
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 586abc1..156f702 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.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 @@
@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 @@
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 bc9fa4b..dbf0940 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 @@
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 26d4037..5b45cbe 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 @@
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 @@
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 @@
}
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 @@
}
@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 f5b52fc..065133b 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 @@
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 1575694..165a409 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 @@
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");
+ @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;
+ }
+
+ // There can only be one adding request, silly caller!
+ mService.mAnimationHandler.removeCallbacks(this);
+
+ startingData = mContainer.startingData;
+ container = mContainer;
+ }
+
+ 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;
}
- startingData = mContainer.startingData;
- container = mContainer;
- }
- 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 (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting "
+ + AppWindowContainerController.this + ": startingData="
+ + container.startingData);
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting "
- + 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;
+ 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 (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);
}
- if (abort) {
- surface.remove();
- }
- } else if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG_WM, "Surface returned was null: " + mContainer);
}
};
@@ -558,8 +568,10 @@
// 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 fa7eff2..2b5620c 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 @@
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 @@
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 @@
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 0ec16b5..8f989df 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 d908b8e..cecc94b 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 @@
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.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 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.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.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 @@
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 @@
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 @@
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 @@
return mTelephonyManager;
case Context.NOTIFICATION_SERVICE:
return mNotifManager;
+ case Context.CONNECTIVITY_SERVICE:
+ return mConnectivityManager;
default:
return super.getSystemService(name);
}
@@ -394,6 +405,8 @@
.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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,16 +1713,20 @@
hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
}
+ private void expectNetworkState(boolean roaming) throws Exception {
+ when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
+ new NetworkState(buildNetworkInfo(),
+ buildLinkProperties(TEST_IFACE),
+ 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);
- when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
- new NetworkState(buildNetworkInfo(),
- buildLinkProperties(TEST_IFACE),
- buildNetworkCapabilities(TEST_SUB_ID),
- new Network(TEST_NET_ID), TEST_IMSI, null)
- });
+ expectNetworkState(false /* roaming */);
}
private void verifyAdvisePersistThreshold() throws Exception {
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 1192114..592f7b1 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 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 @@
}
@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 @@
}
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 2f2afd7..ceee60c 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 @@
+ " 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 d3b9d4a..11e8f09 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 3acc277..d02a983 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 @@
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 754fe68..a9389be 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -477,6 +477,9 @@
* <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 @@
* </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 @@
* {@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 @@
* 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 @@
* 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 4ffb70b..ef2a364 100644
--- a/telephony/java/android/telephony/SubscriptionPlan.java
+++ b/telephony/java/android/telephony/SubscriptionPlan.java
@@ -24,7 +24,7 @@
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 @@
* 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 @@
/**
* 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 @@
}
/**
- * 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 2f52c0a..dfb6e2c 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -77,6 +77,11 @@
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 03fc84d..7e8b2de 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -829,6 +829,16 @@
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 8ed19f8..fb1bef6 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 0b623fb..4affad3 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 f8ecc6b..6e020a3 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 b0e11c4..482d6e1 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.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 @@
return mMetricsService;
}
+ @Override
+ protected void registerNetdEventCallback() {
+ }
+
public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
return mLastCreatedNetworkMonitor;
}
@@ -3777,6 +3782,11 @@
// 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 @@
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 @@
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 @@
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 @@
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 0000000..bcd8bf3
--- /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 764eb2b..45c7a17 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>