Merge "Return a boolean from the mandatory backup transport setter." into pi-dev
diff --git a/api/current.txt b/api/current.txt
index eb73c6f..6a9f00e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7193,6 +7193,7 @@
field public static final deprecated java.lang.String EXTRA_SLIDER_VALUE = "android.app.slice.extra.SLIDER_VALUE";
field public static final java.lang.String EXTRA_TOGGLE_STATE = "android.app.slice.extra.TOGGLE_STATE";
field public static final java.lang.String HINT_ACTIONS = "actions";
+ field public static final java.lang.String HINT_ERROR = "error";
field public static final java.lang.String HINT_HORIZONTAL = "horizontal";
field public static final java.lang.String HINT_KEY_WORDS = "key_words";
field public static final java.lang.String HINT_LARGE = "large";
@@ -7218,29 +7219,22 @@
}
public static class Slice.Builder {
- ctor public Slice.Builder(android.net.Uri);
+ ctor public deprecated Slice.Builder(android.net.Uri);
+ ctor public Slice.Builder(android.net.Uri, android.app.slice.SliceSpec);
ctor public Slice.Builder(android.app.slice.Slice.Builder);
- method public android.app.slice.Slice.Builder addAction(android.app.PendingIntent, android.app.slice.Slice);
method public android.app.slice.Slice.Builder addAction(android.app.PendingIntent, android.app.slice.Slice, java.lang.String);
- method public android.app.slice.Slice.Builder addBundle(android.os.Bundle, java.lang.String, java.lang.String...);
method public android.app.slice.Slice.Builder addBundle(android.os.Bundle, java.lang.String, java.util.List<java.lang.String>);
- method public android.app.slice.Slice.Builder addHints(java.lang.String...);
method public android.app.slice.Slice.Builder addHints(java.util.List<java.lang.String>);
- method public android.app.slice.Slice.Builder addIcon(android.graphics.drawable.Icon, java.lang.String, java.lang.String...);
method public android.app.slice.Slice.Builder addIcon(android.graphics.drawable.Icon, java.lang.String, java.util.List<java.lang.String>);
- method public android.app.slice.Slice.Builder addInt(int, java.lang.String, java.lang.String...);
method public android.app.slice.Slice.Builder addInt(int, java.lang.String, java.util.List<java.lang.String>);
+ method public android.app.slice.Slice.Builder addLong(long, java.lang.String, java.util.List<java.lang.String>);
method public android.app.slice.Slice.Builder addRemoteInput(android.app.RemoteInput, java.lang.String, java.util.List<java.lang.String>);
- method public android.app.slice.Slice.Builder addRemoteInput(android.app.RemoteInput, java.lang.String, java.lang.String...);
- method public android.app.slice.Slice.Builder addSubSlice(android.app.slice.Slice);
method public android.app.slice.Slice.Builder addSubSlice(android.app.slice.Slice, java.lang.String);
- method public android.app.slice.Slice.Builder addText(java.lang.CharSequence, java.lang.String, java.lang.String...);
method public android.app.slice.Slice.Builder addText(java.lang.CharSequence, java.lang.String, java.util.List<java.lang.String>);
- method public android.app.slice.Slice.Builder addTimestamp(long, java.lang.String, java.lang.String...);
- method public android.app.slice.Slice.Builder addTimestamp(long, java.lang.String, java.util.List<java.lang.String>);
+ method public deprecated android.app.slice.Slice.Builder addTimestamp(long, java.lang.String, java.util.List<java.lang.String>);
method public android.app.slice.Slice build();
method public android.app.slice.Slice.Builder setCallerNeeded(boolean);
- method public android.app.slice.Slice.Builder setSpec(android.app.slice.SliceSpec);
+ method public deprecated android.app.slice.Slice.Builder setSpec(android.app.slice.SliceSpec);
}
public final class SliceItem implements android.os.Parcelable {
@@ -7263,10 +7257,11 @@
field public static final java.lang.String FORMAT_BUNDLE = "bundle";
field public static final java.lang.String FORMAT_IMAGE = "image";
field public static final java.lang.String FORMAT_INT = "int";
+ field public static final java.lang.String FORMAT_LONG = "long";
field public static final java.lang.String FORMAT_REMOTE_INPUT = "input";
field public static final java.lang.String FORMAT_SLICE = "slice";
field public static final java.lang.String FORMAT_TEXT = "text";
- field public static final java.lang.String FORMAT_TIMESTAMP = "timestamp";
+ field public static final deprecated java.lang.String FORMAT_TIMESTAMP = "long";
}
public class SliceManager {
@@ -51597,7 +51592,6 @@
field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
field public static final int RECORD_UNTIL_FULL = 0; // 0x0
- field public static final int RECORD_UNTIL_FULL_LARGE_BUFFER = 2; // 0x2
}
public static class TracingConfig.Builder {
diff --git a/api/system-current.txt b/api/system-current.txt
index a5be12f..1e2fe3d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -725,6 +725,8 @@
method public java.lang.String getNotificationChannelId();
field public static final int NOTIFICATION_INTERRUPTION = 12; // 0xc
field public static final int NOTIFICATION_SEEN = 10; // 0xa
+ field public static final int SLICE_PINNED = 14; // 0xe
+ field public static final int SLICE_PINNED_PRIV = 13; // 0xd
field public static final int SYSTEM_INTERACTION = 6; // 0x6
}
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0d70375..e238f06 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -20,8 +20,20 @@
Landroid/app/ActivityManager;->PROCESS_STATE_IMPORTANT_BACKGROUND:I
Landroid/app/ActivityManager;->PROCESS_STATE_TOP:I
Landroid/app/ActivityManager$RecentTaskInfo;->firstActiveTime:J
+Landroid/app/ActivityManager$RecentTaskInfo;->lastActiveTime:J
+Landroid/app/ActivityManager$RecentTaskInfo;->resizeMode:I
+Landroid/app/ActivityManager$RecentTaskInfo;->supportsSplitScreenMultiWindow:Z
+Landroid/app/ActivityManager$RecentTaskInfo;->userId:I
Landroid/app/ActivityManager$RunningAppProcessInfo;->flags:I
Landroid/app/ActivityManager$RunningAppProcessInfo;->processState:I
+Landroid/app/ActivityManager;->setPersistentVrThread(I)V
+Landroid/app/ActivityManager$TaskDescription;->getBackgroundColor()I
+Landroid/app/ActivityManager$TaskDescription;->getInMemoryIcon()Landroid/graphics/Bitmap;
+Landroid/app/ActivityManager$TaskSnapshot;->getContentInsets()Landroid/graphics/Rect;
+Landroid/app/ActivityManager$TaskSnapshot;->getOrientation()I
+Landroid/app/ActivityManager$TaskSnapshot;->getScale()F
+Landroid/app/ActivityManager$TaskSnapshot;->isRealSnapshot()Z
+Landroid/app/ActivityManager$TaskSnapshot;->isReducedResolution()Z
Landroid/app/Activity;->mApplication:Landroid/app/Application;
Landroid/app/Activity;->mComponent:Landroid/content/ComponentName;
Landroid/app/Activity;->mFragments:Landroid/app/FragmentController;
@@ -35,6 +47,7 @@
Landroid/app/Activity;->mToken:Landroid/os/IBinder;
Landroid/app/Activity;->mWindow:Landroid/view/Window;
Landroid/app/Activity;->mWindowManager:Landroid/view/WindowManager;
+Landroid/app/ActivityOptions;->makeMultiThumbFutureAspectScaleAnimation(Landroid/content/Context;Landroid/os/Handler;Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/app/ActivityOptions$OnAnimationStartedListener;Z)Landroid/app/ActivityOptions;
Landroid/app/Activity;->setDisablePreviewScreenshots(Z)V
Landroid/app/Activity;->setPersistent(Z)V
Landroid/app/ActivityThread$ActivityClientRecord;->activityInfo:Landroid/content/pm/ActivityInfo;
@@ -317,6 +330,13 @@
Landroid/app/usage/UsageStatsManager;->mService:Landroid/app/usage/IUsageStatsManager;
Landroid/app/usage/UsageStats;->mLastEvent:I
Landroid/app/usage/UsageStats;->mTotalTimeInForeground:J
+Landroid/app/Vr2dDisplayProperties$Builder;->build()Landroid/app/Vr2dDisplayProperties;
+Landroid/app/Vr2dDisplayProperties$Builder;-><init>()V
+Landroid/app/Vr2dDisplayProperties$Builder;->setEnabled(Z)Landroid/app/Vr2dDisplayProperties$Builder;
+Landroid/app/Vr2dDisplayProperties;-><init>(III)V
+Landroid/app/VrManager;->getPersistentVrModeEnabled()Z
+Landroid/app/VrManager;->registerVrStateCallback(Landroid/app/VrStateCallback;Landroid/os/Handler;)V
+Landroid/app/VrManager;->setVr2dDisplayProperties(Landroid/app/Vr2dDisplayProperties;)V
Landroid/app/WallpaperColors;->getColorHints()I
Landroid/app/WallpaperManager;->getBitmap()Landroid/graphics/Bitmap;
Landroid/app/WallpaperManager;->getBitmap(Z)Landroid/graphics/Bitmap;
@@ -564,6 +584,7 @@
Landroid/database/sqlite/SQLiteDebug$PagerStats;->pageCacheOverflow:I
Landroid/database/sqlite/SQLiteOpenHelper;->mName:Ljava/lang/String;
Landroid/ddm/DdmHandleAppName;->getAppName()Ljava/lang/String;
+Landroid/graphics/AvoidXfermode$Mode;->TARGET:Landroid/graphics/AvoidXfermode$Mode;
Landroid/graphics/BaseCanvas;->mNativeCanvasWrapper:J
Landroid/graphics/Bitmap$Config;->nativeInt:I
Landroid/graphics/Bitmap$Config;->nativeToConfig(I)Landroid/graphics/Bitmap$Config;
@@ -644,6 +665,7 @@
Landroid/graphics/fonts/FontVariationAxis;->mStyleValue:F
Landroid/graphics/fonts/FontVariationAxis;->mTag:I
Landroid/graphics/GraphicBuffer;->createFromExisting(IIIIJ)Landroid/graphics/GraphicBuffer;
+Landroid/graphics/GraphicBuffer;->CREATOR:Landroid/os/Parcelable$Creator;
Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
Landroid/graphics/GraphicBuffer;->mNativeObject:J
Landroid/graphics/ImageDecoder;-><init>(JIIZ)V
@@ -672,8 +694,13 @@
Landroid/graphics/Typeface;->setDefault(Landroid/graphics/Typeface;)V
Landroid/graphics/Typeface;->sSystemFontMap:Ljava/util/Map;
Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
+Landroid/hardware/camera2/CaptureResult;->STATISTICS_OIS_TIMESTAMPS:Landroid/hardware/camera2/CaptureResult$Key;
+Landroid/hardware/camera2/CaptureResult;->STATISTICS_OIS_X_SHIFTS:Landroid/hardware/camera2/CaptureResult$Key;
+Landroid/hardware/camera2/CaptureResult;->STATISTICS_OIS_Y_SHIFTS:Landroid/hardware/camera2/CaptureResult$Key;
Landroid/hardware/camera2/impl/CameraMetadataNative;->mMetadataPtr:J
Landroid/hardware/Camera;->addCallbackBuffer([BI)V
Landroid/hardware/Camera;->mNativeContext:J
@@ -893,6 +920,7 @@
Landroid/media/IAudioService;->setStreamVolume(IIILjava/lang/String;)V
Landroid/media/IAudioService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioService;
Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
Landroid/media/JetPlayer;->mNativePlayerInJavaObj:J
Landroid/media/JetPlayer;->postEventFromNative(Ljava/lang/Object;III)V
Landroid/media/MediaCodec$CodecException;-><init>(IILjava/lang/String;)V
@@ -1130,6 +1158,7 @@
Landroid/os/Binder;->execTransact(IJJI)Z
Landroid/os/Binder;->mObject:J
Landroid/os/Build;->getString(Ljava/lang/String;)Ljava/lang/String;
+Landroid/os/Build;->IS_DEBUGGABLE:Z
Landroid/os/Build$VERSION;->ACTIVE_CODENAMES:[Ljava/lang/String;
Landroid/os/Bundle;->getIBinder(Ljava/lang/String;)Landroid/os/IBinder;
Landroid/os/Bundle;->putIBinder(Ljava/lang/String;Landroid/os/IBinder;)V
@@ -1214,8 +1243,10 @@
Landroid/os/ParcelFileDescriptor;-><init>(Ljava/io/FileDescriptor;)V
Landroid/os/Parcel;->mNativePtr:J
Landroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
+Landroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;)Ljava/util/List;
Landroid/os/Parcel$ReadWriteHelper;-><init>()V
Landroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
+Landroid/os/Parcel;->writeParcelableList(Ljava/util/List;I)V
Landroid/os/PowerManager;->getDefaultScreenBrightnessSetting()I
Landroid/os/PowerManager;->getMaximumScreenBrightnessSetting()I
Landroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I
@@ -1677,6 +1708,7 @@
Landroid/service/notification/NotificationListenerService;->unregisterAsSystemService()V
Landroid/service/voice/AlwaysOnHotwordDetector$EventPayload;->getCaptureSession()Ljava/lang/Integer;
Landroid/service/voice/VoiceInteractionService;->isKeyphraseAndLocaleSupportedForHotword(Ljava/lang/String;Ljava/util/Locale;)Z
+Landroid/service/vr/IVrManager;->getVr2dDisplayId()I
Landroid/service/wallpaper/WallpaperService$Engine;->setFixedSizeAllowed(Z)V
Landroid/speech/tts/TextToSpeech;->getCurrentEngine()Ljava/lang/String;
Landroid/system/Int32Ref;->value:I
@@ -1967,9 +1999,11 @@
Landroid/view/inputmethod/InputMethodManager;->windowDismissed(Landroid/os/IBinder;)V
Landroid/view/inputmethod/InputMethodSubtypeArray;-><init>(Ljava/util/List;)V
Landroid/view/InputQueue;->finishInputEvent(JZ)V
+Landroid/view/IRecentsAnimationController;->setAnimationTargetsBehindSystemBars(Z)V
Landroid/view/IWindowManager;->getAnimationScale(I)F
Landroid/view/IWindowManager;->hasNavigationBar()Z
Landroid/view/IWindowManager;->setAnimationScale(IF)V
+Landroid/view/IWindowManager;->setShelfHeight(ZI)V
Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)V
Landroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
Landroid/view/IWindowManager$Stub$Proxy;->getBaseDisplayDensity(I)I
@@ -2017,6 +2051,18 @@
Landroid/view/PointerIcon;->mHotSpotX:F
Landroid/view/PointerIcon;->mHotSpotY:F
Landroid/view/PointerIcon;->mType:I
+Landroid/view/RemoteAnimationDefinition;->addRemoteAnimation(IILandroid/view/RemoteAnimationAdapter;)V
+Landroid/view/RemoteAnimationTarget;->clipRect:Landroid/graphics/Rect;
+Landroid/view/RemoteAnimationTarget;->contentInsets:Landroid/graphics/Rect;
+Landroid/view/RemoteAnimationTarget;->isNotInRecents:Z
+Landroid/view/RemoteAnimationTarget;->isTranslucent:Z
+Landroid/view/RemoteAnimationTarget;->leash:Landroid/view/SurfaceControl;
+Landroid/view/RemoteAnimationTarget;->mode:I
+Landroid/view/RemoteAnimationTarget;->position:Landroid/graphics/Point;
+Landroid/view/RemoteAnimationTarget;->prefixOrderIndex:I
+Landroid/view/RemoteAnimationTarget;->sourceContainerBounds:Landroid/graphics/Rect;
+Landroid/view/RemoteAnimationTarget;->taskId:I
+Landroid/view/RemoteAnimationTarget;->windowConfiguration:Landroid/app/WindowConfiguration;
Landroid/view/RenderNodeAnimator;->callOnFinished(Landroid/view/RenderNodeAnimator;)V
Landroid/view/ScaleGestureDetector;->mListener:Landroid/view/ScaleGestureDetector$OnScaleGestureListener;
Landroid/view/ScaleGestureDetector;->mMinSpan:I
@@ -2154,6 +2200,7 @@
Landroid/view/ViewRootImpl;->enqueueInputEvent(Landroid/view/InputEvent;)V
Landroid/view/ViewRootImpl;->invokeFunctor(JZ)V
Landroid/view/ViewRootImpl;->mStopped:Z
+Landroid/view/ViewRootImpl;->mSurface:Landroid/view/Surface;
Landroid/view/ViewRootImpl;->mView:Landroid/view/View;
Landroid/view/View$ScrollabilityCache;->scrollBar:Landroid/widget/ScrollBarDrawable;
Landroid/view/View;->setAlphaNoInvalidation(F)Z
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index 952b28b..fe9a5db 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -1,9 +1,24 @@
+Landroid/accounts/AccountManager;-><init>(Landroid/content/Context;Landroid/accounts/IAccountManager;Landroid/os/Handler;)V
+Landroid/app/Activity;->managedQuery(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
+Landroid/app/ActivityManagerNative;->broadcastStickyIntent(Landroid/content/Intent;Ljava/lang/String;I)V
Landroid/app/ActivityManager$RecentTaskInfo;->configuration:Landroid/content/res/Configuration;
Landroid/app/ActivityManager$TaskDescription;->loadTaskDescriptionIcon(Ljava/lang/String;I)Landroid/graphics/Bitmap;
Landroid/app/ActivityManager$TaskSnapshot;->getSnapshot()Landroid/graphics/GraphicBuffer;
Landroid/app/ActivityOptions;->makeRemoteAnimation(Landroid/view/RemoteAnimationAdapter;)Landroid/app/ActivityOptions;
Landroid/app/ActivityOptions;->setSplitScreenCreateMode(I)V
Landroid/app/Activity;->registerRemoteAnimations(Landroid/view/RemoteAnimationDefinition;)V
+Landroid/app/ActivityView;-><init>(Landroid/content/Context;)V
+Landroid/app/ActivityView;->release()V
+Landroid/app/ActivityView;->startActivity(Landroid/app/PendingIntent;)V
+Landroid/app/ActivityView;->startActivity(Landroid/content/Intent;)V
+Landroid/app/AppOpsManager;->getPackagesForOps([I)Ljava/util/List;
+Landroid/app/AppOpsManager;->getToken(Lcom/android/internal/app/IAppOpsService;)Landroid/os/IBinder;
+Landroid/app/AppOpsManager$OpEntry;->getOp()I
+Landroid/app/AppOpsManager$OpEntry;->getTime()J
+Landroid/app/AppOpsManager$OpEntry;->isRunning()Z
+Landroid/app/AppOpsManager$PackageOps;->getOps()Ljava/util/List;
+Landroid/app/AppOpsManager$PackageOps;->getPackageName()Ljava/lang/String;
+Landroid/app/AppOpsManager$PackageOps;->getUid()I
Landroid/app/IActivityController$Stub;-><init>()V
Landroid/app/IActivityManager;->cancelRecentsAnimation()V
Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
@@ -11,12 +26,18 @@
Landroid/app/IActivityManager;->getCurrentUser()Landroid/content/pm/UserInfo;
Landroid/app/IActivityManager;->getFilteredTasks(III)Ljava/util/List;
Landroid/app/IActivityManager;->getLockTaskModeState()I
+Landroid/app/IActivityManager;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
Landroid/app/IActivityManager;->getRecentTasks(III)Landroid/content/pm/ParceledListSlice;
+Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
Landroid/app/IActivityManager;->removeTask(I)Z
+Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
+Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
Landroid/app/IActivityManager;->startRecentsActivity(Landroid/content/Intent;Landroid/app/IAssistDataReceiver;Landroid/view/IRecentsAnimationRunner;)V
+Landroid/app/IAlarmManager;->setTime(J)Z
+Landroid/app/IAlarmManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IAlarmManager;
Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
Landroid/app/IAssistDataReceiver$Stub;-><init>()V
@@ -40,6 +61,8 @@
Landroid/app/VrStateCallback;-><init>()V
Landroid/app/VrStateCallback;->onPersistentVrStateChanged(Z)V
Landroid/app/WallpaperColors;-><init>(Landroid/graphics/Color;Landroid/graphics/Color;Landroid/graphics/Color;I)V
+Landroid/bluetooth/BluetoothHeadset;->phoneStateChanged(IIILjava/lang/String;I)V
+Landroid/bluetooth/IBluetooth;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V
Landroid/companion/AssociationRequest;->getDeviceFilters()Ljava/util/List;
Landroid/companion/AssociationRequest;->isSingleDevice()Z
Landroid/companion/BluetoothDeviceFilter;->getAddress()Ljava/lang/String;
@@ -53,19 +76,31 @@
Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V
Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
Landroid/companion/IFindDeviceCallback;->onSuccess(Landroid/app/PendingIntent;)V
+Landroid/content/ContentProvider;->attachInfoForTesting(Landroid/content/Context;Landroid/content/pm/ProviderInfo;)V
+Landroid/content/ContentProvider;->getIContentProvider()Landroid/content/IContentProvider;
+Landroid/content/ContentProvider;-><init>(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;[Landroid/content/pm/PathPermission;)V
+Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;I)V
+Landroid/content/ContentValues;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
+Landroid/content/ContentValues;->putStringArrayList(Ljava/lang/String;Ljava/util/ArrayList;)V
Landroid/content/Context;->getOpPackageName()Ljava/lang/String;
Landroid/content/Context;->registerReceiverAsUser(Landroid/content/BroadcastReceiver;Landroid/os/UserHandle;Landroid/content/IntentFilter;Ljava/lang/String;Landroid/os/Handler;)Landroid/content/Intent;
Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V
Landroid/content/Context;->startServiceAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)Landroid/content/ComponentName;
Landroid/content/ContextWrapper;->getThemeResId()I
+Landroid/content/Intent;->getExtra(Ljava/lang/String;)Ljava/lang/Object;
+Landroid/content/Intent;->getIBinderExtra(Ljava/lang/String;)Landroid/os/IBinder;
+Landroid/content/Intent;->resolveSystemService(Landroid/content/pm/PackageManager;I)Landroid/content/ComponentName;
Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
Landroid/content/pm/IPackageDeleteObserver;->packageDeleted(Ljava/lang/String;I)V
Landroid/content/pm/IPackageDeleteObserver$Stub;-><init>()V
Landroid/content/pm/IPackageManager;->getActivityInfo(Landroid/content/ComponentName;II)Landroid/content/pm/ActivityInfo;
+Landroid/content/pm/IPackageManager;->getApplicationInfo(Ljava/lang/String;II)Landroid/content/pm/ApplicationInfo;
Landroid/content/pm/IPackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
+Landroid/content/pm/IPackageManager;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
Landroid/database/sqlite/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
+Landroid/database/sqlite/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
Landroid/graphics/AvoidXfermode;-><init>(IILandroid/graphics/AvoidXfermode$Mode;)V
Landroid/graphics/Bitmap;->createGraphicBufferHandle()Landroid/graphics/GraphicBuffer;
Landroid/graphics/Bitmap;->createHardwareBitmap(Landroid/graphics/GraphicBuffer;)Landroid/graphics/Bitmap;
@@ -74,17 +109,25 @@
Landroid/graphics/drawable/Drawable;->isProjected()Z
Landroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
+Landroid/hardware/display/DisplayManagerGlobal;->getInstance()Landroid/hardware/display/DisplayManagerGlobal;
+Landroid/hardware/display/DisplayManagerGlobal;->getRealDisplay(I)Landroid/view/Display;
Landroid/hardware/location/GeofenceHardware;-><init>(Landroid/hardware/location/IGeofenceHardware;)V
Landroid/hardware/location/IActivityRecognitionHardwareClient;->onAvailabilityChanged(ZLandroid/hardware/location/IActivityRecognitionHardware;)V
Landroid/location/IFusedProvider;->onFusedLocationHardwareChange(Landroid/hardware/location/IFusedLocationHardware;)V
Landroid/location/IGeocodeProvider;->getFromLocation(DDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
Landroid/location/IGeocodeProvider;->getFromLocationName(Ljava/lang/String;DDDDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
Landroid/location/IGeofenceProvider;->setGeofenceHardware(Landroid/hardware/location/IGeofenceHardware;)V
+Landroid/location/ILocationManager;->getNetworkProviderPackage()Ljava/lang/String;
Landroid/location/ILocationManager;->reportLocation(Landroid/location/Location;Z)V
+Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
+Landroid/location/INetInitiatedListener$Stub;-><init>()V
+Landroid/location/Location;->setExtraLocation(Ljava/lang/String;Landroid/location/Location;)V
Landroid/media/AudioManager;->registerAudioPortUpdateListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
Landroid/media/AudioManager;->unregisterAudioPortUpdateListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
Landroid/media/AudioSystem;->checkAudioFlinger()I
+Landroid/media/AudioSystem;->getForceUse(I)I
Landroid/media/AudioSystem;->getParameters(Ljava/lang/String;)Ljava/lang/String;
+Landroid/media/AudioSystem;->setForceUse(II)I
Landroid/media/AudioSystem;->setParameters(Ljava/lang/String;)I
Landroid/media/MediaDrm$Certificate;->getContent()[B
Landroid/media/MediaDrm$Certificate;->getWrappedPrivateKey()[B
@@ -103,14 +146,18 @@
Landroid/media/tv/ITvRemoteServiceInput;->sendPointerSync(Landroid/os/IBinder;)V
Landroid/media/tv/ITvRemoteServiceInput;->sendPointerUp(Landroid/os/IBinder;I)V
Landroid/media/tv/ITvRemoteServiceInput;->sendTimestamp(Landroid/os/IBinder;J)V
+Landroid/net/ConnectivityManager;->getActiveNetworkQuotaInfo()Landroid/net/NetworkQuotaInfo;
Landroid/net/ConnectivityManager$PacketKeepaliveCallback;-><init>()V
Landroid/net/ConnectivityManager$PacketKeepaliveCallback;->onError(I)V
Landroid/net/ConnectivityManager$PacketKeepaliveCallback;->onStarted()V
Landroid/net/ConnectivityManager$PacketKeepaliveCallback;->onStopped()V
Landroid/net/ConnectivityManager$PacketKeepalive;->stop()V
+Landroid/net/ConnectivityManager;->setAirplaneMode(Z)V
Landroid/net/ConnectivityManager;->startNattKeepalive(Landroid/net/Network;ILandroid/net/ConnectivityManager$PacketKeepaliveCallback;Ljava/net/InetAddress;ILjava/net/InetAddress;)Landroid/net/ConnectivityManager$PacketKeepalive;
Landroid/net/ConnectivityManager;->startUsingNetworkFeature(ILjava/lang/String;)I
Landroid/net/ConnectivityManager;->stopUsingNetworkFeature(ILjava/lang/String;)I
+Landroid/net/ConnectivityManager;->tether(Ljava/lang/String;)I
+Landroid/net/ConnectivityManager;->untether(Ljava/lang/String;)I
Landroid/net/DhcpResults;-><init>(Landroid/net/DhcpResults;)V
Landroid/net/DhcpResults;-><init>(Landroid/net/StaticIpConfiguration;)V
Landroid/net/DhcpResults;-><init>()V
@@ -138,6 +185,8 @@
Landroid/net/LinkProperties;->addStackedLink(Landroid/net/LinkProperties;)Z
Landroid/net/LinkProperties;->clear()V
Landroid/net/LinkProperties;->compareProvisioning(Landroid/net/LinkProperties;Landroid/net/LinkProperties;)Landroid/net/LinkProperties$ProvisioningChange;
+Landroid/net/LinkProperties;->getAllInterfaceNames()Ljava/util/List;
+Landroid/net/LinkProperties;->getAllRoutes()Ljava/util/List;
Landroid/net/LinkProperties;->getMtu()I
Landroid/net/LinkProperties;->getStackedLinks()Ljava/util/List;
Landroid/net/LinkProperties;->hasGlobalIPv6Address()Z
@@ -226,12 +275,23 @@
Landroid/net/NetworkCapabilities;->hasSignalStrength()Z
Landroid/net/NetworkCapabilities;->transportNamesOf([I)Ljava/lang/String;
Landroid/net/Network;-><init>(I)V
+Landroid/net/Network;->netId:I
Landroid/net/NetworkQuotaInfo;->getEstimatedBytes()J
Landroid/net/NetworkQuotaInfo;->getHardLimitBytes()J
Landroid/net/NetworkQuotaInfo;->getSoftLimitBytes()J
Landroid/net/NetworkRequest$Builder;->setSignalStrength(I)Landroid/net/NetworkRequest$Builder;
+Landroid/net/NetworkRequest;->networkCapabilities:Landroid/net/NetworkCapabilities;
+Landroid/net/NetworkState;->network:Landroid/net/Network;
Landroid/net/NetworkStats;->combineValues(Landroid/net/NetworkStats$Entry;)Landroid/net/NetworkStats;
+Landroid/net/NetworkStats$Entry;->iface:Ljava/lang/String;
Landroid/net/NetworkStats$Entry;-><init>()V
+Landroid/net/NetworkStats$Entry;->rxBytes:J
+Landroid/net/NetworkStats$Entry;->rxPackets:J
+Landroid/net/NetworkStats$Entry;->set:I
+Landroid/net/NetworkStats$Entry;->tag:I
+Landroid/net/NetworkStats$Entry;->txBytes:J
+Landroid/net/NetworkStats$Entry;->txPackets:J
+Landroid/net/NetworkStats$Entry;->uid:I
Landroid/net/NetworkStatsHistory$Entry;->txBytes:J
Landroid/net/NetworkStatsHistory;->getStart()J
Landroid/net/NetworkStatsHistory;->getValues(JJLandroid/net/NetworkStatsHistory$Entry;)Landroid/net/NetworkStatsHistory$Entry;
@@ -245,7 +305,10 @@
Landroid/net/NetworkUtils;->protectFromVpn(Ljava/io/FileDescriptor;)Z
Landroid/net/RouteInfo;->hasGateway()Z
Landroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;Ljava/net/InetAddress;Ljava/lang/String;)V
+Landroid/net/RouteInfo;->selectBestRoute(Ljava/util/Collection;Ljava/net/InetAddress;)Landroid/net/RouteInfo;
Landroid/net/SntpClient;->getNtpTime()J
+Landroid/net/SntpClient;->getNtpTimeReference()J
+Landroid/net/SntpClient;->getRoundTripTime()J
Landroid/net/SntpClient;->requestTime(Ljava/lang/String;I)Z
Landroid/net/StaticIpConfiguration;->dnsServers:Ljava/util/ArrayList;
Landroid/net/StaticIpConfiguration;->domains:Ljava/lang/String;
@@ -268,27 +331,36 @@
Landroid/os/BatteryStats$HistoryItem;-><init>()V
Landroid/os/BatteryStats$HistoryItem;->states:I
Landroid/os/BatteryStats$HistoryItem;->time:J
+Landroid/os/BatteryStats$Timer;->getCountLocked(I)I
Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
Landroid/os/BatteryStats$Uid;-><init>()V
Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
+Landroid/os/Broadcaster;->broadcast(Landroid/os/Message;)V
+Landroid/os/Broadcaster;->cancelRequest(ILandroid/os/Handler;I)V
+Landroid/os/Broadcaster;-><init>()V
+Landroid/os/Broadcaster;->request(ILandroid/os/Handler;I)V
+Landroid/os/Environment;->getLegacyExternalStorageDirectory()Ljava/io/File;
Landroid/os/Handler;->getMain()Landroid/os/Handler;
Landroid/os/Handler;-><init>(Landroid/os/Looper;Landroid/os/Handler$Callback;Z)V
Landroid/os/HwBinder;->reportSyspropChanged()V
Landroid/os/INetworkManagementService;->clearInterfaceAddresses(Ljava/lang/String;)V
Landroid/os/INetworkManagementService;->disableIpv6(Ljava/lang/String;)V
Landroid/os/INetworkManagementService;->enableIpv6(Ljava/lang/String;)V
+Landroid/os/INetworkManagementService;->isBandwidthControlEnabled()Z
Landroid/os/INetworkManagementService;->registerObserver(Landroid/net/INetworkManagementEventObserver;)V
Landroid/os/INetworkManagementService;->setInterfaceConfig(Ljava/lang/String;Landroid/net/InterfaceConfiguration;)V
Landroid/os/INetworkManagementService;->setInterfaceIpv6PrivacyExtensions(Ljava/lang/String;Z)V
Landroid/os/INetworkManagementService;->setIPv6AddrGenMode(Ljava/lang/String;I)V
Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
Landroid/os/INetworkManagementService;->unregisterObserver(Landroid/net/INetworkManagementEventObserver;)V
+Landroid/os/IPowerManager;->goToSleep(JII)V
Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
Landroid/os/IRemoteCallback$Stub;-><init>()V
Landroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
Landroid/os/Parcel;->readBlob()[B
Landroid/os/Parcel;->readStringArray()[Ljava/lang/String;
Landroid/os/Parcel;->writeBlob([B)V
+Landroid/os/PowerManager;->goToSleep(J)V
Landroid/os/PowerManager;->isScreenBrightnessBoosted()Z
Landroid/os/Registrant;->clear()V
Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
@@ -303,10 +375,35 @@
Landroid/os/Registrant;->notifyRegistrant()V
Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException;
Landroid/os/ServiceSpecificException;->errorCode:I
+Landroid/os/storage/DiskInfo;->getId()Ljava/lang/String;
+Landroid/os/storage/StorageEventListener;-><init>()V
+Landroid/os/storage/StorageManager;->findVolumeById(Ljava/lang/String;)Landroid/os/storage/VolumeInfo;
+Landroid/os/storage/StorageManager;->from(Landroid/content/Context;)Landroid/os/storage/StorageManager;
+Landroid/os/storage/StorageManager;->registerListener(Landroid/os/storage/StorageEventListener;)V
+Landroid/os/storage/StorageManager;->unregisterListener(Landroid/os/storage/StorageEventListener;)V
+Landroid/os/storage/StorageVolume;->getId()Ljava/lang/String;
+Landroid/os/storage/VolumeInfo;->getId()Ljava/lang/String;
Landroid/os/SystemProperties;->reportSyspropChanged()V
+Landroid/os/SystemService;->start(Ljava/lang/String;)V
+Landroid/os/SystemService;->stop(Ljava/lang/String;)V
+Landroid/os/SystemVibrator;-><init>()V
+Landroid/os/UserHandle;->isSameApp(II)Z
+Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
+Landroid/os/UserManager;->isAdminUser()Z
Landroid/print/PrintDocumentAdapter$LayoutResultCallback;-><init>()V
Landroid/print/PrintDocumentAdapter$WriteResultCallback;-><init>()V
Landroid/provider/CalendarContract$Events;->PROVIDER_WRITABLE_COLUMNS:[Ljava/lang/String;
+Landroid/provider/ContactsContract$CommonDataKinds$Phone;->getDisplayLabel(Landroid/content/Context;ILjava/lang/CharSequence;)Ljava/lang/CharSequence;
+Landroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+Landroid/provider/Settings$Secure;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+Landroid/provider/Telephony$Mms;->isEmailAddress(Ljava/lang/String;)Z
+Landroid/provider/Telephony$Sms$Draft;->addMessage(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;)Landroid/net/Uri;
+Landroid/provider/Telephony$Sms$Outbox;->addMessage(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZJ)Landroid/net/Uri;
+Landroid/R$styleable;->CheckBoxPreference:[I
+Landroid/service/dreams/DreamService;->canDoze()Z
+Landroid/service/dreams/DreamService;->isDozing()Z
+Landroid/service/dreams/DreamService;->startDozing()V
+Landroid/service/dreams/DreamService;->stopDozing()V
Landroid/service/vr/VrListenerService;->onCurrentVrActivityChanged(Landroid/content/ComponentName;ZI)V
Landroid/system/NetlinkSocketAddress;-><init>(II)V
Landroid/system/Os;->bind(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V
@@ -316,6 +413,11 @@
Landroid/system/Os;->setsockoptTimeval(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V
Landroid/system/PacketSocketAddress;-><init>(I[B)V
Landroid/system/PacketSocketAddress;-><init>(SI)V
+Landroid/telecom/ParcelableCall;->CREATOR:Landroid/os/Parcelable$Creator;
+Landroid/telecom/ParcelableCall;->getConnectTimeMillis()J
+Landroid/telecom/ParcelableCall;->getDisconnectCause()Landroid/telecom/DisconnectCause;
+Landroid/telecom/ParcelableCall;->getHandle()Landroid/net/Uri;
+Landroid/telecom/ParcelableCall;->getId()Ljava/lang/String;
Landroid/telecom/TelecomManager;->from(Landroid/content/Context;)Landroid/telecom/TelecomManager;
Landroid/telecom/VideoProfile$CameraCapabilities;-><init>(IIZF)V
Landroid/telephony/ims/compat/feature/MMTelFeature;-><init>()V
@@ -329,6 +431,14 @@
Landroid/telephony/ims/ImsReasonInfo;-><init>(IILjava/lang/String;)V
Landroid/telephony/ims/ImsReasonInfo;-><init>(II)V
Landroid/telephony/ims/ImsStreamMediaProfile;-><init>()V
+Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
+Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->getPlaybackUri(ILjava/lang/String;)Landroid/net/Uri;
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->initialize(Landroid/telephony/mbms/IMbmsStreamingSessionCallback;I)I
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->requestUpdateStreamingServices(ILjava/util/List;)I
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->startStreaming(ILjava/lang/String;Landroid/telephony/mbms/IStreamingServiceCallback;)I
+Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
+Landroid/telephony/PhoneNumberUtils;->formatNumber(Ljava/lang/String;I)Ljava/lang/String;
Landroid/telephony/PhoneNumberUtils;->isEmergencyNumber(ILjava/lang/String;)Z
Landroid/telephony/PhoneNumberUtils;->isPotentialEmergencyNumber(ILjava/lang/String;)Z
Landroid/telephony/PhoneNumberUtils;->isPotentialLocalEmergencyNumber(Landroid/content/Context;ILjava/lang/String;)Z
@@ -342,12 +452,20 @@
Landroid/telephony/Rlog;->e(Ljava/lang/String;Ljava/lang/String;)I
Landroid/telephony/Rlog;->e(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I
Landroid/telephony/Rlog;->i(Ljava/lang/String;Ljava/lang/String;)I
+Landroid/telephony/ServiceState;->getDataRegState()I
Landroid/telephony/ServiceState;->getDataRoaming()Z
Landroid/telephony/ServiceState;->getRilDataRadioTechnology()I
+Landroid/telephony/ServiceState;->getVoiceNetworkType()I
Landroid/telephony/ServiceState;->getVoiceRegState()I
Landroid/telephony/ServiceState;->isCdma(I)Z
Landroid/telephony/ServiceState;->isEmergencyOnly()Z
+Landroid/telephony/ServiceState;->isGsm(I)Z
Landroid/telephony/ServiceState;->mergeServiceStates(Landroid/telephony/ServiceState;Landroid/telephony/ServiceState;)Landroid/telephony/ServiceState;
+Landroid/telephony/ServiceState;->rilRadioTechnologyToString(I)Ljava/lang/String;
+Landroid/telephony/SubscriptionInfo;->setDisplayName(Ljava/lang/CharSequence;)V
+Landroid/telephony/SubscriptionInfo;->setIconTint(I)V
+Landroid/telephony/SubscriptionManager;->clearDefaultsForInactiveSubIds()V
+Landroid/telephony/SubscriptionManager;->getDefaultVoicePhoneId()I
Landroid/telephony/SubscriptionManager;->getResourcesForSubId(Landroid/content/Context;I)Landroid/content/res/Resources;
Landroid/telephony/SubscriptionManager;->isActiveSubId(I)Z
Landroid/telephony/SubscriptionManager;->isUsableSubIdValue(I)Z
@@ -355,9 +473,18 @@
Landroid/telephony/SubscriptionManager;->isValidSlotIndex(I)Z
Landroid/telephony/SubscriptionManager;->isValidSubscriptionId(I)Z
Landroid/telephony/SubscriptionManager;->putPhoneIdAndSubIdExtra(Landroid/content/Intent;II)V
+Landroid/telephony/SubscriptionManager;->putPhoneIdAndSubIdExtra(Landroid/content/Intent;I)V
+Landroid/telephony/SubscriptionManager;->setDefaultDataSubId(I)V
+Landroid/telephony/SubscriptionManager;->setDisplayName(Ljava/lang/String;IJ)I
+Landroid/telephony/SubscriptionManager;->setIconTint(II)I
Landroid/telephony/TelephonyManager;->getIntAtIndex(Landroid/content/ContentResolver;Ljava/lang/String;I)I
+Landroid/telephony/TelephonyManager;->getNetworkTypeName()Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getVoiceMessageCount()I
Landroid/telephony/TelephonyManager;->getVoiceNetworkType(I)I
+Landroid/telephony/TelephonyManager$MultiSimVariants;->DSDA:Landroid/telephony/TelephonyManager$MultiSimVariants;
+Landroid/telephony/TelephonyManager$MultiSimVariants;->DSDS:Landroid/telephony/TelephonyManager$MultiSimVariants;
Landroid/telephony/TelephonyManager;->putIntAtIndex(Landroid/content/ContentResolver;Ljava/lang/String;II)Z
+Landroid/text/TextUtils;->isPrintableAsciiOnly(Ljava/lang/CharSequence;)Z
Landroid/util/FloatMath;->ceil(F)F
Landroid/util/FloatMath;->cos(F)F
Landroid/util/FloatMath;->exp(F)F
@@ -374,6 +501,9 @@
Landroid/util/LongArray;->get(I)J
Landroid/util/LongArray;-><init>()V
Landroid/util/LongArray;->size()I
+Landroid/util/Slog;->e(Ljava/lang/String;Ljava/lang/String;)I
+Landroid/util/Slog;->e(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I
+Landroid/util/Slog;->println(ILjava/lang/String;Ljava/lang/String;)I
Landroid/util/Slog;->wtf(Ljava/lang/String;Ljava/lang/String;)I
Landroid/view/AppTransitionAnimationSpec;-><init>(ILandroid/graphics/GraphicBuffer;Landroid/graphics/Rect;)V
Landroid/view/BatchedInputEventReceiver;-><init>(Landroid/view/InputChannel;Landroid/os/Looper;Landroid/view/Choreographer;)V
@@ -525,6 +655,19 @@
Lcom/android/ims/internal/uce/uceservice/IUceService;->startService(Lcom/android/ims/internal/uce/uceservice/IUceListener;)Z
Lcom/android/ims/internal/uce/uceservice/IUceService;->stopService()Z
Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
+Lcom/android/internal/app/AlertController$AlertParams;->mIconId:I
+Lcom/android/internal/app/AlertController$AlertParams;->mMessage:Ljava/lang/CharSequence;
+Lcom/android/internal/app/AlertController$AlertParams;->mNegativeButtonListener:Landroid/content/DialogInterface$OnClickListener;
+Lcom/android/internal/app/AlertController$AlertParams;->mNegativeButtonText:Ljava/lang/CharSequence;
+Lcom/android/internal/app/AlertController$AlertParams;->mPositiveButtonListener:Landroid/content/DialogInterface$OnClickListener;
+Lcom/android/internal/app/AlertController$AlertParams;->mPositiveButtonText:Ljava/lang/CharSequence;
+Lcom/android/internal/app/AlertController$AlertParams;->mTitle:Ljava/lang/CharSequence;
+Lcom/android/internal/app/AlertController$AlertParams;->mView:Landroid/view/View;
+Lcom/android/internal/app/AlertController;->getButton(I)Landroid/widget/Button;
+Lcom/android/internal/app/IAppOpsService;->finishOperation(Landroid/os/IBinder;IILjava/lang/String;)V
+Lcom/android/internal/content/PackageMonitor;-><init>()V
+Lcom/android/internal/content/PackageMonitor;->register(Landroid/content/Context;Landroid/os/Looper;Landroid/os/UserHandle;Z)V
+Lcom/android/internal/content/PackageMonitor;->unregister()V
Lcom/android/internal/location/ILocationProvider;->disable()V
Lcom/android/internal/location/ILocationProvider;->enable()V
Lcom/android/internal/location/ILocationProvider;->getProperties()Lcom/android/internal/location/ProviderProperties;
@@ -532,6 +675,11 @@
Lcom/android/internal/location/ILocationProvider;->getStatusUpdateTime()J
Lcom/android/internal/location/ILocationProvider;->sendExtraCommand(Ljava/lang/String;Landroid/os/Bundle;)Z
Lcom/android/internal/location/ILocationProvider;->setRequest(Lcom/android/internal/location/ProviderRequest;Landroid/os/WorkSource;)V
+Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
+Lcom/android/internal/location/ProviderRequest;-><init>()V
+Lcom/android/internal/location/ProviderRequest;->interval:J
+Lcom/android/internal/location/ProviderRequest;->locationRequests:Ljava/util/List;
+Lcom/android/internal/location/ProviderRequest;->reportLocation:Z
Lcom/android/internal/os/BatteryStatsImpl;->getDischargeCurrentLevel()I
Lcom/android/internal/os/BatteryStatsImpl;->getDischargeStartLevel()I
Lcom/android/internal/os/BatteryStatsImpl;->getPhoneOnTime(JI)J
@@ -541,7 +689,22 @@
Lcom/android/internal/os/BatteryStatsImpl;->getWifiOnTime(JI)J
Lcom/android/internal/os/SomeArgs;->obtain()Lcom/android/internal/os/SomeArgs;
Lcom/android/internal/os/SomeArgs;->recycle()V
+Lcom/android/internal/R$styleable;->NumberPicker:[I
+Lcom/android/internal/R$styleable;->TwoLineListItem:[I
+Lcom/android/internal/telephony/GsmAlphabet;->gsm7BitPackedToString([BII)Ljava/lang/String;
+Lcom/android/internal/telephony/GsmAlphabet;->stringToGsm7BitPacked(Ljava/lang/String;)[B
Lcom/android/internal/telephony/ITelephony;->getDataEnabled(I)Z
+Lcom/android/internal/telephony/OperatorInfo;->CREATOR:Landroid/os/Parcelable$Creator;
+Lcom/android/internal/telephony/OperatorInfo;->getOperatorAlphaLong()Ljava/lang/String;
+Lcom/android/internal/telephony/OperatorInfo;->getOperatorAlphaShort()Ljava/lang/String;
+Lcom/android/internal/telephony/OperatorInfo;->getOperatorNumeric()Ljava/lang/String;
+Lcom/android/internal/telephony/OperatorInfo;->getState()Lcom/android/internal/telephony/OperatorInfo$State;
+Lcom/android/internal/telephony/OperatorInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/OperatorInfo$State;->CURRENT:Lcom/android/internal/telephony/OperatorInfo$State;
+Lcom/android/internal/telephony/OperatorInfo$State;->FORBIDDEN:Lcom/android/internal/telephony/OperatorInfo$State;
+Lcom/android/internal/util/AsyncChannel;->connect(Landroid/content/Context;Landroid/os/Handler;Landroid/os/Messenger;)V
+Lcom/android/internal/util/AsyncChannel;-><init>()V
+Lcom/android/internal/util/AsyncChannel;->sendMessage(Landroid/os/Message;)V
Lcom/android/internal/util/IndentingPrintWriter;->decreaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
Lcom/android/internal/util/IndentingPrintWriter;->increaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
Lcom/android/internal/util/IndentingPrintWriter;-><init>(Ljava/io/Writer;Ljava/lang/String;)V
@@ -550,3 +713,4 @@
Ljava/lang/System;->arraycopy([BI[BII)V
Ljava/net/Inet4Address;->ALL:Ljava/net/InetAddress;
Ljava/net/Inet4Address;->ANY:Ljava/net/InetAddress;
+Ljava/net/Inet6Address;->ANY:Ljava/net/InetAddress;
diff --git a/core/java/android/app/slice/Slice.java b/core/java/android/app/slice/Slice.java
index d6f2352..61679cb 100644
--- a/core/java/android/app/slice/Slice.java
+++ b/core/java/android/app/slice/Slice.java
@@ -66,10 +66,27 @@
HINT_HORIZONTAL,
HINT_PARTIAL,
HINT_SEE_MORE,
- HINT_KEY_WORDS
+ HINT_KEY_WORDS,
+ HINT_ERROR,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SliceHint {}
+ /**
+ * @hide
+ */
+ @StringDef(prefix = { "SUBTYPE_" }, value = {
+ SUBTYPE_COLOR,
+ SUBTYPE_CONTENT_DESCRIPTION,
+ SUBTYPE_MAX,
+ SUBTYPE_MESSAGE,
+ SUBTYPE_PRIORITY,
+ SUBTYPE_RANGE,
+ SUBTYPE_SOURCE,
+ SUBTYPE_TOGGLE,
+ SUBTYPE_VALUE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SliceSubtype {}
/**
* Hint that this content is a title of other content in the slice. This can also indicate that
@@ -149,9 +166,14 @@
/**
* A hint to indicate that the contents of this subslice represent a list of keywords
* related to the parent slice.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_SLICE}.
*/
public static final String HINT_KEY_WORDS = "key_words";
/**
+ * A hint to indicate that this slice represents an error.
+ */
+ public static final String HINT_ERROR = "error";
+ /**
* Key to retrieve an extra added to an intent when a control is changed.
*/
public static final String EXTRA_TOGGLE_STATE = "android.app.slice.extra.TOGGLE_STATE";
@@ -168,14 +190,18 @@
/**
* Subtype to indicate that this is a message as part of a communication
* sequence in this slice.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_SLICE}.
*/
public static final String SUBTYPE_MESSAGE = "message";
/**
* Subtype to tag the source (i.e. sender) of a {@link #SUBTYPE_MESSAGE}.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_TEXT},
+ * {@link SliceItem#FORMAT_IMAGE} or an {@link SliceItem#FORMAT_SLICE} containing them.
*/
public static final String SUBTYPE_SOURCE = "source";
/**
* Subtype to tag an item as representing a color.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_INT}.
*/
public static final String SUBTYPE_COLOR = "color";
/**
@@ -186,14 +212,18 @@
public static final String SUBTYPE_SLIDER = "slider";
/**
* Subtype to tag an item as representing a range.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_SLICE} containing
+ * a {@link #SUBTYPE_VALUE} and possibly a {@link #SUBTYPE_MAX}.
*/
public static final String SUBTYPE_RANGE = "range";
/**
* Subtype to tag an item as representing the max int value for a {@link #SUBTYPE_RANGE}.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_INT}.
*/
public static final String SUBTYPE_MAX = "max";
/**
* Subtype to tag an item as representing the current int value for a {@link #SUBTYPE_RANGE}.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_INT}.
*/
public static final String SUBTYPE_VALUE = "value";
/**
@@ -205,10 +235,12 @@
public static final String SUBTYPE_TOGGLE = "toggle";
/**
* Subtype to tag an item representing priority.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_INT}.
*/
public static final String SUBTYPE_PRIORITY = "priority";
/**
* Subtype to tag an item to use as a content description.
+ * Expected to be on an item of format {@link SliceItem#FORMAT_TEXT}.
*/
public static final String SUBTYPE_CONTENT_DESCRIPTION = "content_description";
@@ -305,14 +337,24 @@
private SliceSpec mSpec;
/**
- * Create a builder which will construct a {@link Slice} for the Given Uri.
- * @param uri Uri to tag for this slice.
+ * @deprecated TO BE REMOVED
*/
+ @Deprecated
public Builder(@NonNull Uri uri) {
mUri = uri;
}
/**
+ * Create a builder which will construct a {@link Slice} for the given Uri.
+ * @param uri Uri to tag for this slice.
+ * @param spec the spec for this slice.
+ */
+ public Builder(@NonNull Uri uri, SliceSpec spec) {
+ mUri = uri;
+ mSpec = spec;
+ }
+
+ /**
* Create a builder for a {@link Slice} that is a sub-slice of the slice
* being constructed by the provided builder.
* @param parent The builder constructing the parent slice
@@ -340,20 +382,13 @@
/**
* Add hints to the Slice being constructed
*/
- public Builder addHints(@SliceHint String... hints) {
- mHints.addAll(Arrays.asList(hints));
+ public Builder addHints(@SliceHint List<String> hints) {
+ mHints.addAll(hints);
return this;
}
/**
- * Add hints to the Slice being constructed
- */
- public Builder addHints(@SliceHint List<String> hints) {
- return addHints(hints.toArray(new String[hints.size()]));
- }
-
- /**
- * Add the spec for this slice.
+ * @deprecated TO BE REMOVED
*/
public Builder setSpec(SliceSpec spec) {
mSpec = spec;
@@ -362,17 +397,10 @@
/**
* Add a sub-slice to the slice being constructed
- */
- public Builder addSubSlice(@NonNull Slice slice) {
- return addSubSlice(slice, null);
- }
-
- /**
- * Add a sub-slice to the slice being constructed
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
- public Builder addSubSlice(@NonNull Slice slice, @Nullable String subType) {
+ public Builder addSubSlice(@NonNull Slice slice, @Nullable @SliceSubtype String subType) {
mItems.add(new SliceItem(slice, SliceItem.FORMAT_SLICE, subType,
slice.getHints().toArray(new String[slice.getHints().size()])));
return this;
@@ -380,18 +408,11 @@
/**
* Add an action to the slice being constructed
- */
- public Slice.Builder addAction(@NonNull PendingIntent action, @NonNull Slice s) {
- return addAction(action, s, null);
- }
-
- /**
- * Add an action to the slice being constructed
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
public Slice.Builder addAction(@NonNull PendingIntent action, @NonNull Slice s,
- @Nullable String subType) {
+ @Nullable @SliceSubtype String subType) {
List<String> hints = s.getHints();
s.mSpec = null;
mItems.add(new SliceItem(action, s, SliceItem.FORMAT_ACTION, subType, hints.toArray(
@@ -404,58 +425,31 @@
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
- public Builder addText(CharSequence text, @Nullable String subType,
- @SliceHint String... hints) {
+ public Builder addText(CharSequence text, @Nullable @SliceSubtype String subType,
+ @SliceHint List<String> hints) {
mItems.add(new SliceItem(text, SliceItem.FORMAT_TEXT, subType, hints));
return this;
}
/**
- * Add text to the slice being constructed
- * @param subType Optional template-specific type information
- * @see {@link SliceItem#getSubType()}
- */
- public Builder addText(CharSequence text, @Nullable String subType,
- @SliceHint List<String> hints) {
- return addText(text, subType, hints.toArray(new String[hints.size()]));
- }
-
- /**
* Add an image to the slice being constructed
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
- public Builder addIcon(Icon icon, @Nullable String subType, @SliceHint String... hints) {
+ public Builder addIcon(Icon icon, @Nullable @SliceSubtype String subType,
+ @SliceHint List<String> hints) {
mItems.add(new SliceItem(icon, SliceItem.FORMAT_IMAGE, subType, hints));
return this;
}
/**
- * Add an image to the slice being constructed
- * @param subType Optional template-specific type information
- * @see {@link SliceItem#getSubType()}
- */
- public Builder addIcon(Icon icon, @Nullable String subType, @SliceHint List<String> hints) {
- return addIcon(icon, subType, hints.toArray(new String[hints.size()]));
- }
-
- /**
* Add remote input to the slice being constructed
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
- public Slice.Builder addRemoteInput(RemoteInput remoteInput, @Nullable String subType,
+ public Slice.Builder addRemoteInput(RemoteInput remoteInput,
+ @Nullable @SliceSubtype String subType,
@SliceHint List<String> hints) {
- return addRemoteInput(remoteInput, subType, hints.toArray(new String[hints.size()]));
- }
-
- /**
- * Add remote input to the slice being constructed
- * @param subType Optional template-specific type information
- * @see {@link SliceItem#getSubType()}
- */
- public Slice.Builder addRemoteInput(RemoteInput remoteInput, @Nullable String subType,
- @SliceHint String... hints) {
mItems.add(new SliceItem(remoteInput, SliceItem.FORMAT_REMOTE_INPUT,
subType, hints));
return this;
@@ -466,70 +460,48 @@
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
- public Builder addInt(int value, @Nullable String subType, @SliceHint String... hints) {
+ public Builder addInt(int value, @Nullable @SliceSubtype String subType,
+ @SliceHint List<String> hints) {
mItems.add(new SliceItem(value, SliceItem.FORMAT_INT, subType, hints));
return this;
}
/**
- * Add an integer to the slice being constructed
- * @param subType Optional template-specific type information
- * @see {@link SliceItem#getSubType()}
+ * @deprecated TO BE REMOVED.
*/
- public Builder addInt(int value, @Nullable String subType,
+ @Deprecated
+ public Slice.Builder addTimestamp(long time, @Nullable @SliceSubtype String subType,
@SliceHint List<String> hints) {
- return addInt(value, subType, hints.toArray(new String[hints.size()]));
+ return addLong(time, subType, hints);
}
/**
- * Add a timestamp to the slice being constructed
+ * Add a long to the slice being constructed
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
- public Slice.Builder addTimestamp(long time, @Nullable String subType,
- @SliceHint String... hints) {
- mItems.add(new SliceItem(time, SliceItem.FORMAT_TIMESTAMP, subType,
- hints));
+ public Slice.Builder addLong(long value, @Nullable @SliceSubtype String subType,
+ @SliceHint List<String> hints) {
+ mItems.add(new SliceItem(value, SliceItem.FORMAT_LONG, subType,
+ hints.toArray(new String[hints.size()])));
return this;
}
/**
- * Add a timestamp to the slice being constructed
- * @param subType Optional template-specific type information
- * @see {@link SliceItem#getSubType()}
- */
- public Slice.Builder addTimestamp(long time, @Nullable String subType,
- @SliceHint List<String> hints) {
- return addTimestamp(time, subType, hints.toArray(new String[hints.size()]));
- }
-
- /**
* Add a bundle to the slice being constructed.
* <p>Expected to be used for support library extension, should not be used for general
* development
* @param subType Optional template-specific type information
* @see {@link SliceItem#getSubType()}
*/
- public Slice.Builder addBundle(Bundle bundle, @Nullable String subType,
- @SliceHint String... hints) {
+ public Slice.Builder addBundle(Bundle bundle, @Nullable @SliceSubtype String subType,
+ @SliceHint List<String> hints) {
mItems.add(new SliceItem(bundle, SliceItem.FORMAT_BUNDLE, subType,
hints));
return this;
}
/**
- * Add a bundle to the slice being constructed.
- * <p>Expected to be used for support library extension, should not be used for general
- * development
- * @param subType Optional template-specific type information
- * @see {@link SliceItem#getSubType()}
- */
- public Slice.Builder addBundle(Bundle bundle, @Nullable String subType,
- @SliceHint List<String> hints) {
- return addBundle(bundle, subType, hints.toArray(new String[hints.size()]));
- }
-
- /**
* Construct the slice.
*/
public Slice build() {
diff --git a/core/java/android/app/slice/SliceItem.java b/core/java/android/app/slice/SliceItem.java
index 9eb2bb8..019ae49 100644
--- a/core/java/android/app/slice/SliceItem.java
+++ b/core/java/android/app/slice/SliceItem.java
@@ -67,7 +67,7 @@
FORMAT_IMAGE,
FORMAT_ACTION,
FORMAT_INT,
- FORMAT_TIMESTAMP,
+ FORMAT_LONG,
FORMAT_REMOTE_INPUT,
FORMAT_BUNDLE,
})
@@ -98,9 +98,14 @@
*/
public static final String FORMAT_INT = "int";
/**
- * A {@link SliceItem} that contains a timestamp.
+ * A {@link SliceItem} that contains a long.
*/
- public static final String FORMAT_TIMESTAMP = "timestamp";
+ public static final String FORMAT_LONG = "long";
+ /**
+ * @deprecated TO BE REMOVED
+ */
+ @Deprecated
+ public static final String FORMAT_TIMESTAMP = FORMAT_LONG;
/**
* A {@link SliceItem} that contains a {@link RemoteInput}.
*/
@@ -123,6 +128,14 @@
* @hide
*/
public SliceItem(Object obj, @SliceType String format, String subType,
+ List<String> hints) {
+ this(obj, format, subType, hints.toArray(new String[hints.size()]));
+ }
+
+ /**
+ * @hide
+ */
+ public SliceItem(Object obj, @SliceType String format, String subType,
@Slice.SliceHint String[] hints) {
mHints = hints;
mFormat = format;
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index aa2cf46..dd89293 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -41,6 +41,7 @@
import android.util.Log;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -430,9 +431,11 @@
return new Slice.Builder(sliceUri)
.addAction(createPermissionIntent(context, sliceUri, callingPackage),
new Slice.Builder(sliceUri.buildUpon().appendPath("permission").build())
- .addText(getPermissionString(context, callingPackage), null)
- .build())
- .addHints(Slice.HINT_LIST_ITEM)
+ .addText(getPermissionString(context, callingPackage), null,
+ Collections.emptyList())
+ .build(),
+ null)
+ .addHints(Arrays.asList(Slice.HINT_LIST_ITEM))
.build();
}
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 8550ac0..b354e81 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -125,6 +125,20 @@
@SystemApi
public static final int NOTIFICATION_INTERRUPTION = 12;
+ /**
+ * A Slice was pinned by the default launcher or the default assistant.
+ * @hide
+ */
+ @SystemApi
+ public static final int SLICE_PINNED_PRIV = 13;
+
+ /**
+ * A Slice was pinned by an app.
+ * @hide
+ */
+ @SystemApi
+ public static final int SLICE_PINNED = 14;
+
/** @hide */
public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 2a791ec..316c796 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -293,9 +293,7 @@
(mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
// Use compatibility WAL unless an app explicitly set journal/synchronous mode
// or DISABLE_COMPATIBILITY_WAL flag is set
- final boolean useCompatibilityWal = mConfiguration.journalMode == null
- && mConfiguration.syncMode == null
- && (mConfiguration.openFlags & SQLiteDatabase.DISABLE_COMPATIBILITY_WAL) == 0;
+ final boolean useCompatibilityWal = mConfiguration.useCompatibilityWal();
if (walEnabled || useCompatibilityWal) {
setJournalMode("WAL");
if (useCompatibilityWal && SQLiteCompatibilityWalFlags.areFlagsSet()) {
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index dadb95b..e519302 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -23,6 +23,7 @@
import android.os.Message;
import android.os.OperationCanceledException;
import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.Log;
import android.util.PrefixPrinter;
import android.util.Printer;
@@ -1111,6 +1112,11 @@
printer.println(" Open: " + mIsOpen);
printer.println(" Max connections: " + mMaxConnectionPoolSize);
printer.println(" Total execution time: " + mTotalExecutionTimeCounter);
+ printer.println(" Configuration: openFlags=" + mConfiguration.openFlags
+ + ", useCompatibilityWal=" + mConfiguration.useCompatibilityWal()
+ + ", journalMode=" + TextUtils.emptyIfNull(mConfiguration.journalMode)
+ + ", syncMode=" + TextUtils.emptyIfNull(mConfiguration.syncMode));
+
if (SQLiteCompatibilityWalFlags.areFlagsSet()) {
printer.println(" Compatibility WAL settings: compatibility_wal_supported="
+ SQLiteCompatibilityWalFlags
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 275043f..8b9dfcf 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -194,6 +194,11 @@
return path.equalsIgnoreCase(MEMORY_DB_PATH);
}
+ boolean useCompatibilityWal() {
+ return journalMode == null && syncMode == null
+ && (openFlags & SQLiteDatabase.DISABLE_COMPATIBILITY_WAL) == 0;
+ }
+
private static String stripPathForLogs(String path) {
if (path.indexOf('@') == -1) {
return path;
diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl
index 3ce0283..3a3ddcc 100644
--- a/core/java/android/net/IIpSecService.aidl
+++ b/core/java/android/net/IIpSecService.aidl
@@ -16,6 +16,7 @@
package android.net;
+import android.net.LinkAddress;
import android.net.Network;
import android.net.IpSecConfig;
import android.net.IpSecUdpEncapResponse;
@@ -48,11 +49,11 @@
void addAddressToTunnelInterface(
int tunnelResourceId,
- String localAddr);
+ in LinkAddress localAddr);
void removeAddressFromTunnelInterface(
int tunnelResourceId,
- String localAddr);
+ in LinkAddress localAddr);
void deleteTunnelInterface(int resourceId);
diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
index c69a4d4..f4b328e 100644
--- a/core/java/android/net/IpSecAlgorithm.java
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -38,6 +38,13 @@
private static final String TAG = "IpSecAlgorithm";
/**
+ * Null cipher.
+ *
+ * @hide
+ */
+ public static final String CRYPT_NULL = "ecb(cipher_null)";
+
+ /**
* AES-CBC Encryption/Ciphering Algorithm.
*
* <p>Valid lengths for this key are {128, 192, 256}.
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index fbf3056..4e1f834 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -656,10 +656,14 @@
* tunneled traffic.
*
* @param address the local address for traffic inside the tunnel
- * @throws IOException if the address could not be added
* @hide
*/
- public void addAddress(LinkAddress address) throws IOException {
+ public void addAddress(LinkAddress address) {
+ try {
+ mService.addAddressToTunnelInterface(mResourceId, address);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -668,10 +672,14 @@
* <p>Remove an address which was previously added to the IpSecTunnelInterface
*
* @param address to be removed
- * @throws IOException if the address could not be removed
* @hide
*/
- public void removeAddress(LinkAddress address) throws IOException {
+ public void removeAddress(LinkAddress address) {
+ try {
+ mService.removeAddressFromTunnelInterface(mResourceId, address);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
private IpSecTunnelInterface(@NonNull IIpSecService service,
diff --git a/core/java/android/webkit/TracingConfig.java b/core/java/android/webkit/TracingConfig.java
index 68badec..d95ca61 100644
--- a/core/java/android/webkit/TracingConfig.java
+++ b/core/java/android/webkit/TracingConfig.java
@@ -35,9 +35,9 @@
private @TracingMode int mTracingMode;
/** @hide */
- @IntDef(flag = true, value = {CATEGORIES_NONE, CATEGORIES_WEB_DEVELOPER,
- CATEGORIES_INPUT_LATENCY, CATEGORIES_RENDERING, CATEGORIES_JAVASCRIPT_AND_RENDERING,
- CATEGORIES_FRAME_VIEWER})
+ @IntDef(flag = true, value = {CATEGORIES_NONE, CATEGORIES_ALL, CATEGORIES_ANDROID_WEBVIEW,
+ CATEGORIES_WEB_DEVELOPER, CATEGORIES_INPUT_LATENCY, CATEGORIES_RENDERING,
+ CATEGORIES_JAVASCRIPT_AND_RENDERING, CATEGORIES_FRAME_VIEWER})
@Retention(RetentionPolicy.SOURCE)
public @interface PredefinedCategories {}
@@ -90,34 +90,28 @@
public static final int CATEGORIES_FRAME_VIEWER = 1 << 6;
/** @hide */
- @IntDef({RECORD_UNTIL_FULL, RECORD_CONTINUOUSLY, RECORD_UNTIL_FULL_LARGE_BUFFER})
+ @IntDef({RECORD_UNTIL_FULL, RECORD_CONTINUOUSLY})
@Retention(RetentionPolicy.SOURCE)
public @interface TracingMode {}
/**
- * Record trace events until the internal tracing buffer is full. Default tracing mode.
- * Typically the buffer memory usage is between {@link #RECORD_CONTINUOUSLY} and the
- * {@link #RECORD_UNTIL_FULL_LARGE_BUFFER}. Depending on the implementation typically allows
- * up to 256k events to be stored.
+ * Record trace events until the internal tracing buffer is full.
+ *
+ * Typically the buffer memory usage is larger than {@link #RECORD_CONTINUOUSLY}.
+ * Depending on the implementation typically allows up to 256k events to be stored.
*/
public static final int RECORD_UNTIL_FULL = 0;
/**
- * Record trace events continuously using an internal ring buffer. Overwrites
- * old events if they exceed buffer capacity. Uses less memory than both
- * {@link #RECORD_UNTIL_FULL} and {@link #RECORD_UNTIL_FULL_LARGE_BUFFER} modes.
- * Depending on the implementation typically allows up to 64k events to be stored.
+ * Record trace events continuously using an internal ring buffer. Default tracing mode.
+ *
+ * Overwrites old events if they exceed buffer capacity. Uses less memory than the
+ * {@link #RECORD_UNTIL_FULL} mode. Depending on the implementation typically allows
+ * up to 64k events to be stored.
*/
public static final int RECORD_CONTINUOUSLY = 1;
/**
- * Record trace events using a larger internal tracing buffer until it is full.
- * Uses significantly more memory than {@link #RECORD_UNTIL_FULL} and may not be
- * suitable on devices with smaller RAM.
- */
- public static final int RECORD_UNTIL_FULL_LARGE_BUFFER = 2;
-
- /**
* @hide
*/
public TracingConfig(@PredefinedCategories int predefinedCategories,
@@ -182,7 +176,7 @@
public static class Builder {
private @PredefinedCategories int mPredefinedCategories = CATEGORIES_NONE;
private final List<String> mCustomIncludedCategories = new ArrayList<String>();
- private @TracingMode int mTracingMode = RECORD_UNTIL_FULL;
+ private @TracingMode int mTracingMode = RECORD_CONTINUOUSLY;
/**
* Default constructor for Builder.
@@ -202,7 +196,9 @@
*
* @param predefinedCategories list or bitmask of predefined category sets to use:
* {@link #CATEGORIES_NONE}, {@link #CATEGORIES_ALL},
- * {@link #CATEGORIES_WEB_DEVELOPER}, {@link #CATEGORIES_INPUT_LATENCY},
+ * {@link #CATEGORIES_ANDROID_WEBVIEW},
+ * {@link #CATEGORIES_WEB_DEVELOPER},
+ * {@link #CATEGORIES_INPUT_LATENCY},
* {@link #CATEGORIES_RENDERING},
* {@link #CATEGORIES_JAVASCRIPT_AND_RENDERING} or
* {@link #CATEGORIES_FRAME_VIEWER}.
@@ -250,9 +246,8 @@
/**
* Sets the tracing mode for this configuration.
*
- * @param tracingMode tracing mode to use, one of {@link #RECORD_UNTIL_FULL},
- * {@link #RECORD_CONTINUOUSLY} or
- * {@link #RECORD_UNTIL_FULL_LARGE_BUFFER}.
+ * @param tracingMode tracing mode to use, one of {@link #RECORD_UNTIL_FULL} or
+ * {@link #RECORD_CONTINUOUSLY}.
* @return The builder to facilitate chaining.
*/
public Builder setTracingMode(@TracingMode int tracingMode) {
diff --git a/core/java/android/webkit/TracingController.java b/core/java/android/webkit/TracingController.java
index 7871021..50068f5 100644
--- a/core/java/android/webkit/TracingController.java
+++ b/core/java/android/webkit/TracingController.java
@@ -60,9 +60,8 @@
* Starts tracing all webviews. Depending on the trace mode in traceConfig
* specifies how the trace events are recorded.
*
- * For tracing modes {@link TracingConfig#RECORD_UNTIL_FULL},
- * {@link TracingConfig#RECORD_CONTINUOUSLY} and
- * {@link TracingConfig#RECORD_UNTIL_FULL_LARGE_BUFFER} the events are recorded
+ * For tracing modes {@link TracingConfig#RECORD_UNTIL_FULL} and
+ * {@link TracingConfig#RECORD_CONTINUOUSLY} the events are recorded
* using an internal buffer and flushed to the outputStream when
* {@link #stop(OutputStream, Executor)} is called.
*
diff --git a/core/java/com/android/internal/util/NotificationMessagingUtil.java b/core/java/com/android/internal/util/NotificationMessagingUtil.java
index b962d4f..bf796cd 100644
--- a/core/java/com/android/internal/util/NotificationMessagingUtil.java
+++ b/core/java/com/android/internal/util/NotificationMessagingUtil.java
@@ -26,7 +26,6 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
-import android.text.TextUtils;
import android.util.ArrayMap;
import java.util.Objects;
@@ -47,6 +46,18 @@
Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING), false, mSmsContentObserver);
}
+ public boolean isImportantMessaging(StatusBarNotification sbn, int importance) {
+ if (importance < NotificationManager.IMPORTANCE_LOW) {
+ return false;
+ }
+
+ return hasMessagingStyle(sbn) || (isCategoryMessage(sbn) && isDefaultMessagingApp(sbn));
+ }
+
+ public boolean isMessaging(StatusBarNotification sbn) {
+ return hasMessagingStyle(sbn) || isDefaultMessagingApp(sbn) || isCategoryMessage(sbn);
+ }
+
@SuppressWarnings("deprecation")
private boolean isDefaultMessagingApp(StatusBarNotification sbn) {
final int userId = sbn.getUserId();
@@ -73,25 +84,12 @@
}
};
- public boolean isImportantMessaging(StatusBarNotification sbn, int importance) {
- if (importance < NotificationManager.IMPORTANCE_LOW) {
- return false;
- }
-
- return isMessaging(sbn);
+ private boolean hasMessagingStyle(StatusBarNotification sbn) {
+ Class<? extends Notification.Style> style = sbn.getNotification().getNotificationStyle();
+ return Notification.MessagingStyle.class.equals(style);
}
- public boolean isMessaging(StatusBarNotification sbn) {
- Class<? extends Notification.Style> style = sbn.getNotification().getNotificationStyle();
- if (Notification.MessagingStyle.class.equals(style)) {
- return true;
- }
-
- if (Notification.CATEGORY_MESSAGE.equals(sbn.getNotification().category)
- && isDefaultMessagingApp(sbn)) {
- return true;
- }
-
- return false;
+ private boolean isCategoryMessage(StatusBarNotification sbn) {
+ return Notification.CATEGORY_MESSAGE.equals(sbn.getNotification().category);
}
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index fde7e96..d4ab426 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -16,6 +16,15 @@
package com.android.internal.widget;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
@@ -59,7 +68,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-
/**
* Utilities for the lock pattern and its settings.
*/
@@ -585,7 +593,7 @@
return quality;
}
- return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ return PASSWORD_QUALITY_UNSPECIFIED;
}
/**
@@ -604,13 +612,16 @@
* Clear any lock pattern or password.
*/
public void clearLock(String savedCredential, int userHandle) {
- setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle);
+ final int currentQuality = getKeyguardStoredPasswordQuality(userHandle);
+ setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle);
try{
getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential,
- DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle);
- } catch (RemoteException e) {
- // well, we tried...
+ PASSWORD_QUALITY_UNSPECIFIED, userHandle);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to clear lock", e);
+ setKeyguardStoredPasswordQuality(currentQuality, userHandle);
+ return;
}
if (userHandle == UserHandle.USER_SYSTEM) {
@@ -669,32 +680,34 @@
* @param userId the user whose pattern is to be saved.
*/
public void saveLockPattern(List<LockPatternView.Cell> pattern, String savedPattern, int userId) {
- try {
- if (pattern == null || pattern.size() < MIN_LOCK_PATTERN_SIZE) {
- throw new IllegalArgumentException("pattern must not be null and at least "
- + MIN_LOCK_PATTERN_SIZE + " dots long.");
- }
-
- setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
- getLockSettings().setLockCredential(patternToString(pattern), CREDENTIAL_TYPE_PATTERN,
- savedPattern, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
-
- // Update the device encryption password.
- if (userId == UserHandle.USER_SYSTEM
- && LockPatternUtils.isDeviceEncryptionEnabled()) {
- if (!shouldEncryptWithCredentials(true)) {
- clearEncryptionPassword();
- } else {
- String stringPattern = patternToString(pattern);
- updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern);
- }
- }
-
- reportPatternWasChosen(userId);
- onAfterChangingPassword(userId);
- } catch (RemoteException re) {
- Log.e(TAG, "Couldn't save lock pattern " + re);
+ if (pattern == null || pattern.size() < MIN_LOCK_PATTERN_SIZE) {
+ throw new IllegalArgumentException("pattern must not be null and at least "
+ + MIN_LOCK_PATTERN_SIZE + " dots long.");
}
+
+ final String stringPattern = patternToString(pattern);
+ final int currentQuality = getKeyguardStoredPasswordQuality(userId);
+ setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId);
+ try {
+ getLockSettings().setLockCredential(stringPattern, CREDENTIAL_TYPE_PATTERN,
+ savedPattern, PASSWORD_QUALITY_SOMETHING, userId);
+ } catch (Exception e) {
+ Log.e(TAG, "Couldn't save lock pattern", e);
+ setKeyguardStoredPasswordQuality(currentQuality, userId);
+ return;
+ }
+ // Update the device encryption password.
+ if (userId == UserHandle.USER_SYSTEM
+ && LockPatternUtils.isDeviceEncryptionEnabled()) {
+ if (!shouldEncryptWithCredentials(true)) {
+ clearEncryptionPassword();
+ } else {
+ updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern);
+ }
+ }
+
+ reportPatternWasChosen(userId);
+ onAfterChangingPassword(userId);
}
private void updateCryptoUserInfo(int userId) {
@@ -796,25 +809,27 @@
*/
public void saveLockPassword(String password, String savedPassword, int requestedQuality,
int userHandle) {
- try {
- if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) {
- throw new IllegalArgumentException("password must not be null and at least "
- + "of length " + MIN_LOCK_PASSWORD_SIZE);
- }
-
- setLong(PASSWORD_TYPE_KEY,
- computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality),
- userHandle);
- getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
- requestedQuality, userHandle);
-
- updateEncryptionPasswordIfNeeded(password,
- PasswordMetrics.computeForPassword(password).quality, userHandle);
- updatePasswordHistory(password, userHandle);
- } catch (RemoteException re) {
- // Cant do much
- Log.e(TAG, "Unable to save lock password " + re);
+ if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) {
+ throw new IllegalArgumentException("password must not be null and at least "
+ + "of length " + MIN_LOCK_PASSWORD_SIZE);
}
+
+ final int currentQuality = getKeyguardStoredPasswordQuality(userHandle);
+ setKeyguardStoredPasswordQuality(
+ computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality),
+ userHandle);
+ try {
+ getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD,
+ savedPassword, requestedQuality, userHandle);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to save lock password", e);
+ setKeyguardStoredPasswordQuality(currentQuality, userHandle);
+ return;
+ }
+
+ updateEncryptionPasswordIfNeeded(password,
+ PasswordMetrics.computeForPassword(password).quality, userHandle);
+ updatePasswordHistory(password, userHandle);
}
/**
@@ -828,9 +843,8 @@
if (!shouldEncryptWithCredentials(true)) {
clearEncryptionPassword();
} else {
- boolean numeric = quality == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
- boolean numericComplex = quality
- == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
+ boolean numeric = quality == PASSWORD_QUALITY_NUMERIC;
+ boolean numericComplex = quality == PASSWORD_QUALITY_NUMERIC_COMPLEX;
int type = numeric || numericComplex ? StorageManager.CRYPT_TYPE_PIN
: StorageManager.CRYPT_TYPE_PASSWORD;
updateEncryptionPassword(type, password);
@@ -894,8 +908,11 @@
* @return stored password quality
*/
public int getKeyguardStoredPasswordQuality(int userHandle) {
- return (int) getLong(PASSWORD_TYPE_KEY,
- DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userHandle);
+ return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle);
+ }
+
+ private void setKeyguardStoredPasswordQuality(int quality, int userHandle) {
+ setLong(PASSWORD_TYPE_KEY, quality, userHandle);
}
/**
@@ -909,9 +926,9 @@
int computedQuality = PasswordMetrics.computeForPassword(credential).quality;
quality = Math.max(requestedQuality, computedQuality);
} else if (type == CREDENTIAL_TYPE_PATTERN) {
- quality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+ quality = PASSWORD_QUALITY_SOMETHING;
} else /* if (type == CREDENTIAL_TYPE_NONE) */ {
- quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ quality = PASSWORD_QUALITY_UNSPECIFIED;
}
return quality;
}
@@ -1125,12 +1142,12 @@
}
private boolean isLockPasswordEnabled(int mode, int userId) {
- final boolean passwordEnabled = mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
- || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
- || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
- || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
- || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
- || mode == DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
+ final boolean passwordEnabled = mode == PASSWORD_QUALITY_ALPHABETIC
+ || mode == PASSWORD_QUALITY_NUMERIC
+ || mode == PASSWORD_QUALITY_NUMERIC_COMPLEX
+ || mode == PASSWORD_QUALITY_ALPHANUMERIC
+ || mode == PASSWORD_QUALITY_COMPLEX
+ || mode == PASSWORD_QUALITY_MANAGED;
return passwordEnabled && savedPasswordExists(userId);
}
@@ -1155,8 +1172,7 @@
}
private boolean isLockPatternEnabled(int mode, int userId) {
- return mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
- && savedPatternExists(userId);
+ return mode == PASSWORD_QUALITY_SOMETHING && savedPatternExists(userId);
}
/**
@@ -1551,7 +1567,7 @@
token, quality, userId)) {
return false;
}
- setLong(PASSWORD_TYPE_KEY, quality, userId);
+ setKeyguardStoredPasswordQuality(quality, userId);
updateEncryptionPasswordIfNeeded(credential, quality, userId);
updatePasswordHistory(credential, userId);
@@ -1560,12 +1576,10 @@
throw new IllegalArgumentException("password must be emtpy for NONE type");
}
if (!localService.setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE,
- tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
- userId)) {
+ tokenHandle, token, PASSWORD_QUALITY_UNSPECIFIED, userId)) {
return false;
}
- setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
- userId);
+ setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userId);
if (userId == UserHandle.USER_SYSTEM) {
// Set the encryption password to default.
diff --git a/core/jni/android/graphics/AnimatedImageDrawable.cpp b/core/jni/android/graphics/AnimatedImageDrawable.cpp
index d6496cd..7166c75 100644
--- a/core/jni/android/graphics/AnimatedImageDrawable.cpp
+++ b/core/jni/android/graphics/AnimatedImageDrawable.cpp
@@ -42,7 +42,6 @@
}
auto* imageDecoder = reinterpret_cast<ImageDecoder*>(nativeImageDecoder);
- auto info = imageDecoder->mCodec->getInfo();
const SkISize scaledSize = SkISize::Make(width, height);
SkIRect subset;
if (jsubset) {
@@ -51,6 +50,35 @@
subset = SkIRect::MakeWH(width, height);
}
+ auto info = imageDecoder->mCodec->getInfo();
+ bool hasRestoreFrame = false;
+ if (imageDecoder->mCodec->getEncodedFormat() == SkEncodedImageFormat::kWEBP) {
+ if (width < info.width() && height < info.height()) {
+ // WebP will scale its SkBitmap to the scaled size.
+ // FIXME: b/73529447 GIF should do the same.
+ info = info.makeWH(width, height);
+ }
+ } else {
+ const int frameCount = imageDecoder->mCodec->codec()->getFrameCount();
+ for (int i = 0; i < frameCount; ++i) {
+ SkCodec::FrameInfo frameInfo;
+ if (!imageDecoder->mCodec->codec()->getFrameInfo(i, &frameInfo)) {
+ doThrowIOE(env, "Failed to read frame info!");
+ return 0;
+ }
+ if (frameInfo.fDisposalMethod == SkCodecAnimation::DisposalMethod::kRestorePrevious) {
+ hasRestoreFrame = true;
+ break;
+ }
+ }
+ }
+
+ size_t bytesUsed = info.computeMinByteSize();
+ // SkAnimatedImage has one SkBitmap for decoding, plus an extra one if there is a
+ // kRestorePrevious frame. AnimatedImageDrawable has two SkPictures storing the current
+ // frame and the next frame. (The former assumes that the image is animated, and the
+ // latter assumes that it is drawn to a hardware canvas.)
+ bytesUsed *= hasRestoreFrame ? 4 : 3;
sk_sp<SkPicture> picture;
if (jpostProcess) {
SkRect bounds = SkRect::MakeWH(subset.width(), subset.height());
@@ -63,6 +91,7 @@
return 0;
}
picture = recorder.finishRecordingAsPicture();
+ bytesUsed += picture->approximateBytesUsed();
}
@@ -74,7 +103,10 @@
return 0;
}
- sk_sp<AnimatedImageDrawable> drawable(new AnimatedImageDrawable(animatedImg));
+ bytesUsed += sizeof(animatedImg.get());
+
+ sk_sp<AnimatedImageDrawable> drawable(new AnimatedImageDrawable(std::move(animatedImg),
+ bytesUsed));
return reinterpret_cast<jlong>(drawable.release());
}
@@ -202,10 +234,9 @@
}
}
-static long AnimatedImageDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+static jlong AnimatedImageDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
- // FIXME: Report the size of the internal SkBitmap etc.
- return sizeof(drawable);
+ return drawable->byteSize();
}
static void AnimatedImageDrawable_nMarkInvisible(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index 5c5b985..fa69038 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -35,8 +35,8 @@
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
android:orientation="vertical">
<LinearLayout
@@ -52,7 +52,7 @@
<TextView
android:id="@+id/autofill_save_title"
- android:paddingLeft="8dp"
+ android:paddingStart="8dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/autofill_save_title"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4a72bf9..75b3bcf 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2151,6 +2151,9 @@
@see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
-->
<enum name="shortEdges" value="1" />
+ <!-- Use {@code shortEdges} instead. This is temporarily here to unblock pushing the SDK
+ until all usages have been migrated to {@code shortEdges} -->
+ <enum name="always" value="1" />
<!-- The window is never allowed to overlap with the DisplayCutout area.
<p>
This should be used with windows that transiently set {@code SYSTEM_UI_FLAG_FULLSCREEN}
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index 6e8134b..3609fb8 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -97,7 +97,7 @@
<color name="material_deep_teal_100">#ffb2dfdb</color>
<color name="material_deep_teal_200">#ff80cbc4</color>
<color name="material_deep_teal_300">#ff4db6ac</color>
- <color name="material_deep_teal_500">#ff009688</color>
+ <color name="material_deep_teal_500">#ff008577</color>
<color name="material_blue_grey_200">#ffb0bec5</color>
<color name="material_blue_grey_700">#ff455a64</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1083630..bbb0b0a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1996,7 +1996,7 @@
<!-- If true, the doze component is not started until after the screen has been
turned off and the screen off animation has been performed. -->
- <bool name="config_dozeAfterScreenOff">false</bool>
+ <bool name="config_dozeAfterScreenOffByDefault">false</bool>
<!-- Doze: should the TYPE_PICK_UP_GESTURE sensor be used as a pulse signal. -->
<bool name="config_dozePulsePickup">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ac01c4e..cf9ac2a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1817,7 +1817,7 @@
<java-symbol type="bool" name="config_notificationHeaderClickableForExpand" />
<java-symbol type="bool" name="config_enableNightMode" />
<java-symbol type="bool" name="config_tintNotificationActionButtons" />
- <java-symbol type="bool" name="config_dozeAfterScreenOff" />
+ <java-symbol type="bool" name="config_dozeAfterScreenOffByDefault" />
<java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" />
<java-symbol type="bool" name="config_enableFusedLocationOverlay" />
<java-symbol type="bool" name="config_enableHardwareFlpOverlay" />
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index c0f4920..a47ecf5 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -292,8 +292,7 @@
mState = new State(nCreate(nativeImageDecoder, decoder, width, height, cropRect),
inputStream, afd);
- // FIXME: Use the right size for the native allocation.
- long nativeSize = 200;
+ final long nativeSize = nNativeByteSize(mState.mNativePtr);
NativeAllocationRegistry registry = new NativeAllocationRegistry(
AnimatedImageDrawable.class.getClassLoader(), nGetNativeFinalizer(), nativeSize);
registry.registerNativeAllocation(mState, mState.mNativePtr);
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index 28d0bc4..c529f87 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -26,8 +26,8 @@
namespace android {
-AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage)
- : mSkAnimatedImage(std::move(animatedImage)) {
+AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed)
+ : mSkAnimatedImage(std::move(animatedImage)), mBytesUsed(bytesUsed) {
mTimeToShowNextSnapshot = mSkAnimatedImage->currentFrameDuration();
}
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.h b/libs/hwui/hwui/AnimatedImageDrawable.h
index f4e2ba7..a92b62d 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.h
+++ b/libs/hwui/hwui/AnimatedImageDrawable.h
@@ -45,7 +45,9 @@
*/
class ANDROID_API AnimatedImageDrawable : public SkDrawable {
public:
- AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage);
+ // bytesUsed includes the approximate sizes of the SkAnimatedImage and the SkPictures in the
+ // Snapshots.
+ AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed);
/**
* This updates the internal time and returns true if the animation needs
@@ -100,11 +102,17 @@
Snapshot decodeNextFrame();
Snapshot reset();
+ size_t byteSize() const {
+ return sizeof(this) + mBytesUsed;
+ }
+
protected:
virtual void onDraw(SkCanvas* canvas) override;
private:
sk_sp<SkAnimatedImage> mSkAnimatedImage;
+ const size_t mBytesUsed;
+
bool mRunning = false;
bool mStarting = false;
diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h
index 4857a87..7ac0d96 100644
--- a/libs/hwui/utils/Color.h
+++ b/libs/hwui/utils/Color.h
@@ -34,7 +34,7 @@
LightBlue_300 = 0xFF4FC3F7,
LightBlue_500 = 0xFF03A9F4,
Cyan_500 = 0xFF00BCD4,
- Teal_500 = 0xFF009688,
+ Teal_500 = 0xFF008577,
Teal_700 = 0xFF00796B,
Green_500 = 0xFF4CAF50,
Green_700 = 0xFF388E3C,
diff --git a/packages/PrintSpooler/res/drawable/ic_pdf_printer.xml b/packages/PrintSpooler/res/drawable/ic_pdf_printer.xml
index 8196650..b8a0689 100644
--- a/packages/PrintSpooler/res/drawable/ic_pdf_printer.xml
+++ b/packages/PrintSpooler/res/drawable/ic_pdf_printer.xml
@@ -18,7 +18,7 @@
android:height="36dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0"
- android:tint="@color/pdf_printer_color">
+ android:tint="@*android:color/accent_device_default_light">
<path
android:pathData="M40,4L16,4c-2.21,0 -4,1.79 -4,4v24c0,2.21 1.79,4 4,4h24c2.21,0 4,-1.79 4,-4L44,8c0,-2.21 -1.79,-4 -4,-4zM23,19c0,1.66 -1.34,3 -3,3h-2v4h-3L15,14h5c1.66,0 3,1.34 3,3v2zM33,23c0,1.66 -1.34,3 -3,3h-5L25,14h5c1.66,0 3,1.34 3,3v6zM41,17h-3v2h3v3h-3v4h-3L35,14h6v3zM18,19h2v-2h-2v2zM8,12L4,12v28c0,2.21 1.79,4 4,4h28v-4L8,40L8,12zM28,23h2v-6h-2v6z"
android:fillColor="@android:color/black"/>
diff --git a/packages/PrintSpooler/res/values/colors.xml b/packages/PrintSpooler/res/values/colors.xml
index a15fff5..68bc6f2 100644
--- a/packages/PrintSpooler/res/values/colors.xml
+++ b/packages/PrintSpooler/res/values/colors.xml
@@ -23,6 +23,4 @@
<color name="unselected_page_background_color">#C0C0C0</color>
<color name="material_grey_500">#ffa3a3a3</color>
-
- <color name="pdf_printer_color">#009688</color>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
new file mode 100644
index 0000000..cc69e0e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
@@ -0,0 +1,367 @@
+/*
+ * 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.settingslib.users;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import com.android.internal.util.UserIcons;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Helper class for managing users, providing methods for removing, adding and switching users.
+ */
+public final class UserManagerHelper {
+ private static final String TAG = "UserManagerHelper";
+ private final Context mContext;
+ private final UserManager mUserManager;
+ private OnUsersUpdateListener mUpdateListener;
+ private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mUpdateListener.onUsersUpdate();
+ }
+ };
+
+ public UserManagerHelper(Context context) {
+ mContext = context;
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ }
+
+ /**
+ * Registers a listener for updates to all users - removing, adding users or changing user info.
+ *
+ * @param listener Instance of {@link OnUsersUpdateListener}.
+ */
+ public void registerOnUsersUpdateListener(OnUsersUpdateListener listener) {
+ mUpdateListener = listener;
+ registerReceiver();
+ }
+
+ /**
+ * Unregisters listener by unregistering {@code BroadcastReceiver}.
+ */
+ public void unregisterOnUsersUpdateListener() {
+ unregisterReceiver();
+ }
+
+ /**
+ * Gets {@link UserInfo} for the current user.
+ *
+ * @return {@link UserInfo} for the current user.
+ */
+ public UserInfo getCurrentUserInfo() {
+ return mUserManager.getUserInfo(UserHandle.myUserId());
+ }
+
+ /**
+ * Gets all the other users on the system that are not the current user.
+ *
+ * @return List of {@code UserInfo} for each user that is not the current user.
+ */
+ public List<UserInfo> getAllUsersExcludesCurrentUser() {
+ List<UserInfo> others = mUserManager.getUsers(true);
+
+ for (Iterator<UserInfo> iterator = others.iterator(); iterator.hasNext(); ) {
+ UserInfo userInfo = iterator.next();
+ if (userInfo.id == UserHandle.myUserId()) {
+ // Remove current user from the list.
+ iterator.remove();
+ }
+ }
+ return others;
+ }
+
+ // User information accessors
+
+ /**
+ * Checks whether the user is system user (admin).
+ *
+ * @param userInfo User to check against system user.
+ * @return {@code true} if system user, {@code false} otherwise.
+ */
+ public boolean userIsSystemUser(UserInfo userInfo) {
+ return userInfo.id == UserHandle.USER_SYSTEM;
+ }
+
+ /**
+ * Returns whether this user can be removed from the system.
+ *
+ * @param userInfo User to be removed
+ * @return {@code true} if they can be removed, {@code false} otherwise.
+ */
+ public boolean userCanBeRemoved(UserInfo userInfo) {
+ return !userIsSystemUser(userInfo);
+ }
+
+ /**
+ * Checks whether passed in user is the user that's currently logged in.
+ *
+ * @param userInfo User to check.
+ * @return {@code true} if current user, {@code false} otherwise.
+ */
+ public boolean userIsCurrentUser(UserInfo userInfo) {
+ return getCurrentUserInfo().id == userInfo.id;
+ }
+
+ // Current user information accessors
+
+ /**
+ * Checks if the current user is a demo user.
+ */
+ public boolean isDemoUser() {
+ return mUserManager.isDemoUser();
+ }
+
+ /**
+ * Checks if the current user is a guest user.
+ */
+ public boolean isGuestUser() {
+ return mUserManager.isGuestUser();
+ }
+
+ /**
+ * Checks if the current user is the system user (User 0).
+ */
+ public boolean isSystemUser() {
+ return mUserManager.isSystemUser();
+ }
+
+ // Current user restriction accessors
+
+ /**
+ * Return whether the current user has a restriction.
+ *
+ * @param restriction Restriction to check. Should be a UserManager.* restriction.
+ * @return Whether that restriction exists for the current user.
+ */
+ public boolean hasUserRestriction(String restriction) {
+ return mUserManager.hasUserRestriction(restriction);
+ }
+
+ /**
+ * Checks if the current user can add new users.
+ */
+ public boolean canAddUsers() {
+ return !hasUserRestriction(UserManager.DISALLOW_ADD_USER);
+ }
+
+ /**
+ * Checks if the current user can remove users.
+ */
+ public boolean canRemoveUsers() {
+ return !hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
+ }
+
+ /**
+ * Checks if the current user is allowed to switch to another user.
+ */
+ public boolean canSwitchUsers() {
+ return !hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
+ }
+
+ /**
+ * Checks if the current user can modify accounts. Demo and Guest users cannot modify accounts
+ * even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied.
+ */
+ public boolean canModifyAccounts() {
+ return !hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS) && !isDemoUser()
+ && !isGuestUser();
+ }
+
+ // User actions
+
+ /**
+ * Creates a new user on the system.
+ *
+ * @param userName Name to give to the newly created user.
+ * @return Newly created user.
+ */
+ public UserInfo createNewUser(String userName) {
+ UserInfo user = mUserManager.createUser(userName, 0 /* flags */);
+ if (user == null) {
+ // Couldn't create user, most likely because there are too many, but we haven't
+ // been able to reload the list yet.
+ Log.w(TAG, "can't create user.");
+ return null;
+ }
+ assignDefaultIcon(user);
+ return user;
+ }
+
+ /**
+ * Tries to remove the user that's passed in. System user cannot be removed.
+ * If the user to be removed is current user, it switches to the system user first, and then
+ * removes the user.
+ *
+ * @param userInfo User to be removed
+ * @return {@code true} if user is successfully removed, {@code false} otherwise.
+ */
+ public boolean removeUser(UserInfo userInfo) {
+ if (userInfo.id == UserHandle.USER_SYSTEM) {
+ Log.w(TAG, "User " + userInfo.id + " is system user, could not be removed.");
+ return false;
+ }
+
+ if (userInfo.id == getCurrentUserInfo().id) {
+ switchToUserId(UserHandle.USER_SYSTEM);
+ }
+
+ return mUserManager.removeUser(userInfo.id);
+ }
+
+ /**
+ * Switches (logs in) to another user.
+ *
+ * @param userInfo User to switch to.
+ */
+ public void switchToUser(UserInfo userInfo) {
+ if (userInfo.id == getCurrentUserInfo().id) {
+ return;
+ }
+
+ if (userInfo.isGuest()) {
+ switchToGuest(userInfo.name);
+ return;
+ }
+
+ if (UserManager.isGuestUserEphemeral()) {
+ // If switching from guest, we want to bring up the guest exit dialog instead of
+ // switching
+ UserInfo currUserInfo = getCurrentUserInfo();
+ if (currUserInfo != null && currUserInfo.isGuest()) {
+ return;
+ }
+ }
+
+ switchToUserId(userInfo.id);
+ }
+
+ /**
+ * Creates a guest session and switches into the guest session.
+ *
+ * @param guestName Username for the guest user.
+ */
+ public void switchToGuest(String guestName) {
+ UserInfo guest = mUserManager.createGuest(mContext, guestName);
+ if (guest == null) {
+ // Couldn't create user, most likely because there are too many, but we haven't
+ // been able to reload the list yet.
+ Log.w(TAG, "can't create user.");
+ return;
+ }
+ switchToUserId(guest.id);
+ }
+
+ /**
+ * Gets an icon for the user.
+ *
+ * @param userInfo User for which we want to get the icon.
+ * @return a Bitmap for the icon
+ */
+ public Bitmap getUserIcon(UserInfo userInfo) {
+ Bitmap picture = mUserManager.getUserIcon(userInfo.id);
+
+ if (picture == null) {
+ return assignDefaultIcon(userInfo);
+ }
+
+ return picture;
+ }
+
+ /**
+ * Method for scaling a Bitmap icon to a desirable size.
+ *
+ * @param icon Bitmap to scale.
+ * @param desiredSize Wanted size for the icon.
+ * @return Drawable for the icon, scaled to the new size.
+ */
+ public Drawable scaleUserIcon(Bitmap icon, int desiredSize) {
+ Bitmap scaledIcon = Bitmap.createScaledBitmap(
+ icon, desiredSize, desiredSize, true /* filter */);
+ return new BitmapDrawable(mContext.getResources(), scaledIcon);
+ }
+
+ /**
+ * Sets new Username for the user.
+ *
+ * @param user User whose name should be changed.
+ * @param name New username.
+ */
+ public void setUserName(UserInfo user, String name) {
+ mUserManager.setUserName(user.id, name);
+ }
+
+ private void registerReceiver() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(Intent.ACTION_USER_ADDED);
+ filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
+ mContext.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, null);
+ }
+
+ /**
+ * Assigns a default icon to a user according to the user's id.
+ *
+ * @param userInfo User to assign a default icon to.
+ * @return Bitmap that has been assigned to the user.
+ */
+ private Bitmap assignDefaultIcon(UserInfo userInfo) {
+ Bitmap bitmap = UserIcons.convertToBitmap(
+ UserIcons.getDefaultUserIcon(mContext.getResources(), userInfo.id, false));
+ mUserManager.setUserIcon(userInfo.id, bitmap);
+ return bitmap;
+ }
+
+ private void switchToUserId(int id) {
+ try {
+ final ActivityManager am = (ActivityManager)
+ mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ am.switchUser(id);
+ } catch (Exception e) {
+ Log.e(TAG, "Couldn't switch user.", e);
+ }
+ }
+
+ private void unregisterReceiver() {
+ mContext.unregisterReceiver(mUserChangeReceiver);
+ }
+
+ /**
+ * Interface for listeners that want to register for receiving updates to changes to the users
+ * on the system including removing and adding users, and changing user info.
+ */
+ public interface OnUsersUpdateListener {
+ /**
+ * Method that will get called when users list has been changed.
+ */
+ void onUsersUpdate();
+ }
+}
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
index fd48eea..61efabc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java
@@ -76,7 +76,8 @@
* ["rssi 5Ghz", "num results on 5GHz" / "rssi 5Ghz", "num results on 5GHz"]
* For instance [-40,5/-30,2]
*/
- private static String getVisibilityStatus(AccessPoint accessPoint) {
+ @VisibleForTesting
+ static String getVisibilityStatus(AccessPoint accessPoint) {
final WifiInfo info = accessPoint.getInfo();
StringBuilder visibility = new StringBuilder();
StringBuilder scans24GHz = new StringBuilder();
@@ -110,6 +111,9 @@
// TODO: sort list by RSSI or age
long nowMs = SystemClock.elapsedRealtime();
for (ScanResult result : accessPoint.getScanResults()) {
+ if (result == null) {
+ continue;
+ }
if (result.frequency >= AccessPoint.LOWER_FREQ_5GHZ
&& result.frequency <= AccessPoint.HIGHER_FREQ_5GHZ) {
// Strictly speaking: [4915, 5825]
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
new file mode 100644
index 0000000..325ef3a
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
@@ -0,0 +1,318 @@
+/*
+ * 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.settingslib.users;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class UserManagerHelperTest {
+ @Mock
+ private Context mContext;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private ActivityManager mActivityManager;
+ @Mock
+ private UserManagerHelper.OnUsersUpdateListener mTestListener;
+
+ private UserManagerHelper mHelper;
+ private UserInfo mCurrentUser;
+ private UserInfo mSystemUser;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
+ when(mContext.getResources())
+ .thenReturn(InstrumentationRegistry.getTargetContext().getResources());
+ mHelper = new UserManagerHelper(mContext);
+
+ mCurrentUser = createUserInfoForId(UserHandle.myUserId());
+ mSystemUser = createUserInfoForId(UserHandle.USER_SYSTEM);
+ when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mCurrentUser);
+ }
+
+ @Test
+ public void testUserIsSystemUser() {
+ UserInfo testInfo = new UserInfo();
+
+ testInfo.id = UserHandle.USER_SYSTEM;
+ assertThat(mHelper.userIsSystemUser(testInfo)).isTrue();
+
+ testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
+ assertThat(mHelper.userIsSystemUser(testInfo)).isFalse();
+ }
+
+ @Test
+ public void testGetAllUsersExcludesCurrentUser() {
+ int currentUser = UserHandle.myUserId();
+
+ UserInfo otherUser1 = createUserInfoForId(currentUser + 1);
+ UserInfo otherUser2 = createUserInfoForId(currentUser - 1);
+ UserInfo otherUser3 = createUserInfoForId(currentUser + 2);
+
+ List<UserInfo> testUsers = new ArrayList<>();
+ testUsers.add(otherUser1);
+ testUsers.add(otherUser2);
+ testUsers.add(mCurrentUser);
+ testUsers.add(otherUser3);
+
+ when(mUserManager.getUsers(true)).thenReturn(testUsers);
+
+ // Should return 3 users that don't have currentUser id.
+ assertThat(mHelper.getAllUsersExcludesCurrentUser().size()).isEqualTo(3);
+ // Should not contain current user.
+ assertThat(mHelper.getAllUsersExcludesCurrentUser()).doesNotContain(mCurrentUser);
+ // Should contain non-current users.
+ assertThat(mHelper.getAllUsersExcludesCurrentUser()).contains(otherUser1);
+ assertThat(mHelper.getAllUsersExcludesCurrentUser()).contains(otherUser2);
+ assertThat(mHelper.getAllUsersExcludesCurrentUser()).contains(otherUser3);
+ }
+
+ @Test
+ public void testUserCanBeRemoved() {
+ UserInfo testInfo = new UserInfo();
+
+ // System user cannot be removed.
+ testInfo.id = UserHandle.USER_SYSTEM;
+ assertThat(mHelper.userCanBeRemoved(testInfo)).isFalse();
+
+ testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
+ assertThat(mHelper.userCanBeRemoved(testInfo)).isTrue();
+ }
+
+ @Test
+ public void testUserIsCurrentUser() {
+ UserInfo testInfo = new UserInfo();
+
+ // System user cannot be removed.
+ testInfo.id = UserHandle.myUserId();
+ assertThat(mHelper.userIsCurrentUser(testInfo)).isTrue();
+
+ testInfo.id = UserHandle.myUserId() + 2;
+ assertThat(mHelper.userIsCurrentUser(testInfo)).isFalse();
+ }
+
+ @Test
+ public void testCanAddUsers() {
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(false);
+ assertThat(mHelper.canAddUsers()).isTrue();
+
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(true);
+ assertThat(mHelper.canAddUsers()).isFalse();
+ }
+
+ @Test
+ public void testCanRemoveUsers() {
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(false);
+ assertThat(mHelper.canRemoveUsers()).isTrue();
+
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(true);
+ assertThat(mHelper.canRemoveUsers()).isFalse();
+ }
+
+ @Test
+ public void testCanSwitchUsers() {
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
+ assertThat(mHelper.canSwitchUsers()).isTrue();
+
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
+ assertThat(mHelper.canSwitchUsers()).isFalse();
+ }
+
+ @Test
+ public void testGuestCannotModifyAccounts() {
+ assertThat(mHelper.canModifyAccounts()).isTrue();
+
+ when(mUserManager.isGuestUser()).thenReturn(true);
+ assertThat(mHelper.canModifyAccounts()).isFalse();
+ }
+
+ @Test
+ public void testDemoUserCannotModifyAccounts() {
+ assertThat(mHelper.canModifyAccounts()).isTrue();
+
+ when(mUserManager.isDemoUser()).thenReturn(true);
+ assertThat(mHelper.canModifyAccounts()).isFalse();
+ }
+
+ @Test
+ public void testUserWithDisallowModifyAccountsRestrictionCannotModifyAccounts() {
+ assertThat(mHelper.canModifyAccounts()).isTrue();
+
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS))
+ .thenReturn(true);
+ assertThat(mHelper.canModifyAccounts()).isFalse();
+ }
+
+ @Test
+ public void testCreateNewUser() {
+ // Verify createUser on UserManager gets called.
+ mHelper.createNewUser("Test User");
+ verify(mUserManager).createUser("Test User", 0);
+
+ when(mUserManager.createUser("Test User", 0)).thenReturn(null);
+ assertThat(mHelper.createNewUser("Test User")).isNull();
+
+ UserInfo newUser = new UserInfo();
+ newUser.name = "Test User";
+ when(mUserManager.createUser("Test User", 0)).thenReturn(newUser);
+ assertThat(mHelper.createNewUser("Test User")).isEqualTo(newUser);
+ }
+
+ @Test
+ public void testRemoveUser() {
+ // Cannot remove system user.
+ assertThat(mHelper.removeUser(mSystemUser)).isFalse();
+
+ // Removing current user, calls "switch" to system user.
+ mHelper.removeUser(mCurrentUser);
+ verify(mActivityManager).switchUser(UserHandle.USER_SYSTEM);
+ verify(mUserManager).removeUser(mCurrentUser.id);
+
+ // Removing non-current, non-system user, simply calls removeUser.
+ UserInfo userToRemove = createUserInfoForId(mCurrentUser.id + 2);
+ mHelper.removeUser(userToRemove);
+ verify(mUserManager).removeUser(mCurrentUser.id + 2);
+ }
+
+ @Test
+ public void testSwitchToUser() {
+ // Switching to current user doesn't do anything.
+ mHelper.switchToUser(mCurrentUser);
+ verify(mActivityManager, never()).switchUser(mCurrentUser.id);
+
+ // Switching to Guest calls createGuest.
+ UserInfo guestInfo = new UserInfo(mCurrentUser.id + 1, "Test Guest", UserInfo.FLAG_GUEST);
+ mHelper.switchToUser(guestInfo);
+ verify(mUserManager).createGuest(mContext, "Test Guest");
+
+ // Switching to non-current, non-guest user, simply calls switchUser.
+ UserInfo userToSwitchTo = new UserInfo(mCurrentUser.id + 5, "Test User", 0);
+ mHelper.switchToUser(userToSwitchTo);
+ verify(mActivityManager).switchUser(mCurrentUser.id + 5);
+ }
+
+ @Test
+ public void testSwitchToGuest() {
+ mHelper.switchToGuest("Test Guest");
+ verify(mUserManager).createGuest(mContext, "Test Guest");
+
+ UserInfo guestInfo = new UserInfo(mCurrentUser.id + 2, "Test Guest", UserInfo.FLAG_GUEST);
+ when(mUserManager.createGuest(mContext, "Test Guest")).thenReturn(guestInfo);
+ mHelper.switchToGuest("Test Guest");
+ verify(mActivityManager).switchUser(mCurrentUser.id + 2);
+ }
+
+ @Test
+ public void testGetUserIcon() {
+ mHelper.getUserIcon(mCurrentUser);
+ verify(mUserManager).getUserIcon(mCurrentUser.id);
+ }
+
+ @Test
+ public void testScaleUserIcon() {
+ Bitmap fakeIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ Drawable scaledIcon = mHelper.scaleUserIcon(fakeIcon, 300);
+ assertThat(scaledIcon.getIntrinsicWidth()).isEqualTo(300);
+ assertThat(scaledIcon.getIntrinsicHeight()).isEqualTo(300);
+ }
+
+ @Test
+ public void testSetUserName() {
+ UserInfo testInfo = createUserInfoForId(mCurrentUser.id + 3);
+ mHelper.setUserName(testInfo, "New Test Name");
+ verify(mUserManager).setUserName(mCurrentUser.id + 3, "New Test Name");
+ }
+
+ @Test
+ public void testRegisterUserChangeReceiver() {
+ mHelper.registerOnUsersUpdateListener(mTestListener);
+
+ ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ ArgumentCaptor<UserHandle> handleCaptor = ArgumentCaptor.forClass(UserHandle.class);
+ ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
+ ArgumentCaptor<String> permissionCaptor = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+
+ verify(mContext).registerReceiverAsUser(
+ receiverCaptor.capture(),
+ handleCaptor.capture(),
+ filterCaptor.capture(),
+ permissionCaptor.capture(),
+ handlerCaptor.capture());
+
+ // Verify we're listening to Intents from ALL users.
+ assertThat(handleCaptor.getValue()).isEqualTo(UserHandle.ALL);
+
+ // Verify the presence of each intent in the filter.
+ // Verify the exact number of filters. Every time a new intent is added, this test should
+ // get updated.
+ assertThat(filterCaptor.getValue().countActions()).isEqualTo(3);
+ assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_REMOVED)).isTrue();
+ assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_ADDED)).isTrue();
+ assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue();
+
+ // Verify that calling the receiver calls the listener.
+ receiverCaptor.getValue().onReceive(mContext, new Intent());
+ verify(mTestListener).onUsersUpdate();
+
+ assertThat(permissionCaptor.getValue()).isNull();
+ assertThat(handlerCaptor.getValue()).isNull();
+
+
+ // Unregister the receiver.
+ mHelper.unregisterOnUsersUpdateListener();
+ verify(mContext).unregisterReceiver(receiverCaptor.getValue());
+ }
+
+ private UserInfo createUserInfoForId(int id) {
+ UserInfo userInfo = new UserInfo();
+ userInfo.id = id;
+ return userInfo;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
index ea8ecba..91d9f91 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiUtilsTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -31,6 +32,7 @@
import android.os.Parcelable;
import android.os.SystemClock;
import android.text.format.DateUtils;
+import android.util.ArraySet;
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
@@ -43,6 +45,7 @@
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
+import java.util.Set;
@RunWith(SettingsLibRobolectricTestRunner.class)
public class WifiUtilsTest {
@@ -56,6 +59,8 @@
private RssiCurve mockBadgeCurve;
@Mock
private WifiNetworkScoreCache mockWifiNetworkScoreCache;
+ @Mock
+ private AccessPoint mAccessPoint;
@Before
public void setUp() {
@@ -84,6 +89,15 @@
assertThat(summary.contains(mContext.getString(R.string.speed_label_very_fast))).isTrue();
}
+ @Test
+ public void testGetVisibilityStatus_nullResultDoesNotCrash() {
+ doReturn(null).when(mAccessPoint).getInfo();
+ Set<ScanResult> set = new ArraySet<>();
+ set.add(null);
+ doReturn(set).when(mAccessPoint).getScanResults();
+ WifiUtils.getVisibilityStatus(mAccessPoint);
+ }
+
private static ArrayList<ScanResult> buildScanResultCache() {
ArrayList<ScanResult> scanResults = new ArrayList<>();
for (int i = 0; i < 5; i++) {
diff --git a/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml b/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
index 3345f61..6a7f18b 100644
--- a/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
+++ b/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:pathData="M20.000000,5.000000L4.000000,5.000000C2.900000,5.000000 2.000000,5.900000 2.000000,7.000000l0.000000,10.000000c0.000000,1.100000 0.900000,2.000000 2.000000,2.000000l16.000000,0.000000c1.100000,0.000000 2.000000,-0.900000 2.000000,-2.000000L22.000000,7.000000C22.000000,5.900000 21.100000,5.000000 20.000000,5.000000zM11.000000,8.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000L11.000000,8.000000zM11.000000,11.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000L11.000000,11.000000zM8.000000,8.000000l2.000000,0.000000l0.000000,2.000000L8.000000,10.000000L8.000000,8.000000zM8.000000,11.000000l2.000000,0.000000l0.000000,2.000000L8.000000,13.000000L8.000000,11.000000zM7.000000,13.000000L5.000000,13.000000l0.000000,-2.000000l2.000000,0.000000L7.000000,13.000000zM7.000000,10.000000L5.000000,10.000000L5.000000,8.000000l2.000000,0.000000L7.000000,10.000000zM16.000000,17.000000L8.000000,17.000000l0.000000,-2.000000l8.000000,0.000000L16.000000,17.000000zM16.000000,13.000000l-2.000000,0.000000l0.000000,-2.000000l2.000000,0.000000L16.000000,13.000000zM16.000000,10.000000l-2.000000,0.000000L14.000000,8.000000l2.000000,0.000000L16.000000,10.000000zM19.000000,13.000000l-2.000000,0.000000l0.000000,-2.000000l2.000000,0.000000L19.000000,13.000000zM19.000000,10.000000l-2.000000,0.000000L17.000000,8.000000l2.000000,0.000000L19.000000,10.000000z"
+ android:pathData="M21,4H3C1.9,4 1,4.9 1,6v13c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2V6C23,4.9 22.1,4 21,4zM21,19H3V6h18V19zM9,8h2v2H9V8zM5,8h2v2H5V8zM8,16h8v1H8V16zM13,8h2v2h-2V8zM9,12h2v2H9V12zM5,12h2v2H5V12zM13,12h2v2h-2V12zM17,8h2v2h-2V8zM17,12h2v2h-2V12z"
android:fillColor="?attr/singleToneColor"/>
</vector>
diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml
index 734c877..26cf792 100644
--- a/packages/SystemUI/res/layout/rounded_corners.xml
+++ b/packages/SystemUI/res/layout/rounded_corners.xml
@@ -14,7 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
-->
-<FrameLayout
+<com.android.systemui.RegionInterceptingFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -32,4 +32,4 @@
android:tint="#ff000000"
android:layout_gravity="right|bottom"
android:src="@drawable/rounded" />
-</FrameLayout>
+</com.android.systemui.RegionInterceptingFrameLayout>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c5b3222..3c8a695 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1845,7 +1845,7 @@
<string name="right_icon">Right icon</string>
<!-- Label for area where tiles can be dragged out of [CHAR LIMIT=60] -->
- <string name="drag_to_add_tiles">Drag to add tiles</string>
+ <string name="drag_to_add_tiles">Hold and drag to add tiles</string>
<!-- Label for area where tiles can be dragged in to [CHAR LIMIT=60] -->
<string name="drag_to_remove_tiles">Drag here to remove</string>
diff --git a/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java
new file mode 100644
index 0000000..646f69e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.content.Context;
+import android.graphics.Region;
+import android.graphics.Region.Op;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.InternalInsetsInfo;
+import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
+import android.widget.FrameLayout;
+
+/**
+ * Frame layout that will intercept the touches of children if they want to
+ */
+public class RegionInterceptingFrameLayout extends FrameLayout {
+ public RegionInterceptingFrameLayout(Context context) {
+ super(context);
+ }
+
+ public RegionInterceptingFrameLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public RegionInterceptingFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public RegionInterceptingFrameLayout(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
+ }
+
+ private final OnComputeInternalInsetsListener mInsetsListener = internalInsetsInfo -> {
+ internalInsetsInfo.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ internalInsetsInfo.touchableRegion.setEmpty();
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (!(child instanceof RegionInterceptableView)) {
+ continue;
+ }
+ RegionInterceptableView riv = (RegionInterceptableView) child;
+ if (!riv.shouldInterceptTouch()) {
+ continue;
+ }
+ Region unionRegion = riv.getInterceptRegion();
+ if (unionRegion == null) {
+ continue;
+ }
+
+ internalInsetsInfo.touchableRegion.op(riv.getInterceptRegion(), Op.UNION);
+ }
+ };
+
+ public interface RegionInterceptableView {
+ default public boolean shouldInterceptTouch() {
+ return false;
+ }
+
+ public Region getInterceptRegion();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 9a20c81..a0fa69e 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -49,6 +49,7 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
+import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
@@ -232,8 +233,7 @@
ViewGroup.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
- WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
- | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY
@@ -317,7 +317,8 @@
}
}
- public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener {
+ public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener,
+ RegionInterceptableView {
private final DisplayInfo mInfo = new DisplayInfo();
private final Paint mPaint = new Paint();
@@ -468,5 +469,19 @@
}
}
}
+
+ @Override
+ public boolean shouldInterceptTouch() {
+ return mInfo.displayCutout != null && getVisibility() == VISIBLE;
+ }
+
+ @Override
+ public Region getInterceptRegion() {
+ if (mInfo.displayCutout == null) {
+ return null;
+ }
+
+ return mInfo.displayCutout.getBounds();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index b493d7a..a39800d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -464,7 +464,10 @@
private void onRotationSuggestionsDisabled() {
// Immediately hide the rotate button and clear any planned removal
setRotateSuggestionButtonState(false, true);
- getView().removeCallbacks(mRemoveRotationProposal);
+
+ // This method can be called before view setup is done, ensure getView isn't null
+ final View v = getView();
+ if (v != null) v.removeCallbacks(mRemoveRotationProposal);
}
private void showAndLogRotationSuggestion() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index fcbd37c..8fb0620 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -679,11 +679,12 @@
public void updateStates() {
updateSlippery();
+ reloadNavIcons();
updateNavButtonIcons();
}
private void updateSlippery() {
- setSlippery(mOverviewProxyService.getProxy() != null && mPanelView.isFullyExpanded());
+ setSlippery(!isQuickStepSwipeUpEnabled() || mPanelView.isFullyExpanded());
}
private void setSlippery(boolean slippery) {
@@ -818,8 +819,6 @@
public void onOverviewProxyConnectionChanged(boolean isConnected) {
updateStates();
setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
- reloadNavIcons();
- updateNavButtonIcons();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 5c91fd5..6852df6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1146,6 +1146,14 @@
@Override
public void run() {
mKeyguardStatusViewAnimating = false;
+ mKeyguardStatusView.setVisibility(View.INVISIBLE);
+ }
+ };
+
+ private final Runnable mAnimateKeyguardStatusViewGoneEndRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mKeyguardStatusViewAnimating = false;
mKeyguardStatusView.setVisibility(View.GONE);
}
};
@@ -1234,16 +1242,17 @@
private void setKeyguardStatusViewVisibility(int statusBarState, boolean keyguardFadingAway,
boolean goingToFullShade) {
+ mKeyguardStatusView.animate().cancel();
+ mKeyguardStatusViewAnimating = false;
if ((!keyguardFadingAway && mStatusBarState == StatusBarState.KEYGUARD
&& statusBarState != StatusBarState.KEYGUARD) || goingToFullShade) {
- mKeyguardStatusView.animate().cancel();
mKeyguardStatusViewAnimating = true;
mKeyguardStatusView.animate()
.alpha(0f)
.setStartDelay(0)
.setDuration(160)
.setInterpolator(Interpolators.ALPHA_OUT)
- .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable);
+ .withEndAction(mAnimateKeyguardStatusViewGoneEndRunnable);
if (keyguardFadingAway) {
mKeyguardStatusView.animate()
.setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
@@ -1252,7 +1261,6 @@
}
} else if (mStatusBarState == StatusBarState.SHADE_LOCKED
&& statusBarState == StatusBarState.KEYGUARD) {
- mKeyguardStatusView.animate().cancel();
mKeyguardStatusView.setVisibility(View.VISIBLE);
mKeyguardStatusViewAnimating = true;
mKeyguardStatusView.setAlpha(0f);
@@ -1263,13 +1271,21 @@
.setInterpolator(Interpolators.ALPHA_IN)
.withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable);
} else if (statusBarState == StatusBarState.KEYGUARD) {
- mKeyguardStatusView.animate().cancel();
- mKeyguardStatusViewAnimating = false;
- mKeyguardStatusView.setVisibility(View.VISIBLE);
- mKeyguardStatusView.setAlpha(1f);
+ if (keyguardFadingAway) {
+ mKeyguardStatusViewAnimating = true;
+ mKeyguardStatusView.animate()
+ .alpha(0)
+ .translationYBy(-getHeight() * 0.05f)
+ .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
+ .setDuration(125)
+ .setStartDelay(0)
+ .withEndAction(mAnimateKeyguardStatusViewInvisibleEndRunnable)
+ .start();
+ } else {
+ mKeyguardStatusView.setVisibility(View.VISIBLE);
+ mKeyguardStatusView.setAlpha(1f);
+ }
} else {
- mKeyguardStatusView.animate().cancel();
- mKeyguardStatusViewAnimating = false;
mKeyguardStatusView.setVisibility(View.GONE);
mKeyguardStatusView.setAlpha(1f);
}
@@ -2728,4 +2744,13 @@
HeadsUpAppearanceController headsUpAppearanceController) {
mHeadsUpAppearanceController = headsUpAppearanceController;
}
+
+ /**
+ * Starts the animation before we dismiss Keyguard, i.e. an disappearing animation on the
+ * security view of the bouncer.
+ */
+ public void onBouncerPreHideAnimation() {
+ setKeyguardStatusViewVisibility(mStatusBarState, true /* keyguardFadingAway */,
+ false /* goingToFullShade */);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 8b23fdb..a9c467e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -377,6 +377,7 @@
public void startPreHideAnimation(Runnable finishRunnable) {
if (mBouncer.isShowing()) {
mBouncer.startPreHideAnimation(finishRunnable);
+ mNotificationPanelView.onBouncerPreHideAnimation();
} else if (finishRunnable != null) {
finishRunnable.run();
}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 0cc60e3..5d2e241 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5541,6 +5541,11 @@
// OS: P
FIELD_ANOMALY_TYPE = 1366;
+ // ACTION: Settings > Anomaly receiver > Anomaly received
+ // CATEGORY: SETTINGS
+ // OS: P
+ ACTION_ANOMALY_TRIGGERED = 1367;
+
// ---- 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/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d6f6c6c..4cac707 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -215,13 +215,6 @@
// Timeout interval for deciding that a bind or clear-data has taken too long
private static final long TIMEOUT_INTERVAL = 10 * 1000;
- // Timeout intervals for agent backup & restore operations
- public static final long TIMEOUT_BACKUP_INTERVAL = 30 * 1000;
- public static final long TIMEOUT_FULL_BACKUP_INTERVAL = 5 * 60 * 1000;
- public static final long TIMEOUT_SHARED_BACKUP_INTERVAL = 30 * 60 * 1000;
- public static final long TIMEOUT_RESTORE_INTERVAL = 60 * 1000;
- public static final long TIMEOUT_RESTORE_FINISHED_INTERVAL = 30 * 1000;
-
// User confirmation timeout for a full backup/restore operation. It's this long in
// order to give them time to enter the backup password.
private static final long TIMEOUT_FULL_CONFIRMATION = 60 * 1000;
@@ -232,6 +225,7 @@
private static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2; // two hours
private BackupManagerConstants mConstants;
+ private BackupAgentTimeoutParameters mAgentTimeoutParameters;
private Context mContext;
private PackageManager mPackageManager;
private IPackageManager mPackageManagerBinder;
@@ -315,6 +309,10 @@
return mConstants;
}
+ public BackupAgentTimeoutParameters getAgentTimeoutParameters() {
+ return mAgentTimeoutParameters;
+ }
+
public Context getContext() {
return mContext;
}
@@ -856,6 +854,10 @@
// require frequent starting and stopping.
mConstants.start();
+ mAgentTimeoutParameters = new
+ BackupAgentTimeoutParameters(mBackupHandler, mContext.getContentResolver());
+ mAgentTimeoutParameters.start();
+
// Set up the various sorts of package tracking we do
mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
initPackageTracking();
@@ -3407,7 +3409,7 @@
}
mActiveRestoreSession = new ActiveRestoreSession(this, packageName, transport);
mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT,
- TIMEOUT_RESTORE_INTERVAL);
+ mAgentTimeoutParameters.getRestoreAgentTimeoutMillis());
}
return mActiveRestoreSession;
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
index 7b021c6..aabe7f6 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
@@ -191,4 +191,7 @@
void dump(FileDescriptor fd, PrintWriter pw, String[] args);
IBackupManager getBackupManagerBinder();
+
+ // Gets access to the backup/restore agent timeout parameters.
+ BackupAgentTimeoutParameters getAgentTimeoutParameters();
}
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index 4755877..f08c655 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -4,8 +4,8 @@
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
+
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_BACKUP_INTERVAL;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
@@ -59,6 +59,7 @@
private ParcelFileDescriptor mSavedState;
private ParcelFileDescriptor mBackupData;
private ParcelFileDescriptor mNewState;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
public KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
BackupManagerServiceInterface backupManagerService, PackageManager packageManager,
@@ -81,6 +82,7 @@
pkg + BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX);
mManifestFile = new File(mDataDir, BackupManagerService.BACKUP_MANIFEST_FILENAME);
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
}
public void backupOnePackage() throws IOException {
@@ -148,8 +150,9 @@
// Return true on backup success, false otherwise
private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
int token = mBackupManagerService.generateRandomIntegerToken();
+ long kvBackupAgentTimeoutMillis = mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
try {
- mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
+ mBackupManagerService.prepareOperationTimeout(token, kvBackupAgentTimeoutMillis, null,
OP_TYPE_BACKUP_WAIT);
// Start backup and wait for BackupManagerService to get callback for success or timeout
@@ -231,14 +234,14 @@
}
private void writeBackupData() throws IOException {
-
int token = mBackupManagerService.generateRandomIntegerToken();
+ long kvBackupAgentTimeoutMillis = mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
ParcelFileDescriptor[] pipes = null;
try {
pipes = ParcelFileDescriptor.createPipe();
- mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
+ mBackupManagerService.prepareOperationTimeout(token, kvBackupAgentTimeoutMillis, null,
OP_TYPE_BACKUP_WAIT);
// We will have to create a runnable that will read the manifest and backup data we
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 0582aba..597da21 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -25,9 +25,6 @@
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
-import static com.android.server.backup.BackupManagerService
- .TIMEOUT_SHARED_BACKUP_INTERVAL;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
@@ -45,8 +42,9 @@
import android.util.StringBuilderPrinter;
import com.android.server.AppWidgetBackupBridge;
-import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
+import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.utils.FullBackupUtils;
import java.io.BufferedOutputStream;
@@ -75,6 +73,7 @@
private final long mQuota;
private final int mOpToken;
private final int mTransportFlags;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
class FullBackupRunner implements Runnable {
@@ -137,8 +136,8 @@
final boolean isSharedStorage =
mPackage.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
final long timeout = isSharedStorage ?
- TIMEOUT_SHARED_BACKUP_INTERVAL :
- TIMEOUT_FULL_BACKUP_INTERVAL;
+ mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis() :
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
if (DEBUG) {
Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
@@ -180,6 +179,7 @@
mQuota = quota;
mOpToken = opToken;
mTransportFlags = transportFlags;
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
}
public int preflightCheck() throws RemoteException {
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
index 40b6967..d441cf6 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
@@ -19,7 +19,6 @@
import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
import android.app.backup.IBackupManager;
import android.content.ComponentName;
@@ -33,6 +32,7 @@
import android.util.Slog;
import com.android.internal.backup.IObbBackupService;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.utils.FullBackupUtils;
@@ -46,10 +46,12 @@
private BackupManagerService backupManagerService;
volatile IObbBackupService mService;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
public FullBackupObbConnection(BackupManagerService backupManagerService) {
this.backupManagerService = backupManagerService;
mService = null;
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
}
public void establish() {
@@ -75,8 +77,10 @@
try {
pipes = ParcelFileDescriptor.createPipe();
int token = backupManagerService.generateRandomIntegerToken();
+ long fullBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
backupManagerService.prepareOperationTimeout(
- token, TIMEOUT_FULL_BACKUP_INTERVAL, null, OP_TYPE_BACKUP_WAIT);
+ token, fullBackupAgentTimeoutMillis, null, OP_TYPE_BACKUP_WAIT);
mService.backupObbs(pkg.packageName, pipes[1], token,
backupManagerService.getBackupManagerBinder());
FullBackupUtils.routeSocketDataToOutput(pipes[0], out);
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 2c2dd85..1ea3eb5 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -22,7 +22,6 @@
import static com.android.server.backup.BackupManagerService.OP_PENDING;
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
import android.annotation.Nullable;
import android.app.IBackupAgent;
@@ -44,6 +43,7 @@
import com.android.internal.backup.IBackupTransport;
import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.FullBackupJob;
import com.android.server.backup.BackupManagerService;
@@ -146,6 +146,7 @@
private volatile boolean mIsDoingBackup;
private volatile boolean mCancelAll;
private final int mCurrentOpToken;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
public PerformFullTransportBackupTask(BackupManagerService backupManagerService,
TransportClient transportClient,
@@ -167,6 +168,7 @@
mUserInitiated = userInitiated;
mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
mBackupRunnerOpToken = backupManagerService.generateRandomIntegerToken();
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
if (backupManagerService.isBackupOperationInProgress()) {
if (DEBUG) {
@@ -698,9 +700,11 @@
@Override
public int preflightFullBackup(PackageInfo pkg, IBackupAgent agent) {
int result;
+ long fullBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
try {
backupManagerService.prepareOperationTimeout(
- mCurrentOpToken, TIMEOUT_FULL_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+ mCurrentOpToken, fullBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
backupManagerService.addBackupTrace("preflighting");
if (MORE_DEBUG) {
Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
@@ -713,7 +717,7 @@
// timeout had been produced. In case of a real backstop timeout, mResult
// will still contain the value it was constructed with, AGENT_ERROR, which
// intentionaly falls into the "just report failure" code.
- mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ mLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
long totalSize = mResult.get();
// If preflight timed out, mResult will contain error code as int.
@@ -769,8 +773,10 @@
@Override
public long getExpectedSizeOrErrorCode() {
+ long fullBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
try {
- mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ mLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
return mResult.get();
} catch (InterruptedException e) {
return BackupTransport.NO_MORE_DATA;
@@ -863,8 +869,10 @@
// If preflight succeeded, returns positive number - preflight size,
// otherwise return negative error code.
long getPreflightResultBlocking() {
+ long fullBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
try {
- mPreflightLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ mPreflightLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
if (mIsCancelled) {
return BackupManager.ERROR_BACKUP_CANCELLED;
}
@@ -879,8 +887,10 @@
}
int getBackupResultBlocking() {
+ long fullBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
try {
- mBackupLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ mBackupLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
if (mIsCancelled) {
return BackupManager.ERROR_BACKUP_CANCELLED;
}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index 136fada..5886862 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -19,7 +19,6 @@
import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
import android.app.backup.RestoreSet;
import android.content.Intent;
@@ -34,6 +33,7 @@
import com.android.internal.backup.IBackupTransport;
import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
@@ -81,10 +81,12 @@
public static final int MSG_OP_COMPLETE = 21;
private final BackupManagerService backupManagerService;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
public BackupHandler(BackupManagerService backupManagerService, Looper looper) {
super(looper);
this.backupManagerService = backupManagerService;
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
}
public void handleMessage(Message msg) {
@@ -322,7 +324,8 @@
// Done: reset the session timeout clock
removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
- sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
+ sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT,
+ mAgentTimeoutParameters.getRestoreAgentTimeoutMillis());
params.listener.onFinished(callerLogString);
}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 11394e66..0313066 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -24,7 +24,6 @@
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.BackupManagerService.PACKAGE_MANAGER_SENTINEL;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_BACKUP_INTERVAL;
import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
@@ -57,6 +56,7 @@
import com.android.internal.backup.IBackupTransport;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
import com.android.server.backup.KeyValueBackupJob;
@@ -142,6 +142,7 @@
private boolean mFinished;
private final boolean mUserInitiated;
private final boolean mNonIncremental;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
private volatile boolean mCancelAll;
@@ -162,6 +163,7 @@
mPendingFullBackups = pendingFullBackups;
mUserInitiated = userInitiated;
mNonIncremental = nonIncremental;
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
mStateDir = new File(backupManagerService.getBaseStateDir(), dirName);
mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
@@ -711,8 +713,10 @@
// Initiate the target's backup pass
backupManagerService.addBackupTrace("setting timeout");
+ long kvBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
backupManagerService.prepareOperationTimeout(
- mEphemeralOpToken, TIMEOUT_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+ mEphemeralOpToken, kvBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
backupManagerService.addBackupTrace("calling agent doBackup()");
agent.doBackup(
diff --git a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
index e4f3a9d..6175629 100644
--- a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
+++ b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
@@ -18,10 +18,10 @@
import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
import android.util.Slog;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
@@ -37,18 +37,22 @@
private BackupManagerService backupManagerService;
final CountDownLatch mLatch;
private final int mCurrentOpToken;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
public AdbRestoreFinishedLatch(BackupManagerService backupManagerService,
int currentOpToken) {
this.backupManagerService = backupManagerService;
mLatch = new CountDownLatch(1);
mCurrentOpToken = currentOpToken;
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
}
void await() {
boolean latched = false;
+ long fullBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
try {
- latched = mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+ latched = mLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Slog.w(TAG, "Interrupted!");
}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index c1a1c1d..f168afed 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -23,9 +23,6 @@
import static com.android.server.backup.BackupManagerService.OP_TYPE_RESTORE_WAIT;
import static com.android.server.backup.BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
-import static com.android.server.backup.BackupManagerService
- .TIMEOUT_SHARED_BACKUP_INTERVAL;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
import android.app.ApplicationThreadConstants;
@@ -43,10 +40,11 @@
import android.util.Slog;
import com.android.server.LocalServices;
+import com.android.server.backup.BackupAgentTimeoutParameters;
+import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.FileMetadata;
import com.android.server.backup.KeyValueAdbRestoreEngine;
-import com.android.server.backup.BackupManagerService;
import com.android.server.backup.fullbackup.FullBackupObbConnection;
import com.android.server.backup.utils.BytesReadListener;
import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
@@ -121,6 +119,8 @@
final int mEphemeralOpToken;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
+
public FullRestoreEngine(BackupManagerService backupManagerService,
BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
IBackupManagerMonitor monitor, PackageInfo onlyPackage, boolean allowApks,
@@ -135,6 +135,7 @@
mAllowObbs = allowObbs;
mBuffer = new byte[32 * 1024];
mBytes = 0;
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
}
public IBackupAgent getAgent() {
@@ -381,8 +382,8 @@
long toCopy = info.size;
final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
final long timeout = isSharedStorage ?
- TIMEOUT_SHARED_BACKUP_INTERVAL :
- TIMEOUT_RESTORE_INTERVAL;
+ mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis() :
+ mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
try {
mBackupManagerService.prepareOperationTimeout(token,
timeout,
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index dacde0b..221637c 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -16,8 +16,6 @@
package com.android.server.backup.restore;
-import static com.android.server.backup.BackupPasswordManager.PBKDF_CURRENT;
-import static com.android.server.backup.BackupPasswordManager.PBKDF_FALLBACK;
import static com.android.server.backup.BackupManagerService.BACKUP_FILE_HEADER_MAGIC;
import static com.android.server.backup.BackupManagerService.BACKUP_FILE_VERSION;
import static com.android.server.backup.BackupManagerService.BACKUP_MANIFEST_FILENAME;
@@ -28,8 +26,8 @@
import static com.android.server.backup.BackupManagerService.SETTINGS_PACKAGE;
import static com.android.server.backup.BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.BackupPasswordManager.PBKDF_CURRENT;
+import static com.android.server.backup.BackupPasswordManager.PBKDF_FALLBACK;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
import android.app.ApplicationThreadConstants;
@@ -49,6 +47,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.FileMetadata;
import com.android.server.backup.KeyValueAdbRestoreEngine;
@@ -101,6 +100,7 @@
private byte[] mWidgetData = null;
private long mBytes;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
// Runner that can be placed on a separate thread to do in-process invocation
// of the "restore finished" API asynchronously. Used by adb restore.
@@ -155,6 +155,7 @@
mAgentPackage = null;
mTargetApp = null;
mObbConnection = new FullBackupObbConnection(backupManagerService);
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
// Which packages we've already wiped data on. We prepopulate this
// with a whitelist of packages known to be unclearable.
@@ -643,9 +644,11 @@
if (okay) {
boolean agentSuccess = true;
long toCopy = info.size;
+ long restoreAgentTimeoutMillis =
+ mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
try {
mBackupManagerService.prepareOperationTimeout(
- token, TIMEOUT_RESTORE_INTERVAL, null, OP_TYPE_RESTORE_WAIT);
+ token, restoreAgentTimeoutMillis, null, OP_TYPE_RESTORE_WAIT);
if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
if (DEBUG) {
@@ -820,10 +823,12 @@
// In the adb restore case, we do restore-finished here
if (doRestoreFinished) {
final int token = mBackupManagerService.generateRandomIntegerToken();
+ long fullBackupAgentTimeoutMillis =
+ mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(
mBackupManagerService, token);
mBackupManagerService.prepareOperationTimeout(
- token, TIMEOUT_FULL_BACKUP_INTERVAL, latch, OP_TYPE_RESTORE_WAIT);
+ token, fullBackupAgentTimeoutMillis, latch, OP_TYPE_RESTORE_WAIT);
if (mTargetApp.processName.equals("system")) {
if (MORE_DEBUG) {
Slog.d(TAG, "system agent - restoreFinished on thread");
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 4b467e5..069e3b6 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -23,9 +23,6 @@
import static com.android.server.backup.BackupManagerService.PACKAGE_MANAGER_SENTINEL;
import static com.android.server.backup.BackupManagerService.SETTINGS_PACKAGE;
import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService
- .TIMEOUT_RESTORE_FINISHED_INTERVAL;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
@@ -59,6 +56,7 @@
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.BackupUtils;
import com.android.server.backup.PackageManagerBackupAgent;
@@ -160,6 +158,7 @@
ParcelFileDescriptor mNewState;
private final int mEphemeralOpToken;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
// This task can assume that the wakelock is properly held for it and doesn't have to worry
// about releasing it.
@@ -190,6 +189,7 @@
mFinished = false;
mDidLaunch = false;
mListener = listener;
+ mAgentTimeoutParameters = backupManagerService.getAgentTimeoutParameters();
if (targetPackage != null) {
// Single package restore
@@ -760,8 +760,9 @@
// Kick off the restore, checking for hung agents. The timeout or
// the operationComplete() callback will schedule the next step,
// so we do not do that here.
+ long restoreAgentTimeoutMillis = mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
backupManagerService.prepareOperationTimeout(
- mEphemeralOpToken, TIMEOUT_RESTORE_INTERVAL, this, OP_TYPE_RESTORE_WAIT);
+ mEphemeralOpToken, restoreAgentTimeoutMillis, this, OP_TYPE_RESTORE_WAIT);
mAgent.doRestore(mBackupData, appVersionCode, mNewState,
mEphemeralOpToken, backupManagerService.getBackupManagerBinder());
} catch (Exception e) {
@@ -813,9 +814,11 @@
Slog.d(TAG, "restoreFinished packageName=" + mCurrentPackage.packageName);
}
try {
+ long restoreAgentFinishedTimeoutMillis =
+ mAgentTimeoutParameters.getRestoreAgentFinishedTimeoutMillis();
backupManagerService
.prepareOperationTimeout(mEphemeralOpToken,
- TIMEOUT_RESTORE_FINISHED_INTERVAL, this,
+ restoreAgentFinishedTimeoutMillis, this,
OP_TYPE_RESTORE_WAIT);
mAgent.doRestoreFinished(mEphemeralOpToken,
backupManagerService.getBackupManagerBinder());
@@ -1109,9 +1112,10 @@
} else {
// We were invoked via an active restore session, not by the Package
// Manager, so start up the session timeout again.
+ long restoreAgentTimeoutMillis = mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
backupManagerService.getBackupHandler().sendEmptyMessageDelayed(
MSG_RESTORE_SESSION_TIMEOUT,
- TIMEOUT_RESTORE_INTERVAL);
+ restoreAgentTimeoutMillis);
}
// Kick off any work that may be needed regarding app widget restores
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 45a4dfb9..f1f251f 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -36,6 +36,7 @@
import android.net.IpSecTransformResponse;
import android.net.IpSecTunnelInterfaceResponse;
import android.net.IpSecUdpEncapResponse;
+import android.net.LinkAddress;
import android.net.Network;
import android.net.NetworkUtils;
import android.net.TrafficStats;
@@ -618,10 +619,8 @@
spi,
mConfig.getMarkValue(),
mConfig.getMarkMask());
- } catch (ServiceSpecificException e) {
- // FIXME: get the error code and throw is at an IOException from Errno Exception
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to delete SA with ID: " + mResourceId);
+ } catch (RemoteException | ServiceSpecificException e) {
+ Log.e(TAG, "Failed to delete SA with ID: " + mResourceId, e);
}
getResourceTracker().give();
@@ -681,10 +680,8 @@
.getNetdInstance()
.ipSecDeleteSecurityAssociation(
mResourceId, mSourceAddress, mDestinationAddress, mSpi, 0, 0);
- } catch (ServiceSpecificException e) {
- // FIXME: get the error code and throw is at an IOException from Errno Exception
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId);
+ } catch (ServiceSpecificException | RemoteException e) {
+ Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
}
mSpi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
@@ -829,15 +826,13 @@
0, direction, wildcardAddr, wildcardAddr, mark, 0xffffffff);
}
}
- } catch (ServiceSpecificException e) {
- // FIXME: get the error code and throw is at an IOException from Errno Exception
- } catch (RemoteException e) {
+ } catch (ServiceSpecificException | RemoteException e) {
Log.e(
TAG,
"Failed to delete VTI with interface name: "
+ mInterfaceName
+ " and id: "
- + mResourceId);
+ + mResourceId, e);
}
getResourceTracker().give();
@@ -1319,7 +1314,9 @@
* from multiple local IP addresses over the same tunnel.
*/
@Override
- public synchronized void addAddressToTunnelInterface(int tunnelResourceId, String localAddr) {
+ public synchronized void addAddressToTunnelInterface(
+ int tunnelResourceId, LinkAddress localAddr) {
+ enforceNetworkStackPermission();
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
// Get tunnelInterface record; if no such interface is found, will throw
@@ -1327,8 +1324,21 @@
TunnelInterfaceRecord tunnelInterfaceInfo =
userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
- // TODO: Add calls to netd:
- // Add address to TunnelInterface
+ try {
+ // We can assume general validity of the IP address, since we get them as a
+ // LinkAddress, which does some validation.
+ mSrvConfig
+ .getNetdInstance()
+ .interfaceAddAddress(
+ tunnelInterfaceInfo.mInterfaceName,
+ localAddr.getAddress().getHostAddress(),
+ localAddr.getPrefixLength());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ // If we get here, one of the arguments provided was invalid. Wrap the SSE, and throw.
+ throw new IllegalArgumentException(e);
+ }
}
/**
@@ -1337,7 +1347,8 @@
*/
@Override
public synchronized void removeAddressFromTunnelInterface(
- int tunnelResourceId, String localAddr) {
+ int tunnelResourceId, LinkAddress localAddr) {
+ enforceNetworkStackPermission();
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
// Get tunnelInterface record; if no such interface is found, will throw
@@ -1345,8 +1356,21 @@
TunnelInterfaceRecord tunnelInterfaceInfo =
userRecord.mTunnelInterfaceRecords.getResourceOrThrow(tunnelResourceId);
- // TODO: Add calls to netd:
- // Remove address from TunnelInterface
+ try {
+ // We can assume general validity of the IP address, since we get them as a
+ // LinkAddress, which does some validation.
+ mSrvConfig
+ .getNetdInstance()
+ .interfaceDelAddress(
+ tunnelInterfaceInfo.mInterfaceName,
+ localAddr.getAddress().getHostAddress(),
+ localAddr.getPrefixLength());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (ServiceSpecificException e) {
+ // If we get here, one of the arguments provided was invalid. Wrap the SSE, and throw.
+ throw new IllegalArgumentException(e);
+ }
}
/**
@@ -1467,6 +1491,13 @@
IpSecAlgorithm crypt = c.getEncryption();
IpSecAlgorithm authCrypt = c.getAuthenticatedEncryption();
+ String cryptName;
+ if (crypt == null) {
+ cryptName = (authCrypt == null) ? IpSecAlgorithm.CRYPT_NULL : "";
+ } else {
+ cryptName = crypt.getName();
+ }
+
mSrvConfig
.getNetdInstance()
.ipSecAddSecurityAssociation(
@@ -1481,7 +1512,7 @@
(auth != null) ? auth.getName() : "",
(auth != null) ? auth.getKey() : new byte[] {},
(auth != null) ? auth.getTruncationLengthBits() : 0,
- (crypt != null) ? crypt.getName() : "",
+ cryptName,
(crypt != null) ? crypt.getKey() : new byte[] {},
(crypt != null) ? crypt.getTruncationLengthBits() : 0,
(authCrypt != null) ? authCrypt.getName() : "",
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 19ca3be..17acb3b 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -2738,11 +2738,6 @@
} else {
service.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
setState(PAUSED, "relaunchActivityLocked");
- // if the app is relaunched when it's stopped, and we're not resuming,
- // put it back into stopped state.
- if (stopped) {
- getStack().addToStopping(this, true /* scheduleIdle */, false /* idleDelayed */);
- }
}
configChangeFlags = 0;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 19fffbb..be72216 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -643,7 +643,7 @@
void setWindowManager(WindowManagerService wm) {
synchronized (mService) {
mWindowManager = wm;
- mKeyguardController.setWindowManager(wm);
+ getKeyguardController().setWindowManager(wm);
mDisplayManager =
(DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
@@ -1199,6 +1199,12 @@
for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
final int displayId = mTmpOrderedDisplayIds.get(i);
final ActivityDisplay display = mActivityDisplays.get(displayId);
+
+ // If WindowManagerService has encountered the display before we have, ignore as there
+ // will be no stacks present and therefore no activities.
+ if (display == null) {
+ continue;
+ }
for (int j = display.getChildCount() - 1; j >= 0; --j) {
final ActivityStack stack = display.getChildAt(j);
if (stack != focusedStack && stack.isTopStackOnDisplay() && stack.isFocusable()) {
@@ -1312,7 +1318,7 @@
r.setProcess(app);
- if (mKeyguardController.isKeyguardLocked()) {
+ if (getKeyguardController().isKeyguardLocked()) {
r.notifyUnknownVisibilityLaunched();
}
@@ -3377,7 +3383,7 @@
} else {
stack.awakeFromSleepingLocked();
if (isFocusedStack(stack)
- && !mKeyguardController.isKeyguardShowing(display.mDisplayId)) {
+ && !getKeyguardController().isKeyguardShowing(display.mDisplayId)) {
// If the keyguard is unlocked - resume immediately.
// It is possible that the display will not be awake at the time we
// process the keyguard going away, which can happen before the sleep token
@@ -3501,7 +3507,7 @@
void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- mKeyguardController.beginActivityVisibilityUpdate();
+ getKeyguardController().beginActivityVisibilityUpdate();
try {
// First the front stacks. In case any are not fullscreen and are in front of home.
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
@@ -3512,7 +3518,7 @@
}
}
} finally {
- mKeyguardController.endActivityVisibilityUpdate();
+ getKeyguardController().endActivityVisibilityUpdate();
}
}
@@ -3799,7 +3805,7 @@
pw.print(prefix); pw.print("isHomeRecentsComponent=");
pw.print(mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
- mKeyguardController.dump(pw, prefix);
+ getKeyguardController().dump(pw, prefix);
mService.mLockTaskController.dump(pw, prefix);
}
@@ -3810,7 +3816,7 @@
ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
activityDisplay.writeToProto(proto, DISPLAYS);
}
- mKeyguardController.writeToProto(proto, KEYGUARD_CONTROLLER);
+ getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER);
if (mFocusedStack != null) {
proto.write(FOCUSED_STACK_ID, mFocusedStack.mStackId);
ActivityRecord focusedActivity = getResumedActivityLocked();
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index bd53eac..a30a944 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1834,7 +1834,8 @@
mNoAnimation, mOptions, mStartActivity.appTimeTracker,
"bringToFrontInsteadOfAdjacentLaunch");
}
- mMovedToFront = true;
+ mMovedToFront = launchStack != launchStack.getDisplay()
+ .getTopStackInWindowingMode(launchStack.getWindowingMode());
} else if (launchStack.mDisplayId != mTargetStack.mDisplayId) {
// Target and computed stacks are on different displays and we've
// found a matching task - move the existing instance to that display and
@@ -2393,6 +2394,11 @@
return this;
}
+ @VisibleForTesting
+ Intent getIntent() {
+ return mRequest.intent;
+ }
+
ActivityStarter setReason(String reason) {
mRequest.reason = reason;
return this;
diff --git a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
index 690d985..5bf5020 100644
--- a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
@@ -43,7 +43,7 @@
{Settings.Global.FPS_DEVISOR, ThreadedRenderer.DEBUG_FPS_DIVISOR},
{Settings.Global.DISPLAY_PANEL_LPM, "sys.display_panel_lpm"},
{Settings.Global.SYS_UIDCPUPOWER, "sys.uidcpupower"},
- {Settings.Global.SYS_TRACED, "persist.traced.enable"},
+ {Settings.Global.SYS_TRACED, "sys.traced.enable_override"},
};
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 578a32c..a1e066e 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -95,11 +95,18 @@
public static final long MIN_TRIGGER_MAX_DELAY = 1000;
final JobInfo job;
- /** Uid of the package requesting this job. */
+ /**
+ * Uid of the package requesting this job. This can differ from the "source"
+ * uid when the job was scheduled on the app's behalf, such as with the jobs
+ * that underly Sync Manager operation.
+ */
final int callingUid;
final int targetSdkVersion;
final String batteryName;
+ /**
+ * Identity of the app in which the job is hosted.
+ */
final String sourcePackageName;
final int sourceUserId;
final int sourceUid;
@@ -263,6 +270,31 @@
return callingUid;
}
+ /**
+ * Core constructor for JobStatus instances. All other ctors funnel down to this one.
+ *
+ * @param job The actual requested parameters for the job
+ * @param callingUid Identity of the app that is scheduling the job. This may not be the
+ * app in which the job is implemented; such as with sync jobs.
+ * @param targetSdkVersion The targetSdkVersion of the app in which the job will run.
+ * @param sourcePackageName The package name of the app in which the job will run.
+ * @param sourceUserId The user in which the job will run
+ * @param standbyBucket The standby bucket that the source package is currently assigned to,
+ * cached here for speed of handling during runnability evaluations (and updated when bucket
+ * assignments are changed)
+ * @param heartbeat Timestamp of when the job was created, in the standby-related
+ * timebase.
+ * @param tag A string associated with the job for debugging/logging purposes.
+ * @param numFailures Count of how many times this job has requested a reschedule because
+ * its work was not yet finished.
+ * @param earliestRunTimeElapsedMillis Milestone: earliest point in time at which the job
+ * is to be considered runnable
+ * @param latestRunTimeElapsedMillis Milestone: point in time at which the job will be
+ * considered overdue
+ * @param lastSuccessfulRunTime When did we last run this job to completion?
+ * @param lastFailedRunTime When did we last run this job only to have it stop incomplete?
+ * @param internalFlags Non-API property flags about this job
+ */
private JobStatus(JobInfo job, int callingUid, int targetSdkVersion, String sourcePackageName,
int sourceUserId, int standbyBucket, long heartbeat, String tag, int numFailures,
long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
@@ -399,8 +431,8 @@
/**
* Create a newly scheduled job.
* @param callingUid Uid of the package that scheduled this job.
- * @param sourcePkg Package name on whose behalf this job is scheduled. Null indicates
- * the calling package is the source.
+ * @param sourcePkg Package name of the app that will actually run the job. Null indicates
+ * that the calling package is the source.
* @param sourceUserId User id for whom this job is scheduled. -1 indicates this is same as the
* caller.
*/
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 40a94a7..dd88cd1 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -896,7 +896,7 @@
mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
mDozeAfterScreenOff = resources.getBoolean(
- com.android.internal.R.bool.config_dozeAfterScreenOff);
+ com.android.internal.R.bool.config_dozeAfterScreenOffByDefault);
mMinimumScreenOffTimeoutConfig = resources.getInteger(
com.android.internal.R.integer.config_minimumScreenOffTimeout);
mMaximumScreenDimDurationConfig = resources.getInteger(
@@ -1723,7 +1723,7 @@
// Update wireless dock detection state.
final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
- mIsPowered, mPlugType, mBatteryLevel);
+ mIsPowered, mPlugType);
// Treat plugging and unplugging the devices as a user activity.
// Users find it disconcerting when they plug or unplug the device
diff --git a/services/core/java/com/android/server/power/WirelessChargerDetector.java b/services/core/java/com/android/server/power/WirelessChargerDetector.java
index 54487e3..18e5ce4 100644
--- a/services/core/java/com/android/server/power/WirelessChargerDetector.java
+++ b/services/core/java/com/android/server/power/WirelessChargerDetector.java
@@ -84,10 +84,6 @@
// The minimum number of samples that must be collected.
private static final int MIN_SAMPLES = 3;
- // Upper bound on the battery charge percentage in order to consider turning
- // the screen on when the device starts charging wirelessly.
- private static final int WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT = 95;
-
// To detect movement, we compute the angle between the gravity vector
// at rest and the current gravity vector. This field specifies the
// cosine of the maximum angle variance that we tolerate while at rest.
@@ -214,11 +210,10 @@
*
* @param isPowered True if the device is powered.
* @param plugType The current plug type.
- * @param batteryLevel The current battery level.
* @return True if the device is determined to have just been docked on a wireless
* charger, after suppressing spurious docking or undocking signals.
*/
- public boolean update(boolean isPowered, int plugType, int batteryLevel) {
+ public boolean update(boolean isPowered, int plugType) {
synchronized (mLock) {
final boolean wasPoweredWirelessly = mPoweredWirelessly;
@@ -249,13 +244,9 @@
}
// Report that the device has been docked only if the device just started
- // receiving power wirelessly, has a high enough battery level that we
- // can be assured that charging was not delayed due to the battery previously
- // having been full, and the device is not known to already be at rest
+ // receiving power wirelessly and the device is not known to already be at rest
// on the wireless charger from earlier.
- return mPoweredWirelessly && !wasPoweredWirelessly
- && batteryLevel < WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT
- && !mAtRest;
+ return mPoweredWirelessly && !wasPoweredWirelessly && !mAtRest;
}
}
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index a7dfd35..0b7d9d0 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -16,6 +16,8 @@
package com.android.server.slice;
+import static android.app.usage.UsageEvents.Event.SLICE_PINNED;
+import static android.app.usage.UsageEvents.Event.SLICE_PINNED_PRIV;
import static android.content.ContentProvider.getUriWithoutUserId;
import static android.content.ContentProvider.getUserIdFromUri;
import static android.content.ContentProvider.maybeAddUserId;
@@ -31,6 +33,7 @@
import android.app.slice.ISliceManager;
import android.app.slice.SliceManager;
import android.app.slice.SliceSpec;
+import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -95,6 +98,7 @@
private final AtomicFile mSliceAccessFile;
@GuardedBy("mAccessList")
private final SliceFullAccessList mAccessList;
+ private final UsageStatsManagerInternal mAppUsageStats;
public SliceManagerService(Context context) {
this(context, createHandler().getLooper());
@@ -112,6 +116,7 @@
final File systemDir = new File(Environment.getDataDirectory(), "system");
mSliceAccessFile = new AtomicFile(new File(systemDir, "slice_access.xml"));
mAccessList = new SliceFullAccessList(mContext);
+ mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
synchronized (mSliceAccessFile) {
if (!mSliceAccessFile.exists()) return;
@@ -166,8 +171,19 @@
public void pinSlice(String pkg, Uri uri, SliceSpec[] specs, IBinder token) throws RemoteException {
verifyCaller(pkg);
enforceAccess(pkg, uri);
- uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
+ int user = Binder.getCallingUserHandle().getIdentifier();
+ uri = maybeAddUserId(uri, user);
getOrCreatePinnedSlice(uri, pkg).pin(pkg, specs, token);
+
+ Uri finalUri = uri;
+ mHandler.post(() -> {
+ String slicePkg = getProviderPkg(finalUri, user);
+ if (slicePkg != null && !Objects.equals(pkg, slicePkg)) {
+ mAppUsageStats.reportEvent(slicePkg, user,
+ isAssistant(pkg, user) || isDefaultHomeApp(pkg, user)
+ ? SLICE_PINNED_PRIV : SLICE_PINNED);
+ }
+ });
}
@Override
@@ -352,38 +368,45 @@
if (getContext().checkUriPermission(uri, pid, uid,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != PERMISSION_GRANTED) {
// Last fallback (if the calling app owns the authority, then it can have access).
- long ident = Binder.clearCallingIdentity();
- try {
- IBinder token = new Binder();
- IActivityManager activityManager = ActivityManager.getService();
- ContentProviderHolder holder = null;
- String providerName = getUriWithoutUserId(uri).getAuthority();
- try {
- try {
- holder = activityManager.getContentProviderExternal(
- providerName, getUserIdFromUri(uri, user), token);
- if (holder == null || holder.info == null
- || !Objects.equals(holder.info.packageName, pkg)) {
- return PERMISSION_DENIED;
- }
- } finally {
- if (holder != null && holder.provider != null) {
- activityManager.removeContentProviderExternal(providerName, token);
- }
- }
- } catch (RemoteException e) {
- // Can't happen.
- e.rethrowAsRuntimeException();
- }
- } finally {
- // I know, the double finally seems ugly, but seems safest for the identity.
- Binder.restoreCallingIdentity(ident);
+ if (!Objects.equals(getProviderPkg(uri, user), pkg)) {
+ return PERMISSION_DENIED;
}
}
}
return PERMISSION_GRANTED;
}
+ private String getProviderPkg(Uri uri, int user) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ IBinder token = new Binder();
+ IActivityManager activityManager = ActivityManager.getService();
+ ContentProviderHolder holder = null;
+ String providerName = getUriWithoutUserId(uri).getAuthority();
+ try {
+ try {
+ holder = activityManager.getContentProviderExternal(
+ providerName, getUserIdFromUri(uri, user), token);
+ if (holder != null && holder.info != null) {
+ return holder.info.packageName;
+ } else {
+ return null;
+ }
+ } finally {
+ if (holder != null && holder.provider != null) {
+ activityManager.removeContentProviderExternal(providerName, token);
+ }
+ }
+ } catch (RemoteException e) {
+ // Can't happen.
+ throw e.rethrowAsRuntimeException();
+ }
+ } finally {
+ // I know, the double finally seems ugly, but seems safest for the identity.
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
private void enforceCrossUser(String pkg, Uri uri) {
int user = Binder.getCallingUserHandle().getIdentifier();
if (getUserIdFromUri(uri, user) != user) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index f8a4540..f52f91c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1482,11 +1482,13 @@
void layoutLetterbox(WindowState winHint) {
final WindowState w = findMainWindow();
- if (w != winHint && winHint != null && w != null) {
+ if (w == null || winHint != null && w != winHint) {
return;
}
- final boolean needsLetterbox = w != null && w.isLetterboxedAppWindow()
- && fillsParent() && w.hasDrawnLw();
+ final boolean surfaceReady = w.hasDrawnLw() // Regular case
+ || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
+ || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
+ final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
if (needsLetterbox) {
if (mLetterbox == null) {
mLetterbox = new Letterbox(() -> makeChildSurface(null));
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 5ae4dc5..27c0b3b 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -285,7 +285,14 @@
}
if (mSurfaceControl != null) {
- getPendingTransaction().destroy(mSurfaceControl);
+ mPendingTransaction.destroy(mSurfaceControl);
+
+ // Merge to parent transaction to ensure the transactions on this WindowContainer are
+ // applied in native even if WindowContainer is removed.
+ if (mParent != null) {
+ mParent.getPendingTransaction().merge(mPendingTransaction);
+ }
+
mSurfaceControl = null;
scheduleAnimation();
}
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index f603a09..d0398ad 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -148,16 +148,22 @@
Looper backupLooper = startBackupThreadAndGetLooper();
mShadowBackupLooper = shadowOf(backupLooper);
mBackupHandler = new BackupHandler(mBackupManagerService, backupLooper);
+ Handler mainHandler = new Handler(Looper.getMainLooper());
mBackupManager = spy(FakeIBackupManager.class);
+ BackupAgentTimeoutParameters agentTimeoutParameters =
+ new BackupAgentTimeoutParameters(mainHandler, application.getContentResolver());
+ agentTimeoutParameters.start();
+
setUpBackupManagerServiceBasics(
mBackupManagerService,
application,
mTransportManager,
packageManager,
mBackupHandler,
- mWakeLock);
+ mWakeLock,
+ agentTimeoutParameters);
when(mBackupManagerService.getBaseStateDir()).thenReturn(mBaseStateDir);
when(mBackupManagerService.getDataDir()).thenReturn(dataDir);
when(mBackupManagerService.getBackupManagerBinder()).thenReturn(mBackupManager);
diff --git a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
index 03792b1..869c50b 100644
--- a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
+++ b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
@@ -41,12 +41,14 @@
import android.app.backup.RestoreSet;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
+import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.TransportManager;
import com.android.server.backup.internal.BackupHandler;
@@ -115,6 +117,15 @@
Looper backupLooper = startBackupThreadAndGetLooper();
mShadowBackupLooper = shadowOf(backupLooper);
+
+ Handler mainHandler = new Handler(Looper.getMainLooper());
+ BackupAgentTimeoutParameters agentTimeoutParameters =
+ new BackupAgentTimeoutParameters(mainHandler, application.getContentResolver());
+ agentTimeoutParameters.start();
+
+ // We need to mock BMS timeout parameters before initializing the BackupHandler since
+ // the constructor of BackupHandler relies on the timeout parameters.
+ when(mBackupManagerService.getAgentTimeoutParameters()).thenReturn(agentTimeoutParameters);
BackupHandler backupHandler = new BackupHandler(mBackupManagerService, backupLooper);
mWakeLock = createBackupWakeLock(application);
@@ -125,7 +136,8 @@
mTransportManager,
application.getPackageManager(),
backupHandler,
- mWakeLock);
+ mWakeLock,
+ agentTimeoutParameters);
when(mBackupManagerService.getPendingRestores()).thenReturn(new ArrayDeque<>());
}
diff --git a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index c210fde..5a886e3 100644
--- a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -28,6 +28,7 @@
import android.os.PowerManager;
import android.util.SparseArray;
+import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.TransportManager;
import com.android.server.backup.internal.BackupHandler;
@@ -43,7 +44,8 @@
TransportManager transportManager,
PackageManager packageManager,
BackupHandler backupHandler,
- PowerManager.WakeLock wakeLock) {
+ PowerManager.WakeLock wakeLock,
+ BackupAgentTimeoutParameters agentTimeoutParameters) {
when(backupManagerService.getContext()).thenReturn(context);
when(backupManagerService.getTransportManager()).thenReturn(transportManager);
when(backupManagerService.getPackageManager()).thenReturn(packageManager);
@@ -53,6 +55,7 @@
when(backupManagerService.getCurrentOperations()).thenReturn(new SparseArray<>());
when(backupManagerService.getActivityManager()).thenReturn(mock(IActivityManager.class));
when(backupManagerService.getWakelock()).thenReturn(wakeLock);
+ when(backupManagerService.getAgentTimeoutParameters()).thenReturn(agentTimeoutParameters);
}
public static PowerManager.WakeLock createBackupWakeLock(Application application) {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index 2378e6d..b452ea5 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -22,23 +22,39 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.ArgumentMatchers.any;
import android.app.ActivityManager;
import android.app.WaitResult;
import android.content.ComponentName;
+import android.content.res.Configuration;
import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseIntArray;
import org.junit.runner.RunWith;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -180,4 +196,73 @@
assertEquals(deliverToTopWait.who, firstActivity.realActivity);
}
}
+
+ @Test
+ public void testApplySleepTokensLocked() throws Exception {
+ final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+ final KeyguardController keyguard = mSupervisor.getKeyguardController();
+ final ActivityStack stack = mock(ActivityStack.class);
+ display.addChild(stack, 0 /* position */);
+
+ // Make sure we wake and resume in the case the display is turning on and the keyguard is
+ // not showing.
+ verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
+ false /* displayShouldSleep */, true /* isFocusedStack */,
+ false /* keyguardShowing */, true /* expectWakeFromSleep */,
+ true /* expectResumeTopActivity */);
+
+ // Make sure we wake and don't resume when the display is turning on and the keyguard is
+ // showing.
+ verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
+ false /* displayShouldSleep */, true /* isFocusedStack */,
+ true /* keyguardShowing */, true /* expectWakeFromSleep */,
+ false /* expectResumeTopActivity */);
+
+ // Make sure we wake and don't resume when the display is turning on and the keyguard is
+ // not showing as unfocused.
+ verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
+ false /* displayShouldSleep */, false /* isFocusedStack */,
+ false /* keyguardShowing */, true /* expectWakeFromSleep */,
+ false /* expectResumeTopActivity */);
+
+ // Should not do anything if the display state hasn't changed.
+ verifySleepTokenBehavior(display, keyguard, stack, false /*displaySleeping*/,
+ false /* displayShouldSleep */, true /* isFocusedStack */,
+ false /* keyguardShowing */, false /* expectWakeFromSleep */,
+ false /* expectResumeTopActivity */);
+ }
+
+ private void verifySleepTokenBehavior(ActivityDisplay display, KeyguardController keyguard,
+ ActivityStack stack, boolean displaySleeping, boolean displayShouldSleep,
+ boolean isFocusedStack, boolean keyguardShowing, boolean expectWakeFromSleep,
+ boolean expectResumeTopActivity) {
+ reset(stack);
+
+ doReturn(displayShouldSleep).when(display).shouldSleep();
+ doReturn(displaySleeping).when(display).isSleeping();
+ doReturn(keyguardShowing).when(keyguard).isKeyguardShowing(anyInt());
+
+ mSupervisor.mFocusedStack = isFocusedStack ? stack : null;
+ mSupervisor.applySleepTokensLocked(true);
+ verify(stack, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleepingLocked();
+ verify(stack, times(expectResumeTopActivity ? 1 : 0)).resumeTopActivityUncheckedLocked(
+ null /* target */, null /* targetOptions */);
+ }
+
+ @Test
+ public void testTopRunningActivityLockedWithNonExistentDisplay() throws Exception {
+ // Create display that ActivityManagerService does not know about
+ final int unknownDisplayId = 100;
+
+ doAnswer((InvocationOnMock invocationOnMock) -> {
+ final SparseIntArray displayIds = invocationOnMock.<SparseIntArray>getArgument(0);
+ displayIds.put(0, unknownDisplayId);
+ return null;
+ }).when(mSupervisor.mWindowManager).getDisplaysInFocusOrder(any());
+
+ mSupervisor.mFocusedStack = mock(ActivityStack.class);
+
+ // Supervisor should skip over the non-existent display.
+ assertEquals(null, mSupervisor.topRunningActivityLocked());
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index 5906db3..8ff3e45 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -18,13 +18,19 @@
import static android.app.ActivityManager.START_ABORTED;
import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
+import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
import static android.app.ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
+import static android.app.ActivityManager.START_INTENT_NOT_RESOLVED;
import static android.app.ActivityManager.START_NOT_VOICE_COMPATIBLE;
+import static android.app.ActivityManager.START_PERMISSION_DENIED;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_SWITCHES_CANCELED;
+import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import android.app.ActivityOptions;
import android.app.IApplicationThread;
@@ -45,6 +51,7 @@
import org.junit.runner.RunWith;
import org.junit.Test;
+import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
import static com.android.server.am.ActivityManagerService.ANIMATE;
import static org.junit.Assert.assertEquals;
@@ -62,9 +69,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
-import static android.app.ActivityManager.START_PERMISSION_DENIED;
-import static android.app.ActivityManager.START_INTENT_NOT_RESOLVED;
-
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.am.ActivityStarter.Factory;
import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
@@ -290,7 +294,7 @@
}
}
- private ActivityStarter prepareStarter() {
+ private ActivityStarter prepareStarter(int launchFlags) {
// always allow test to start activity.
doReturn(true).when(mService.mStackSupervisor).checkStartAnyActivityPermission(
any(), any(), any(), anyInt(), anyInt(), anyInt(), any(),
@@ -325,8 +329,20 @@
// ignore requests to create window container.
doNothing().when(task).createWindowContainer(anyBoolean(), anyBoolean());
+
+ final Intent intent = new Intent();
+ intent.addFlags(launchFlags);
+ intent.setComponent(ActivityBuilder.getDefaultComponent());
+
+ final ActivityInfo info = new ActivityInfo();
+
+ info.applicationInfo = new ApplicationInfo();
+ info.applicationInfo.packageName = ActivityBuilder.getDefaultComponent().getPackageName();
+
return new ActivityStarter(mController, mService,
- mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+ mService.mStackSupervisor, mock(ActivityStartInterceptor.class))
+ .setIntent(intent)
+ .setActivityInfo(info);
}
/**
@@ -342,9 +358,6 @@
// add custom values to activity info to make unique.
final ActivityInfo info = new ActivityInfo();
final Rect launchBounds = new Rect(0, 0, 20, 30);
- final Intent intent = new Intent();
-
- intent.setComponent(ActivityBuilder.getDefaultComponent());
final WindowLayout windowLayout =
new WindowLayout(10, .5f, 20, 1.0f, Gravity.NO_GRAVITY, 1, 1);
@@ -354,14 +367,13 @@
info.applicationInfo.packageName = ActivityBuilder.getDefaultComponent().getPackageName();
// create starter.
- final ActivityStarter optionStarter = prepareStarter();
+ final ActivityStarter optionStarter = prepareStarter(0 /* launchFlags */);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchBounds(launchBounds);
// run starter.
optionStarter
- .setIntent(intent)
.setReason("testCreateTaskLayout")
.setActivityInfo(info)
.setActivityOptions(new SafeActivityOptions(options))
@@ -371,4 +383,69 @@
verify(modifier, times(1)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options),
any(), any());
}
+
+ /**
+ * This test ensures that if the intent is being delivered to a
+ */
+ @Test
+ public void testSplitScreenDeliverToTop() {
+ final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+ final ActivityRecord focusActivity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .build();
+
+ focusActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+ final ActivityRecord reusableActivity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .build();
+
+ // Create reusable activity after entering split-screen so that it is the top secondary
+ // stack.
+ reusableActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+
+ // Set focus back to primary.
+ mService.mStackSupervisor.setFocusStackUnchecked("testSplitScreenDeliverToTop",
+ focusActivity.getStack());
+
+ doReturn(reusableActivity).when(mService.mStackSupervisor).findTaskLocked(any(), anyInt());
+
+ final int result = starter.setReason("testSplitScreenDeliverToTop").execute();
+
+ // Ensure result is delivering intent to top.
+ assertEquals(result, START_DELIVERED_TO_TOP);
+ }
+
+ /**
+ * This test ensures that if the intent is being delivered to a split-screen unfocused task
+ * reports it is brought to front instead of delivering to top.
+ */
+ @Test
+ public void testSplitScreenTaskToFront() {
+ final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+ // Create reusable activity here first. Setting the windowing mode of the primary stack
+ // will move the existing standard full screen stack to secondary, putting this one on the
+ // bottom.
+ final ActivityRecord reusableActivity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .build();
+
+ reusableActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+
+ final ActivityRecord focusActivity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .build();
+
+ // Enter split-screen. Primary stack should have focus.
+ focusActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+ doReturn(reusableActivity).when(mService.mStackSupervisor).findTaskLocked(any(), anyInt());
+
+ final int result = starter.setReason("testSplitScreenMoveToFront").execute();
+
+ // Ensure result is moving task to front.
+ assertEquals(result, START_TASK_TO_FRONT);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index c130592..6fb1b2e 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -353,22 +353,29 @@
*/
protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
private ActivityDisplay mDisplay;
+ private KeyguardController mKeyguardController;
public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
super(service, looper);
mDisplayManager =
(DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
mWindowManager = prepareMockWindowManager();
+ mKeyguardController = mock(KeyguardController.class);
}
@Override
public void initialize() {
super.initialize();
- mDisplay = new TestActivityDisplay(this, DEFAULT_DISPLAY);
+ mDisplay = spy(new TestActivityDisplay(this, DEFAULT_DISPLAY));
attachDisplay(mDisplay);
}
@Override
+ public KeyguardController getKeyguardController() {
+ return mKeyguardController;
+ }
+
+ @Override
ActivityDisplay getDefaultDisplay() {
return mDisplay;
}
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index edf1f74..552c915 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -17,6 +17,8 @@
package com.android.server.usage;
import static android.app.usage.UsageEvents.Event.NOTIFICATION_SEEN;
+import static android.app.usage.UsageEvents.Event.SLICE_PINNED;
+import static android.app.usage.UsageEvents.Event.SLICE_PINNED_PRIV;
import static android.app.usage.UsageEvents.Event.USER_INTERACTION;
import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED;
@@ -406,6 +408,30 @@
}
@Test
+ public void testSlicePinnedEvent() throws Exception {
+ setChargingState(mController, false);
+
+ reportEvent(mController, USER_INTERACTION, 0);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ mInjector.mElapsedRealtime = 1;
+ reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+
+ mController.forceIdleState(PACKAGE_1, USER_ID, true);
+ reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime);
+ assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
+ }
+
+ @Test
+ public void testSlicePinnedPrivEvent() throws Exception {
+ setChargingState(mController, false);
+
+ mController.forceIdleState(PACKAGE_1, USER_ID, true);
+ reportEvent(mController, SLICE_PINNED_PRIV, mInjector.mElapsedRealtime);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ }
+
+ @Test
public void testPredictionTimedout() throws Exception {
setChargingState(mController, false);
// Set it to timeout or usage, so that prediction can override it
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index 4f446a9..1073a80 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -30,6 +30,7 @@
import android.app.AppOpsManager;
import android.app.slice.SliceSpec;
+import android.app.usage.UsageStatsManagerInternal;
import android.content.pm.PackageManagerInternal;
import android.net.Uri;
import android.os.Binder;
@@ -66,6 +67,8 @@
@Before
public void setup() {
LocalServices.addService(PackageManagerInternal.class, mock(PackageManagerInternal.class));
+ LocalServices.addService(UsageStatsManagerInternal.class,
+ mock(UsageStatsManagerInternal.class));
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
mContext.getTestablePermissions().setPermission(TEST_URI, PERMISSION_GRANTED);
@@ -77,6 +80,7 @@
@After
public void teardown() {
LocalServices.removeServiceForTest(PackageManagerInternal.class);
+ LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
}
@Test
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index e836677..1af5f46 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -36,6 +36,7 @@
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
+
import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
@@ -43,8 +44,8 @@
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.usage.AppStandbyInfo;
-import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager.StandbyBuckets;
import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
@@ -100,7 +101,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -690,7 +690,9 @@
|| event.mEventType == UsageEvents.Event.MOVE_TO_BACKGROUND
|| event.mEventType == UsageEvents.Event.SYSTEM_INTERACTION
|| event.mEventType == UsageEvents.Event.USER_INTERACTION
- || event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN)) {
+ || event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN
+ || event.mEventType == UsageEvents.Event.SLICE_PINNED
+ || event.mEventType == UsageEvents.Event.SLICE_PINNED_PRIV)) {
final AppUsageHistory appHistory = mAppIdleHistory.getAppUsageHistory(
event.mPackage, userId, elapsedRealtime);
@@ -699,7 +701,8 @@
final long nextCheckTime;
final int subReason = usageEventToSubReason(event.mEventType);
final int reason = REASON_MAIN_USAGE | subReason;
- if (event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN) {
+ if (event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN
+ || event.mEventType == UsageEvents.Event.SLICE_PINNED) {
// Mild usage elevates to WORKING_SET but doesn't change usage time.
mAppIdleHistory.reportUsage(appHistory, event.mPackage,
STANDBY_BUCKET_WORKING_SET, subReason,
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index d974282..c2e38f2 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -761,6 +761,10 @@
return "STANDBY_BUCKET_CHANGED";
case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
return "NOTIFICATION_INTERRUPTION";
+ case UsageEvents.Event.SLICE_PINNED:
+ return "SLICE_PINNED";
+ case UsageEvents.Event.SLICE_PINNED_PRIV:
+ return "SLICE_PINNED_PRIV";
default:
return "UNKNOWN";
}
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index c073d1a..aaf1a1cf8 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -139,34 +139,44 @@
@Override
public int queryCapabilityStatus() throws RemoteException {
- return MmTelFeature.this.queryCapabilityStatus().mCapabilities;
+ synchronized (mLock) {
+ return MmTelFeature.this.queryCapabilityStatus().mCapabilities;
+ }
}
@Override
public void addCapabilityCallback(IImsCapabilityCallback c) {
+ // no need to lock, structure already handles multithreading.
MmTelFeature.this.addCapabilityCallback(c);
}
@Override
public void removeCapabilityCallback(IImsCapabilityCallback c) {
+ // no need to lock, structure already handles multithreading.
MmTelFeature.this.removeCapabilityCallback(c);
}
@Override
public void changeCapabilitiesConfiguration(CapabilityChangeRequest request,
IImsCapabilityCallback c) throws RemoteException {
- MmTelFeature.this.requestChangeEnabledCapabilities(request, c);
+ synchronized (mLock) {
+ MmTelFeature.this.requestChangeEnabledCapabilities(request, c);
+ }
}
@Override
public void queryCapabilityConfiguration(int capability, int radioTech,
IImsCapabilityCallback c) {
- queryCapabilityConfigurationInternal(capability, radioTech, c);
+ synchronized (mLock) {
+ queryCapabilityConfigurationInternal(capability, radioTech, c);
+ }
}
@Override
public void setSmsListener(IImsSmsListener l) throws RemoteException {
- MmTelFeature.this.setSmsListener(l);
+ synchronized (mLock) {
+ MmTelFeature.this.setSmsListener(l);
+ }
}
@Override
diff --git a/tests/net/java/android/net/IpSecManagerTest.java b/tests/net/java/android/net/IpSecManagerTest.java
index cc3366f..0ca20de 100644
--- a/tests/net/java/android/net/IpSecManagerTest.java
+++ b/tests/net/java/android/net/IpSecManagerTest.java
@@ -50,13 +50,18 @@
private static final int TEST_UDP_ENCAP_PORT = 34567;
private static final int DROID_SPI = 0xD1201D;
+ private static final int DUMMY_RESOURCE_ID = 0x1234;
private static final InetAddress GOOGLE_DNS_4;
+ private static final String VTI_INTF_NAME = "ipsec_test";
+ private static final InetAddress VTI_LOCAL_ADDRESS;
+ private static final LinkAddress VTI_INNER_ADDRESS = new LinkAddress("10.0.1.1/24");
static {
try {
// Google Public DNS Addresses;
GOOGLE_DNS_4 = InetAddress.getByName("8.8.8.8");
+ VTI_LOCAL_ADDRESS = InetAddress.getByName("8.8.4.4");
} catch (UnknownHostException e) {
throw new RuntimeException("Could not resolve DNS Addresses", e);
}
@@ -77,9 +82,8 @@
*/
@Test
public void testAllocSpi() throws Exception {
- int resourceId = 1;
IpSecSpiResponse spiResp =
- new IpSecSpiResponse(IpSecManager.Status.OK, resourceId, DROID_SPI);
+ new IpSecSpiResponse(IpSecManager.Status.OK, DUMMY_RESOURCE_ID, DROID_SPI);
when(mMockIpSecService.allocateSecurityParameterIndex(
eq(GOOGLE_DNS_4.getHostAddress()),
eq(DROID_SPI),
@@ -92,14 +96,13 @@
droidSpi.close();
- verify(mMockIpSecService).releaseSecurityParameterIndex(resourceId);
+ verify(mMockIpSecService).releaseSecurityParameterIndex(DUMMY_RESOURCE_ID);
}
@Test
public void testAllocRandomSpi() throws Exception {
- int resourceId = 1;
IpSecSpiResponse spiResp =
- new IpSecSpiResponse(IpSecManager.Status.OK, resourceId, DROID_SPI);
+ new IpSecSpiResponse(IpSecManager.Status.OK, DUMMY_RESOURCE_ID, DROID_SPI);
when(mMockIpSecService.allocateSecurityParameterIndex(
eq(GOOGLE_DNS_4.getHostAddress()),
eq(IpSecManager.INVALID_SECURITY_PARAMETER_INDEX),
@@ -113,7 +116,7 @@
randomSpi.close();
- verify(mMockIpSecService).releaseSecurityParameterIndex(resourceId);
+ verify(mMockIpSecService).releaseSecurityParameterIndex(DUMMY_RESOURCE_ID);
}
/*
@@ -165,11 +168,10 @@
@Test
public void testOpenEncapsulationSocket() throws Exception {
- int resourceId = 1;
IpSecUdpEncapResponse udpEncapResp =
new IpSecUdpEncapResponse(
IpSecManager.Status.OK,
- resourceId,
+ DUMMY_RESOURCE_ID,
TEST_UDP_ENCAP_PORT,
Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
when(mMockIpSecService.openUdpEncapsulationSocket(eq(TEST_UDP_ENCAP_PORT), anyObject()))
@@ -182,16 +184,15 @@
encapSocket.close();
- verify(mMockIpSecService).closeUdpEncapsulationSocket(resourceId);
+ verify(mMockIpSecService).closeUdpEncapsulationSocket(DUMMY_RESOURCE_ID);
}
@Test
public void testOpenEncapsulationSocketOnRandomPort() throws Exception {
- int resourceId = 1;
IpSecUdpEncapResponse udpEncapResp =
new IpSecUdpEncapResponse(
IpSecManager.Status.OK,
- resourceId,
+ DUMMY_RESOURCE_ID,
TEST_UDP_ENCAP_PORT,
Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
@@ -206,7 +207,7 @@
encapSocket.close();
- verify(mMockIpSecService).closeUdpEncapsulationSocket(resourceId);
+ verify(mMockIpSecService).closeUdpEncapsulationSocket(DUMMY_RESOURCE_ID);
}
@Test
@@ -219,4 +220,45 @@
}
// TODO: add test when applicable transform builder interface is available
-}
+
+ private IpSecManager.IpSecTunnelInterface createAndValidateVti(int resourceId, String intfName)
+ throws Exception {
+ IpSecTunnelInterfaceResponse dummyResponse =
+ new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
+ when(mMockIpSecService.createTunnelInterface(
+ eq(VTI_LOCAL_ADDRESS.getHostAddress()), eq(GOOGLE_DNS_4.getHostAddress()),
+ anyObject(), anyObject()))
+ .thenReturn(dummyResponse);
+
+ IpSecManager.IpSecTunnelInterface tunnelIntf = mIpSecManager.createIpSecTunnelInterface(
+ VTI_LOCAL_ADDRESS, GOOGLE_DNS_4, mock(Network.class));
+
+ assertNotNull(tunnelIntf);
+ return tunnelIntf;
+ }
+
+ @Test
+ public void testCreateVti() throws Exception {
+ IpSecManager.IpSecTunnelInterface tunnelIntf =
+ createAndValidateVti(DUMMY_RESOURCE_ID, VTI_INTF_NAME);
+
+ assertEquals(VTI_INTF_NAME, tunnelIntf.getInterfaceName());
+
+ tunnelIntf.close();
+ verify(mMockIpSecService).deleteTunnelInterface(eq(DUMMY_RESOURCE_ID));
+ }
+
+ @Test
+ public void testAddRemoveAddressesFromVti() throws Exception {
+ IpSecManager.IpSecTunnelInterface tunnelIntf =
+ createAndValidateVti(DUMMY_RESOURCE_ID, VTI_INTF_NAME);
+
+ tunnelIntf.addAddress(VTI_INNER_ADDRESS);
+ verify(mMockIpSecService)
+ .addAddressToTunnelInterface(eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS));
+
+ tunnelIntf.removeAddress(VTI_INNER_ADDRESS);
+ verify(mMockIpSecService)
+ .addAddressToTunnelInterface(eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS));
+ }
+}
\ No newline at end of file
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 3e1ff6d..a5c55e8 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -17,6 +17,7 @@
package com.android.server;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
@@ -32,6 +33,9 @@
import android.net.IpSecManager;
import android.net.IpSecSpiResponse;
import android.net.IpSecTransformResponse;
+import android.net.IpSecTunnelInterfaceResponse;
+import android.net.LinkAddress;
+import android.net.Network;
import android.net.NetworkUtils;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
@@ -56,10 +60,15 @@
private final String mDestinationAddr;
private final String mSourceAddr;
+ private final LinkAddress mLocalInnerAddress;
@Parameterized.Parameters
public static Collection ipSecConfigs() {
- return Arrays.asList(new Object[][] {{"1.2.3.4", "8.8.4.4"}, {"2601::2", "2601::10"}});
+ return Arrays.asList(
+ new Object[][] {
+ {"1.2.3.4", "8.8.4.4", "10.0.1.1/24"},
+ {"2601::2", "2601::10", "2001:db8::1/64"}
+ });
}
private static final byte[] AEAD_KEY = {
@@ -86,6 +95,7 @@
INetd mMockNetd;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
+ Network fakeNetwork = new Network(0xAB);
private static final IpSecAlgorithm AUTH_ALGO =
new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
@@ -94,9 +104,11 @@
private static final IpSecAlgorithm AEAD_ALGO =
new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
- public IpSecServiceParameterizedTest(String sourceAddr, String destAddr) {
+ public IpSecServiceParameterizedTest(
+ String sourceAddr, String destAddr, String localInnerAddr) {
mSourceAddr = sourceAddr;
mDestinationAddr = destAddr;
+ mLocalInnerAddress = new LinkAddress(localInnerAddr);
}
@Before
@@ -406,4 +418,103 @@
verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
}
+
+ private IpSecTunnelInterfaceResponse createAndValidateTunnel(
+ String localAddr, String remoteAddr) {
+ IpSecTunnelInterfaceResponse createTunnelResp =
+ mIpSecService.createTunnelInterface(
+ mSourceAddr, mDestinationAddr, fakeNetwork, new Binder());
+
+ assertNotNull(createTunnelResp);
+ assertEquals(IpSecManager.Status.OK, createTunnelResp.status);
+ return createTunnelResp;
+ }
+
+ @Test
+ public void testCreateTunnelInterface() throws Exception {
+ IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+
+ // Check that we have stored the tracking object, and retrieve it
+ IpSecService.UserRecord userRecord =
+ mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.RefcountedResource refcountedRecord =
+ userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
+ createTunnelResp.resourceId);
+
+ assertEquals(1, userRecord.mTunnelQuotaTracker.mCurrent);
+ verify(mMockNetd)
+ .addVirtualTunnelInterface(
+ eq(createTunnelResp.interfaceName),
+ eq(mSourceAddr),
+ eq(mDestinationAddr),
+ anyInt(),
+ anyInt());
+ }
+
+ @Test
+ public void testDeleteTunnelInterface() throws Exception {
+ IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+
+ IpSecService.UserRecord userRecord =
+ mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+
+ mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId);
+
+ // Verify quota and RefcountedResource objects cleaned up
+ assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
+ verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName));
+ try {
+ userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
+ createTunnelResp.resourceId);
+ fail("Expected IllegalArgumentException on attempt to access deleted resource");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testTunnelInterfaceBinderDeath() throws Exception {
+ IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+
+ IpSecService.UserRecord userRecord =
+ mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.RefcountedResource refcountedRecord =
+ userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
+ createTunnelResp.resourceId);
+
+ refcountedRecord.binderDied();
+
+ // Verify quota and RefcountedResource objects cleaned up
+ assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
+ verify(mMockNetd).removeVirtualTunnelInterface(eq(createTunnelResp.interfaceName));
+ try {
+ userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
+ createTunnelResp.resourceId);
+ fail("Expected IllegalArgumentException on attempt to access deleted resource");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testAddRemoveAddressFromTunnelInterface() throws Exception {
+ IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+
+ mIpSecService.addAddressToTunnelInterface(createTunnelResp.resourceId, mLocalInnerAddress);
+ verify(mMockNetd)
+ .interfaceAddAddress(
+ eq(createTunnelResp.interfaceName),
+ eq(mLocalInnerAddress.getAddress().getHostAddress()),
+ eq(mLocalInnerAddress.getPrefixLength()));
+
+ mIpSecService.removeAddressFromTunnelInterface(
+ createTunnelResp.resourceId, mLocalInnerAddress);
+ verify(mMockNetd)
+ .interfaceDelAddress(
+ eq(createTunnelResp.interfaceName),
+ eq(mLocalInnerAddress.getAddress().getHostAddress()),
+ eq(mLocalInnerAddress.getPrefixLength()));
+ }
}