diff options
186 files changed, 2406 insertions, 1164 deletions
diff --git a/Android.mk b/Android.mk index ccf3894a3d02..66c9529317f2 100644 --- a/Android.mk +++ b/Android.mk @@ -945,21 +945,21 @@ $(LOCAL_LIGHT_GREYLIST): $(LOCAL_SRC_ALL) $(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API)) $(call assert-has-no-overlap,$@,$(LOCAL_SRC_FORCE_BLACKLIST)) -# Generate dark greylist as remaining members of classes on the light greylist, -# as well as the members of their inner classes. +# Generate dark greylist as remaining classes and class members in the same +# package as classes listed in the light greylist. # The algorithm is as follows: # (1) extract the class descriptor from each entry in LOCAL_LIGHT_GREYLIST -# (2) strip the final semicolon and anything after (and including) a dollar sign, -# e.g. 'Lpackage/class$inner;' turns into 'Lpackage/class' -# (3) insert all entries from LOCAL_SRC_PRIVATE_API which begin with the stripped -# descriptor followed by a semi-colon or a dollar sign, e.g. matching a regex -# '^Lpackage/class[;$]' +# (2) strip everything after the last forward-slash, +# e.g. 'Lpackage/subpackage/class$inner;' turns into 'Lpackage/subpackage/' +# (3) insert all entries from LOCAL_SRC_PRIVATE_API which begin with the package +# name but do not contain another forward-slash in the class name, e.g. +# matching '^Lpackage/subpackage/[^/;]*;' # (4) subtract entries shared with LOCAL_LIGHT_GREYLIST $(LOCAL_DARK_GREYLIST): $(LOCAL_SRC_ALL) $(LOCAL_LIGHT_GREYLIST) comm -13 <(sort $(LOCAL_LIGHT_GREYLIST) $(LOCAL_SRC_FORCE_BLACKLIST)) \ - <(sed 's/;\->.*//' $(LOCAL_LIGHT_GREYLIST) | sed 's/$$.*//' | sort | uniq | \ - while read CLASS_DESC; do \ - grep -E "^$${CLASS_DESC}[;$$]" $(LOCAL_SRC_PRIVATE_API); \ + <(sed 's/\->.*//' $(LOCAL_LIGHT_GREYLIST) | sed 's/\(.*\/\).*/\1/' | sort | uniq | \ + while read PKG_NAME; do \ + grep -E "^$${PKG_NAME}[^/;]*;" $(LOCAL_SRC_PRIVATE_API); \ done | sort | uniq) \ > $@ $(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API)) @@ -988,4 +988,3 @@ include $(call first-makefiles-under,$(LOCAL_PATH)) endif endif # ANDROID_BUILD_EMBEDDED - diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blacklist.txt index 2a10f77b862f..0c689e82eb4b 100644 --- a/config/hiddenapi-force-blacklist.txt +++ b/config/hiddenapi-force-blacklist.txt @@ -1 +1,37 @@ Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V +Ljava/lang/invoke/VarHandle;->acquireFence()V +Ljava/lang/invoke/VarHandle;->compareAndExchange([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->compareAndExchangeAcquire([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->compareAndExchangeRelease([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->compareAndSet([[Ljava/lang/Object;)Z +Ljava/lang/invoke/VarHandle;->fullFence()V +Ljava/lang/invoke/VarHandle;->get([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAcquire([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndAdd([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndAddAcquire([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndAddRelease([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseAnd([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseAndAcquire([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseAndRelease([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseOr([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseOrAcquire([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseOrRelease([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseXor([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseXorAcquire([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndBitwiseXorRelease([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndSet([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndSetAcquire([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getAndSetRelease([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getOpaque([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->getVolatile([[Ljava/lang/Object;)Ljava/lang/Object; +Ljava/lang/invoke/VarHandle;->loadLoadFence()V +Ljava/lang/invoke/VarHandle;->releaseFence()V +Ljava/lang/invoke/VarHandle;->set([[Ljava/lang/Object;)V +Ljava/lang/invoke/VarHandle;->setOpaque([[Ljava/lang/Object;)V +Ljava/lang/invoke/VarHandle;->setRelease([[Ljava/lang/Object;)V +Ljava/lang/invoke/VarHandle;->setVolatile([[Ljava/lang/Object;)V +Ljava/lang/invoke/VarHandle;->storeStoreFence()V +Ljava/lang/invoke/VarHandle;->weakCompareAndSet([[Ljava/lang/Object;)Z +Ljava/lang/invoke/VarHandle;->weakCompareAndSetAcquire([[Ljava/lang/Object;)Z +Ljava/lang/invoke/VarHandle;->weakCompareAndSetPlain([[Ljava/lang/Object;)Z +Ljava/lang/invoke/VarHandle;->weakCompareAndSetRelease([[Ljava/lang/Object;)Z diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 9b47d556a4a1..b9ead8bf8965 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -376,6 +376,7 @@ Landroid/app/AppOpsManager;->OP_AUDIO_NOTIFICATION_VOLUME:I Landroid/app/AppOpsManager;->OP_AUDIO_RING_VOLUME:I Landroid/app/AppOpsManager;->OP_AUDIO_VOICE_VOLUME:I Landroid/app/AppOpsManager;->OP_BIND_ACCESSIBILITY_SERVICE:I +Landroid/app/AppOpsManager;->OP_BLUETOOTH_SCAN:I Landroid/app/AppOpsManager;->OP_BODY_SENSORS:I Landroid/app/AppOpsManager;->OP_CALL_PHONE:I Landroid/app/AppOpsManager;->OP_CAMERA:I @@ -634,6 +635,7 @@ Landroid/app/IActivityManager;->unlockUser(I[B[BLandroid/os/IProgressListener;)Z Landroid/app/IActivityManager;->unregisterProcessObserver(Landroid/app/IProcessObserver;)V Landroid/app/IActivityManager;->unregisterReceiver(Landroid/content/IIntentReceiver;)V Landroid/app/IActivityManager;->unstableProviderDied(Landroid/os/IBinder;)V +Landroid/app/IActivityManager;->updateConfiguration(Landroid/content/res/Configuration;)Z Landroid/app/IActivityManager;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V Landroid/app/IAlarmManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/app/IAlarmManager$Stub;-><init>()V @@ -654,6 +656,7 @@ Landroid/app/IApplicationThread;->scheduleUnbindService(Landroid/os/IBinder;Land Landroid/app/IApplicationThread;->updateTimeZone()V Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo; Landroid/app/IBackupAgent$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IBackupAgent; +Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z Landroid/app/IInstrumentationWatcher$Stub;-><init>()V Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher; Landroid/app/IInstrumentationWatcher;->instrumentationFinished(Landroid/content/ComponentName;ILandroid/os/Bundle;)V @@ -2376,6 +2379,7 @@ Landroid/hardware/input/IInputManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/input/IInputManager; Landroid/hardware/input/IInputManager$Stub;->TRANSACTION_injectInputEvent:I Landroid/hardware/input/IInputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z +Landroid/hardware/input/InputManager;->createInputForwarder(I)Landroid/app/IInputForwarder; Landroid/hardware/input/InputManager;->getInstance()Landroid/hardware/input/InputManager; Landroid/hardware/input/InputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z Landroid/hardware/input/InputManager;->INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH:I @@ -3958,6 +3962,7 @@ Landroid/os/storage/StorageManager;->unmount(Ljava/lang/String;)V Landroid/os/storage/StorageVolume;->allowMassStorage()Z Landroid/os/storage/StorageVolume;->getFatVolumeId()I Landroid/os/storage/StorageVolume;->getMaxFileSize()J +Landroid/os/storage/StorageVolume;->getOwner()Landroid/os/UserHandle; Landroid/os/storage/StorageVolume;->getPath()Ljava/lang/String; Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File; Landroid/os/storage/StorageVolume;->getUserLabel()Ljava/lang/String; @@ -4916,6 +4921,7 @@ Landroid/telecom/TelecomManager;->setUserSelectedOutgoingPhoneAccount(Landroid/t Landroid/telecom/TelecomManager;->TTY_MODE_OFF:I Landroid/telecom/VideoCallImpl;->destroy()V Landroid/telephony/CarrierConfigManager;->KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY:Ljava/lang/String; +Landroid/telephony/CarrierConfigManager;->KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL:Ljava/lang/String; Landroid/telephony/CarrierMessagingServiceManager;-><init>()V Landroid/telephony/CellBroadcastMessage;-><init>(Landroid/telephony/SmsCbMessage;)V Landroid/telephony/CellBroadcastMessage;->createFromCursor(Landroid/database/Cursor;)Landroid/telephony/CellBroadcastMessage; @@ -8043,6 +8049,7 @@ Lcom/android/org/conscrypt/TrustedCertificateStore;->getCertificateChain(Ljava/s Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List; Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;)V +Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;Z)V Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String; Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList; Ldalvik/system/BlockGuard$BlockGuardPolicyException;-><init>(IILjava/lang/String;)V @@ -8088,6 +8095,7 @@ Ldalvik/system/DexPathList;->systemNativeLibraryDirectories:Ljava/util/List; Ldalvik/system/SocketTagger;->get()Ldalvik/system/SocketTagger; Ldalvik/system/SocketTagger;->tag(Ljava/net/Socket;)V Ldalvik/system/SocketTagger;->untag(Ljava/net/Socket;)V +Ldalvik/system/VMDebug;->allowHiddenApiReflectionFrom(Ljava/lang/Class;)V Ldalvik/system/VMDebug;->dumpReferenceTables()V Ldalvik/system/VMDebug;->isDebuggerConnected()Z Ldalvik/system/VMRuntime;->addressOf(Ljava/lang/Object;)J diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt index fe10f41360a7..1285cb5453ca 100644 --- a/config/hiddenapi-vendor-list.txt +++ b/config/hiddenapi-vendor-list.txt @@ -534,8 +534,7 @@ Landroid/view/IRecentsAnimationController;->screenshotTask(I)Landroid/app/Activi Landroid/view/IRecentsAnimationController;->setInputConsumerEnabled(Z)V Landroid/view/IRecentsAnimationRunner$Stub;-><init>()V Landroid/view/IRecentsAnimationRunner;->onAnimationCanceled()V -Landroid/view/IRecentsAnimationRunner;->onAnimationStart(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;)V -Landroid/view/IRecentsAnimationRunner;->onAnimationStart_New(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;Landroid/graphics/Rect;Landroid/graphics/Rect;)V +Landroid/view/IRecentsAnimationRunner;->onAnimationStart(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;Landroid/graphics/Rect;Landroid/graphics/Rect;)V Landroid/view/IRemoteAnimationFinishedCallback;->onAnimationFinished()V Landroid/view/IRemoteAnimationRunner$Stub;-><init>()V Landroid/view/IRemoteAnimationRunner;->onAnimationCancelled()V diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 539a01043657..3c7541f92e5d 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -2110,9 +2110,12 @@ public class ActivityManager { private final boolean mIsRealSnapshot; private final int mWindowingMode; private final float mScale; + private final int mSystemUiVisibility; + private final boolean mIsTranslucent; public TaskSnapshot(GraphicBuffer snapshot, int orientation, Rect contentInsets, - boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode) { + boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode, + int systemUiVisibility, boolean isTranslucent) { mSnapshot = snapshot; mOrientation = orientation; mContentInsets = new Rect(contentInsets); @@ -2120,6 +2123,8 @@ public class ActivityManager { mScale = scale; mIsRealSnapshot = isRealSnapshot; mWindowingMode = windowingMode; + mSystemUiVisibility = systemUiVisibility; + mIsTranslucent = isTranslucent; } private TaskSnapshot(Parcel source) { @@ -2130,6 +2135,8 @@ public class ActivityManager { mScale = source.readFloat(); mIsRealSnapshot = source.readBoolean(); mWindowingMode = source.readInt(); + mSystemUiVisibility = source.readInt(); + mIsTranslucent = source.readBoolean(); } /** @@ -2170,6 +2177,13 @@ public class ActivityManager { } /** + * @return Whether or not the snapshot is of a translucent app window. + */ + public boolean isTranslucent() { + return mIsTranslucent; + } + + /** * @return The windowing mode of the task when this snapshot was taken. */ public int getWindowingMode() { @@ -2177,6 +2191,14 @@ public class ActivityManager { } /** + * @return The system ui visibility flags for the top most visible fullscreen window at the + * time that the snapshot was taken. + */ + public int getSystemUiVisibility() { + return mSystemUiVisibility; + } + + /** * @return The scale this snapshot was taken in. */ public float getScale() { @@ -2197,6 +2219,8 @@ public class ActivityManager { dest.writeFloat(mScale); dest.writeBoolean(mIsRealSnapshot); dest.writeInt(mWindowingMode); + dest.writeInt(mSystemUiVisibility); + dest.writeBoolean(mIsTranslucent); } @Override @@ -2207,7 +2231,9 @@ public class ActivityManager { + " mOrientation=" + mOrientation + " mContentInsets=" + mContentInsets.toShortString() + " mReducedResolution=" + mReducedResolution + " mScale=" + mScale - + " mIsRealSnapshot=" + mIsRealSnapshot + " mWindowingMode=" + mWindowingMode; + + " mIsRealSnapshot=" + mIsRealSnapshot + " mWindowingMode=" + mWindowingMode + + " mSystemUiVisibility=" + mSystemUiVisibility + + " mIsTranslucent=" + mIsTranslucent; } public static final Creator<TaskSnapshot> CREATOR = new Creator<TaskSnapshot>() { diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 7032a2fe21cf..e469098e22d5 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -24,6 +24,7 @@ import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.hardware.input.InputManager; import android.os.RemoteException; +import android.os.UserHandle; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; @@ -111,6 +112,11 @@ public class ActivityView extends ViewGroup { * @see #startActivity(Intent) */ public abstract void onActivityViewDestroyed(ActivityView view); + /** + * Called when a task is moved to the front of the stack inside the container. + * This is a filtered version of {@link TaskStackListener} + */ + public void onTaskMovedToFront(ActivityManager.StackInfo stackInfo) { } } /** @@ -155,6 +161,28 @@ public class ActivityView extends ViewGroup { /** * Launch a new activity into this container. + * <p>Activity resolved by the provided {@link Intent} must have + * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be + * launched here. Also, if activity is not owned by the owner of this container, it must allow + * embedding and the caller must have permission to embed. + * <p>Note: This class must finish initializing and + * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before + * this method can be called. + * + * @param intent Intent used to launch an activity. + * @param user The UserHandle of the user to start this activity for. + * + * + * @see StateCallback + * @see #startActivity(PendingIntent) + */ + public void startActivity(@NonNull Intent intent, UserHandle user) { + final ActivityOptions options = prepareActivityOptions(); + getContext().startActivityAsUser(intent, options.toBundle(), user); + } + + /** + * Launch a new activity into this container. * <p>Activity resolved by the provided {@link PendingIntent} must have * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be * launched here. Also, if activity is not owned by the owner of this container, it must allow @@ -303,7 +331,9 @@ public class ActivityView extends ViewGroup { final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); mVirtualDisplay = displayManager.createVirtualDisplay( DISPLAY_NAME + "@" + System.identityHashCode(this), - width, height, getBaseDisplayDensity(), mSurface, 0 /* flags */); + width, height, getBaseDisplayDensity(), mSurface, + DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC + | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); if (mVirtualDisplay == null) { Log.e(TAG, "Failed to initialize ActivityView"); return; @@ -317,7 +347,7 @@ public class ActivityView extends ViewGroup { e.rethrowAsRuntimeException(); } mInputForwarder = InputManager.getInstance().createInputForwarder(displayId); - mTaskStackListener = new TaskBackgroundChangeListener(); + mTaskStackListener = new TaskStackListenerImpl(); try { mActivityManager.registerTaskStackListener(mTaskStackListener); } catch (RemoteException e) { @@ -403,8 +433,11 @@ public class ActivityView extends ViewGroup { * A task change listener that detects background color change of the topmost stack on our * virtual display and updates the background of the surface view. This background will be shown * when surface view is resized, but the app hasn't drawn its content in new size yet. + * It also calls StateCallback.onTaskMovedToFront to notify interested parties that the stack + * associated with the {@link ActivityView} has had a Task moved to the front. This is useful + * when needing to also bring the host Activity to the foreground at the same time. */ - private class TaskBackgroundChangeListener extends TaskStackListener { + private class TaskStackListenerImpl extends TaskStackListener { @Override public void onTaskDescriptionChanged(int taskId, ActivityManager.TaskDescription td) @@ -413,6 +446,31 @@ public class ActivityView extends ViewGroup { return; } + StackInfo stackInfo = getTopMostStackInfo(); + if (stackInfo == null) { + return; + } + // Found the topmost stack on target display. Now check if the topmost task's + // description changed. + if (taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) { + mSurfaceView.setResizeBackgroundColor(td.getBackgroundColor()); + } + } + + @Override + public void onTaskMovedToFront(int taskId) throws RemoteException { + if (mActivityViewCallback != null) { + StackInfo stackInfo = getTopMostStackInfo(); + // if StackInfo was null or unrelated to the "move to front" then there's no use + // notifying the callback + if (stackInfo != null + && taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) { + mActivityViewCallback.onTaskMovedToFront(stackInfo); + } + } + } + + private StackInfo getTopMostStackInfo() throws RemoteException { // Find the topmost task on our virtual display - it will define the background // color of the surface view during resizing. final int displayId = mVirtualDisplay.getDisplay().getDisplayId(); @@ -426,14 +484,10 @@ public class ActivityView extends ViewGroup { if (stackInfo.displayId != displayId) { continue; } - // Found the topmost stack on target display. Now check if the topmost task's - // description changed. - if (taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) { - mSurfaceView.setResizeBackgroundColor(td.getBackgroundColor()); - } - break; + // Found the topmost stack on target display. + return stackInfo; } + return null; } } - } diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java index 22df6c03aee2..f682ec1c31d4 100644 --- a/core/java/android/app/slice/SliceManager.java +++ b/core/java/android/app/slice/SliceManager.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; +import android.annotation.WorkerThread; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; @@ -217,6 +218,7 @@ public class SliceManager { * @return All slices within the space. * @see SliceProvider#onGetSliceDescendants(Uri) */ + @WorkerThread public @NonNull Collection<Uri> getSliceDescendants(@NonNull Uri uri) { ContentResolver resolver = mContext.getContentResolver(); try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) { diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index 9e4e97a011fa..6c57d81e317d 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -398,12 +398,7 @@ public abstract class SliceProvider extends ContentProvider { private Collection<Uri> handleGetDescendants(Uri uri) { mCallback = "onGetSliceDescendants"; - Handler.getMain().postDelayed(mAnr, SLICE_BIND_ANR); - try { - return onGetSliceDescendants(uri); - } finally { - Handler.getMain().removeCallbacks(mAnr); - } + return onGetSliceDescendants(uri); } private void handlePinSlice(Uri sliceUri) { diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 7fb97d3a0d22..1b0540230d66 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -572,13 +572,14 @@ public final class UsageStatsManager { * the sum of usages of apps in the packages array exceeds the {@code timeLimit} specified. The * observer will automatically be unregistered when the time limit is reached and the intent * is delivered. Registering an {@code observerId} that was already registered will override - * the previous one. + * the previous one. No more than 1000 unique {@code observerId} may be registered by a single + * uid at any one time. * @param observerId A unique id associated with the group of apps to be monitored. There can * be multiple groups with common packages and different time limits. * @param packages The list of packages to observe for foreground activity time. Cannot be null * and must include at least one package. * @param timeLimit The total time the set of apps can be in the foreground before the - * callbackIntent is delivered. Must be greater than 0. + * callbackIntent is delivered. Must be at least one minute. * @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null. * @param callbackIntent The PendingIntent that will be dispatched when the time limit is * exceeded by the group of apps. The delivered Intent will also contain diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index dec2cd42c5f9..ea0811086d52 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1420,6 +1420,9 @@ public class Intent implements Parcelable, Cloneable { * Activity Action: Start Voice Command. * <p>Input: Nothing. * <p>Output: Nothing. + * <p class="note"> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND"; @@ -5683,9 +5686,24 @@ public class Intent implements Parcelable, Cloneable { /** - * If set, resolution of this intent may take place via an instant app not - * yet on the device if there does not yet exist an app on device to - * resolve it. + * If set in an Intent passed to {@link Context#startActivity Context.startActivity()}, + * this flag will attempt to launch an instant app if no full app on the device can already + * handle the intent. + * <p> + * When attempting to resolve instant apps externally, the following {@link Intent} properties + * are supported: + * <ul> + * <li>{@link Intent#setAction(String)}</li> + * <li>{@link Intent#addCategory(String)}</li> + * <li>{@link Intent#setData(Uri)}</li> + * <li>{@link Intent#setType(String)}</li> + * <li>{@link Intent#setPackage(String)}</li> + * <li>{@link Intent#addFlags(int)}</li> + * </ul> + * <p> + * In the case that no instant app can be found, the installer will be launched to notify the + * user that the intent could not be resolved. On devices that do not support instant apps, + * the flag will be ignored. */ public static final int FLAG_ACTIVITY_MATCH_EXTERNAL = 0x00000800; diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index a10cc120ad6c..edacbb0bb2b4 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -18,7 +18,6 @@ package android.content.om; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; @@ -39,6 +38,7 @@ public final class OverlayInfo implements Parcelable { STATE_NO_IDMAP, STATE_DISABLED, STATE_ENABLED, + STATE_ENABLED_STATIC, STATE_TARGET_UPGRADING, STATE_OVERLAY_UPGRADING, }) @@ -91,7 +91,16 @@ public final class OverlayInfo implements Parcelable { public static final int STATE_OVERLAY_UPGRADING = 5; /** - * Category for theme overlays. + * The overlay package is currently enabled because it is marked as + * 'static'. It cannot be disabled but will change state if for instance + * its target is uninstalled. + */ + public static final int STATE_ENABLED_STATIC = 6; + + /** + * Overlay category: theme. + * <p> + * Change how Android (including the status bar, dialogs, ...) looks. */ public static final String CATEGORY_THEME = "android.theme"; @@ -126,6 +135,23 @@ public final class OverlayInfo implements Parcelable { public final int userId; /** + * Priority as read from the manifest. Used if isStatic is true. Not + * intended to be exposed to 3rd party. + * + * @hide + */ + public final int priority; + + /** + * isStatic as read from the manifest. If true, the overlay is + * unconditionally loaded and cannot be unloaded. Not intended to be + * exposed to 3rd party. + * + * @hide + */ + public final boolean isStatic; + + /** * Create a new OverlayInfo based on source with an updated state. * * @param source the source OverlayInfo to base the new instance on @@ -133,17 +159,20 @@ public final class OverlayInfo implements Parcelable { */ public OverlayInfo(@NonNull OverlayInfo source, @State int state) { this(source.packageName, source.targetPackageName, source.category, source.baseCodePath, - state, source.userId); + state, source.userId, source.priority, source.isStatic); } public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName, - @Nullable String category, @NonNull String baseCodePath, int state, int userId) { + @NonNull String category, @NonNull String baseCodePath, int state, int userId, + int priority, boolean isStatic) { this.packageName = packageName; this.targetPackageName = targetPackageName; this.category = category; this.baseCodePath = baseCodePath; this.state = state; this.userId = userId; + this.priority = priority; + this.isStatic = isStatic; ensureValidState(); } @@ -154,6 +183,8 @@ public final class OverlayInfo implements Parcelable { baseCodePath = source.readString(); state = source.readInt(); userId = source.readInt(); + priority = source.readInt(); + isStatic = source.readBoolean(); ensureValidState(); } @@ -173,6 +204,7 @@ public final class OverlayInfo implements Parcelable { case STATE_NO_IDMAP: case STATE_DISABLED: case STATE_ENABLED: + case STATE_ENABLED_STATIC: case STATE_TARGET_UPGRADING: case STATE_OVERLAY_UPGRADING: break; @@ -194,6 +226,8 @@ public final class OverlayInfo implements Parcelable { dest.writeString(baseCodePath); dest.writeInt(state); dest.writeInt(userId); + dest.writeInt(priority); + dest.writeBoolean(isStatic); } public static final Parcelable.Creator<OverlayInfo> CREATOR = @@ -220,6 +254,7 @@ public final class OverlayInfo implements Parcelable { public boolean isEnabled() { switch (state) { case STATE_ENABLED: + case STATE_ENABLED_STATIC: return true; default: return false; @@ -244,6 +279,8 @@ public final class OverlayInfo implements Parcelable { return "STATE_DISABLED"; case STATE_ENABLED: return "STATE_ENABLED"; + case STATE_ENABLED_STATIC: + return "STATE_ENABLED_STATIC"; case STATE_TARGET_UPGRADING: return "STATE_TARGET_UPGRADING"; case STATE_OVERLAY_UPGRADING: diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 8543b26ada38..29bbddc00fab 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -123,6 +123,10 @@ public final class Settings { * Input: Nothing. * <p> * Output: Nothing. + * + * <p class="note"> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_APN_SETTINGS = "android.settings.APN_SETTINGS"; @@ -882,6 +886,10 @@ public final class Settings { * Applications can also use {@link android.net.ConnectivityManager#getRestrictBackgroundStatus * ConnectivityManager#getRestrictBackgroundStatus()} to determine the * status of the background data restrictions for them. + * + * <p class="note"> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS = @@ -1148,6 +1156,10 @@ public final class Settings { * Input: Nothing. * <p> * Output: Nothing. + * + * <p class="note"> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS @@ -12728,6 +12740,25 @@ public final class Settings { public static final String SHOW_ZEN_UPGRADE_NOTIFICATION = "show_zen_upgrade_notification"; /** + * If nonzero, will show the zen update settings suggestion. + * @hide + */ + public static final String SHOW_ZEN_SETTINGS_SUGGESTION = "show_zen_settings_suggestion"; + + /** + * If nonzero, zen has not been updated to reflect new changes. + * @hide + */ + public static final String ZEN_SETTINGS_UPDATED = "zen_settings_updated"; + + /** + * If nonzero, zen setting suggestion has beem viewed by user + * @hide + */ + public static final String ZEN_SETTINGS_SUGGESTION_VIEWED = + "zen_settings_suggestion_viewed"; + + /** * Backup and restore agent timeout parameters. * These parameters are represented by a comma-delimited key-value list. * diff --git a/core/java/android/security/keystore/recovery/TrustedRootCertificates.java b/core/java/android/security/keystore/recovery/TrustedRootCertificates.java index a96dab68003b..c5f82c15858e 100644 --- a/core/java/android/security/keystore/recovery/TrustedRootCertificates.java +++ b/core/java/android/security/keystore/recovery/TrustedRootCertificates.java @@ -73,34 +73,34 @@ public final class TrustedRootCertificates { "INSECURE_PSWD_"; private static final String GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_BASE64 = "" - + "MIIFJjCCAw6gAwIBAgIJAIobXsJlzhNdMA0GCSqGSIb3DQEBDQUAMCAxHjAcBgNV" - + "BAMMFUdvb2dsZSBDcnlwdEF1dGhWYXVsdDAeFw0xODAyMDIxOTM5MTRaFw0zODAx" - + "MjgxOTM5MTRaMCAxHjAcBgNVBAMMFUdvb2dsZSBDcnlwdEF1dGhWYXVsdDCCAiIw" - + "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2OT5i40/H7LINg/lq/0G0hR65P" - + "Q4Mud3OnuVt6UIYV2T18+v6qW1yJd5FcnND/ZKPau4aUAYklqJuSVjOXQD0BjgS2" - + "98Xa4dSn8Ci1rUR+5tdmrxqbYUdT2ZvJIUMMR6fRoqi+LlAbKECrV+zYQTyLU68w" - + "V66hQpAButjJKiZzkXjmKLfJ5IWrNEn17XM988rk6qAQn/BYCCQGf3rQuJeksGmA" - + "N1lJOwNYxmWUyouVwqwZthNEWqTuEyBFMkAT+99PXW7oVDc7oU5cevuihxQWNTYq" - + "viGB8cck6RW3cmqrDSaJF/E+N0cXFKyYC7FDcggt6k3UrxNKTuySdDEa8+2RTQqU" - + "Y9npxBlQE+x9Ig56OI1BG3bSBsGdPgjpyHadZeh2tgk+oqlGsSsum24YxaxuSysT" - + "Qfcu/XhyfUXavfmGrBOXerTzIl5oBh/F5aHTV85M2tYEG0qsPPvSpZAWtdJ/2rca" - + "OxvhwOL+leZKr8McjXVR00lBsRuKXX4nTUMwya09CO3QHFPFZtZvqjy2HaMOnVLQ" - + "I6b6dHEfmsHybzVOe3yPEoFQSU9UhUdmi71kwwoanPD3j9fJHmXTx4PzYYBRf1ZE" - + "o+uPgMPk7CDKQFZLjnR40z1uzu3O8aZ3AKZzP+j7T4XQKJLQLmllKtPgLgNdJyib" - + "2Glg7QhXH/jBTL6hAgMBAAGjYzBhMB0GA1UdDgQWBBSbZfrqOYH54EJpkdKMZjMc" - + "z/Hp+DAfBgNVHSMEGDAWgBSbZfrqOYH54EJpkdKMZjMcz/Hp+DAPBgNVHRMBAf8E" - + "BTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQ0FAAOCAgEAKh9nm/vW" - + "glMWp3vcCwWwJW286ecREDlI+CjGh5h+f2N4QRrXd/tKE3qQJWCqGx8sFfIUjmI7" - + "KYdsC2gyQ2cA2zl0w7pB2QkuqE6zVbnh1D17Hwl19IMyAakFaM9ad4/EoH7oQmqX" - + "nF/f5QXGZw4kf1HcgKgoCHWXjqR8MqHOcXR8n6WFqxjzJf1jxzi6Yo2dZ7PJbnE6" - + "+kHIJuiCpiHL75v5g1HM41gT3ddFFSrn88ThNPWItT5Z8WpFjryVzank2Yt02LLl" - + "WqZg9IC375QULc5B58NMnaiVJIDJQ8zoNgj1yaxqtUMnJX570lotO2OXe4ec9aCQ" - + "DIJ84YLM/qStFdeZ9416E80dchskbDG04GuVJKlzWjxAQNMRFhyaPUSBTLLg+kwP" - + "t9+AMmc+A7xjtFQLZ9fBYHOBsndJOmeSQeYeckl+z/1WQf7DdwXn/yijon7mxz4z" - + "cCczfKwTJTwBh3wR5SQr2vQm7qaXM87qxF8PCAZrdZaw5I80QwkgTj0WTZ2/GdSw" - + "d3o5SyzzBAjpwtG+4bO/BD9h9wlTsHpT6yWOZs4OYAKU5ykQrncI8OyavMggArh3" - + "/oM58v0orUWINtIc2hBlka36PhATYQiLf+AiWKnwhCaaHExoYKfQlMtXBodNvOK8" - + "xqx69x05q/qbHKEcTHrsss630vxrp1niXvA="; + + "MIIFDzCCAvegAwIBAgIQbNdueU2o0vM9gGq4N6bhjzANBgkqhkiG9w0BAQsFADAx" + + "MS8wLQYDVQQDEyZHb29nbGUgQ2xvdWQgS2V5IFZhdWx0IFNlcnZpY2UgUm9vdCBD" + + "QTAeFw0xODA1MDcxODI0MDJaFw0zODA1MDgxOTI0MDJaMDExLzAtBgNVBAMTJkdv" + + "b2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBSb290IENBMIICIjANBgkqhkiG" + + "9w0BAQEFAAOCAg8AMIICCgKCAgEArUgzu+4o9yl22eql1BiGBq3gWXooh2ql3J+v" + + "Vuzf/ThjzdIg0xkkkw/NAFxYFi49Eo1fa/hf8wCIoAqCEs1lD6tE3cCD3T3+EQPq" + + "uh6CB2KmZDJ6mPnXvVUlUuFr0O2MwZkwylqBETzK0x5NCHgL/p47vkjhHx6LqVao" + + "bigKlHxszvVi4fkt/qq7KW3YTVxhwdLGEab+OqSfwMxdBLhMfE0K0dvFt8bs8yJA" + + "F04DJsMbRChFFBpT17Z0u53iIAAu5qVQhKrQXiIAwgboZqd+JkHLXU1fJeVT5WJO" + + "JgoJFWHkdWkHta4mSYlS72J1Q927JD1JdET1kFtH+EDtYAtx7x7F9xAAbb2tMITw" + + "s/wwd2rAzZTX/kxRbDlXVLToU05LFYPr+dFV1wvXmi0jlkIxnhdaVBqWC93p528U" + + "iUcLpib+HVzMWGdYI3G1NOa/lTp0c8LcbJjapiiVneRQJ3cIqDPOSEnEq40hyZd1" + + "jx3JnOxJMwHs8v4s9GIlb3BcOmDvA/Mu09xEMKwpHBm4TFDKXeGHOWha7ccWEECb" + + "yO5ncu6XuN2iyz9S+TuMyjZBE552p6Pu5gEC2xk+qab0NGDTHdLKLbyWn3IxdmBH" + + "yTr7iPCqmpyHngkC/pbGfvGusc5BpBugsBtlz67m4RWLJ72yAeVPO/ly/8w4orNs" + + "GWjn3s0CAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w" + + "DQYJKoZIhvcNAQELBQADggIBAGiWlu+4qyxgPb6RsA0mwR7V21UJ9rEpYhSN+ARp" + + "TWGiI22RCJSGK0ZrPGeFQzE2BpnVRdmLTV5jf9JUStjHoPvNYFnwLTJ0E2e9Olj8" + + "MrHrAucAUFLhl4woWz0kU/X0EB1j6Y2SXrAaZPiMMpq8BKj3mH1MbV4stZ0kiHUp" + + "Zu6PEmrojYG7FKKN30na2xXfiOfl2JusVsyHDqmUn/HjTh6zASKqE6hxE+FJRl2V" + + "Q4dcr4SviHtdbimMy2LghLnZ4FE4XhJgRnw9TeRV5C9Sn7pmnAA5X0C8ZXhXvfvr" + + "dx4fL3UKlk1Lqlb5skxoK1R9wwr+aNIO+cuR8JA5DmEDWFw5Budh/uWWZlBTyVW2" + + "ybbTB6tkmOc8c08XOgxBaKrsXALmJcluabjmN1jp81ae1epeN31jJ4N5IE5aq7Xb" + + "TFmKkwpgTTvJmqCR2XzWujlvdbdjfiABliWsnLzLQCP8eZwcM4LA5UK3f1ktHolr" + + "1OI9etSOkebE2py8LPYBJWlX36tRAagZhU/NoyOtvhRzq9rb3rbf96APEHKUFsXG" + + "9nBEd2BUKZghLKPf+JNCU/2pOGx0jdMcf+K+a1DeG0YzGYMRkFvpN3hvHYrJdByL" + + "3kSP3UtD0H2g8Ps7gRLELG2HODxbSn8PV3XtuSvxVanA6uyaaS3AZ6SxeVLvmw50" + + "7aYI"; private static final String TEST_ONLY_INSECURE_CERTIFICATE_BASE64 = "" + "MIIFMDCCAxigAwIBAgIJAIZ9/G8KQie9MA0GCSqGSIb3DQEBDQUAMCUxIzAhBgNV" @@ -134,8 +134,6 @@ public final class TrustedRootCertificates { /** * The X509 certificate of the trusted root CA cert for the recoverable key store service. - * - * TODO: Change it to the production certificate root CA before the final launch. */ private static final X509Certificate GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_CERTIFICATE = parseBase64Certificate(GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_BASE64); diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java index ce94315c4225..362b94b83c3f 100644 --- a/core/java/android/speech/RecognizerIntent.java +++ b/core/java/android/speech/RecognizerIntent.java @@ -141,6 +141,10 @@ public class RecognizerIntent { * <ul> * <li>{@link #EXTRA_SECURE} * </ul> + * + * <p class="note"> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. */ public static final String ACTION_VOICE_SEARCH_HANDS_FREE = "android.speech.action.VOICE_SEARCH_HANDS_FREE"; diff --git a/core/java/android/view/IRecentsAnimationRunner.aidl b/core/java/android/view/IRecentsAnimationRunner.aidl index 69973e6d367a..4cdf66441514 100644 --- a/core/java/android/view/IRecentsAnimationRunner.aidl +++ b/core/java/android/view/IRecentsAnimationRunner.aidl @@ -29,12 +29,6 @@ import android.view.IRecentsAnimationController; oneway interface IRecentsAnimationRunner { /** - * Deprecated, to be removed once Launcher updates - */ - void onAnimationStart(in IRecentsAnimationController controller, - in RemoteAnimationTarget[] apps) = 0; - - /** * Called when the system needs to cancel the current animation. This can be due to the * wallpaper not drawing in time, or the handler not finishing the animation within a predefined * amount of time. @@ -48,7 +42,7 @@ oneway interface IRecentsAnimationRunner { * @param minimizedHomeBounds Specifies the bounds of the minimized home app, will be * {@code null} if the device is not currently in split screen */ - void onAnimationStart_New(in IRecentsAnimationController controller, + void onAnimationStart(in IRecentsAnimationController controller, in RemoteAnimationTarget[] apps, in Rect homeContentInsets, in Rect minimizedHomeBounds) = 2; } diff --git a/core/java/android/view/textclassifier/SelectionSessionLogger.java b/core/java/android/view/textclassifier/SelectionSessionLogger.java index f2fb63eb01f3..cdacdd504eeb 100644 --- a/core/java/android/view/textclassifier/SelectionSessionLogger.java +++ b/core/java/android/view/textclassifier/SelectionSessionLogger.java @@ -86,8 +86,10 @@ public final class SelectionSessionLogger { .addTaggedData(SMART_START, event.getSmartStart()) .addTaggedData(SMART_END, event.getSmartEnd()) .addTaggedData(EVENT_START, event.getStart()) - .addTaggedData(EVENT_END, event.getEnd()) - .addTaggedData(SESSION_ID, event.getSessionId().flattenToString()); + .addTaggedData(EVENT_END, event.getEnd()); + if (event.getSessionId() != null) { + log.addTaggedData(SESSION_ID, event.getSessionId().flattenToString()); + } mMetricsLogger.write(log); debugLog(log); } diff --git a/core/java/android/view/textclassifier/SystemTextClassifier.java b/core/java/android/view/textclassifier/SystemTextClassifier.java index da86b559c5db..10191e0edbf7 100644 --- a/core/java/android/view/textclassifier/SystemTextClassifier.java +++ b/core/java/android/view/textclassifier/SystemTextClassifier.java @@ -129,6 +129,18 @@ public final class SystemTextClassifier implements TextClassifier { return mFallback.generateLinks(request); } + @Override + public void onSelectionEvent(SelectionEvent event) { + Preconditions.checkNotNull(event); + Utils.checkMainThread(); + + try { + mManagerService.onSelectionEvent(mSessionId, event); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Error reporting selection event.", e); + } + } + /** * @inheritDoc */ diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java index fbf690fa1457..a8ad8102c610 100644 --- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java @@ -25,7 +25,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.hardware.display.DisplayManager; -import android.util.Log; import android.view.Display; import android.view.DisplayInfo; @@ -108,6 +107,12 @@ public class DividerSnapAlgorithm { } public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize, + boolean isHorizontalDivision, Rect insets, int dockSide) { + this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets, + dockSide, false); + } + + public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize, boolean isHorizontalDivision, Rect insets, int dockSide, boolean isMinimizedMode) { mMinFlingVelocityPxPerSecond = MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density; @@ -265,7 +270,11 @@ public class DividerSnapAlgorithm { ? mDisplayHeight : mDisplayWidth; int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right; - mTargets.add(new SnapTarget(-mDividerSize, -mDividerSize, SnapTarget.FLAG_DISMISS_START, + int startPos = -mDividerSize; + if (dockedSide == DOCKED_RIGHT) { + startPos += mInsets.left; + } + mTargets.add(new SnapTarget(startPos, startPos, SnapTarget.FLAG_DISMISS_START, 0.35f)); switch (mSnapMode) { case SNAP_MODE_16_9: diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 7fa224757fd2..fa9f44557d3f 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -75,9 +75,8 @@ static struct assetfiledescriptor_offsets_t { jfieldID mLength; } gAssetFileDescriptorOffsets; -static struct assetmanager_offsets_t { - jfieldID mObject; -} gAssetManagerOffsets; +// This is also used by asset_manager.cpp. +assetmanager_offsets_t gAssetManagerOffsets; static struct { jfieldID native_ptr; diff --git a/core/jni/include/android_runtime/android_util_AssetManager.h b/core/jni/include/android_runtime/android_util_AssetManager.h index 2c1e3579eb92..ac734a908bed 100644 --- a/core/jni/include/android_runtime/android_util_AssetManager.h +++ b/core/jni/include/android_runtime/android_util_AssetManager.h @@ -27,6 +27,11 @@ namespace android { extern AAssetManager* NdkAssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager); extern Guarded<AssetManager2>* AssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager); extern Guarded<AssetManager2>* AssetManagerForNdkAssetManager(AAssetManager* assetmanager); +struct assetmanager_offsets_t +{ + jfieldID mObject; +}; +extern assetmanager_offsets_t gAssetManagerOffsets; } // namespace android diff --git a/core/res/res/drawable/ic_feedback.xml b/core/res/res/drawable/ic_feedback.xml index c316e7df5d4b..d4721b6adeb2 100644 --- a/core/res/res/drawable/ic_feedback.xml +++ b/core/res/res/drawable/ic_feedback.xml @@ -20,5 +20,11 @@ Copyright (C) 2016 The Android Open Source Project android:viewportHeight="24.0"> <path android:fillColor="#FF000000" - android:pathData="M20,2H4C2.9,2 2,2.9 2,4v17.39c0,0.54 0.65,0.81 1.04,0.43L6.86,18H20c1.1,0 2,-0.9 2,-2V4C22,2.9 21.1,2 20,2zM11,7c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v3c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V7zM12,15.2c-0.61,0 -1.1,-0.49 -1.1,-1.1c0,-0.61 0.49,-1.1 1.1,-1.1c0.61,0 1.1,0.49 1.1,1.1C13.1,14.71 12.61,15.2 12,15.2z"/> + android:pathData="M20,2H4C2.9,2 2.01,2.9 2.01,4L2,22l4,-4h14c1.1,0 2,-0.9 2,-2V4C22,2.9 21.1,2 20,2zM20,16H6H5.17l-0.59,0.59L4,17.17V4h16V16z"/> + <path + android:fillColor="#FF000000" + android:pathData="M11,12h2v2h-2z"/> + <path + android:fillColor="#FF000000" + android:pathData="M11,6h2v4h-2z"/> </vector> diff --git a/core/res/res/drawable/ic_lock_power_off.xml b/core/res/res/drawable/ic_lock_power_off.xml index 7e5676bd0ee5..cf778c776541 100644 --- a/core/res/res/drawable/ic_lock_power_off.xml +++ b/core/res/res/drawable/ic_lock_power_off.xml @@ -21,8 +21,8 @@ android:tint="?attr/colorControlNormal"> <path android:fillColor="#FF000000" - android:pathData="M12.0,3.0c-0.6,0.0 -1.0,0.4 -1.0,1.0l0.0,8.0c0.0,0.6 0.4,1.0 1.0,1.0s1.0,-0.4 1.0,-1.0L13.0,4.0c0.0,-0.6 -0.4,-1.0 -1.0,-1.0z"/> + android:pathData="M11,2h2v10h-2z"/> <path android:fillColor="#FF000000" - android:pathData="M17.1,5.9c-0.4,0.4 -0.4,1.0 0.0,1.4 1.3,1.4 2.1,3.4 1.8,5.6 -0.4,3.2 -3.0,5.7 -6.2,6.1 -4.0,0.4 -7.7,-2.9 -7.7,-7.0 0.0,-1.0 0.7,-3.5 1.9,-4.0 0.4,-0.4 0.4,-1.0 0.0,-1.4 -0.4,-0.4 -1.0,-0.4 -1.4,0.0C4.0,7.4 3.1,9.5 3.0,11.7c-0.1,4.9 3.8,9.1 8.7,9.3 5.0,0.2 9.3,-3.9 9.3,-9.0 0.0,-2.4 -0.9,-4.5 -2.4,-6.1 -0.4,-0.4 -1.1,-0.4 -1.5,0.0z"/> + android:pathData="M18.37,5.64l-1.41,1.41c2.73,2.73 2.72,7.16 -0.01,9.89c-2.73,2.73 -7.17,2.73 -9.89,0.01c-2.73,-2.73 -2.74,-7.18 -0.01,-9.91L5.64,5.64c-3.51,3.51 -3.51,9.21 0.01,12.73c3.51,3.51 9.21,3.51 12.72,-0.01C21.88,14.85 21.88,9.16 18.37,5.64z"/> </vector> diff --git a/core/res/res/drawable/ic_restart.xml b/core/res/res/drawable/ic_restart.xml index 30d98a5130e2..8fc285ee5829 100644 --- a/core/res/res/drawable/ic_restart.xml +++ b/core/res/res/drawable/ic_restart.xml @@ -21,8 +21,8 @@ android:tint="?attr/colorControlNormal"> <path android:fillColor="#FF000000" - android:pathData="M10.61,17.83C7.97,17.2 6.0,14.83 6.0,12.0c0.0,-0.71 0.11,-1.34 0.35,-1.93c0.2,-0.51 -0.05,-1.09 -0.56,-1.3c-0.52,-0.21 -1.1,0.05 -1.3,0.56C4.16,10.16 4.0,11.03 4.0,12.0c0.0,3.87 2.76,7.1 6.42,7.84c0.3,0.06 0.58,-0.19 0.58,-0.5l0.0,-1.03C11.0,18.08 10.83,17.88 10.61,17.83z"/> + android:pathData="M6,13c0,-1.65 0.67,-3.15 1.76,-4.24L6.34,7.34C4.9,8.79 4,10.79 4,13c0,4.08 3.05,7.44 7,7.93v-2.02C8.17,18.43 6,15.97 6,13z"/> <path android:fillColor="#FF000000" - android:pathData="M12.01,4.0L12.01,1.9c0.0,-0.45 -0.54,-0.67 -0.86,-0.36L7.77,4.93c-0.39,0.39 -0.39,1.02 0.0,1.41l3.39,3.39c0.31,0.31 0.85,0.09 0.85,-0.35L12.01,6.0C15.32,6.01 18.0,8.69 18.0,12.0c0.0,2.83 -1.97,5.2 -4.61,5.83C13.17,17.88 13.0,18.08 13.0,18.31l0.0,1.03c0.0,0.31 0.28,0.56 0.58,0.5C17.24,19.1 20.0,15.87 20.0,12.0C20.0,7.59 16.42,4.01 12.01,4.0z"/> + android:pathData="M20,13c0,-4.42 -3.58,-8 -8,-8c-0.06,0 -0.12,0.01 -0.18,0.01v0l1.09,-1.09L11.5,2.5L8,6l3.5,3.5l1.41,-1.41l-1.08,-1.08C11.89,7.01 11.95,7 12,7c3.31,0 6,2.69 6,6c0,2.97 -2.17,5.43 -5,5.91v2.02C16.95,20.44 20,17.08 20,13z"/> </vector> diff --git a/core/res/res/drawable/ic_screenshot.xml b/core/res/res/drawable/ic_screenshot.xml index 24dd4d86edaf..8c8b2ceba6d5 100644 --- a/core/res/res/drawable/ic_screenshot.xml +++ b/core/res/res/drawable/ic_screenshot.xml @@ -21,11 +21,11 @@ Copyright (C) 2018 The Android Open Source Project android:tint="?attr/colorControlNormal"> <path android:fillColor="#FF000000" - android:pathData="M17.0,1.0L7.0,1.0C5.9,1.0 5.0,1.9 5.0,3.0l0.0,18.0c0.0,1.1 0.9,2.0 2.0,2.0l10.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L19.0,3.0C19.0,1.9 18.1,1.0 17.0,1.0zM17.0,20.0L7.0,20.0L7.0,4.0l10.0,0.0L17.0,20.0z"/> + android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM17,4H7V3h10V4z"/> <path android:fillColor="#FF000000" - android:pathData="M13.0,6.0l-4.0,0.0 0.0,4.0 1.5,0.0 0.0,-2.5 2.5,0.0z"/> + android:pathData="M9.5,8.5l2.5,0l0,-1.5l-2.5,0l-1.5,0l0,1.5l0,2.5l1.5,0z"/> <path android:fillColor="#FF000000" - android:pathData="M11.0,18.0l4.0,0.0 0.0,-4.0 -1.5,0.0 0.0,2.5 -2.5,0.0z"/> + android:pathData="M12,17l2.5,0l1.5,0l0,-1.5l0,-2.5l-1.5,0l0,2.5l-2.5,0z"/> </vector> diff --git a/core/res/res/drawable/ic_settings_24dp.xml b/core/res/res/drawable/ic_settings_24dp.xml index c70b122358b8..497d802a42c1 100644 --- a/core/res/res/drawable/ic_settings_24dp.xml +++ b/core/res/res/drawable/ic_settings_24dp.xml @@ -19,6 +19,9 @@ Copyright (C) 2015 The Android Open Source Project android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z" - android:fillColor="#FF000000" /> + android:fillColor="#FF000000" + android:pathData="M13.85,22.25h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.53c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46c0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19C1.98,9.9 1.83,9.09 2.2,8.47l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73c0.26,-0.17 0.52,-0.32 0.78,-0.46l0.27,-1.91c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91C15.21,21.71 14.59,22.25 13.85,22.25zM13.32,20.72c0,0.01 0,0.01 0,0.02L13.32,20.72zM10.68,20.7l0,0.02C10.69,20.72 10.69,20.71 10.68,20.7zM10.62,20.25h2.76l0.37,-2.55l0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34l2.38,0.96l1.38,-2.4l-2.03,-1.58l0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78c0,-0.27 -0.03,-0.53 -0.06,-0.78l-0.07,-0.56l2.03,-1.58l-1.39,-2.4l-2.39,0.96l-0.45,-0.35c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77L13.75,6.3l-0.37,-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.7 8.84,6.95 8.38,7.3L7.93,7.63L5.55,6.68L4.16,9.07l2.03,1.58l-0.07,0.56C6.09,11.47 6.06,11.74 6.06,12c0,0.26 0.02,0.53 0.06,0.78l0.07,0.56l-2.03,1.58l1.38,2.4l2.39,-0.96l0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22L10.62,20.25zM18.22,17.72c0,0.01 -0.01,0.02 -0.01,0.03L18.22,17.72zM5.77,17.71l0.01,0.02C5.78,17.72 5.77,17.71 5.77,17.71zM3.93,9.47L3.93,9.47C3.93,9.47 3.93,9.47 3.93,9.47zM18.22,6.27c0,0.01 0.01,0.02 0.01,0.02L18.22,6.27zM5.79,6.25L5.78,6.27C5.78,6.27 5.79,6.26 5.79,6.25zM13.31,3.28c0,0.01 0,0.01 0,0.02L13.31,3.28zM10.69,3.26l0,0.02C10.69,3.27 10.69,3.27 10.69,3.26z"/> + <path + android:fillColor="#FF000000" + android:pathData="M12,12m-3.5,0a3.5,3.5 0,1 1,7 0a3.5,3.5 0,1 1,-7 0"/> </vector> diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index b7395cdabe09..0697c9758f3c 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -126,7 +126,6 @@ android:visibility="gone" android:contentDescription="@string/notification_work_profile_content_description" /> - <LinearLayout android:id="@+id/app_ops" android:layout_height="match_parent" @@ -140,6 +139,8 @@ android:src="@drawable/ic_camera" android:background="?android:selectableItemBackgroundBorderless" android:visibility="gone" + android:clickable="false" + android:contentDescription="@string/notification_appops_camera_active" /> <ImageButton android:id="@+id/mic" @@ -149,6 +150,8 @@ android:background="?android:selectableItemBackgroundBorderless" android:layout_marginStart="4dp" android:visibility="gone" + android:clickable="false" + android:contentDescription="@string/notification_appops_microphone_active" /> <ImageButton android:id="@+id/overlay" @@ -158,6 +161,8 @@ android:background="?android:selectableItemBackgroundBorderless" android:layout_marginStart="4dp" android:visibility="gone" + android:clickable="false" + android:contentDescription="@string/notification_appops_overlay_active" /> </LinearLayout> </NotificationHeaderView> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index dd869dc78c2e..bc43d91d9d19 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -506,11 +506,11 @@ <!-- String containing the apn value for tethering. May be overriden by secure settings TETHER_DUN_APN. Value is a comma separated series of strings: "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type", - Or string format of ApnSettingV3. + Or string format of ApnSettingV3 or higher. note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" Multiple entries are separated by using string-array: "<item>[ApnSettingV3]Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14,,,,,,,spn,testspn</item> - <item>[ApnSettingV3]Name1,apn2,,,,,,,,,123,46,,mms|*,IPV6,IP,true,12,,,,,,,,</item>" --> + <item>[ApnSettingV5]Name1,apn2,,,,,,,,,123,46,,mms|*,IPV6,IP,true,12,,,,,,,,,,</item>" --> <string-array translatable="false" name="config_tether_apndata"> </string-array> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index bf7ca524c93e..3c5159c89bf6 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4714,11 +4714,11 @@ <!-- Menu item in the locale menu [CHAR LIMIT=30] --> <string name="locale_search_menu">Search</string> - <!-- Title of the dialog that is shown when the user tries to launch a suspended application [CHAR LIMIT=30] --> - <string name="app_suspended_title">Can\u2019t open app</string> + <!-- Title of the dialog that is shown when the user tries to launch a suspended application [CHAR LIMIT=50] --> + <string name="app_suspended_title">App isn\u2019t available</string> <!-- Default message shown in the dialog that is shown when the user tries to launch a suspended application [CHAR LIMIT=NONE] --> <string name="app_suspended_default_message"> - The app <xliff:g id="app_name" example="Gmail">%1$s</xliff:g> isn\u2019t available right now. This is managed by <xliff:g id="app_name" example="Settings">%2$s</xliff:g>. + <xliff:g id="app_name" example="Gmail">%1$s</xliff:g> isn\u2019t available right now. This is managed by <xliff:g id="app_name" example="Settings">%2$s</xliff:g>. </string> <!-- Title of the button to show users more details about why the app has been suspended [CHAR LIMIT=50]--> <string name="app_suspended_more_details">Learn more</string> @@ -4969,6 +4969,14 @@ <!-- Application name displayed in notifications [CHAR LIMIT=60] --> <string name="notification_app_name_settings">Settings</string> + <!-- Active Permission - accessibility support --> + <!-- Content description of the camera icon in the notification. [CHAR LIMIT=NONE] --> + <string name="notification_appops_camera_active">Camera</string> + <!-- Content description of the mic icon in the notification. [CHAR LIMIT=NONE] --> + <string name="notification_appops_microphone_active">Microphone</string> + <!-- Content description of the overlay icon in the notification. [CHAR LIMIT=NONE] --> + <string name="notification_appops_overlay_active">displaying over other apps on your screen</string> + <!-- Strings for car --> <!-- String displayed when loading a user in the car [CHAR LIMIT=30] --> <string name="car_loading_profile">Loading</string> diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java index 821ee806743d..44510c2379f5 100644 --- a/core/tests/coretests/src/android/os/VintfObjectTest.java +++ b/core/tests/coretests/src/android/os/VintfObjectTest.java @@ -20,6 +20,9 @@ import junit.framework.Assert; import junit.framework.TestCase; public class VintfObjectTest extends TestCase { + /** + * Sanity check for {@link VintfObject#report VintfObject.report()}. + */ public void testReport() { String[] xmls = VintfObject.report(); assertTrue(xmls.length > 0); @@ -28,6 +31,6 @@ public class VintfObjectTest extends TestCase { "<manifest version=\"1.0\" type=\"framework\">")); // From /system/compatibility-matrix.xml assertTrue(String.join("", xmls).contains( - "<compatibility-matrix version=\"1.0\" type=\"framework\">")); + "<compatibility-matrix version=\"1.0\" type=\"framework\"")); } } diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 18bc20c03475..ab9fc13b6421 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -385,6 +385,9 @@ public class SettingsBackupTest { Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG, Settings.Global.SHOW_TEMPERATURE_WARNING, Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION, + Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, + Settings.Global.ZEN_SETTINGS_UPDATED, + Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED, Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL, Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL, Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS, diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index c486e68d361a..aa457092ca3f 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -2540,19 +2540,20 @@ public class ExifInterface { if (position < 0) { return -1; } - if (mPosition != position) { - in.seek(position); - mPosition = position; - } - - int bytesRead = in.read(buffer, offset, size); - if (bytesRead < 0) { - mPosition = -1; // need to seek on next read - return -1; - } + try { + if (mPosition != position) { + in.seek(position); + mPosition = position; + } - mPosition += bytesRead; - return bytesRead; + int bytesRead = in.read(buffer, offset, size); + if (bytesRead >= 0) { + mPosition += bytesRead; + return bytesRead; + } + } catch (IOException e) {} + mPosition = -1; // need to seek on next read + return -1; } @Override diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java b/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java index 7381d977b7b5..55cd1ab9823a 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java +++ b/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java @@ -191,13 +191,14 @@ public abstract class SoundTriggerDetectionService extends Service { client = mClients.get(uuid); if (client == null) { - throw new IllegalStateException("operationFinished called, but no client for " + Log.w(LOG_TAG, "operationFinished called, but no client for " + uuid + ". Was this called after onDisconnected?"); + return; } } client.onOpFinished(opId); } catch (RemoteException e) { - e.rethrowFromSystemServer(); + Log.e(LOG_TAG, "operationFinished, remote exception for client " + uuid, e); } } diff --git a/native/android/asset_manager.cpp b/native/android/asset_manager.cpp index e70d5ea0d566..69cf80477dde 100644 --- a/native/android/asset_manager.cpp +++ b/native/android/asset_manager.cpp @@ -56,32 +56,10 @@ struct AAsset { // -------------------- Public native C API -------------------- /** - * Supporting information - */ - -static struct assetmanager_offsets_t -{ - jfieldID mObject; -} gAssetManagerOffsets; - -static volatile bool gJNIConfigured = false; -static Mutex gMutex; - -/** * Asset Manager functionality */ AAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager) { - { - Mutex::Autolock _l(gMutex); - - if (gJNIConfigured == false) { - jclass amClass = env->FindClass("android/content/res/AssetManager"); - gAssetManagerOffsets.mObject = env->GetFieldID(amClass, "mObject", "J"); - gJNIConfigured = true; - } - } - return (AAssetManager*) env->GetLongField(assetManager, gAssetManagerOffsets.mObject); } diff --git a/packages/SettingsLib/res/drawable/ic_help_actionbar.xml b/packages/SettingsLib/res/drawable/ic_help_actionbar.xml index 36146256b28e..9089a930c254 100644 --- a/packages/SettingsLib/res/drawable/ic_help_actionbar.xml +++ b/packages/SettingsLib/res/drawable/ic_help_actionbar.xml @@ -22,6 +22,6 @@ android:viewportHeight="24.0" android:tint="?android:attr/colorControlNormal"> <path - android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z" - android:fillColor="#FFFFFF"/> + android:fillColor="#FFFFFFFF" + android:pathData="M11,18h2v-2h-2V18zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5C16,7.79 14.21,6 12,6z"/> </vector> diff --git a/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml b/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml index 5a7f954e0dfd..46b83094f9a8 100644 --- a/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml +++ b/packages/SettingsLib/res/drawable/ic_info_outline_24dp.xml @@ -22,11 +22,11 @@ android:tint="?android:attr/textColorSecondary"> <path android:fillColor="#FF000000" - android:pathData="M12,17L12,17c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1l0,0c-0.55,0 -1,0.45 -1,1v4C11,16.55 11.45,17 12,17z"/> + android:pathData="M11,7h2v2h-2z"/> <path android:fillColor="#FF000000" - android:pathData="M12,2c-5.52,0 -10,4.48 -10,10s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/> + android:pathData="M11,11h2v6h-2z"/> <path android:fillColor="#FF000000" - android:pathData="M12,9.1L12,9.1c0.61,0 1.1,-0.49 1.1,-1.1l0,0c0,-0.61 -0.49,-1.1 -1.1,-1.1l0,0c-0.61,0 -1.1,0.49 -1.1,1.1l0,0C10.9,8.61 11.39,9.1 12,9.1z"/> + android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8s8,3.59 8,8C20,16.41 16.41,20 12,20z"/> </vector> diff --git a/packages/SettingsLib/res/drawable/ic_mode_edit.xml b/packages/SettingsLib/res/drawable/ic_mode_edit.xml index 2ad31195ca57..c1d237833cb0 100644 --- a/packages/SettingsLib/res/drawable/ic_mode_edit.xml +++ b/packages/SettingsLib/res/drawable/ic_mode_edit.xml @@ -20,6 +20,6 @@ android:viewportHeight="24.0" android:tint="?android:attr/colorControlNormal"> <path - android:fillColor="#FFFFFF" - android:pathData="M3,18.08v2.42c0,0.28 0.22,0.5 0.5,0.5h2.42c0.53,0 1.04,-0.21 1.41,-0.59L17.81,9.94l-3.75,-3.75L3.59,16.66c-0.38,0.38 -0.59,0.89 -0.59,1.42zM20.71,7.04a0.996,0.996 0,0 0,0 -1.41l-2.34,-2.34a0.996,0.996 0,0 0,-1.41 0l-1.83,1.83 3.75,3.75 1.83,-1.83z" /> + android:fillColor="#FFFFFFFF" + android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0l0,0L3,16.82V21h4.18L20.41,7.77C21.2,6.99 21.2,5.72 20.41,4.94zM6.41,19.06L5,19v-1.36l9.82,-9.82l1.41,1.41L6.41,19.06z"/> </vector> diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml index 59e5cfb20440..c926e1ff48a7 100644 --- a/packages/SettingsLib/res/values/arrays.xml +++ b/packages/SettingsLib/res/values/arrays.xml @@ -563,18 +563,18 @@ <item>0</item> <item>334</item> </array> <array name="batterymeter_plus_points"> + <item>3</item><item>0</item> <item>5</item><item>0</item> - <item>11</item><item>0</item> - <item>11</item><item>5</item> - <item>16</item><item>5</item> - <item>16</item><item>11</item> - <item>11</item><item>11</item> - <item>11</item><item>16</item> - <item>5</item><item>16</item> - <item>5</item><item>11</item> - <item>0</item><item>11</item> - <item>0</item><item>5</item> + <item>5</item><item>3</item> + <item>8</item><item>3</item> + <item>8</item><item>5</item> <item>5</item><item>5</item> + <item>5</item><item>8</item> + <item>3</item><item>8</item> + <item>3</item><item>5</item> + <item>0</item><item>5</item> + <item>0</item><item>3</item> + <item>3</item><item>3</item> </array> </resources> diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml index cf4261c6bc91..aeb0a21b7d41 100644 --- a/packages/SettingsLib/res/values/dimens.xml +++ b/packages/SettingsLib/res/values/dimens.xml @@ -57,6 +57,7 @@ <dimen name="battery_height">14.5dp</dimen> <dimen name="battery_width">9.5dp</dimen> + <dimen name="battery_powersave_outline_thickness">1dp</dimen> <dimen name="bt_battery_padding">2dp</dimen> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index 6b9902425bcb..24037a6ba5b4 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -94,6 +94,11 @@ public class A2dpProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.A2DP; + } + A2dpProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java index a1c8de566578..ac5f5373d8ec 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java @@ -85,6 +85,11 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.A2DP_SINK; + } + A2dpSinkProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java index bab59f1f1c32..c7f8c205ec6d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java @@ -30,4 +30,7 @@ public interface BluetoothCallback { void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state); void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile); void onAudioModeChanged(); + default void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, + int state, int bluetoothProfile) { + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index e7d7ab39b6c4..4e9e566b0d87 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -497,4 +497,13 @@ public class BluetoothEventManager { } } } + + void dispatchProfileConnectionStateChanged(CachedBluetoothDevice device, int state, + int bluetoothProfile) { + synchronized (mCallbacks) { + for (BluetoothCallback callback : mCallbacks) { + callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); + } + } + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java index ad813368fbd0..f7518cd63c5c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java @@ -92,6 +92,11 @@ public class HeadsetProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.HEADSET; + } + HeadsetProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index da2ae7f8a320..a0dfb5d15177 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -93,6 +93,11 @@ public class HearingAidProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.HEARING_AID; + } + HearingAidProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java index 169aac9eb60f..d0819098deb1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java @@ -92,6 +92,11 @@ final class HfpClientProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.HEADSET_CLIENT; + } + HfpClientProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java index 941964a57eb4..45ec4a1e554d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java @@ -98,6 +98,11 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } @Override + public int getProfileId() { + return BluetoothProfile.HID_DEVICE; + } + + @Override public boolean isConnectable() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java index 93c4017fdaf8..93e562179399 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java @@ -80,6 +80,11 @@ public class HidProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.HID_HOST; + } + HidProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java index abcb989802e9..0447f378fca1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java @@ -49,6 +49,8 @@ public interface LocalBluetoothProfile { boolean isProfileReady(); + int getProfileId(); + /** Display order for device profile settings. */ int getOrdinal(); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java index 0715d6927d2a..62f8724870e3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java @@ -375,6 +375,8 @@ public class LocalBluetoothProfileManager { } } + mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState, + mProfile.getProfileId()); cachedDevice.onProfileStateChanged(mProfile, newState); cachedDevice.refresh(); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java index 6efa4687d913..ad0d8ba7ebab 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java @@ -94,6 +94,11 @@ public final class MapClientProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.MAP_CLIENT; + } + MapClientProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java index 0b45f5137026..aa7a7af582a7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java @@ -93,6 +93,11 @@ public class MapProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.MAP; + } + MapProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java index 31e675c2355b..e5c0b147f97b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java @@ -67,6 +67,11 @@ final class OppProfile implements LocalBluetoothProfile { return true; } + @Override + public int getProfileId() { + return BluetoothProfile.OPP; + } + public String toString() { return NAME; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java index e077a6763755..b18b19b1e244 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java @@ -69,6 +69,11 @@ public class PanProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.PAN; + } + PanProfile(Context context, LocalBluetoothAdapter adapter) { mLocalAdapter = adapter; mLocalAdapter.getProfileProxy(context, new PanServiceListener(), diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java index 28137ff64fb5..b735c23e966f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java @@ -100,6 +100,11 @@ public final class PbapClientProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.PBAP_CLIENT; + } + PbapClientProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java index 58465f299578..e9d8cb5a4b2b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java @@ -71,6 +71,11 @@ public class PbapServerProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.PBAP; + } + PbapServerProfile(Context context) { BluetoothPbap pbap = new BluetoothPbap(context, new PbapServiceListener()); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java index 25c53e693a56..93e6be6559f6 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java @@ -91,6 +91,11 @@ final class SapProfile implements LocalBluetoothProfile { return mIsProfileReady; } + @Override + public int getProfileId() { + return BluetoothProfile.SAP; + } + SapProfile(Context context, LocalBluetoothAdapter adapter, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager) { diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java index 54a1af4da1ca..dd8bfda43ff9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java @@ -47,8 +47,10 @@ public final class CategoryKey { "com.android.settings.category.ia.development"; public static final String CATEGORY_NOTIFICATIONS = "com.android.settings.category.ia.notifications"; - public static final String CATEGORY_DO_NOT_DISTURB = - "com.android.settings.category.ia.dnd"; + public static final String CATEGORY_DO_NOT_DISTURB = "com.android.settings.category.ia.dnd"; + public static final String CATEGORY_GESTURES = "com.android.settings.category.ia.gestures"; + public static final String CATEGORY_NIGHT_DISPLAY = + "com.android.settings.category.ia.night_display"; public static final Map<String, String> KEY_COMPAT_MAP; diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java index 06e2ee103600..b7699f180281 100644 --- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java +++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java @@ -67,6 +67,19 @@ public class PowerWhitelistBackend { return mWhitelistedApps.contains(pkg); } + public boolean isWhitelisted(String[] pkgs) { + if (ArrayUtils.isEmpty(pkgs)) { + return false; + } + for (String pkg : pkgs) { + if (isWhitelisted(pkg)) { + return true; + } + } + + return false; + } + public boolean isSysWhitelistedExceptIdle(String pkg) { return mSysWhitelistedAppsExceptIdle.contains(pkg); } diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java index 343191dd35fa..5b8e1fc7f6f8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java +++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java @@ -24,9 +24,11 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Paint; +import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.Path.Direction; import android.graphics.Path.FillType; +import android.graphics.Path.Op; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Typeface; @@ -49,6 +51,7 @@ public class BatteryMeterDrawableBase extends Drawable { protected final Paint mTextPaint; protected final Paint mBoltPaint; protected final Paint mPlusPaint; + protected final Paint mPowersavePaint; protected float mButtonHeightFraction; private int mLevel = -1; @@ -90,6 +93,7 @@ public class BatteryMeterDrawableBase extends Drawable { private final RectF mPlusFrame = new RectF(); private final Path mShapePath = new Path(); + private final Path mOutlinePath = new Path(); private final Path mTextPath = new Path(); public BatteryMeterDrawableBase(Context context, int frameColor) { @@ -155,6 +159,12 @@ public class BatteryMeterDrawableBase extends Drawable { mPlusPaint.setColor(Utils.getDefaultColor(mContext, R.color.batterymeter_plus_color)); mPlusPoints = loadPoints(res, R.array.batterymeter_plus_points); + mPowersavePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPowersavePaint.setColor(mPlusPaint.getColor()); + mPowersavePaint.setStyle(Style.STROKE); + mPowersavePaint.setStrokeWidth(context.getResources() + .getDimensionPixelSize(R.dimen.battery_powersave_outline_thickness)); + mIntrinsicWidth = context.getResources().getDimensionPixelSize(R.dimen.battery_width); mIntrinsicHeight = context.getResources().getDimensionPixelSize(R.dimen.battery_height); } @@ -286,7 +296,9 @@ public class BatteryMeterDrawableBase extends Drawable { } protected int batteryColorForLevel(int level) { - return mCharging ? mChargeColor : getColorForLevel(level); + return (mCharging || (mPowerSaveEnabled && mPowerSaveAsColorError)) + ? mChargeColor + : getColorForLevel(level); } @Override @@ -331,10 +343,15 @@ public class BatteryMeterDrawableBase extends Drawable { // define the battery shape mShapePath.reset(); + mOutlinePath.reset(); final float radius = getRadiusRatio() * (mFrame.height() + buttonHeight); mShapePath.setFillType(FillType.WINDING); mShapePath.addRoundRect(mFrame, radius, radius, Direction.CW); mShapePath.addRect(mButtonFrame, Direction.CW); + mOutlinePath.addRoundRect(mFrame, radius, radius, Direction.CW); + Path p = new Path(); + p.addRect(mButtonFrame, Direction.CW); + mOutlinePath.op(p, Op.XOR); if (mCharging) { // define the bolt shape @@ -443,6 +460,11 @@ public class BatteryMeterDrawableBase extends Drawable { c.drawText(pctText, pctX, pctY, mTextPaint); } } + + // Draw the powersave outline last + if (!mCharging && mPowerSaveEnabled && mPowerSaveAsColorError) { + c.drawPath(mOutlinePath, mPowersavePaint); + } } // Some stuff required by Drawable. diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java index 6025d68a6d0e..13364aba00fd 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java +++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java @@ -26,6 +26,7 @@ import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.support.annotation.VisibleForTesting; +import android.text.format.DateUtils; import android.util.IconDrawableFactory; import android.util.Log; import java.util.ArrayList; @@ -41,7 +42,8 @@ public class RecentLocationApps { @VisibleForTesting static final String ANDROID_SYSTEM_PACKAGE_NAME = "android"; - private static final int RECENT_TIME_INTERVAL_MILLIS = 15 * 60 * 1000; + // Keep last 24 hours of location app information. + private static final long RECENT_TIME_INTERVAL_MILLIS = DateUtils.DAY_IN_MILLIS; @VisibleForTesting static final int[] LOCATION_OPS = new int[] { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java index d1e37f6e945b..466980c38e8e 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java @@ -15,13 +15,17 @@ */ package com.android.settingslib.bluetooth; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothHeadset; +import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,6 +43,8 @@ public class BluetoothEventManagerTest { private CachedBluetoothDeviceManager mCachedDeviceManager; @Mock private BluetoothCallback mBluetoothCallback; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; private Context mContext; private Intent mIntent; @@ -78,4 +84,19 @@ public class BluetoothEventManagerTest { verify(mBluetoothCallback).onAudioModeChanged(); } + + /** + * dispatchProfileConnectionStateChanged should dispatch to onProfileConnectionStateChanged + * callback. + */ + @Test + public void dispatchProfileConnectionStateChanged_registerCallback_shouldDispatchCallback() { + mBluetoothEventManager.registerCallback(mBluetoothCallback); + + mBluetoothEventManager.dispatchProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); + + verify(mBluetoothCallback).onProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java index 88c7a556d51e..d342bc878477 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java @@ -18,12 +18,23 @@ package com.android.settingslib.bluetooth; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHeadset; +import android.bluetooth.BluetoothHearingAid; +import android.bluetooth.BluetoothPan; +import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.content.Context; +import android.content.Intent; import android.os.ParcelUuid; import java.util.ArrayList; @@ -41,18 +52,29 @@ import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) @Config(resourceDir = "../../res") public class LocalBluetoothProfileManagerTest { - @Mock private CachedBluetoothDeviceManager mDeviceManager; - @Mock private BluetoothEventManager mEventManager; - @Mock private LocalBluetoothAdapter mAdapter; - @Mock private BluetoothDevice mDevice; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private BluetoothEventManager mEventManager; + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private BluetoothDevice mDevice; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + private Context mContext; private LocalBluetoothProfileManager mProfileManager; + private Intent mIntent; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = spy(RuntimeEnvironment.application); + mEventManager = spy(new BluetoothEventManager(mAdapter, + mDeviceManager, mContext)); when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON); + when(mDeviceManager.findDevice(mDevice)).thenReturn(mCachedBluetoothDevice); } /** @@ -74,7 +96,7 @@ public class LocalBluetoothProfileManagerTest { public void updateLocalProfiles_addA2dpToLocalProfiles() { mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager); - when(mAdapter.getUuids()).thenReturn(new ParcelUuid[] {BluetoothUuid.AudioSource}); + when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource}); assertThat(mProfileManager.getA2dpProfile()).isNull(); assertThat(mProfileManager.getHeadsetProfile()).isNull(); @@ -104,4 +126,143 @@ public class LocalBluetoothProfileManagerTest { assertThat(profiles.contains(mProfileManager.getHidProfile())).isTrue(); assertThat(removedProfiles.contains(mProfileManager.getHidProfile())).isFalse(); } + + /** + * Verify BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to + * profile connection state changed callback + */ + @Test + public void stateChangedHandler_receiveA2dpConnectionStateChanged_shouldDispatchCallback() { + when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource}); + mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, + mEventManager); + // Refer to BluetoothControllerImpl, it will call setReceiverHandler after + // LocalBluetoothProfileManager created. + mEventManager.setReceiverHandler(null); + mIntent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); + mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); + mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING); + mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); + + mContext.sendBroadcast(mIntent); + + verify(mEventManager).dispatchProfileConnectionStateChanged( + mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); + } + + /** + * Verify BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to + * profile connection state changed callback + */ + @Test + public void stateChangedHandler_receiveHeadsetConnectionStateChanged_shouldDispatchCallback() { + when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.Handsfree_AG}); + mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, + mEventManager); + // Refer to BluetoothControllerImpl, it will call setReceiverHandler after + // LocalBluetoothProfileManager created. + mEventManager.setReceiverHandler(null); + mIntent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); + mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); + mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING); + mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); + + mContext.sendBroadcast(mIntent); + + verify(mEventManager).dispatchProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEADSET); + } + + /** + * Verify BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to + * profile connection state changed callback + */ + @Test + public void stateChangedHandler_receiveHAPConnectionStateChanged_shouldDispatchCallback() { + ArrayList<Integer> supportProfiles = new ArrayList<>(); + supportProfiles.add(BluetoothProfile.HEARING_AID); + when(mAdapter.getSupportedProfiles()).thenReturn(supportProfiles); + when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.HearingAid}); + mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, + mEventManager); + // Refer to BluetoothControllerImpl, it will call setReceiverHandler after + // LocalBluetoothProfileManager created. + mEventManager.setReceiverHandler(null); + mIntent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); + mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); + mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING); + mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); + + mContext.sendBroadcast(mIntent); + + verify(mEventManager).dispatchProfileConnectionStateChanged(mCachedBluetoothDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); + } + + /** + * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuid will dispatch to + * profile connection state changed callback + */ + @Test + public void stateChangedHandler_receivePanConnectionStateChanged_shouldNotDispatchCallback() { + when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource}); + mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, + mEventManager); + // Refer to BluetoothControllerImpl, it will call setReceiverHandler after + // LocalBluetoothProfileManager created. + mEventManager.setReceiverHandler(null); + mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); + mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); + mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING); + mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); + + mContext.sendBroadcast(mIntent); + + verify(mEventManager).dispatchProfileConnectionStateChanged( + any(CachedBluetoothDevice.class), anyInt(), anyInt()); + } + + /** + * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent without uuids will not dispatch to + * handler and refresh CachedBluetoothDevice + */ + @Test + public void stateChangedHandler_receivePanConnectionStateChangedWithoutUuid_shouldNotRefresh() { + when(mAdapter.getUuids()).thenReturn(null); + mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, + mEventManager); + // Refer to BluetoothControllerImpl, it will call setReceiverHandler after + // LocalBluetoothProfileManager created. + mEventManager.setReceiverHandler(null); + mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); + mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); + mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING); + mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); + + mContext.sendBroadcast(mIntent); + + verify(mCachedBluetoothDevice).refresh(); + } + + /** + * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuids will dispatch to + * handler and refresh CachedBluetoothDevice + */ + @Test + public void stateChangedHandler_receivePanConnectionStateChangedWithUuids_shouldRefresh() { + when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource}); + mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, + mEventManager); + // Refer to BluetoothControllerImpl, it will call setReceiverHandler after + // LocalBluetoothProfileManager created. + mEventManager.setReceiverHandler(null); + mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED); + mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); + mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING); + mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED); + + mContext.sendBroadcast(mIntent); + + verify(mCachedBluetoothDevice).refresh(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java index d12473e23ef9..605c861fa07f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java @@ -57,8 +57,10 @@ public class CategoryKeyTest { allKeys.add(CategoryKey.CATEGORY_SYSTEM); allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE); allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT); + allKeys.add(CategoryKey.CATEGORY_GESTURES); + allKeys.add(CategoryKey.CATEGORY_NIGHT_DISPLAY); // DO NOT REMOVE ANYTHING ABOVE - assertThat(allKeys.size()).isEqualTo(16); + assertThat(allKeys.size()).isEqualTo(18); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java index f591781db5d7..0af2c05a6f10 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java @@ -61,24 +61,32 @@ public class PowerWhitelistBackendTest { assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue(); assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse(); + assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_ONE})).isTrue(); + assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_TWO})).isFalse(); mPowerWhitelistBackend.addApp(PACKAGE_TWO); verify(mDeviceIdleService, atLeastOnce()).addPowerSaveWhitelistApp(PACKAGE_TWO); assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue(); assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isTrue(); + assertThat(mPowerWhitelistBackend.isWhitelisted( + new String[]{PACKAGE_ONE, PACKAGE_TWO})).isTrue(); mPowerWhitelistBackend.removeApp(PACKAGE_TWO); verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_TWO); assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue(); assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse(); + assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_ONE})).isTrue(); + assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_TWO})).isFalse(); mPowerWhitelistBackend.removeApp(PACKAGE_ONE); verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_ONE); assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isFalse(); assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse(); + assertThat(mPowerWhitelistBackend.isWhitelisted( + new String[]{PACKAGE_ONE, PACKAGE_TWO})).isFalse(); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java index 5e0fcefc5209..8a54aeec6d79 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java @@ -37,8 +37,8 @@ public class RecentLocationAppsTest { // App running duration in milliseconds private static final int DURATION = 10; private static final long ONE_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(1); - private static final long FOURTEEN_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(14); - private static final long TWENTY_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(20); + private static final long TWENTY_THREE_HOURS_AGO = NOW - TimeUnit.HOURS.toMillis(23); + private static final long TWO_DAYS_AGO = NOW - TimeUnit.DAYS.toMillis(2); private static final String[] TEST_PACKAGE_NAMES = {"package_1MinAgo", "package_14MinAgo", "package_20MinAgo"}; @@ -74,7 +74,7 @@ public class RecentLocationAppsTest { when(mUserManager.getUserProfiles()) .thenReturn(Collections.singletonList(new UserHandle(mTestUserId))); - long[] testRequestTime = {ONE_MIN_AGO, FOURTEEN_MIN_AGO, TWENTY_MIN_AGO}; + long[] testRequestTime = {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO}; List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime); when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_OPS)).thenReturn(appOps); mockTestApplicationInfos(mTestUserId, TEST_PACKAGE_NAMES); @@ -91,7 +91,7 @@ public class RecentLocationAppsTest { assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]); assertThat(requests.get(0).requestFinishTime).isEqualTo(ONE_MIN_AGO + DURATION); assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]); - assertThat(requests.get(1).requestFinishTime).isEqualTo(FOURTEEN_MIN_AGO + DURATION); + assertThat(requests.get(1).requestFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO + DURATION); } @Test @@ -105,7 +105,7 @@ public class RecentLocationAppsTest { ONE_MIN_AGO, DURATION); long[] testRequestTime = - {ONE_MIN_AGO, FOURTEEN_MIN_AGO, TWENTY_MIN_AGO, ONE_MIN_AGO}; + {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO, ONE_MIN_AGO}; List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime); appOps.add(androidSystemPackageOps); when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_OPS)).thenReturn(appOps); @@ -119,7 +119,7 @@ public class RecentLocationAppsTest { assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]); assertThat(requests.get(0).requestFinishTime).isEqualTo(ONE_MIN_AGO + DURATION); assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]); - assertThat(requests.get(1).requestFinishTime).isEqualTo(FOURTEEN_MIN_AGO + DURATION); + assertThat(requests.get(1).requestFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO + DURATION); } private void mockTestApplicationInfos(int userId, String... packageNameList) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 32aafeafb203..7b76fce45fef 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2935,7 +2935,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 165; + private static final int SETTINGS_VERSION = 166; private final int mUserId; @@ -3733,7 +3733,7 @@ public class SettingsProvider extends ContentProvider { } if (currentVersion == 164) { - // Version 164: Add a gesture for silencing phones + // Version 164: show zen upgrade notification final SettingsState settings = getGlobalSettingsLocked(); final Setting currentSetting = settings.getSettingLocked( Global.SHOW_ZEN_UPGRADE_NOTIFICATION); @@ -3747,6 +3747,36 @@ public class SettingsProvider extends ContentProvider { currentVersion = 165; } + if (currentVersion == 165) { + // Version 165: Show zen settings suggestion and zen updated + final SettingsState settings = getGlobalSettingsLocked(); + final Setting currentSetting = settings.getSettingLocked( + Global.SHOW_ZEN_SETTINGS_SUGGESTION); + if (currentSetting.isNull()) { + settings.insertSettingLocked( + Global.SHOW_ZEN_SETTINGS_SUGGESTION, "1", + null, true, SettingsState.SYSTEM_PACKAGE_NAME); + } + + final Setting currentUpdatedSetting = settings.getSettingLocked( + Global.ZEN_SETTINGS_UPDATED); + if (currentUpdatedSetting.isNull()) { + settings.insertSettingLocked( + Global.ZEN_SETTINGS_UPDATED, "0", + null, true, SettingsState.SYSTEM_PACKAGE_NAME); + } + + final Setting currentSettingSuggestionViewed = settings.getSettingLocked( + Global.ZEN_SETTINGS_SUGGESTION_VIEWED); + if (currentSettingSuggestionViewed.isNull()) { + settings.insertSettingLocked( + Global.ZEN_SETTINGS_SUGGESTION_VIEWED, "0", + null, true, SettingsState.SYSTEM_PACKAGE_NAME); + } + + currentVersion = 166; + } + // vXXX: Add new settings above this point. if (currentVersion != newVersion) { diff --git a/packages/SystemUI/res/drawable/ic_delete.xml b/packages/SystemUI/res/drawable/ic_delete.xml index 4e80ddf3e78e..3580fdfde87e 100644 --- a/packages/SystemUI/res/drawable/ic_delete.xml +++ b/packages/SystemUI/res/drawable/ic_delete.xml @@ -16,9 +16,15 @@ Copyright (C) 2015 The Android Open Source Project <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24.0dp" android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path - android:fillColor="#ffffffff" - android:pathData="M12 38c0 2.21 1.79 4 4 4h16c2.21 0 4,-1.79 4,-4V14H12v24zM38 8h-7l-2,-2H19l-2 2h-7v4h28V8z"/> + android:fillColor="#FFFFFFFF" + android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M9,8h2v9h-2z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M13,8h2v9h-2z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/packages/SystemUI/res/drawable/ic_dnd.xml index 9a1d502e21e5..09a6aabf40bb 100644 --- a/packages/SystemUI/res/drawable/ic_dnd.xml +++ b/packages/SystemUI/res/drawable/ic_dnd.xml @@ -22,6 +22,9 @@ <path android:fillColor="#FFFFFFFF" - android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/> + android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M7,11h10v2h-10z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_dnd_disable.xml b/packages/SystemUI/res/drawable/ic_dnd_disable.xml deleted file mode 100644 index ba4692a14cd7..000000000000 --- a/packages/SystemUI/res/drawable/ic_dnd_disable.xml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:name="ic_dnd_disable" - android:width="24dp" - android:viewportWidth="24" - android:height="24dp" - android:viewportHeight="24" > - <group - android:name="dnd_icon" - android:translateX="12" - android:translateY="12" > - <clip-path - android:name="mask_1" - android:pathData="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z" /> - <group - android:name="bar01" - android:translateX="-12" - android:translateY="-12" > - <path - android:name="bar01_0" - android:pathData="M 0.680404663086,3.53039550781 c 0.0,0.0 -0.01416015625,0.00492858886719 -0.01416015625,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151519775391,-0.00492858886719 0.0151519775391,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z" - android:fillColor="#FFFFFFFF" /> - </group> - <group - android:name="circle" > - <path - android:name="icon_center_merged" - android:pathData="M 5.0,1.0 c 0.0,0.0 -10.0,0.0 -10.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 10.0,0.0 10.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-10.0 c -5.52000427246,0.0 -10.0,4.47999572754 -10.0,10.0 c 0.0,5.52000427246 4.47999572754,10.0 10.0,10.0 c 5.52000427246,0.0 10.0,-4.47999572754 10.0,-10.0 c 0.0,-5.52000427246 -4.47999572754,-10.0 -10.0,-10.0 Z" - android:fillColor="#FFFFFFFF" /> - </group> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml deleted file mode 100644 index e7b9fa7e6988..000000000000 --- a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- - 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="24dp" - android:viewportHeight="24.0" - android:viewportWidth="24.0" - android:width="24dp" - android:tint="?android:attr/colorControlNormal"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/> - -</vector> diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable.xml deleted file mode 100644 index 1a332557ebe9..000000000000 --- a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:name="ic_dnd_total_silence_disable" - android:width="24dp" - android:viewportWidth="24" - android:height="24dp" - android:viewportHeight="24" > - <group - android:name="tot_silence" - android:translateX="12" - android:translateY="12" > - <clip-path - android:name="mask_1" - android:pathData="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z" /> - <group - android:name="icon_shape" > - <path - android:name="outer_ring_merged" - android:pathData="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 -0.0141754150391,0.00492858886719 -0.014175415039,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151672363281,-0.00492858886719 0.0151672363281,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 3.0,1.0 c 0.0,0.0 -6.0,0.0 -6.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 6.0,0.0 6.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-6.0 c -3.30000305176,0.0 -6.0,2.69999694824 -6.0,6.0 c 0.0,3.30000305176 2.69999694824,6.0 6.0,6.0 c 3.30000305176,0.0 6.0,-2.69999694824 6.0,-6.0 c 0.0,-3.30000305176 -2.60000610352,-6.0 -6.0,-6.0 Z" - android:fillColor="#FFFFFFFF" /> - </group> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_headset.xml b/packages/SystemUI/res/drawable/ic_headset.xml index 58759f9afa2f..27efe80c5ae0 100644 --- a/packages/SystemUI/res/drawable/ic_headset.xml +++ b/packages/SystemUI/res/drawable/ic_headset.xml @@ -19,10 +19,13 @@ <vector android:width="17.0dp" android:height="17.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M24.0,2.0C14.06,2.0 6.0,10.06 6.0,20.0l0.0,14.0c0.0,3.31 2.69,6.0 6.0,6.0l6.0,0.0L18.0,24.0l-8.0,0.0l0.0,-4.0c0.0,-7.73 6.27,-14.0 14.0,-14.0s14.0,6.27 14.0,14.0l0.0,4.0l-8.0,0.0l0.0,16.0l6.0,0.0c3.31,0.0 6.0,-2.69 6.0,-6.0L42.0,20.0c0.0,-9.94 -8.06,-18.0 -18.0,-18.0z"/> + android:viewportWidth="24" + android:viewportHeight="24"> + <group + android:translateY="-1"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M19,15v3c0,0.55 -0.45,1 -1,1h-1v-4H19M7,15v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7M12,2c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h3c1.66,0 3,-1.34 3,-3v-7C21,6.03 16.97,2 12,2L12,2z"/> + </group> </vector> </inset> diff --git a/packages/SystemUI/res/drawable/ic_headset_mic.xml b/packages/SystemUI/res/drawable/ic_headset_mic.xml index 5d02120ee3d0..1260e0f42949 100644 --- a/packages/SystemUI/res/drawable/ic_headset_mic.xml +++ b/packages/SystemUI/res/drawable/ic_headset_mic.xml @@ -19,10 +19,10 @@ <vector android:width="17.0dp" android:height="17.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path android:fillColor="#FFFFFFFF" - android:pathData="M24.0,2.0C14.06,2.0 6.0,10.06 6.0,20.0l0.0,14.0c0.0,3.31 2.69,6.0 6.0,6.0l6.0,0.0L18.0,24.0l-8.0,0.0l0.0,-4.0c0.0,-7.73 6.27,-14.0 14.0,-14.0s14.0,6.27 14.0,14.0l0.0,4.0l-8.0,0.0l0.0,16.0l8.0,0.0l0.0,2.0L24.0,42.0l0.0,4.0l12.0,0.0c3.31,0.0 6.0,-2.69 6.0,-6.0L42.0,20.0c0.0,-9.94 -8.06,-18.0 -18.0,-18.0z"/> + android:pathData="M12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-1.71C5,6.45 7.96,3.11 11.79,3C15.76,2.89 19,6.06 19,10v2h-4v8h4v1h-6v2h6c1.1,0 2,-0.9 2,-2V10C21,5.03 16.97,1 12,1zM7,14v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7zM19,18h-2v-4h2V18z"/> </vector> </inset> diff --git a/packages/SystemUI/res/drawable/ic_qs_cancel.xml b/packages/SystemUI/res/drawable/ic_qs_cancel.xml index e4f4174b9ca1..a66d772695e8 100644 --- a/packages/SystemUI/res/drawable/ic_qs_cancel.xml +++ b/packages/SystemUI/res/drawable/ic_qs_cancel.xml @@ -16,10 +16,12 @@ Copyright (C) 2014 The Android Open Source Project <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,2C6.47,2 2,6.47 2,12c0,5.53 4.47,10 10,10c5.53,0 10,-4.47 10,-10C22,6.47 17.53,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/> <path android:fillColor="#FFFFFFFF" - android:pathData="M24.0,4.0C12.9,4.0 4.0,12.9 4.0,24.0s8.9,20.0 20.0,20.0c11.1,0.0 20.0,-8.9 20.0,-20.0S35.1,4.0 24.0,4.0zM34.0,31.2L31.2,34.0L24.0,26.8L16.8,34.0L14.0,31.2l7.2,-7.2L14.0,16.8l2.8,-2.8l7.2,7.2l7.2,-7.2l2.8,2.8L26.8,24.0L34.0,31.2z"/> + android:pathData="M15.59,7l-3.59,3.59l-3.59,-3.59l-1.41,1.41l3.59,3.59l-3.59,3.59l1.41,1.41l3.59,-3.59l3.59,3.59l1.41,-1.41l-3.59,-3.59l3.59,-3.59z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml index d71018b79857..40c5e1495f17 100644 --- a/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml +++ b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml @@ -21,6 +21,9 @@ android:alpha="0.14" android:tint="?android:attr/colorForeground"> <path - android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z" - android:fillColor="#FFFFFF"/> + android:fillColor="#FFFFFFFF" + android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M7,11h10v2h-10z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml index 233b9b992430..c64d5e94bfe6 100644 --- a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml +++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml @@ -19,6 +19,9 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z" - android:fillColor="#FFFFFFFF"/> + android:fillColor="#FFFFFFFF" + android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M7,11h10v2h-10z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml deleted file mode 100644 index 5012aa494928..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml index 9c5983d4d6e4..29741577c039 100644 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml +++ b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml @@ -21,5 +21,8 @@ Copyright (C) 2014 The Android Open Source Project <path android:fillColor="#FFFFFFFF" - android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/> + android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml index 904ccdfb70ad..6db508cd31e8 100644 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml +++ b/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml @@ -21,5 +21,11 @@ Copyright (C) 2014 The Android Open Source Project <path android:fillColor="#FFFFFFFF" - android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7C9.5,4.3 9.0,4.5 8.6,4.7l9.4,9.4L18.0,10.5zM17.7,19.0l2.0,2.0l1.3,-1.3L4.3,3.0L3.0,4.3l2.9,2.9C5.3,8.2 5.0,9.3 5.0,10.5L5.0,16.0l-2.0,2.0l0.0,1.0L17.7,19.0z" /> + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M16,16L2.81,2.81L1.39,4.22l4.85,4.85C6.09,9.68 6,10.33 6,11v6H4v2h12.17l3.61,3.61l1.41,-1.41L16,16zM8,17c0,0 0.01,-6.11 0.01,-6.16L14.17,17H8z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,6.5c2.49,0 4,2.02 4,4.5v2.17l2,2V11c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.72,4.86 9.05,5.2 8.46,5.63L9.93,7.1C10.51,6.73 11.2,6.5 12,6.5z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml index a23c6f0afa9c..c87b595a20f2 100644 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml +++ b/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml @@ -21,5 +21,5 @@ Copyright (C) 2014 The Android Open Source Project <path android:fillColor="#FFFFFFFF" - android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/> + android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_screenshot_delete.xml b/packages/SystemUI/res/drawable/ic_screenshot_delete.xml index e35c73dad760..d60ee414888d 100644 --- a/packages/SystemUI/res/drawable/ic_screenshot_delete.xml +++ b/packages/SystemUI/res/drawable/ic_screenshot_delete.xml @@ -16,9 +16,15 @@ Copyright (C) 2015 The Android Open Source Project <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="32dp" android:height="32dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path android:fillColor="#FF000000" - android:pathData="M12,38c0,2.21 1.79,4 4,4h16c2.21,0 4,-1.79 4,-4V14H12v24zM38,8h-7l-2,-2H19l-2,2h-7v4h28V8z"/> + android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z"/> + <path + android:fillColor="#FF000000" + android:pathData="M9,8h2v9h-2z"/> + <path + android:fillColor="#FF000000" + android:pathData="M13,8h2v9h-2z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_screenshot_edit.xml b/packages/SystemUI/res/drawable/ic_screenshot_edit.xml index d90129260fcc..7abd63c6a5a0 100644 --- a/packages/SystemUI/res/drawable/ic_screenshot_edit.xml +++ b/packages/SystemUI/res/drawable/ic_screenshot_edit.xml @@ -19,9 +19,6 @@ Copyright (C) 2014 The Android Open Source Project android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:fillColor="#FF000000" - android:pathData="M3.0,17.25L3.0,21.0l3.75,0.0L17.81,9.94l-3.75,-3.75L3.0,17.25zM20.71,7.04c0.39,-0.3 0.39,-1.02 0.0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0.0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/> - <path - android:pathData="M0 0h24v24H0z" - android:fillColor="#00000000"/> + android:fillColor="#FFFFFFFF" + android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0l0,0L3,16.82V21h4.18L20.41,7.77C21.2,6.99 21.2,5.72 20.41,4.94zM6.41,19.06L5,19v-1.36l9.82,-9.82l1.41,1.41L6.41,19.06z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_settings.xml b/packages/SystemUI/res/drawable/ic_settings.xml index 6d24c7e44c01..7080d882b1f1 100644 --- a/packages/SystemUI/res/drawable/ic_settings.xml +++ b/packages/SystemUI/res/drawable/ic_settings.xml @@ -18,6 +18,9 @@ limitations under the License. android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" - android:fillColor="#FFFFFFFF"/> + android:fillColor="#FFFFFFFF" + android:pathData="M13.85,22.25h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.53c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46c0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19C1.98,9.9 1.83,9.09 2.2,8.47l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73c0.26,-0.17 0.52,-0.32 0.78,-0.46l0.27,-1.91c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91C15.21,21.71 14.59,22.25 13.85,22.25zM13.32,20.72c0,0.01 0,0.01 0,0.02L13.32,20.72zM10.68,20.7l0,0.02C10.69,20.72 10.69,20.71 10.68,20.7zM10.62,20.25h2.76l0.37,-2.55l0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34l2.38,0.96l1.38,-2.4l-2.03,-1.58l0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78c0,-0.27 -0.03,-0.53 -0.06,-0.78l-0.07,-0.56l2.03,-1.58l-1.39,-2.4l-2.39,0.96l-0.45,-0.35c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77L13.75,6.3l-0.37,-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.7 8.84,6.95 8.38,7.3L7.93,7.63L5.55,6.68L4.16,9.07l2.03,1.58l-0.07,0.56C6.09,11.47 6.06,11.74 6.06,12c0,0.26 0.02,0.53 0.06,0.78l0.07,0.56l-2.03,1.58l1.38,2.4l2.39,-0.96l0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22L10.62,20.25zM18.22,17.72c0,0.01 -0.01,0.02 -0.01,0.03L18.22,17.72zM5.77,17.71l0.01,0.02C5.78,17.72 5.77,17.71 5.77,17.71zM3.93,9.47L3.93,9.47C3.93,9.47 3.93,9.47 3.93,9.47zM18.22,6.27c0,0.01 0.01,0.02 0.01,0.02L18.22,6.27zM5.79,6.25L5.78,6.27C5.78,6.27 5.79,6.26 5.79,6.25zM13.31,3.28c0,0.01 0,0.01 0,0.02L13.31,3.28zM10.69,3.26l0,0.02C10.69,3.27 10.69,3.27 10.69,3.26z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,12m-3.5,0a3.5,3.5 0,1 1,7 0a3.5,3.5 0,1 1,-7 0"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_settings_16dp.xml b/packages/SystemUI/res/drawable/ic_settings_16dp.xml index e3ed2298b1b5..89764cff03e0 100644 --- a/packages/SystemUI/res/drawable/ic_settings_16dp.xml +++ b/packages/SystemUI/res/drawable/ic_settings_16dp.xml @@ -19,6 +19,9 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" - android:fillColor="#FFFFFFFF"/> + android:fillColor="#FFFFFFFF" + android:pathData="M13.85,22.25h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.53c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46c0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19C1.98,9.9 1.83,9.09 2.2,8.47l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73c0.26,-0.17 0.52,-0.32 0.78,-0.46l0.27,-1.91c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91C15.21,21.71 14.59,22.25 13.85,22.25zM13.32,20.72c0,0.01 0,0.01 0,0.02L13.32,20.72zM10.68,20.7l0,0.02C10.69,20.72 10.69,20.71 10.68,20.7zM10.62,20.25h2.76l0.37,-2.55l0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34l2.38,0.96l1.38,-2.4l-2.03,-1.58l0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78c0,-0.27 -0.03,-0.53 -0.06,-0.78l-0.07,-0.56l2.03,-1.58l-1.39,-2.4l-2.39,0.96l-0.45,-0.35c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77L13.75,6.3l-0.37,-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.7 8.84,6.95 8.38,7.3L7.93,7.63L5.55,6.68L4.16,9.07l2.03,1.58l-0.07,0.56C6.09,11.47 6.06,11.74 6.06,12c0,0.26 0.02,0.53 0.06,0.78l0.07,0.56l-2.03,1.58l1.38,2.4l2.39,-0.96l0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22L10.62,20.25zM18.22,17.72c0,0.01 -0.01,0.02 -0.01,0.03L18.22,17.72zM5.77,17.71l0.01,0.02C5.78,17.72 5.77,17.71 5.77,17.71zM3.93,9.47L3.93,9.47C3.93,9.47 3.93,9.47 3.93,9.47zM18.22,6.27c0,0.01 0.01,0.02 0.01,0.02L18.22,6.27zM5.79,6.25L5.78,6.27C5.78,6.27 5.79,6.26 5.79,6.25zM13.31,3.28c0,0.01 0,0.01 0,0.02L13.31,3.28zM10.69,3.26l0,0.02C10.69,3.27 10.69,3.27 10.69,3.26z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,12m-3.5,0a3.5,3.5 0,1 1,7 0a3.5,3.5 0,1 1,-7 0"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight.xml index 38979a899854..e63595300d5f 100644 --- a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml +++ b/packages/SystemUI/res/drawable/ic_signal_flashlight.xml @@ -19,11 +19,10 @@ android:height="48dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> - <group - android:translateX="-0.05" - android:translateY="0.85" > - <path - android:pathData="M8.28,2h7.43c0.55,0 1,0.45 1,1v0.96L7.28,3.96L7.28,3c0,-0.55 0.45,-1 1,-1zM14.8,9.76L14.8,21c0,0.55 -0.45,1 -1,1h-3.61c-0.55,0 -1,-0.45 -1,-1L9.19,9.78c-2.2,-1.17 -1.91,-3.76 -1.91,-3.76L7.28,5.7h9.44v0.32s0.26,2.57 -1.92,3.74zM13.38,12.47c0,-0.76 -0.62,-1.38 -1.38,-1.38s-1.38,0.62 -1.38,1.38 0.62,1.38 1.38,1.38 1.38,-0.62 1.38,-1.38z" - android:fillColor="#FFFFFFFF"/> - </group> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M18,2H6v6l2,3v11h8V11l2,-3L18,2zM16,4l0,1H8V4H16zM14,10.4V20h-4v-9.61l-2,-3V7h8l0,0.39L14,10.4z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,14m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media.xml b/packages/SystemUI/res/drawable/ic_volume_media.xml index 53c0740d88ea..c8fa3fbdd50b 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media.xml @@ -21,7 +21,7 @@ android:tint="?android:attr/colorControlNormal" > <path - android:fillColor="#FFFFFF" - android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/> + android:fillColor="#FFFFFFFF" + android:pathData="M12,3l0.01,10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17V7h4V3H12zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml index 60d0184c0ba2..9f7744e3c1bf 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml @@ -21,7 +21,7 @@ android:tint="?android:attr/colorControlNormal"> <path - android:fillColor="#FFFFFF" - android:pathData="M16,3h-5c-0.55,0 -1,0.45 -1,1v8.3c-0.93,-0.39 -1.96,-0.4 -2.9,-0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26C4,19 6.01,21 8.49,21c0,0 0.01,0 0.01,0c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4C17,3.45 16.55,3 16,3zM20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l0.02,-0.02l2.23,-2.23c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,10.75V8.78l0.99,0.99L20.75,10.75zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/> + android:fillColor="#FFFFFFFF" + android:pathData="M9,3l0.01,10.55C8.41,13.21 7.73,13 7.01,13C4.79,13 3,14.79 3,17c0,2.21 1.79,4 4.01,4S11,19.21 11,17V7h4V3H9zM7.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C9.01,18.1 8.11,19 7.01,19zM21,12.43L17.57,9h-0.6v4.55l-2.75,-2.75l-0.85,0.85L16.73,15l-3.35,3.35l0.85,0.85l2.75,-2.75V21h0.6L21,17.57L18.42,15L21,12.43zM18.17,11.3l1.13,1.13l-1.13,1.13V11.3zM19.3,17.57l-1.13,1.13v-2.26L19.3,17.57z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml index 49fcfc4d4919..12e0f2ee02c9 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml @@ -21,13 +21,7 @@ android:tint="?android:attr/colorControlNormal"> <path - android:fillColor="#FFFFFF" - android:pathData="M13,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6z"/> - <path - android:fillColor="#FFFFFF" - android:pathData="M4,5.1C3.67,4.76 3.12,4.75 2.78,5.08C2.41,5.42 2.4,6 2.75,6.35L8.4,12C6,12.1 4,14 4,16.5c0,2.51 2.33,4.67 4.84,4.48C11.35,20.81 13,18.62 13,16.7v-0.1l3.27,3.27c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L4,5.1z"/> - <path - android:fillColor="#FFFFFF" - android:pathData="M20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,8.78l0.99,0.99l-0.99,0.98V8.78zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/> + android:fillColor="#FFFFFFFF" + android:pathData="M9,6.17L9,3h6v4h-4v1.17L9,6.17zM19.42,15L22,17.57l-0.8,0.8l-6.78,-6.78l0.8,-0.8l2.75,2.75V9h0.6L22,12.43L19.42,15zM19.17,13.55l1.13,-1.13l-1.13,-1.13V13.55zM17.21,17.21l3.98,3.98l-1.41,1.41l-3.98,-3.98l-0.58,0.58l-0.85,-0.85l0.58,-0.58L11,13.83V17c0,2.21 -1.78,4 -3.99,4S3,19.21 3,17c0,-2.21 1.79,-4 4.01,-4c0.73,0 1.41,0.21 2,0.55l0,-1.72L1.39,4.22l1.41,-1.41l13.56,13.56L17.21,17.21zM9.01,17c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2c0,1.1 0.9,2 2,2S9.01,18.1 9.01,17z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml index ebb86e896d21..45b5b87e8ab5 100644 --- a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml @@ -21,7 +21,10 @@ android:tint="?android:attr/colorControlNormal" > <path - android:fillColor="#FFFFFF" - android:pathData="M15,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6zM4.18,4.48c-0.37,0.34 -0.38,0.92 -0.03,1.27L10.4,12C8,12.1 6,14 6,16.5c0,2.51 2.33,4.67 4.84,4.48 2.51,-0.17 4.16,-2.36 4.16,-4.28v-0.1l3.37,3.37c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L5.4,4.5a0.866,0.866 0,0 0,-1.22 -0.02z"/> + android:fillColor="#FFFFFFFF" + android:pathData="M21.19,21.19L14,14l-2,-2l-9.2,-9.2L1.39,4.22l8.79,8.79c-0.06,0 -0.12,-0.01 -0.18,-0.01C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17v-0.17l5.78,5.78L21.19,21.19zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/> + <path + android:fillColor="#FFffffff" + android:pathData="M14,11.17l0,-4.17l4,0l0,-4l-6,0l0,6.17z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer.xml b/packages/SystemUI/res/drawable/ic_volume_ringer.xml index f258856696bb..42eb7b7f3f88 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer.xml +++ b/packages/SystemUI/res/drawable/ic_volume_ringer.xml @@ -15,17 +15,16 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" - android:viewportHeight="23.4" - android:viewportWidth="23.4" android:width="24dp" + android:viewportHeight="24" + android:viewportWidth="24" android:tint="?android:attr/colorControlNormal" > - <group - android:translateX="-0.78" - android:translateY="-0.5" > - <path - android:fillColor="#FFFFFF" - android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.63,5.36 6,7.92 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h15.6c0.45,0 0.67,-0.54 0.35,-0.85L18,16z"/> - </group> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml index 106d899f1b64..9cb7ca3679b9 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml @@ -15,23 +15,19 @@ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" - android:viewportHeight="23.4" - android:viewportWidth="23.3" + android:viewportHeight="24" + android:viewportWidth="24" android:width="24dp" android:tint="?android:attr/colorControlNormal" > - <group - android:translateX="-0.85" - android:translateY="-0.5" > - <path - android:fillColor="#FF0" - android:pathData="M20.73,19.46l-0.6,-0.6c0,0 0,0 0,0L5.54,4.26c-0.35,-0.35 -0.92,-0.35 -1.27,0c-0.35,0.35 -0.35,0.92 0,1.27l2.4,2.4C6.25,8.85 6,9.88 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h13.53l1.73,1.73c0.35,0.35 0.92,0.35 1.27,0C21.09,20.38 21.09,19.81 20.73,19.46z"/> - <path - android:fillColor="#FF0" - android:pathData="M18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.87,4.83 9.31,5.08 8.8,5.4l9.2,9.2V11z"/> - <path - android:fillColor="#FF0" - android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> - </group> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M16,16L2.81,2.81L1.39,4.22l4.85,4.85C6.09,9.68 6,10.33 6,11v6H4v2h12.17l3.61,3.61l1.41,-1.41L16,16zM8,17c0,0 0.01,-6.11 0.01,-6.16L14.17,17H8z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,6.5c2.49,0 4,2.02 4,4.5v2.17l2,2V11c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.72,4.86 9.05,5.2 8.46,5.63L9.93,7.1C10.51,6.73 11.2,6.5 12,6.5z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml index 9db8511c3623..aa13f1e2a9e7 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml +++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml @@ -21,7 +21,7 @@ android:tint="?android:attr/colorControlNormal" > <path - android:fillColor="#FFFFFF" - android:pathData="M1,15c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4c0,0.55 0.45,1 1,1zM4,17c0.55,0 1,-0.45 1,-1L5,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM22,10v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1zM20,17c0.55,0 1,-0.45 1,-1L21,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM16.5,3h-9C6.67,3 6,3.67 6,4.5v15c0,0.83 0.67,1.5 1.5,1.5h9c0.83,0 1.5,-0.67 1.5,-1.5v-15c0,-0.83 -0.67,-1.5 -1.5,-1.5zM16,19L8,19L8,5h8v14z"/> + android:fillColor="#FFFFFFFF" + android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/> </vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml index bd4cb0ab4438..68a06d013bf7 100644 --- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml +++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml @@ -22,14 +22,13 @@ <vector android:width="17dp" android:height="17dp" - android:viewportWidth="16.6" - android:viewportHeight="16.6"> - <group - android:translateX="-0.2" - android:translateY="-0.2"> - <path - android:pathData="M8.5,1.59c-3.81,0 -6.91,3.09 -6.91,6.91s3.09,6.91 6.91,6.91 6.91,-3.09 6.91,-6.91 -3.1,-6.91 -6.91,-6.91zM11.16,9.56L5.84,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h5.31a1.06,1.06 0,0 1,0.01 2.12z" - android:fillColor="#FFF"/> - </group> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M7,11h10v2h-10z"/> </vector> </inset> diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml index 36e6cefc3a4b..a8f0cc3a1d92 100644 --- a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml +++ b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml @@ -18,10 +18,16 @@ Copyright (C) 2015 The Android Open Source Project android:insetRight="3dp"> <vector android:width="18dp" android:height="18dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path android:fillColor="#FFFFFFFF" - android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z"/> + android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M16,16L2.81,2.81L1.39,4.22l4.85,4.85C6.09,9.68 6,10.33 6,11v6H4v2h12.17l3.61,3.61l1.41,-1.41L16,16zM8,17c0,0 0.01,-6.11 0.01,-6.16L14.17,17H8z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,6.5c2.49,0 4,2.02 4,4.5v2.17l2,2V11c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.72,4.86 9.05,5.2 8.46,5.63L9.93,7.1C10.51,6.73 11.2,6.5 12,6.5z"/> </vector> </inset> diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml index e525fec834bc..0b72f75ff97d 100644 --- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml +++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml @@ -21,15 +21,16 @@ android:insetRight="2.5dp"> <vector android:width="19dp" - android:height="17dp" - android:viewportWidth="21.0" - android:viewportHeight="19.0"> + android:height="19dp" + android:viewportWidth="23.0" + android:viewportHeight="23.0"> <group - android:translateX="1.0" - android:translateY="1.0"> + android:translateX="-0.5" + android:translateY="-0.5"> <path - android:pathData="M13.28,0.53L5.84,0.53c-0.88,0 -1.59,0.71 -1.59,1.59v12.75c0,0.88 0.71,1.59 1.59,1.59h7.44c0.88,0 1.59,-0.71 1.59,-1.59L14.87,2.12c0.01,-0.88 -0.71,-1.59 -1.59,-1.59zM13.28,14.88L5.84,14.88L5.84,2.12h7.44v12.76zM2.66,13.81a0.52,0.52 0,0 1,-0.53 -0.53L2.13,3.72c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v9.56c0,0.3 -0.24,0.53 -0.53,0.53zM0.53,11.69a0.52,0.52 0,0 1,-0.53 -0.53L0,5.84c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v5.31c0,0.3 -0.23,0.54 -0.53,0.54zM16.47,13.81c0.3,0 0.53,-0.23 0.53,-0.53L17,3.72c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v9.56c0,0.3 0.23,0.53 0.53,0.53zM18.59,11.69c0.3,0 0.53,-0.23 0.53,-0.53L19.12,5.84c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v5.31c0,0.3 0.24,0.54 0.53,0.54z" - android:fillColor="#FFF"/> + android:fillColor="#F00" + android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/> + </group> </vector> </inset> diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml index 1be3375b5c07..9130fb454893 100644 --- a/packages/SystemUI/res/layout/menu_ime.xml +++ b/packages/SystemUI/res/layout/menu_ime.xml @@ -19,6 +19,7 @@ android:id="@+id/menu_container" android:layout_width="match_parent" android:layout_height="match_parent" + android:importantForAccessibility="no" > <!-- Use width & height=match_parent for parent FrameLayout and buttons because they are placed inside a view that has a size controlled by weight. Ensure weight is large enough to support diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml index b5d48b4636a8..e902c925c2a9 100644 --- a/packages/SystemUI/res/layout/remote_input.xml +++ b/packages/SystemUI/res/layout/remote_input.xml @@ -42,7 +42,7 @@ android:singleLine="true" android:ellipsize="start" android:inputType="textShortMessage|textAutoCorrect|textCapSentences" - android:imeOptions="actionSend|flagNoExtractUi|flagNoFullscreen" /> + android:imeOptions="actionSend" /> <FrameLayout android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml index c8a554467ceb..7931dfe74587 100644 --- a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml +++ b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml @@ -21,62 +21,70 @@ xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/mobile_combo" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:paddingStart="2dp" - android:orientation="horizontal"> - <FrameLayout - android:id="@+id/inout_container" - android:layout_height="17dp" + android:layout_height="match_parent" + android:gravity="center_vertical" > + + <com.android.keyguard.AlphaOptimizedLinearLayout + android:id="@+id/mobile_group" android:layout_width="wrap_content" - android:layout_gravity="center_vertical"> - <ImageView - android:id="@+id/mobile_in" - android:layout_height="wrap_content" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:paddingStart="2dp" + android:orientation="horizontal" > + + <FrameLayout + android:id="@+id/inout_container" + android:layout_height="17dp" android:layout_width="wrap_content" - android:src="@drawable/ic_activity_down" - android:visibility="gone" - android:paddingEnd="2dp" - /> + android:layout_gravity="center_vertical"> + <ImageView + android:id="@+id/mobile_in" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:src="@drawable/ic_activity_down" + android:visibility="gone" + android:paddingEnd="2dp" + /> + <ImageView + android:id="@+id/mobile_out" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:src="@drawable/ic_activity_up" + android:paddingEnd="2dp" + android:visibility="gone" + /> + </FrameLayout> <ImageView - android:id="@+id/mobile_out" + android:id="@+id/mobile_type" android:layout_height="wrap_content" android:layout_width="wrap_content" - android:src="@drawable/ic_activity_up" - android:paddingEnd="2dp" + android:layout_gravity="center_vertical" + android:paddingEnd="1dp" + android:visibility="gone" /> + <Space + android:id="@+id/mobile_roaming_space" + android:layout_height="match_parent" + android:layout_width="@dimen/roaming_icon_start_padding" android:visibility="gone" /> - </FrameLayout> - <ImageView - android:id="@+id/mobile_type" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:layout_gravity="center_vertical" - android:paddingEnd="1dp" - android:visibility="gone" /> - <Space - android:id="@+id/mobile_roaming_space" - android:layout_height="match_parent" - android:layout_width="@dimen/roaming_icon_start_padding" - android:visibility="gone" - /> - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_vertical"> - <com.android.systemui.statusbar.AnimatedImageView - android:id="@+id/mobile_signal" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - systemui:hasOverlappingRendering="false" - /> - <ImageView - android:id="@+id/mobile_roaming" + <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@drawable/stat_sys_roaming" - android:contentDescription="@string/data_connection_roaming" - android:visibility="gone" /> - </FrameLayout> + android:layout_gravity="center_vertical"> + <com.android.systemui.statusbar.AnimatedImageView + android:id="@+id/mobile_signal" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + systemui:hasOverlappingRendering="false" + /> + <ImageView + android:id="@+id/mobile_roaming" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/stat_sys_roaming" + android:contentDescription="@string/data_connection_roaming" + android:visibility="gone" /> + </FrameLayout> + </com.android.keyguard.AlphaOptimizedLinearLayout> </com.android.systemui.statusbar.StatusBarMobileView> diff --git a/packages/SystemUI/res/layout/system_icons.xml b/packages/SystemUI/res/layout/system_icons.xml index 258b82aacb2e..9237477f17e8 100644 --- a/packages/SystemUI/res/layout/system_icons.xml +++ b/packages/SystemUI/res/layout/system_icons.xml @@ -31,5 +31,6 @@ <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="match_parent" android:layout_width="wrap_content" - /> + android:clipToPadding="false" + android:clipChildren="false" /> </LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java index 7429cb5c19d9..f84c72e0ae22 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java @@ -33,7 +33,9 @@ public class ThumbnailData { public Rect insets; public boolean reducedResolution; public boolean isRealSnapshot; + public boolean isTranslucent; public int windowingMode; + public int systemUiVisibility; public float scale; public ThumbnailData() { @@ -43,7 +45,9 @@ public class ThumbnailData { reducedResolution = false; scale = 1f; isRealSnapshot = true; + isTranslucent = false; windowingMode = WINDOWING_MODE_UNDEFINED; + systemUiVisibility = 0; } public ThumbnailData(TaskSnapshot snapshot) { @@ -53,6 +57,8 @@ public class ThumbnailData { reducedResolution = snapshot.isReducedResolution(); scale = snapshot.getScale(); isRealSnapshot = snapshot.isRealSnapshot(); + isTranslucent = snapshot.isTranslucent(); windowingMode = snapshot.getWindowingMode(); + systemUiVisibility = snapshot.getSystemUiVisibility(); } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index ca5b03473a4d..63a4cd497bc1 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -219,13 +219,6 @@ public class ActivityManagerWrapper { if (animationHandler != null) { runner = new IRecentsAnimationRunner.Stub() { public void onAnimationStart(IRecentsAnimationController controller, - RemoteAnimationTarget[] apps) { - final Rect stableInsets = new Rect(); - WindowManagerWrapper.getInstance().getStableInsets(stableInsets); - onAnimationStart_New(controller, apps, stableInsets, null); - } - - public void onAnimationStart_New(IRecentsAnimationController controller, RemoteAnimationTarget[] apps, Rect homeContentInsets, Rect minimizedHomeBounds) { final RecentsAnimationControllerCompat controllerCompat = diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java index 5a0dddc7656a..cc536a50bfc0 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java @@ -57,6 +57,7 @@ public class NavigationBarCompat { public static final int HIT_TARGET_BACK = 1; public static final int HIT_TARGET_HOME = 2; public static final int HIT_TARGET_OVERVIEW = 3; + public static final int HIT_TARGET_ROTATION = 4; @Retention(RetentionPolicy.SOURCE) @IntDef({FLAG_DISABLE_SWIPE_UP, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java index 00cd5a7b1689..48b413456755 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -246,7 +246,12 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - onUserInput(); + // Fingerprint sensor sends a KeyEvent.KEYCODE_UNKNOWN. + // We don't want to consider it valid user input because the UI + // will already respond to the event. + if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { + onUserInput(); + } return false; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java index a2befefba79e..cb8c119d08eb 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -31,8 +31,7 @@ import com.android.internal.annotations.VisibleForTesting; public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView implements View.OnKeyListener, View.OnTouchListener { - @VisibleForTesting - PasswordTextView mPasswordEntry; + protected PasswordTextView mPasswordEntry; private View mOkButton; private View mDeleteButton; private View mButton0; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index fb1392504965..9f382b00d4f8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -55,6 +55,7 @@ import android.os.BatteryManager; import android.os.CancellationSignal; import android.os.Handler; import android.os.IRemoteCallback; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; @@ -244,7 +245,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms private static final int HW_UNAVAILABLE_RETRY_MAX = 3; - private final Handler mHandler = new Handler() { + private final Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { @@ -339,6 +340,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED: updateLogoutEnabled(); break; + default: + super.handleMessage(msg); + break; } } }; @@ -1181,12 +1185,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); - context.registerReceiver(mBroadcastReceiver, filter); + context.registerReceiver(mBroadcastReceiver, filter, null, mHandler); final IntentFilter bootCompleteFilter = new IntentFilter(); bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED); - context.registerReceiver(mBroadcastReceiver, bootCompleteFilter); + context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler); final IntentFilter allUserFilter = new IntentFilter(); allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED); @@ -1196,7 +1200,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); allUserFilter.addAction(ACTION_USER_UNLOCKED); context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter, - null, null); + null, mHandler); mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener); try { diff --git a/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java b/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java index 68f583695596..922c65e453be 100644 --- a/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java +++ b/packages/SystemUI/src/com/android/systemui/SliceBroadcastRelayHandler.java @@ -87,9 +87,11 @@ public class SliceBroadcastRelayHandler extends SystemUI { private final ArraySet<ComponentName> mReceivers = new ArraySet<>(); private final UserHandle mUserId; + private final Uri mUri; public BroadcastRelay(Uri uri) { mUserId = new UserHandle(ContentProvider.getUserIdFromUri(uri)); + mUri = uri; } public void register(Context context, ComponentName receiver, IntentFilter filter) { @@ -106,6 +108,7 @@ public class SliceBroadcastRelayHandler extends SystemUI { intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); for (ComponentName receiver : mReceivers) { intent.setComponent(receiver); + intent.putExtra(SliceBroadcastRelay.EXTRA_URI, mUri.toString()); if (DEBUG) Log.d(TAG, "Forwarding " + receiver + " " + intent + " " + mUserId); context.sendBroadcastAsUser(intent, mUserId); } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 6d677ab74bee..8d89314c2e21 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -126,8 +126,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, private SnapTarget mSnapTargetBeforeMinimized; private int mDividerInsets; + private final Display mDefaultDisplay; private int mDisplayWidth; private int mDisplayHeight; + private int mDisplayRotation; private int mDividerWindowWidth; private int mDividerSize; private int mTouchElevation; @@ -140,7 +142,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private final Rect mDockedInsetRect = new Rect(); private final Rect mOtherInsetRect = new Rect(); private final Rect mLastResizeRect = new Rect(); - private final Rect mDisplayRect = new Rect(); + private final Rect mTmpRect = new Rect(); private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance(); private DividerWindowManager mWindowManager; private VelocityTracker mVelocityTracker; @@ -274,6 +276,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, super(context, attrs, defStyleAttr, defStyleRes); mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, context.getDisplay(), Choreographer.getInstance()); + final DisplayManager displayManager = + (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); + mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); } @Override @@ -373,7 +378,13 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mStableInsets.isEmpty()) { SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets); } - repositionSnapTargetBeforeMinimized(); + + if (mState.mRatioPositionBeforeMinimized == 0) { + // Set the middle target as the initial state + mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget(); + } else { + repositionSnapTargetBeforeMinimized(); + } } public WindowManagerProxy getWindowManagerProxy() { @@ -403,6 +414,11 @@ public class DividerView extends FrameLayout implements OnTouchListener, mHandle.setTouching(true, animate); } mDockSide = mWindowManagerProxy.getDockSide(); + + // Update snap algorithm if rotation has occurred + if (mDisplayRotation != mDefaultDisplay.getRotation()) { + updateDisplayInfo(); + } initializeSnapAlgorithm(); mWindowManagerProxy.setResizing(true); if (touching) { @@ -453,7 +469,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private void initializeSnapAlgorithm() { if (mSnapAlgorithm == null) { mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth, - mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets); + mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets, mDockSide); } if (mMinimizedSnapAlgorithm == null) { mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), @@ -620,7 +636,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, } else { saveTarget = snapTarget; } - saveSnapTargetBeforeMinimized(saveTarget); + if (saveTarget.position != mSnapAlgorithm.getDismissEndTarget().position + && saveTarget.position != mSnapAlgorithm.getDismissStartTarget().position) { + saveSnapTargetBeforeMinimized(saveTarget); + } } }; Runnable notCancelledEndAction = () -> { @@ -764,6 +783,8 @@ public class DividerView extends FrameLayout implements OnTouchListener, initializeSnapAlgorithm(); if (mIsInMinimizeInteraction != minimized) { if (minimized) { + // Relayout to recalculate the divider shadow when minimizing + requestLayout(); mIsInMinimizeInteraction = true; resizeStack(mMinimizedSnapAlgorithm.getMiddleTarget()); } else { @@ -913,11 +934,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, } private void updateDisplayInfo() { - final DisplayManager displayManager = - (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); - Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + mDisplayRotation = mDefaultDisplay.getRotation(); final DisplayInfo info = new DisplayInfo(); - display.getDisplayInfo(info); + mDefaultDisplay.getDisplayInfo(info); mDisplayWidth = info.logicalWidth; mDisplayHeight = info.logicalHeight; mSnapAlgorithm = null; @@ -991,44 +1010,47 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mHomeStackResizable && mIsInMinimizeInteraction) { calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide, mDockedTaskRect); + calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, + DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); // Move a right-docked-app to line up with the divider while dragging it if (mDockSide == DOCKED_RIGHT) { mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize) - mDockedTaskRect.left + mDividerSize, 0); + mOtherTaskRect.offset(mStableInsets.left, 0); } - calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, - DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect, mOtherTaskRect, null); return; } if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) { - if (mCurrentAnimator != null) { - calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect); - } else { - calculateBoundsForPosition(isHorizontalDivision() ? mDisplayHeight : mDisplayWidth, - mDockSide, mDockedTaskRect); - } + calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect); // Move a docked app if from the right in position with the divider up to insets if (mDockSide == DOCKED_RIGHT) { - mDockedTaskRect.offset(Math.max(position, - mStableInsets.left) - mDockedTaskRect.left, 0); + mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize) + - mDockedTaskRect.left + mDividerSize, 0); + mOtherTaskRect.offset(mStableInsets.left, 0); } calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null, mOtherTaskRect, null); } else if (mExitAnimationRunning && taskPosition != TASK_POSITION_SAME) { - calculateBoundsForPosition(taskPosition, - mDockSide, mDockedTaskRect); + calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect); + mDockedInsetRect.set(mDockedTaskRect); calculateBoundsForPosition(mExitStartPosition, DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); mOtherInsetRect.set(mOtherTaskRect); applyExitAnimationParallax(mOtherTaskRect, position); - mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null, + + // Move a right-docked-app to line up with the divider while dragging it + if (mDockSide == DOCKED_RIGHT) { + mDockedTaskRect.offset(position - mStableInsets.left + mDividerSize, 0); + mOtherTaskRect.offset(mStableInsets.left, 0); + } + mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedInsetRect, mOtherTaskRect, mOtherInsetRect); } else if (taskPosition != TASK_POSITION_SAME) { calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide), @@ -1040,17 +1062,17 @@ public class DividerView extends FrameLayout implements OnTouchListener, restrictDismissingTaskPosition(taskPosition, dockSideInverted, taskSnapTarget); calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect); calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect); - mDisplayRect.set(0, 0, mDisplayWidth, mDisplayHeight); + mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight); alignTopLeft(mDockedRect, mDockedTaskRect); alignTopLeft(mOtherRect, mOtherTaskRect); mDockedInsetRect.set(mDockedTaskRect); mOtherInsetRect.set(mOtherTaskRect); if (dockSideTopLeft(mDockSide)) { - alignTopLeft(mDisplayRect, mDockedInsetRect); - alignBottomRight(mDisplayRect, mOtherInsetRect); + alignTopLeft(mTmpRect, mDockedInsetRect); + alignBottomRight(mTmpRect, mOtherInsetRect); } else { - alignBottomRight(mDisplayRect, mDockedInsetRect); - alignTopLeft(mDisplayRect, mOtherInsetRect); + alignBottomRight(mTmpRect, mDockedInsetRect); + alignTopLeft(mTmpRect, mOtherInsetRect); } applyDismissingParallax(mDockedTaskRect, mDockSide, taskSnapTarget, position, taskPositionDocked); @@ -1269,23 +1291,22 @@ public class DividerView extends FrameLayout implements OnTouchListener, startDragging(false /* animate */, false /* touching */); } updateDockSide(); - int position = DockedDividerUtils.calculatePositionForBounds(event.initialRect, - mDockSide, mDividerSize); mEntranceAnimationRunning = true; - resizeStack(position, mSnapAlgorithm.getMiddleTarget().position, + resizeStack(calculatePositionForInsetBounds(), mSnapAlgorithm.getMiddleTarget().position, mSnapAlgorithm.getMiddleTarget()); } public void onRecentsDrawn() { + updateDockSide(); + final int position = calculatePositionForInsetBounds(); if (mState.animateAfterRecentsDrawn) { mState.animateAfterRecentsDrawn = false; - updateDockSide(); mHandler.post(() -> { // Delay switching resizing mode because this might cause jank in recents animation // that's longer than this animation. - stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), + stopDragging(position, getSnapAlgorithm().getMiddleTarget(), mLongPressEntraceAnimDuration, Interpolators.FAST_OUT_SLOW_IN, 200 /* endDelay */); }); @@ -1294,7 +1315,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, mState.growAfterRecentsDrawn = false; updateDockSide(); EventBus.getDefault().send(new RecentsGrowingEvent()); - stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 336, + stopDragging(position, getSnapAlgorithm().getMiddleTarget(), 336, Interpolators.FAST_OUT_SLOW_IN); } } @@ -1315,4 +1336,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, 0 /* endDelay */, Interpolators.FAST_OUT_SLOW_IN); } } + + private int calculatePositionForInsetBounds() { + mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight); + mTmpRect.inset(mStableInsets); + return DockedDividerUtils.calculatePositionForBounds(mTmpRect, mDockSide, mDividerSize); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 991b47e14028..82cf93e45971 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1651,6 +1651,45 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mMenuRow.resetMenu(); } + void onGutsOpened() { + resetTranslation(); + updateContentAccessibilityImportanceForGuts(false /* isEnabled */); + } + + void onGutsClosed() { + updateContentAccessibilityImportanceForGuts(true /* isEnabled */); + } + + /** + * Updates whether all the non-guts content inside this row is important for accessibility. + * + * @param isEnabled whether the content views should be enabled for accessibility + */ + private void updateContentAccessibilityImportanceForGuts(boolean isEnabled) { + if (mChildrenContainer != null) { + updateChildAccessibilityImportance(mChildrenContainer, isEnabled); + } + if (mLayouts != null) { + for (View view : mLayouts) { + updateChildAccessibilityImportance(view, isEnabled); + } + } + + if (isEnabled) { + this.requestAccessibilityFocus(); + } + } + + /** + * Updates whether the given childView is important for accessibility based on + * {@code isEnabled}. + */ + private void updateChildAccessibilityImportance(View childView, boolean isEnabled) { + childView.setImportantForAccessibility(isEnabled + ? View.IMPORTANT_FOR_ACCESSIBILITY_AUTO + : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); + } + public CharSequence getActiveRemoteInputText() { return mPrivateLayout.getActiveRemoteInputText(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java index 20e5f86ee097..1b613cbcaa41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java @@ -23,8 +23,10 @@ import android.service.notification.StatusBarNotification; import android.support.annotation.VisibleForTesting; import android.util.Log; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dependency; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; +import com.android.systemui.statusbar.notification.NotificationCounters; import com.android.systemui.statusbar.phone.StatusBar; import java.util.Collections; @@ -97,6 +99,9 @@ public class NotificationBlockingHelperManager { // We don't care about the touch origin (x, y) since we're opening guts without any // explicit user interaction. manager.openGuts(mBlockingHelperRow, 0, 0, menuRow.getLongpressMenuItem(mContext)); + + Dependency.get(MetricsLogger.class) + .count(NotificationCounters.BLOCKING_HELPER_SHOWN, 1); return true; } return false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java index dff5f3814f68..8d7668ad6f66 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java @@ -159,6 +159,7 @@ public class NotificationGutsManager implements Dumpable { row.setGutsView(item); row.setTag(sbn.getPackageName()); row.getGuts().setClosedListener((NotificationGuts g) -> { + row.onGutsClosed(); if (!g.willBeRemoved() && !row.isRemoved()) { mListContainer.onHeightChanged( row, !mPresenter.isPresenterFullyCollapsed() /* needsAnimation */); @@ -372,7 +373,7 @@ public class NotificationGutsManager implements Dumpable { @Override public void run() { if (row.getWindowToken() == null) { - Log.e(TAG, "Trying to show notification guts, but not attached to " + Log.e(TAG, "Trying to show notification guts in post(), but not attached to " + "window"); return; } @@ -390,7 +391,7 @@ public class NotificationGutsManager implements Dumpable { x, y, needsFalsingProtection, - row::resetTranslation); + row::onGutsOpened); row.closeRemoteInput(); mListContainer.onHeightChanged(row, true /* needsAnimation */); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java index be5e3f4bce92..98e926807431 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java @@ -199,8 +199,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G bindHeader(); bindPrompt(); bindButtons(); - - logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_SHOWN); } private void bindHeader() throws RemoteException { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index 19980a221576..04c500fc8f6a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar; +import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; +import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; +import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea; @@ -24,10 +27,14 @@ import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.Rect; import android.util.AttributeSet; +import android.util.Log; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.settingslib.graph.SignalDrawable; @@ -35,10 +42,14 @@ import com.android.systemui.R; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; -public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements DarkReceiver, +public class StatusBarMobileView extends FrameLayout implements DarkReceiver, StatusIconDisplayable { private static final String TAG = "StatusBarMobileView"; + /// Used to show etc dots + private StatusBarIconView mDotView; + /// The main icon view + private LinearLayout mMobileGroup; private String mSlot; private MobileIconState mState; private SignalDrawable mMobileDrawable; @@ -47,12 +58,17 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D private ImageView mOut; private ImageView mMobile, mMobileType, mMobileRoaming; private View mMobileRoamingSpace; + private int mVisibleState = -1; - public static StatusBarMobileView fromContext(Context context) { + public static StatusBarMobileView fromContext(Context context, String slot) { LayoutInflater inflater = LayoutInflater.from(context); - - return (StatusBarMobileView) + StatusBarMobileView v = (StatusBarMobileView) inflater.inflate(R.layout.status_bar_mobile_signal_group, null); + + v.setSlot(slot); + v.init(); + v.setVisibleState(STATE_ICON); + return v; } public StatusBarMobileView(Context context) { @@ -72,14 +88,8 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D super(context, attrs, defStyleAttr, defStyleRes); } - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - init(); - } - private void init() { + mMobileGroup = findViewById(R.id.mobile_group); mMobile = findViewById(R.id.mobile_signal); mMobileType = findViewById(R.id.mobile_type); mMobileRoaming = findViewById(R.id.mobile_roaming); @@ -90,6 +100,18 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D mMobileDrawable = new SignalDrawable(getContext()); mMobile.setImageDrawable(mMobileDrawable); + + initDotView(); + } + + private void initDotView() { + mDotView = new StatusBarIconView(mContext, mSlot, null); + mDotView.setVisibleState(STATE_DOT); + + int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size); + LayoutParams lp = new LayoutParams(width, width); + lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START; + addView(mDotView, lp); } public void applyMobileState(MobileIconState state) { @@ -113,9 +135,9 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D private void initViewState() { setContentDescription(mState.contentDescription); if (!mState.visible) { - setVisibility(View.GONE); + mMobileGroup.setVisibility(View.GONE); } else { - setVisibility(View.VISIBLE); + mMobileGroup.setVisibility(View.VISIBLE); } mMobileDrawable.setLevel(mState.strengthId); if (mState.typeId > 0) { @@ -137,7 +159,7 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D private void updateState(MobileIconState state) { setContentDescription(state.contentDescription); if (mState.visible != state.visible) { - setVisibility(state.visible ? View.VISIBLE : View.GONE); + mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE); } if (mState.strengthId != state.strengthId) { mMobileDrawable.setLevel(state.strengthId); @@ -173,6 +195,8 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D mOut.setImageTintList(color); mMobileType.setImageTintList(color); mMobileRoaming.setImageTintList(color); + mDotView.setDecorColor(tint); + mDotView.setIconColor(tint, false); } @Override @@ -194,11 +218,12 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D mOut.setImageTintList(list); mMobileType.setImageTintList(list); mMobileRoaming.setImageTintList(list); + mDotView.setDecorColor(color); } @Override public void setDecorColor(int color) { - //TODO: May also not be needed + mDotView.setDecorColor(color); } @Override @@ -208,12 +233,30 @@ public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements D @Override public void setVisibleState(int state) { - //TODO: May not be needed. Mobile is always expected to be visible (not a dot) + if (state == mVisibleState) { + return; + } + + mVisibleState = state; + switch (state) { + case STATE_ICON: + mMobileGroup.setVisibility(View.VISIBLE); + mDotView.setVisibility(View.GONE); + break; + case STATE_DOT: + mMobileGroup.setVisibility(View.INVISIBLE); + mDotView.setVisibility(View.VISIBLE); + break; + case STATE_HIDDEN: + default: + setVisibility(View.INVISIBLE); + break; + } } @Override public int getVisibleState() { - return 0; + return mVisibleState; } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 46b4078a1801..e0e991b4993f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -237,9 +237,8 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da public void addMobileView(MobileIconState state) { Log.d(TAG, "addMobileView: "); - StatusBarMobileView view = StatusBarMobileView.fromContext(mContext); + StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, state.slot); - view.setSlot(state.slot); view.applyMobileState(state); view.setStaticDrawableColor(mColor); 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 533d5ecfab23..98f9f1abd301 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -88,6 +88,7 @@ import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABL import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON; import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW; +import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION; public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> { final static boolean DEBUG = false; @@ -116,6 +117,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private Rect mHomeButtonBounds = new Rect(); private Rect mBackButtonBounds = new Rect(); private Rect mRecentsButtonBounds = new Rect(); + private Rect mRotationButtonBounds = new Rect(); private int[] mTmpPosition = new int[2]; private KeyButtonDrawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon; @@ -341,6 +343,8 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mDownHitTarget = HIT_TARGET_HOME; } else if (mRecentsButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_OVERVIEW; + } else if (mRotationButtonBounds.contains(x, y)) { + mDownHitTarget = HIT_TARGET_ROTATION; } break; } @@ -893,6 +897,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav updateButtonLocationOnScreen(getBackButton(), mBackButtonBounds); updateButtonLocationOnScreen(getHomeButton(), mHomeButtonBounds); updateButtonLocationOnScreen(getRecentsButton(), mRecentsButtonBounds); + updateButtonLocationOnScreen(getRotateSuggestionButton(), mRotationButtonBounds); mGestureHelper.onLayout(changed, left, top, right, bottom); mRecentsOnboarding.setNavBarHeight(getMeasuredHeight()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 061677c8d1c3..65cb56c7cc13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -249,7 +249,7 @@ import java.util.Map; public class StatusBar extends SystemUI implements DemoMode, DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener, - OnHeadsUpChangedListener, CommandQueue.Callbacks, + OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback, ColorExtractor.OnColorsChangedListener, ConfigurationListener, NotificationPresenter { public static final boolean MULTIUSER_DEBUG = false; @@ -785,12 +785,7 @@ public class StatusBar extends SystemUI implements DemoMode, // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot. mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel); mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller); - mZenController.addCallback(new ZenModeController.Callback() { - @Override - public void onZenChanged(int zen) { - updateEmptyShadeView(); - } - }); + mZenController.addCallback(this); mActivityLaunchAnimator = new ActivityLaunchAnimator(mStatusBarWindow, this, mNotificationPanel, @@ -3376,6 +3371,7 @@ public class StatusBar extends SystemUI implements DemoMode, Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(null); mDeviceProvisionedController.removeCallback(mUserSetupObserver); Dependency.get(ConfigurationController.class).removeCallback(this); + mZenController.removeCallback(this); mAppOpsListener.destroy(); } @@ -5536,6 +5532,11 @@ public class StatusBar extends SystemUI implements DemoMode, } @Override + public void onZenChanged(int zen) { + updateEmptyShadeView(); + } + + @Override public void showAssistDisclosure() { if (mAssistManager != null) { mAssistManager.showDisclosure(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java index 1ba37a9bf9dd..3b9ee8bcd378 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -296,8 +296,7 @@ public interface StatusBarIconController { } private StatusBarMobileView onCreateStatusBarMobileView(String slot) { - StatusBarMobileView view = StatusBarMobileView.fromContext(mContext); - view.setSlot(slot); + StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, slot); return view; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java index 4538977f7a6f..0811179e23d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java @@ -49,7 +49,7 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout { private static final String TAG = "StatusIconContainer"; private static final boolean DEBUG = false; private static final boolean DEBUG_OVERFLOW = false; - // Max 5 status icons including battery + // Max 8 status icons including battery private static final int MAX_ICONS = 7; private static final int MAX_DOTS = 1; @@ -152,7 +152,7 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout { int visibleCount = mMeasureViews.size(); int maxVisible = visibleCount <= MAX_ICONS ? MAX_ICONS : MAX_ICONS - 1; - int totalWidth = getPaddingStart() + getPaddingEnd(); + int totalWidth = mPaddingLeft + mPaddingRight; boolean trackWidth = true; // Measure all children so that they report the correct width @@ -208,8 +208,8 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout { */ private void calculateIconTranslations() { mLayoutStates.clear(); - float width = getWidth() - getPaddingEnd(); - float translationX = width; + float width = getWidth(); + float translationX = width - getPaddingEnd(); float contentStart = getPaddingStart(); int childCount = getChildCount(); // Underflow === don't show content until that index @@ -344,10 +344,11 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout { animate = true; } - icon.setVisibleState(visibleState); if (animate) { animateTo(view, animationProperties); + icon.setVisibleState(visibleState); } else { + icon.setVisibleState(visibleState); super.applyToView(view); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index 59bf982bcfdb..310f14c2fca7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -565,6 +565,11 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { final InputConnection inputConnection = super.onCreateInputConnection(outAttrs); + //if pinned, set imeOption to keep the behavior like in portrait. + if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isPinned()) { + outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI + | EditorInfo.IME_FLAG_NO_FULLSCREEN; + } if (mShowImeOnInputConnection && inputConnection != null) { final InputMethodManager imm = InputMethodManager.getInstance(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java index c279e6388592..cc802a8f85d5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java @@ -495,12 +495,14 @@ public class SmartReplyView extends ViewGroup { // measured with the wrong number of lines). if (child.getPaddingLeft() != buttonPaddingHorizontal) { requiresNewMeasure = true; - if (buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) { - // Decrease padding (2->1 line). - newWidth -= mSingleToDoubleLineButtonWidthIncrease; - } else { - // Increase padding (1->2 lines). - newWidth += mSingleToDoubleLineButtonWidthIncrease; + if (newWidth != Integer.MAX_VALUE) { + if (buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) { + // Change padding (2->1 line). + newWidth -= mSingleToDoubleLineButtonWidthIncrease; + } else { + // Change padding (1->2 lines). + newWidth += mSingleToDoubleLineButtonWidthIncrease; + } } child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(), buttonPaddingHorizontal, child.getPaddingBottom()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java index 339c115c77a3..2031b27c93f2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java @@ -36,6 +36,7 @@ import android.service.notification.Condition; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ZenRule; import android.util.Log; +import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.qs.GlobalSetting; @@ -112,6 +113,10 @@ public class ZenModeControllerImpl extends CurrentUserTracker implements ZenMode @Override public void addCallback(Callback callback) { + if (callback == null) { + Slog.e(TAG, "Attempted to add a null callback."); + return; + } mCallbacks.add(callback); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 176905a31b9b..236ead0b12bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -2222,7 +2222,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updateScrollability() { - boolean scrollable = getScrollRange() > 0; + boolean scrollable = !mQsExpanded && getScrollRange() > 0; if (scrollable != mScrollable) { mScrollable = scrollable; setFocusable(scrollable); @@ -4500,6 +4500,7 @@ public class NotificationStackScrollLayout extends ViewGroup public void setQsExpanded(boolean qsExpanded) { mQsExpanded = qsExpanded; updateAlgorithmLayoutMinHeight(); + updateScrollability(); } public void setQsExpansionFraction(float qsExpansionFraction) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java index e79c9d0c5455..359832f7a542 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java @@ -16,11 +16,15 @@ package com.android.keyguard; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; +import android.view.KeyEvent; import android.view.LayoutInflater; import com.android.systemui.SysuiTestCase; @@ -28,6 +32,7 @@ import com.android.systemui.SysuiTestCase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -37,21 +42,35 @@ import org.mockito.MockitoAnnotations; public class KeyguardPinBasedInputViewTest extends SysuiTestCase { @Mock - private PasswordTextView mPasswordTextView; + private PasswordTextView mPasswordEntry; + @Mock + private SecurityMessageDisplay mSecurityMessageDisplay; + @InjectMocks private KeyguardPinBasedInputView mKeyguardPinView; @Before public void setup() { - MockitoAnnotations.initMocks(this); LayoutInflater inflater = LayoutInflater.from(getContext()); mKeyguardPinView = (KeyguardPinBasedInputView) inflater.inflate(R.layout.keyguard_pin_view, null); - mKeyguardPinView.mPasswordEntry = mPasswordTextView; + MockitoAnnotations.initMocks(this); } @Test public void onResume_requestsFocus() { mKeyguardPinView.onResume(KeyguardSecurityView.SCREEN_ON); - verify(mPasswordTextView).requestFocus(); + verify(mPasswordEntry).requestFocus(); + } + + @Test + public void onKeyDown_clearsSecurityMessage() { + mKeyguardPinView.onKeyDown(KeyEvent.KEYCODE_0, mock(KeyEvent.class)); + verify(mSecurityMessageDisplay).setMessage(eq("")); + } + + @Test + public void onKeyDown_noSecurityMessageInteraction() { + mKeyguardPinView.onKeyDown(KeyEvent.KEYCODE_UNKNOWN, mock(KeyEvent.class)); + verifyZeroInteractions(mSecurityMessageDisplay); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java index 4abac56d7455..383db053b1f5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SliceBroadcastRelayHandlerTest.java @@ -60,6 +60,7 @@ public class SliceBroadcastRelayHandlerTest extends SysuiTestCase { new ComponentName(mContext.getPackageName(), Receiver.class.getName())); IntentFilter value = new IntentFilter(TEST_ACTION); intent.putExtra(SliceBroadcastRelay.EXTRA_FILTER, value); + intent.putExtra(SliceBroadcastRelay.EXTRA_URI, testUri); relayHandler.handleIntent(intent); verify(relayHandler.mContext).registerReceiver(any(), eq(value)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java index b3dddd522b1b..a6d87af17545 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java @@ -20,6 +20,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import android.content.Context; +import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -29,6 +30,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -48,6 +50,7 @@ import static org.mockito.Mockito.when; * Tests for {@link NotificationBlockingHelperManager}. */ @SmallTest +@FlakyTest @org.junit.runner.RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class NotificationBlockingHelperManagerTest extends SysuiTestCase { @@ -56,7 +59,6 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { private NotificationTestHelper mHelper; - @Rule public MockitoRule mockito = MockitoJUnit.rule(); @Mock private NotificationGutsManager mGutsManager; @Mock private NotificationEntryManager mEntryManager; @Mock private NotificationMenuRow mMenuRow; @@ -64,20 +66,22 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { @Before public void setUp() { - mBlockingHelperManager = new NotificationBlockingHelperManager(mContext); - // By default, have the shade visible/expanded. - mBlockingHelperManager.setNotificationShadeExpanded(1f); - - mHelper = new NotificationTestHelper(mContext); + MockitoAnnotations.initMocks(this); when(mGutsManager.openGuts( any(View.class), anyInt(), anyInt(), any(NotificationMenuRowPlugin.MenuItem.class))) .thenReturn(true); + when(mMenuRow.getLongpressMenuItem(any(Context.class))).thenReturn(mMenuItem); mDependency.injectTestDependency(NotificationGutsManager.class, mGutsManager); mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); - when(mMenuRow.getLongpressMenuItem(any(Context.class))).thenReturn(mMenuItem); + + mHelper = new NotificationTestHelper(mContext); + + mBlockingHelperManager = new NotificationBlockingHelperManager(mContext); + // By default, have the shade visible/expanded. + mBlockingHelperManager.setNotificationShadeExpanded(1f); } @Test @@ -89,7 +93,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { @Test public void testDismissCurrentBlockingHelper_withDetachedBlockingHelperRow() throws Exception { - ExpandableNotificationRow row = spy(createBlockableRowSpy()); + ExpandableNotificationRow row = createBlockableRowSpy(); row.setBlockingHelperShowing(true); when(row.isAttachedToWindow()).thenReturn(false); mBlockingHelperManager.setBlockingHelperRowForTest(row); @@ -102,7 +106,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { @Test public void testDismissCurrentBlockingHelper_withAttachedBlockingHelperRow() throws Exception { - ExpandableNotificationRow row = spy(createBlockableRowSpy()); + ExpandableNotificationRow row = createBlockableRowSpy(); row.setBlockingHelperShowing(true); when(row.isAttachedToWindow()).thenReturn(true); mBlockingHelperManager.setBlockingHelperRowForTest(row); @@ -200,7 +204,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { @Test public void testBlockingHelperShowAndDismiss() throws Exception{ - ExpandableNotificationRow row = spy(createBlockableRowSpy()); + ExpandableNotificationRow row = createBlockableRowSpy(); row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE; when(row.isAttachedToWindow()).thenReturn(true); @@ -227,6 +231,4 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { when(row.getIsNonblockable()).thenReturn(false); return row; } - - } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java index cb509e0984ba..bdeb8bcd6fb8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java @@ -314,12 +314,11 @@ public class NotificationInfoTest extends SysuiTestCase { @Test public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception { - // Bind notification logs an event, so this counts as one invocation for the metrics logger. mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, true, true); mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent"); - verify(mMetricsLogger, times(2)).count(anyString(), anyInt()); + verify(mMetricsLogger, times(1)).count(anyString(), anyInt()); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java index f3d79fd58982..c573ca88a471 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java @@ -347,6 +347,30 @@ public class SmartReplyViewTest extends SysuiTestCase { assertEqualLayouts(expectedView.getChildAt(2), mView.getChildAt(2)); } + @Test + public void testMeasure_dropLongest() { + final CharSequence[] choices = new CharSequence[]{"Short", "Short", + "LooooooongUnbreakableReplyyyyy"}; + + // Short choices should be shown as single line views + ViewGroup expectedView = buildExpectedView( + new CharSequence[]{"Short", "Short"}, 1); + expectedView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + expectedView.layout(10, 10, 10 + expectedView.getMeasuredWidth(), + 10 + expectedView.getMeasuredHeight()); + + setRepliesFromRemoteInput(choices); + mView.measure( + MeasureSpec.makeMeasureSpec(expectedView.getMeasuredWidth(), MeasureSpec.AT_MOST), + MeasureSpec.UNSPECIFIED); + mView.layout(10, 10, 10 + mView.getMeasuredWidth(), 10 + mView.getMeasuredHeight()); + + assertEqualLayouts(expectedView, mView); + assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(0), mView.getChildAt(0)); + assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(1)); + assertReplyButtonHidden(mView.getChildAt(2)); + } + private void setRepliesFromRemoteInput(CharSequence[] choices) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(TEST_ACTION), 0); @@ -407,10 +431,7 @@ public class SmartReplyViewTest extends SysuiTestCase { private static void assertReplyButtonShownWithEqualMeasures(View expected, View actual) { assertReplyButtonShown(actual); assertEqualMeasures(expected, actual); - assertEquals(expected.getPaddingLeft(), actual.getPaddingLeft()); - assertEquals(expected.getPaddingTop(), actual.getPaddingTop()); - assertEquals(expected.getPaddingRight(), actual.getPaddingRight()); - assertEquals(expected.getPaddingBottom(), actual.getPaddingBottom()); + assertEqualPadding(expected, actual); } private static void assertReplyButtonShown(View view) { @@ -427,4 +448,11 @@ public class SmartReplyViewTest extends SysuiTestCase { assertEquals(expected.getRight(), actual.getRight()); assertEquals(expected.getBottom(), actual.getBottom()); } + + private static void assertEqualPadding(View expected, View actual) { + assertEquals(expected.getPaddingLeft(), actual.getPaddingLeft()); + assertEquals(expected.getPaddingTop(), actual.getPaddingTop()); + assertEquals(expected.getPaddingRight(), actual.getPaddingRight()); + assertEquals(expected.getPaddingBottom(), actual.getPaddingBottom()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java index da8017e25525..ff6558700650 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java @@ -105,4 +105,10 @@ public class ZenModeControllerImplTest extends SysuiTestCase { assertTrue(mController.areNotificationsHiddenInShade()); } -}
\ No newline at end of file + + @Test + public void testAddNullCallback() { + mController.addCallback(null); + mController.fireConfigChanged(null); + } +} diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 0fa5d2bbd0a6..95dc3abc3a4c 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -5818,10 +5818,39 @@ message MetricsEvent { // Tag used to report whether an activity is being autofilled on compatibility mode. FIELD_AUTOFILL_COMPAT_MODE = 1414; - // OPEN: Settings > Sound > Switch connected devices dialog + // OPEN: Settings > Sound > Switch a2dp devices dialog // CATEGORY: SETTINGS // OS: P - DIALOG_UPDATABLE_LIST_PREFERENCE = 1415; + DIALOG_SWITCH_A2DP_DEVICES = 1415; + + // OPEN: Settings > Sound > Switch hfp devices dialog + // CATEGORY: SETTINGS + // OS: P + DIALOG_SWITCH_HFP_DEVICES = 1416; + + // ACTION: User has started or ended charging + // Type TYPE_DISMISS: Charging has ended + // Type TYPE_ACTION: Charging has started, contains fields: battery level + // Tag FIELD_BATTERY_LEVEL_START: Battery level at the start + // Tag FIELD_BATTERY_LEVEL_END: Battery level at the end + // Tag FIELD_CHARGING_DURATION: Time in ms phone was charging + // Tag FIELD_PLUG_TYPE: Charging plug type + ACTION_CHARGE = 1417; + + // Tag used to determine battery level when device started charging + FIELD_BATTERY_LEVEL_START = 1418; + + // Tag used to determine battery level when device ended charging + FIELD_BATTERY_LEVEL_END = 1419; + + // Tag used to determine length of charging + FIELD_CHARGING_DURATION_MILLIS = 1420; + + // Tag used to determine what type of charging was started/ended + // 1 = Plugged AC + // 2 = Plugged USB + // 3 = Wireless + FIELD_PLUG_TYPE = 1421; // ---- End P Constants, all P constants go above this line ---- // Add new aosp constants above this line. diff --git a/proto/src/task_snapshot.proto b/proto/src/task_snapshot.proto index 27febefc39dc..65d625666562 100644 --- a/proto/src/task_snapshot.proto +++ b/proto/src/task_snapshot.proto @@ -29,4 +29,6 @@ int32 inset_bottom = 5; bool is_real_snapshot = 6; int32 windowing_mode = 7; + int32 system_ui_visibility = 8; + bool is_translucent = 9; }
\ No newline at end of file diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 85b02206a594..f992049ef1fb 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -568,8 +568,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Context userContext = mContext.createPackageContextAsUser(providerPackage, 0, UserHandle.of(providerUserId)); PackageManager pm = userContext.getPackageManager(); - Drawable icon = pm.getApplicationInfo(providerPackage, 0).loadUnbadgedIcon(pm); + Drawable icon = pm.getApplicationInfo(providerPackage, 0).loadUnbadgedIcon(pm).mutate(); // Create a bitmap of the icon which is what the widget's remoteview requires. + icon.setColorFilter(mIconUtilities.getDisabledColorFilter()); return mIconUtilities.createIconBitmap(icon); } catch (NameNotFoundException e) { Slog.e(TAG, "Fail to get application icon", e); diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index 51c0488dcd9f..9b833f71869b 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -157,6 +157,9 @@ public final class AutofillManagerService extends SystemService { } }; + @GuardedBy("mLock") + private boolean mAllowInstantService; + public AutofillManagerService(Context context) { super(context); mContext = context; @@ -518,6 +521,23 @@ public final class AutofillManagerService extends SystemService { sFullScreenMode = mode; } + // Called by Shell command. + boolean getAllowInstantService() { + mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); + synchronized (mLock) { + return mAllowInstantService; + } + } + + // Called by Shell command. + void setAllowInstantService(boolean mode) { + mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); + Slog.i(TAG, "setAllowInstantService(): " + mode); + synchronized (mLock) { + mAllowInstantService = mode; + } + } + private void setDebugLocked(boolean debug) { com.android.server.autofill.Helper.sDebug = debug; android.view.autofill.Helper.sDebug = debug; @@ -866,7 +886,8 @@ public final class AutofillManagerService extends SystemService { synchronized (mLock) { final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); return service.startSessionLocked(activityToken, getCallingUid(), appCallback, - autofillId, bounds, value, hasCallback, flags, componentName, compatMode); + autofillId, bounds, value, hasCallback, componentName, compatMode, + mAllowInstantService, flags); } } @@ -1202,6 +1223,7 @@ public final class AutofillManagerService extends SystemService { mAutofillCompatState.dump(prefix2, pw); pw.print(prefix2); pw.print("from settings: "); pw.println(getWhitelistedCompatModePackagesFromSettings()); + pw.print("Allow instant service: "); pw.println(mAllowInstantService); } if (showHistory) { pw.println(); pw.println("Requests history:"); pw.println(); diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 4bd80638d8c9..d97253e1f5a8 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -342,7 +342,8 @@ final class AutofillManagerServiceImpl { int startSessionLocked(@NonNull IBinder activityToken, int uid, @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId, @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback, - int flags, @NonNull ComponentName componentName, boolean compatMode) { + @NonNull ComponentName componentName, boolean compatMode, + boolean bindInstantServiceAllowed, int flags) { if (!isEnabledLocked()) { return 0; } @@ -372,7 +373,7 @@ final class AutofillManagerServiceImpl { pruneAbandonedSessionsLocked(); final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken, - hasCallback, componentName, compatMode, flags); + hasCallback, componentName, compatMode, bindInstantServiceAllowed, flags); if (newSession == null) { return NO_SESSION; } @@ -491,7 +492,8 @@ final class AutofillManagerServiceImpl { @GuardedBy("mLock") private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid, @NonNull IBinder appCallbackToken, boolean hasCallback, - @NonNull ComponentName componentName, boolean compatMode, int flags) { + @NonNull ComponentName componentName, boolean compatMode, + boolean bindInstantServiceAllowed, int flags) { // use random ids so that one app cannot know that another app creates sessions int sessionId; int tries = 0; @@ -510,7 +512,7 @@ final class AutofillManagerServiceImpl { final Session newSession = new Session(this, mUi, mContext, mHandler, mUserId, mLock, sessionId, uid, activityToken, appCallbackToken, hasCallback, mUiLatencyHistory, mWtfHistory, mInfo.getServiceInfo().getComponentName(), componentName, compatMode, - flags); + bindInstantServiceAllowed, flags); mSessions.put(newSession.id, newSession); return newSession; diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java index c76c8ac61705..f7b7ceb4a6da 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java @@ -86,6 +86,9 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { pw.println(" get fc_score [--algorithm ALGORITHM] value1 value2"); pw.println(" Gets the field classification score for 2 fields."); pw.println(""); + pw.println(" get bind-instant-service-allowed"); + pw.println(" Gets whether binding to services provided by instant apps is allowed"); + pw.println(""); pw.println(" set log_level [off | debug | verbose]"); pw.println(" Sets the Autofill log level."); pw.println(""); @@ -98,6 +101,9 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { pw.println(" set full_screen_mode [true | false | default]"); pw.println(" Sets the Fill UI full screen mode"); pw.println(""); + pw.println(" set bind-instant-service-allowed [true | false]"); + pw.println(" Sets whether binding to services provided by instant apps is allowed"); + pw.println(""); pw.println(" list sessions [--user USER_ID]"); pw.println(" Lists all pending sessions."); pw.println(""); @@ -123,6 +129,8 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { return getFieldClassificationScore(pw); case "full_screen_mode": return getFullScreenMode(pw); + case "bind-instant-service-allowed": + return getBindInstantService(pw); default: pw.println("Invalid set: " + what); return -1; @@ -141,6 +149,8 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { return setMaxVisibileDatasets(); case "full_screen_mode": return setFullScreenMode(pw); + case "bind-instant-service-allowed": + return setBindInstantService(pw); default: pw.println("Invalid set: " + what); return -1; @@ -259,6 +269,30 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { } } + private int getBindInstantService(PrintWriter pw) { + if (mService.getAllowInstantService()) { + pw.println("true"); + } else { + pw.println("false"); + } + return 0; + } + + private int setBindInstantService(PrintWriter pw) { + final String mode = getNextArgRequired(); + switch (mode.toLowerCase()) { + case "true": + mService.setAllowInstantService(true); + return 0; + case "false": + mService.setAllowInstantService(false); + return 0; + default: + pw.println("Invalid mode: " + mode); + return -1; + } + } + private int requestDestroy(PrintWriter pw) { if (!isNextArgSessions(pw)) { return -1; diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java index 9bec856e2308..ba544f17c06c 100644 --- a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java +++ b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java @@ -15,8 +15,6 @@ */ package com.android.server.autofill; -import static android.view.autofill.AutofillManager.FC_SERVICE_TIMEOUT; - import static com.android.server.autofill.Helper.sDebug; import static com.android.server.autofill.Helper.sVerbose; import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS; @@ -52,8 +50,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; /** * Strategy used to bridge the field classification algorithms provided by a service in an external diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java index 5372d0c649cf..f78101338d2e 100644 --- a/services/autofill/java/com/android/server/autofill/Helper.java +++ b/services/autofill/java/com/android/server/autofill/Helper.java @@ -68,6 +68,9 @@ public final class Helper { /** * When non-null, overrides whether the UI should be shown on full-screen mode. + * + * <p>Note: access to this variable is not synchronized because it's "final" on real usage - + * it's only set by Shell cmd, for development purposes. */ public static Boolean sFullScreenMode = null; diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java index f7a4b73e85cb..4ded3fe29f2a 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java @@ -84,6 +84,8 @@ final class RemoteFillService implements DeathRecipient { private final Handler mHandler; + private final boolean mBindInstantServiceAllowed; + private IAutoFillService mAutoFillService; private boolean mBinding; @@ -109,13 +111,14 @@ final class RemoteFillService implements DeathRecipient { } public RemoteFillService(Context context, ComponentName componentName, - int userId, FillServiceCallbacks callbacks) { + int userId, FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) { mContext = context; mCallbacks = callbacks; mComponentName = componentName; mIntent = new Intent(AutofillService.SERVICE_INTERFACE).setComponent(mComponentName); mUserId = userId; mHandler = new Handler(FgThread.getHandler().getLooper()); + mBindInstantServiceAllowed = bindInstantServiceAllowed; } public void destroy() { @@ -207,6 +210,7 @@ final class RemoteFillService implements DeathRecipient { .append(String.valueOf(isBound())).println(); pw.append(prefix).append(tab).append("hasPendingRequest=") .append(String.valueOf(mPendingRequest != null)).println(); + pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed); pw.println(); } @@ -258,12 +262,17 @@ final class RemoteFillService implements DeathRecipient { if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] ensureBound()"); mBinding = true; - boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, - Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, + int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; + if (mBindInstantServiceAllowed) { + flags |= Context.BIND_ALLOW_INSTANT; + } + + final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, new UserHandle(mUserId)); if (!willBind) { - if (sDebug) Slog.d(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent); + Slog.w(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent + " using flags " + + flags); mBinding = false; if (!mServiceDied) { diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 88a679b43cc6..73c71725200c 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -517,7 +517,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory, @NonNull LocalLog wtfHistory, @NonNull ComponentName serviceComponentName, @NonNull ComponentName componentName, - boolean compatMode, int flags) { + boolean compatMode, boolean bindInstantServiceAllowed, int flags) { id = sessionId; mFlags = flags; this.uid = uid; @@ -526,7 +526,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mLock = lock; mUi = ui; mHandler = handler; - mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this); + mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this, + bindInstantServiceAllowed); mActivityToken = activityToken; mHasCallback = hasCallback; mUiLatencyHistory = uiLatencyHistory; diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java index 2a7605552b9b..cff1a84ceafe 100644 --- a/services/autofill/java/com/android/server/autofill/ViewState.java +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -18,7 +18,6 @@ package com.android.server.autofill; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static com.android.server.autofill.Helper.sDebug; -import static com.android.server.autofill.Helper.sVerbose; import android.annotation.Nullable; import android.graphics.Rect; diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 5c5f0f8d3b4b..0775abf574b5 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -3023,20 +3023,26 @@ class AlarmManagerService extends SystemService { } private boolean isBackgroundRestricted(Alarm alarm) { - final boolean allowWhileIdle = (alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0; + boolean exemptOnBatterySaver = (alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0; if (alarm.alarmClock != null) { - // Don't block alarm clocks + // Don't defer alarm clocks return false; } - if (alarm.operation != null - && (alarm.operation.isActivity() || alarm.operation.isForegroundService())) { - // Don't block starting foreground components - return false; + if (alarm.operation != null) { + if (alarm.operation.isActivity()) { + // Don't defer starting actual UI + return false; + } + if (alarm.operation.isForegroundService()) { + // FG service alarms are nearly as important; consult AST policy + exemptOnBatterySaver = true; + } } final String sourcePackage = alarm.sourcePackage; final int sourceUid = alarm.creatorUid; return (mAppStateTracker != null) && - mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage, allowWhileIdle); + mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage, + exemptOnBatterySaver); } private native long init(); diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 7f26575651af..169f2a863e96 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -228,7 +228,7 @@ public class AppOpsService extends IAppOpsService.Stub { public void startMonitoring(ContentResolver resolver) { mResolver = resolver; mResolver.registerContentObserver( - Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS), + Settings.Global.getUriFor(Settings.Global.APP_OPS_CONSTANTS), false, this); updateConstants(); } @@ -239,20 +239,17 @@ public class AppOpsService extends IAppOpsService.Stub { } private void updateConstants() { + String value = mResolver != null ? Settings.Global.getString(mResolver, + Settings.Global.APP_OPS_CONSTANTS) : ""; + synchronized (AppOpsService.this) { try { - if (mResolver != null) { - mParser.setString(Settings.Global.getString(mResolver, - Settings.Global.APP_OPS_CONSTANTS)); - } else { - mParser.setString(""); - } + mParser.setString(value); } catch (IllegalArgumentException e) { // Failed to parse the settings string, log this and move on // with defaults. Slog.e(TAG, "Bad app ops settings", e); } - STATE_SETTLE_TIME = mParser.getDurationMillis( KEY_STATE_SETTLE_TIME, 10 * 1000L); } @@ -557,8 +554,9 @@ public class AppOpsService extends IAppOpsService.Stub { } public void systemReady() { + mConstants.startMonitoring(mContext.getContentResolver()); + synchronized (this) { - mConstants.startMonitoring(mContext.getContentResolver()); boolean changed = false; for (int i = mUidStates.size() - 1; i >= 0; i--) { UidState uidState = mUidStates.valueAt(i); diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java index 23c57797c1f5..9b001ce3f917 100644 --- a/services/core/java/com/android/server/AppStateTracker.java +++ b/services/core/java/com/android/server/AppStateTracker.java @@ -1056,9 +1056,9 @@ public class AppStateTracker { * @return whether alarms should be restricted for a UID package-name. */ public boolean areAlarmsRestricted(int uid, @NonNull String packageName, - boolean allowWhileIdle) { + boolean isExemptOnBatterySaver) { return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false, - /* exemptOnBatterySaver =*/ allowWhileIdle); + isExemptOnBatterySaver); } /** diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index d31a605eac6f..87647ca79fea 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -16,36 +16,27 @@ package com.android.server; -import android.app.ActivityManagerInternal; -import android.database.ContentObserver; -import android.os.BatteryStats; - -import android.os.Bundle; -import android.os.PowerManager; -import android.os.ResultReceiver; -import android.os.ShellCallback; -import android.os.ShellCommand; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.app.IBatteryStats; -import com.android.internal.util.DumpUtils; -import com.android.server.am.BatteryStatsService; -import com.android.server.lights.Light; -import com.android.server.lights.LightsManager; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; -import android.hidl.manager.V1_0.IServiceManager; -import android.hidl.manager.V1_0.IServiceNotification; +import android.database.ContentObserver; import android.hardware.health.V1_0.HealthInfo; -import android.hardware.health.V2_0.IHealthInfoCallback; import android.hardware.health.V2_0.IHealth; +import android.hardware.health.V2_0.IHealthInfoCallback; import android.hardware.health.V2_0.Result; +import android.hidl.manager.V1_0.IServiceManager; +import android.hidl.manager.V1_0.IServiceNotification; +import android.metrics.LogMaker; import android.os.BatteryManager; import android.os.BatteryManagerInternal; import android.os.BatteryProperty; +import android.os.BatteryStats; import android.os.Binder; +import android.os.Bundle; import android.os.DropBoxManager; import android.os.FileUtils; import android.os.Handler; @@ -54,8 +45,12 @@ import android.os.IBatteryPropertiesListener; import android.os.IBatteryPropertiesRegistrar; import android.os.IBinder; import android.os.OsProtoEnums; +import android.os.PowerManager; import android.os.RemoteException; +import android.os.ResultReceiver; import android.os.ServiceManager; +import android.os.ShellCallback; +import android.os.ShellCommand; import android.os.SystemClock; import android.os.Trace; import android.os.UEventObserver; @@ -67,12 +62,19 @@ import android.util.MutableInt; import android.util.Slog; import android.util.proto.ProtoOutputStream; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.IBatteryStats; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.util.DumpUtils; +import com.android.server.am.BatteryStatsService; +import com.android.server.lights.Light; +import com.android.server.lights.LightsManager; + import java.io.File; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; - import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -171,6 +173,9 @@ public final class BatteryService extends SystemService { private long mDischargeStartTime; private int mDischargeStartLevel; + private long mChargeStartTime; + private int mChargeStartLevel; + private boolean mUpdatesStopped; private Led mLed; @@ -185,6 +190,8 @@ public final class BatteryService extends SystemService { private ArrayDeque<Bundle> mBatteryLevelsEventQueue; private long mLastBatteryLevelChangedSentMs; + private MetricsLogger mMetricsLogger; + public BatteryService(Context context) { super(context); @@ -204,6 +211,7 @@ public final class BatteryService extends SystemService { com.android.internal.R.integer.config_shutdownBatteryTemperature); mBatteryLevelsEventQueue = new ArrayDeque<>(); + mMetricsLogger = new MetricsLogger(); // watch for invalid charger messages if the invalid_charger switch exists if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) { @@ -476,6 +484,15 @@ public final class BatteryService extends SystemService { if (mPlugType != mLastPlugType) { if (mLastPlugType == BATTERY_PLUGGED_NONE) { // discharging -> charging + mChargeStartLevel = mHealthInfo.batteryLevel; + mChargeStartTime = SystemClock.elapsedRealtime(); + + final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE); + builder.setType(MetricsEvent.TYPE_ACTION); + builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mPlugType); + builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START, + mHealthInfo.batteryLevel); + mMetricsLogger.write(builder); // There's no value in this data unless we've discharged at least once and the // battery level has changed; so don't log until it does. @@ -491,6 +508,21 @@ public final class BatteryService extends SystemService { // charging -> discharging or we just powered up mDischargeStartTime = SystemClock.elapsedRealtime(); mDischargeStartLevel = mHealthInfo.batteryLevel; + + long chargeDuration = SystemClock.elapsedRealtime() - mChargeStartTime; + if (mChargeStartTime != 0 && chargeDuration != 0) { + final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE); + builder.setType(MetricsEvent.TYPE_DISMISS); + builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mLastPlugType); + builder.addTaggedData(MetricsEvent.FIELD_CHARGING_DURATION_MILLIS, + chargeDuration); + builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START, + mChargeStartLevel); + builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_END, + mHealthInfo.batteryLevel); + mMetricsLogger.write(builder); + } + mChargeStartTime = 0; } } if (mHealthInfo.batteryStatus != mLastBatteryStatus || diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 2c0e97eae537..aa426d3cd31f 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -762,26 +762,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } /** - * Action taken when GattService is turned on + * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on. */ - private void onBluetoothGattServiceUp() { + private void continueFromBleOnState() { if (DBG) { - Slog.d(TAG, "BluetoothGatt Service is Up"); + Slog.d(TAG, "continueFromBleOnState()"); } try { mBluetoothLock.readLock().lock(); if (mBluetooth == null) { - if (DBG) { - Slog.w(TAG, "onBluetoothServiceUp: mBluetooth is null!"); - } - return; - } - int st = mBluetooth.getState(); - if (st != BluetoothAdapter.STATE_BLE_ON) { - if (DBG) { - Slog.v(TAG, "onBluetoothServiceUp: state isn't BLE_ON: " - + BluetoothAdapter.nameForState(st)); - } + Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!"); return; } if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) { @@ -1637,7 +1627,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { mBluetoothGatt = IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service)); - onBluetoothGattServiceUp(); + continueFromBleOnState(); break; } // else must be SERVICE_IBLUETOOTH @@ -2054,21 +2044,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (DBG) { Slog.d(TAG, "Bluetooth is in LE only mode"); } - if (mBluetoothGatt != null) { - if (DBG) { - Slog.d(TAG, "Calling BluetoothGattServiceUp"); - } - onBluetoothGattServiceUp(); + if (mBluetoothGatt != null || !mContext.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { + continueFromBleOnState(); } else { if (DBG) { Slog.d(TAG, "Binding Bluetooth GATT service"); } - if (mContext.getPackageManager() - .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { - Intent i = new Intent(IBluetoothGatt.class.getName()); - doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, - UserHandle.CURRENT); - } + Intent i = new Intent(IBluetoothGatt.class.getName()); + doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, + UserHandle.CURRENT); } sendBleStateChanged(prevState, newState); //Don't broadcase this as std intent diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 27eae57302b0..698b6f7d99f2 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -800,6 +800,20 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } } + /** + * See {@link DisplayWindowController#deferUpdateImeTarget()} + */ + public void deferUpdateImeTarget() { + mWindowContainerController.deferUpdateImeTarget(); + } + + /** + * See {@link DisplayWindowController#deferUpdateImeTarget()} + */ + public void continueUpdateImeTarget() { + mWindowContainerController.continueUpdateImeTarget(); + } + public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size()); final String myPrefix = prefix + " "; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 48090f215921..f83d9e657e1c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -20722,7 +20722,7 @@ public class ActivityManagerService extends IActivityManager.Stub // BROADCASTS // ========================================================= - private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) { + private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) { if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) { return false; } @@ -20731,13 +20731,17 @@ public class ActivityManagerService extends IActivityManager.Stub return record.info.isInstantApp(); } // Otherwise check with PackageManager. - if (callerPackage == null) { - Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name"); - throw new IllegalArgumentException("Calling application did not provide package name"); - } - mAppOpsService.checkPackage(uid, callerPackage); + IPackageManager pm = AppGlobals.getPackageManager(); try { - IPackageManager pm = AppGlobals.getPackageManager(); + if (callerPackage == null) { + final String[] packageNames = pm.getPackagesForUid(uid); + if (packageNames == null || packageNames.length == 0) { + throw new IllegalArgumentException("Unable to determine caller package name"); + } + // Instant Apps can't use shared uids, so its safe to only check the first package. + callerPackage = packageNames[0]; + } + mAppOpsService.checkPackage(uid, callerPackage); return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid)); } catch (RemoteException e) { Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index a85df03e97f6..c18250272b7e 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -639,6 +639,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // so that the divider matches and remove this logic. // TODO: This is currently only called when entering split-screen while in another // task, and from the tests + // TODO (b/78247419): Check if launcher and overview are same then move home stack + // instead of recents stack. Then fix the rotation animation from fullscreen to + // minimized mode final ActivityStack recentStack = display.getOrCreateStack( WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS, true /* onTop */); @@ -4592,46 +4595,58 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } - // Shift all activities with this task up to the top - // of the stack, keeping them in the same internal order. - insertTaskAtTop(tr, null); - - // Don't refocus if invisible to current user - final ActivityRecord top = tr.getTopActivity(); - if (top == null || !top.okToShowLocked()) { - if (top != null) { - mStackSupervisor.mRecentTasks.add(top.getTask()); + try { + // Defer updating the IME target since the new IME target will try to get computed + // before updating all closing and opening apps, which can cause the ime target to + // get calculated incorrectly. + getDisplay().deferUpdateImeTarget(); + + // Shift all activities with this task up to the top + // of the stack, keeping them in the same internal order. + insertTaskAtTop(tr, null); + + // Don't refocus if invisible to current user + final ActivityRecord top = tr.getTopActivity(); + if (top == null || !top.okToShowLocked()) { + if (top != null) { + mStackSupervisor.mRecentTasks.add(top.getTask()); + } + ActivityOptions.abort(options); + return; } - ActivityOptions.abort(options); - return; - } - // Set focus to the top running activity of this stack. - final ActivityRecord r = topRunningActivityLocked(); - mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason); + // Set focus to the top running activity of this stack. + final ActivityRecord r = topRunningActivityLocked(); + mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason); - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); - if (noAnimation) { - mWindowManager.prepareAppTransition(TRANSIT_NONE, false); - if (r != null) { - mStackSupervisor.mNoAnimActivities.add(r); + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); + if (noAnimation) { + mWindowManager.prepareAppTransition(TRANSIT_NONE, false); + if (r != null) { + mStackSupervisor.mNoAnimActivities.add(r); + } + ActivityOptions.abort(options); + } else { + updateTransitLocked(TRANSIT_TASK_TO_FRONT, options); } - ActivityOptions.abort(options); - } else { - updateTransitLocked(TRANSIT_TASK_TO_FRONT, options); - } - // If a new task is moved to the front, then mark the existing top activity as supporting - // picture-in-picture while paused only if the task would not be considered an oerlay on top - // of the current activity (eg. not fullscreen, or the assistant) - if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */, - options)) { - topActivity.supportsEnterPipOnTaskSwitch = true; - } + // If a new task is moved to the front, then mark the existing top activity as + // supporting - mStackSupervisor.resumeFocusedStackTopActivityLocked(); - EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); + // picture-in-picture while paused only if the task would not be considered an oerlay + // on top + // of the current activity (eg. not fullscreen, or the assistant) + if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */, + options)) { + topActivity.supportsEnterPipOnTaskSwitch = true; + } - mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); + EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); + + mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId); + } finally { + getDisplay().continueUpdateImeTarget(); + } } /** diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index a5dfd8c6c6bd..d194db374102 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1224,7 +1224,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) { final ActivityStack focusedStack = mFocusedStack; ActivityRecord r = focusedStack.topRunningActivityLocked(); - if (r != null) { + if (r != null && isValidTopRunningActivity(r, considerKeyguardState)) { return r; } @@ -1257,12 +1257,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D continue; } - final boolean keyguardLocked = getKeyguardController().isKeyguardLocked(); // This activity can be considered the top running activity if we are not // considering the locked state, the keyguard isn't locked, or we can show when // locked. - if (!considerKeyguardState || !keyguardLocked || topActivity.canShowWhenLocked()) { + if (isValidTopRunningActivity(topActivity, considerKeyguardState)) { return topActivity; } } @@ -1270,6 +1269,25 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return null; } + /** + * Verifies an {@link ActivityRecord} can be the top activity based on keyguard state and + * whether we are considering it. + */ + private boolean isValidTopRunningActivity(ActivityRecord record, + boolean considerKeyguardState) { + if (!considerKeyguardState) { + return true; + } + + final boolean keyguardLocked = getKeyguardController().isKeyguardLocked(); + + if (!keyguardLocked) { + return true; + } + + return record.canShowWhenLocked(); + } + @VisibleForTesting void getRunningTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode, diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java index 5e29d10908ca..bbdc9248a256 100644 --- a/services/core/java/com/android/server/am/ActivityStartController.java +++ b/services/core/java/com/android/server/am/ActivityStartController.java @@ -339,7 +339,8 @@ public class ActivityStartController { // Collect information about the target of the Intent. ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, - null, userId, realCallingUid); + null, userId, ActivityStarter.computeResolveFilterUid( + callingUid, realCallingUid)); // TODO: New, check if this is correct aInfo = mService.getActivityInfoForUser(aInfo, userId); diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 3b18d3258237..bbf6e6cffee2 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -791,7 +791,8 @@ class ActivityStarter { callingUid = realCallingUid; callingPid = realCallingPid; - rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0, realCallingUid); + rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0, + computeResolveFilterUid(callingUid, realCallingUid)); aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/); @@ -955,6 +956,16 @@ class ActivityStarter { final int realCallingPid = Binder.getCallingPid(); final int realCallingUid = Binder.getCallingUid(); + int callingPid; + if (callingUid >= 0) { + callingPid = -1; + } else if (caller == null) { + callingPid = realCallingPid; + callingUid = realCallingUid; + } else { + callingPid = callingUid = -1; + } + // Save a copy in case ephemeral needs it final Intent ephemeralIntent = new Intent(intent); // Don't modify the client's object! @@ -973,7 +984,7 @@ class ActivityStarter { } ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, - 0 /* matchFlags */, realCallingUid); + 0 /* matchFlags */, computeResolveFilterUid(callingUid, realCallingUid)); if (rInfo == null) { UserInfo userInfo = mSupervisor.getUserInfo(userId); if (userInfo != null && userInfo.isManagedProfile()) { @@ -995,7 +1006,7 @@ class ActivityStarter { rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - realCallingUid); + computeResolveFilterUid(callingUid, realCallingUid)); } } } @@ -1003,16 +1014,6 @@ class ActivityStarter { ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); synchronized (mService) { - int callingPid; - if (callingUid >= 0) { - callingPid = -1; - } else if (caller == null) { - callingPid = realCallingPid; - callingUid = realCallingUid; - } else { - callingPid = callingUid = -1; - } - final ActivityStack stack = mSupervisor.mFocusedStack; stack.mConfigWillChange = globalConfig != null && mService.getGlobalConfiguration().diff(globalConfig) != 0; @@ -1077,7 +1078,8 @@ class ActivityStarter { callingPid = Binder.getCallingPid(); componentSpecified = true; rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId, - 0 /* matchFlags */, realCallingUid); + 0 /* matchFlags */, computeResolveFilterUid(callingUid, + realCallingUid)); aInfo = rInfo != null ? rInfo.activityInfo : null; if (aInfo != null) { aInfo = mService.getActivityInfoForUser(aInfo, userId); @@ -1164,6 +1166,19 @@ class ActivityStarter { } } + /** + * Compute the logical UID based on which the package manager would filter + * app components i.e. based on which the instant app policy would be applied + * because it is the logical calling UID. + * + * @param customCallingUid The UID on whose behalf to make the call. + * @param actualCallingUid The UID actually making the call. + * @return The logical UID making the call. + */ + static int computeResolveFilterUid(int customCallingUid, int actualCallingUid) { + return customCallingUid >= 0 ? customCallingUid : actualCallingUid; + } + private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 8ad8256225d0..18c095725b09 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -64,6 +64,7 @@ import android.os.IBinder; import android.os.IProgressListener; import android.os.IRemoteCallback; import android.os.IUserManager; +import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteCallbackList; @@ -962,6 +963,11 @@ class UserController implements Handler.Callback { updateStartedUserArrayLU(); needStart = true; updateUmState = true; + } else if (uss.state == UserState.STATE_SHUTDOWN && !isCallingOnHandlerThread()) { + Slog.i(TAG, "User #" + userId + + " is shutting down - will start after full stop"); + mHandler.post(() -> startUser(userId, foreground, unlockListener)); + return true; } final Integer userIdInt = userId; mUserLru.remove(userIdInt); @@ -1086,6 +1092,10 @@ class UserController implements Handler.Callback { return true; } + private boolean isCallingOnHandlerThread() { + return Looper.myLooper() == mHandler.getLooper(); + } + /** * Start user, if its not already running, and bring it to foreground. */ diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 03d8f395e36e..d7057f45e135 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -166,7 +166,7 @@ public final class ContentService extends IContentService.Stub { private SyncManager getSyncManager() { synchronized(mSyncManagerLock) { try { - // Try to create the SyncManager, return null if it fails (e.g. the disk is full). + // Try to create the SyncManager, return null if it fails (which it shouldn't). if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest); } catch (SQLiteException e) { Log.e(TAG, "Can't create SyncManager", e); @@ -199,7 +199,7 @@ public final class ContentService extends IContentService.Stub { final long identityToken = clearCallingIdentity(); try { if (mSyncManager == null) { - pw.println("No SyncManager created! (Disk full?)"); + pw.println("SyncManager not available yet"); } else { mSyncManager.dump(fd, pw, dumpAll); } diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java index 9980930d87c8..089632dbe01c 100644 --- a/services/core/java/com/android/server/content/SyncJobService.java +++ b/services/core/java/com/android/server/content/SyncJobService.java @@ -115,7 +115,10 @@ public class SyncJobService extends JobService { Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: " + params.getStopReason()); } - mLogger.log("onStopJob() ", mLogger.jobParametersToString(params)); + final boolean readyToSync = SyncManager.readyToSync(); + + mLogger.log("onStopJob() ", mLogger.jobParametersToString(params), + " readyToSync=", readyToSync); synchronized (mLock) { final int jobId = params.getJobId(); mJobParamsMap.remove(jobId); @@ -124,13 +127,15 @@ public class SyncJobService extends JobService { final long nowUptime = SystemClock.uptimeMillis(); final long runtime = nowUptime - startUptime; + if (startUptime == 0) { wtf("Job " + jobId + " start uptime not found: " + " params=" + jobParametersToString(params)); } else if (runtime > 60 * 1000) { // WTF if startSyncH() hasn't happened, *unless* onStopJob() was called too soon. // (1 minute threshold.) - if (!mStartedSyncs.get(jobId)) { + // Also don't wtf when it's not ready to sync. + if (readyToSync && !mStartedSyncs.get(jobId)) { wtf("Job " + jobId + " didn't start: " + " startUptime=" + startUptime + " nowUptime=" + nowUptime diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 5fa42457ac2f..33cf11b86650 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -91,6 +91,7 @@ import android.util.Pair; import android.util.Slog; import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; @@ -215,6 +216,10 @@ public class SyncManager { private static final int SYNC_ADAPTER_CONNECTION_FLAGS = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_ALLOW_OOM_MANAGEMENT; + /** Singleton instance. */ + @GuardedBy("SyncManager.class") + private static SyncManager sInstance; + private Context mContext; private static final AccountAndUser[] INITIAL_ACCOUNTS_ARRAY = new AccountAndUser[0]; @@ -571,6 +576,14 @@ public class SyncManager { } public SyncManager(Context context, boolean factoryTest) { + synchronized (SyncManager.class) { + if (sInstance == null) { + sInstance = this; + } else { + Slog.wtf(TAG, "SyncManager instantiated multiple times"); + } + } + // Initialize the SyncStorageEngine first, before registering observers // and creating threads and so on; it may fail if the disk is full. mContext = context; @@ -2851,6 +2864,16 @@ public class SyncManager { } /** + * @return whether the device is ready to run sync jobs. + */ + public static boolean readyToSync() { + synchronized (SyncManager.class) { + return sInstance != null && sInstance.mProvisioned && sInstance.mBootCompleted + && sInstance.mJobServiceReady; + } + } + + /** * Handles SyncOperation Messages that are posted to the associated * HandlerThread. */ diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 658c7f179691..669d5565534d 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -508,6 +508,8 @@ public class ZenModeHelper { public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) { setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/); + Settings.Global.putInt(mContext.getContentResolver(), Global.SHOW_ZEN_SETTINGS_SUGGESTION, + 0); } private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller, @@ -635,6 +637,10 @@ public class ZenModeHelper { appendDefaultRules(config); reason += ", reset to default rules"; } + } else { + // devices not restoring/upgrading already have updated zen settings + Settings.Global.putInt(mContext.getContentResolver(), + Global.ZEN_SETTINGS_UPDATED, 1); } if (DEBUG) Log.d(TAG, reason); synchronized (mConfig) { @@ -813,6 +819,12 @@ public class ZenModeHelper { for (ZenRule automaticRule : mConfig.automaticRules.values()) { if (automaticRule.isAutomaticActive()) { if (zenSeverity(automaticRule.zenMode) > zenSeverity(zen)) { + // automatic rule triggered dnd and user hasn't seen update dnd dialog + if (Settings.Global.getInt(mContext.getContentResolver(), + Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1) == 0) { + Settings.Global.putInt(mContext.getContentResolver(), + Global.SHOW_ZEN_SETTINGS_SUGGESTION, 1); + } zen = automaticRule.zenMode; } } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index a6dfec7821b6..f082271ab094 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -389,16 +389,11 @@ public final class OverlayManagerService extends SystemService { final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, false); if (pi != null) { - /* - * Only update overlay settings when an overlay becomes enabled or disabled. - * Enabling or disabling components of a target should not change the - * target's overlays. Since, overlays do not have components, this will only - * update overlay settings if an overlay package becomes enabled or - * disabled. - */ mPackageManager.cachePackageInfo(packageName, userId, pi); if (pi.isOverlayPackage()) { mImpl.onOverlayPackageChanged(packageName, userId); + } else { + mImpl.onTargetPackageChanged(packageName, userId); } } } diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index bb36ab189765..112059daf95e 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -18,6 +18,7 @@ package com.android.server.om; import static android.content.om.OverlayInfo.STATE_DISABLED; import static android.content.om.OverlayInfo.STATE_ENABLED; +import static android.content.om.OverlayInfo.STATE_ENABLED_STATIC; import static android.content.om.OverlayInfo.STATE_MISSING_TARGET; import static android.content.om.OverlayInfo.STATE_NO_IDMAP; import static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING; @@ -63,6 +64,38 @@ final class OverlayManagerServiceImpl { private final String[] mDefaultOverlays; private final OverlayChangeListener mListener; + /** + * Helper method to merge the overlay manager's (as read from overlays.xml) + * and package manager's (as parsed from AndroidManifest.xml files) views + * on overlays. + * + * Both managers are usually in agreement, but especially after an OTA things + * may differ. The package manager is always providing the truth; the overlay + * manager has to adapt. Depending on what has changed about an overlay, we + * should either scrap the overlay manager's previous settings or merge the old + * settings with the new. + */ + private static boolean mustReinitializeOverlay(@NonNull final PackageInfo theTruth, + @Nullable final OverlayInfo oldSettings) { + if (oldSettings == null) { + return true; + } + if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) { + return true; + } + if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) { + return true; + } + // a change in priority is only relevant for static RROs: specifically, + // a regular RRO should not have its state reset only because a change + // in priority + if (theTruth.isStaticOverlayPackage() && + theTruth.overlayPriority != oldSettings.priority) { + return true; + } + return false; + } + OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager, @NonNull final IdmapManager idmapManager, @NonNull final OverlayManagerSettings settings, @@ -99,42 +132,29 @@ final class OverlayManagerServiceImpl { } } + // Reset overlays if something critical like the target package name + // has changed List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId); final int overlayPackagesSize = overlayPackages.size(); for (int i = 0; i < overlayPackagesSize; i++) { final PackageInfo overlayPackage = overlayPackages.get(i); final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName); - if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) { - // Reset the overlay if it didn't exist or had the wrong target package. + + if (mustReinitializeOverlay(overlayPackage, oi)) { + // if targetPackageName has changed the package that *used* to + // be the target must also update its assets + if (oi != null) { + packagesToUpdateAssets.add(oi.targetPackageName); + } + mSettings.init(overlayPackage.packageName, newUserId, overlayPackage.overlayTarget, overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, overlayPackage.overlayCategory); - - if (oi != null) { - // The targetPackageName we have stored doesn't match the overlay's target. - // Queue the old target for an update as well. - packagesToUpdateAssets.add(oi.targetPackageName); - } - } else { - // Update all other components of an overlay that don't require a hard reset. - if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) { - // When changing categories, it is ok just to update our internal state. - mSettings.setCategory(overlayPackage.packageName, newUserId, - overlayPackage.overlayCategory); - } - } - - try { - updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0); - } catch (OverlayManagerSettings.BadKeyException e) { - Slog.e(TAG, "failed to update settings", e); - mSettings.remove(overlayPackage.packageName, newUserId); } - packagesToUpdateAssets.add(overlayPackage.overlayTarget); storedOverlayInfos.remove(overlayPackage.packageName); } @@ -148,6 +168,22 @@ final class OverlayManagerServiceImpl { packagesToUpdateAssets.add(oi.targetPackageName); } + // make sure every overlay's state is up-to-date; this needs to happen + // after old overlays have been removed, or we risk removing a + // legitimate idmap file if a new overlay package has the same apk path + // as the removed overlay package used to have + for (int i = 0; i < overlayPackagesSize; i++) { + final PackageInfo overlayPackage = overlayPackages.get(i); + try { + updateState(overlayPackage.overlayTarget, overlayPackage.packageName, + newUserId, 0); + } catch (OverlayManagerSettings.BadKeyException e) { + Slog.e(TAG, "failed to update settings", e); + mSettings.remove(overlayPackage.packageName, newUserId); + } + packagesToUpdateAssets.add(overlayPackage.overlayTarget); + } + // remove target packages that are not installed final Iterator<String> iter = packagesToUpdateAssets.iterator(); while (iter.hasNext()) { @@ -212,15 +248,21 @@ final class OverlayManagerServiceImpl { } } + void onTargetPackageChanged(@NonNull final String packageName, final int userId) { + if (DEBUG) { + Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId); + } + + updateAllOverlaysForTarget(packageName, userId, 0); + } + void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) { if (DEBUG) { Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" + userId); } - if (updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING)) { - mListener.onOverlaysChanged(packageName, userId); - } + updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING); } void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) { @@ -228,9 +270,7 @@ final class OverlayManagerServiceImpl { Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId); } - if (updateAllOverlaysForTarget(packageName, userId, 0)) { - mListener.onOverlaysChanged(packageName, userId); - } + updateAllOverlaysForTarget(packageName, userId, 0); } void onTargetPackageRemoved(@NonNull final String packageName, final int userId) { @@ -351,15 +391,13 @@ final class OverlayManagerServiceImpl { try { final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId); - if (!oldOi.targetPackageName.equals(pkg.overlayTarget)) { + if (mustReinitializeOverlay(pkg, oldOi)) { + if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) { + mListener.onOverlaysChanged(pkg.overlayTarget, userId); + } mSettings.init(packageName, userId, pkg.overlayTarget, pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(), pkg.overlayPriority, pkg.overlayCategory); - } else { - if (!Objects.equals(oldOi.category, pkg.overlayCategory)) { - // Update the category in-place. - mSettings.setCategory(packageName, userId, pkg.overlayCategory); - } } if (updateState(pkg.overlayTarget, packageName, userId, 0)) { @@ -604,6 +642,8 @@ final class OverlayManagerServiceImpl { if (overlayPackage != null) { modified |= mSettings.setBaseCodePath(overlayPackageName, userId, overlayPackage.applicationInfo.getBaseCodePath()); + modified |= mSettings.setCategory(overlayPackageName, userId, + overlayPackage.overlayCategory); } final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId); @@ -646,6 +686,10 @@ final class OverlayManagerServiceImpl { return STATE_NO_IDMAP; } + if (overlayPackage.isStaticOverlayPackage()) { + return STATE_ENABLED_STATIC; + } + final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId); return enabled ? STATE_ENABLED : STATE_DISABLED; } @@ -688,6 +732,11 @@ final class OverlayManagerServiceImpl { } interface OverlayChangeListener { + + /** + * An event triggered by changes made to overlay state or settings as well as changes that + * add or remove target packages of overlays. + **/ void onOverlaysChanged(@NonNull String targetPackage, int userId); } diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index e176351fcb76..36bf83dfe92c 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -309,6 +309,7 @@ final class OverlayManagerSettings { pw.print("mState.............: "); pw.println(OverlayInfo.stateToString(item.getState())); pw.print("mIsEnabled.........: "); pw.println(item.isEnabled()); pw.print("mIsStatic..........: "); pw.println(item.isStatic()); + pw.print("mPriority..........: "); pw.println(item.mPriority); pw.print("mCategory..........: "); pw.println(item.mCategory); pw.decreaseIndent(); @@ -528,7 +529,7 @@ final class OverlayManagerSettings { private OverlayInfo getOverlayInfo() { if (mCache == null) { mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath, - mState, mUserId); + mState, mUserId, mPriority, mIsStatic); } return mCache; } diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java index 54bb115c5405..d576d330c4a8 100644 --- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java +++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java @@ -126,6 +126,7 @@ final class OverlayManagerShellCommand extends ShellCommand { final OverlayInfo oi = overlaysForTarget.get(i); String status; switch (oi.state) { + case OverlayInfo.STATE_ENABLED_STATIC: case OverlayInfo.STATE_ENABLED: status = "[x]"; break; diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java index d0a3757be04d..9a5dd5e04b07 100644 --- a/services/core/java/com/android/server/pm/InstantAppResolver.java +++ b/services/core/java/com/android/server/pm/InstantAppResolver.java @@ -47,7 +47,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.RemoteException; -import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -164,6 +163,11 @@ public abstract class InstantAppResolver { Log.d(TAG, "[" + token + "] Phase1; No results matched"); } } + // if the match external flag is set, return an empty resolve info instead of a null result. + if (resolveInfo == null && (origIntent.getFlags() & FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) { + return new AuxiliaryResolveInfo(token, false, createFailureIntent(origIntent, token), + null /* filters */); + } return resolveInfo; } @@ -365,23 +369,20 @@ public abstract class InstantAppResolver { InstantAppDigest digest, String token) { final int[] shaPrefix = digest.getDigestPrefix(); final byte[][] digestBytes = digest.getDigestBytes(); - final Intent failureIntent = new Intent(origIntent); boolean requiresSecondPhase = false; - failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL); - failureIntent.setFlags(failureIntent.getFlags() & ~Intent.FLAG_ACTIVITY_MATCH_EXTERNAL); - failureIntent.setLaunchToken(token); ArrayList<AuxiliaryResolveInfo.AuxiliaryFilter> filters = null; - boolean isWebIntent = origIntent.isWebIntent(); + boolean requiresPrefixMatch = origIntent.isWebIntent() || (shaPrefix.length > 0 + && (origIntent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0); for (InstantAppResolveInfo instantAppResolveInfo : instantAppResolveInfoList) { - if (shaPrefix.length > 0 && instantAppResolveInfo.shouldLetInstallerDecide()) { - Slog.e(TAG, "InstantAppResolveInfo with mShouldLetInstallerDecide=true when digest" - + " provided; ignoring"); + if (requiresPrefixMatch && instantAppResolveInfo.shouldLetInstallerDecide()) { + Slog.d(TAG, "InstantAppResolveInfo with mShouldLetInstallerDecide=true when digest" + + " required; ignoring"); continue; } byte[] filterDigestBytes = instantAppResolveInfo.getDigestBytes(); // Only include matching digests if we have a prefix and we're either dealing with a - // web intent or the resolveInfo specifies digest details. - if (shaPrefix.length > 0 && (isWebIntent || filterDigestBytes.length > 0)) { + // prefixed request or the resolveInfo specifies digest details. + if (shaPrefix.length > 0 && (requiresPrefixMatch || filterDigestBytes.length > 0)) { boolean matchFound = false; // Go in reverse order so we match the narrowest scope first. for (int i = shaPrefix.length - 1; i >= 0; --i) { @@ -409,17 +410,26 @@ public abstract class InstantAppResolver { } } if (filters != null && !filters.isEmpty()) { - return new AuxiliaryResolveInfo(token, requiresSecondPhase, failureIntent, filters); - } - // if the match external flag is set, return an empty resolve info - if ((origIntent.getFlags() & FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) { - return new AuxiliaryResolveInfo(token, false, failureIntent, null /* filters */); + return new AuxiliaryResolveInfo(token, requiresSecondPhase, + createFailureIntent(origIntent, token), filters); } // Hash or filter mis-match; no instant apps for this domain. return null; } /** + * Creates a failure intent for the installer to send in the case that the instant app cannot be + * launched for any reason. + */ + private static Intent createFailureIntent(Intent origIntent, String token) { + final Intent failureIntent = new Intent(origIntent); + failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL); + failureIntent.setFlags(failureIntent.getFlags() & ~Intent.FLAG_ACTIVITY_MATCH_EXTERNAL); + failureIntent.setLaunchToken(token); + return failureIntent; + } + + /** * Returns one of three states: <p/> * <ul> * <li>{@code null} if there are no matches will not be; resolution is unnecessary.</li> diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 0070ca42d46c..36fc1202006f 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -449,9 +449,10 @@ public class PermissionManagerService { userId) == PackageManager.PERMISSION_GRANTED) { EventLog.writeEvent(0x534e4554, "72710897", newPackage.applicationInfo.uid, - "Revoking permission", permissionName, "from package", - packageName, "as the group changed from", - oldPermissionGroupName, "to", newPermissionGroupName); + "Revoking permission " + permissionName + + " from package " + packageName + + " as the group changed from " + oldPermissionGroupName + + " to " + newPermissionGroupName); try { revokeRuntimePermission(permissionName, packageName, false, diff --git a/services/core/java/com/android/server/policy/IconUtilities.java b/services/core/java/com/android/server/policy/IconUtilities.java index b196dec93686..884d7d497a8f 100644 --- a/services/core/java/com/android/server/policy/IconUtilities.java +++ b/services/core/java/com/android/server/policy/IconUtilities.java @@ -16,6 +16,8 @@ package com.android.server.policy; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrixColorFilter; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.PaintDrawable; @@ -38,24 +40,17 @@ import android.content.Context; * Various utilities shared amongst the Launcher's classes. */ public final class IconUtilities { - private static final String TAG = "IconUtilities"; - - private static final int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; private int mIconWidth = -1; private int mIconHeight = -1; private int mIconTextureWidth = -1; private int mIconTextureHeight = -1; - private final Paint mPaint = new Paint(); - private final Paint mBlurPaint = new Paint(); - private final Paint mGlowColorPressedPaint = new Paint(); - private final Paint mGlowColorFocusedPaint = new Paint(); private final Rect mOldBounds = new Rect(); private final Canvas mCanvas = new Canvas(); private final DisplayMetrics mDisplayMetrics; - private int mColorIndex = 0; + private ColorFilter mDisabledColorFilter; public IconUtilities(Context context) { final Resources resources = context.getResources(); @@ -65,39 +60,10 @@ public final class IconUtilities { mIconWidth = mIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size); mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2); - - mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL)); - - TypedValue value = new TypedValue(); - mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute( - android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300); - mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); - mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute( - android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00); - mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); - - ColorMatrix cm = new ColorMatrix(); - cm.setSaturation(0.2f); - mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG)); } - public Drawable createIconDrawable(Drawable src) { - Bitmap scaled = createIconBitmap(src); - - StateListDrawable result = new StateListDrawable(); - - result.addState(new int[] { android.R.attr.state_focused }, - new BitmapDrawable(createSelectedBitmap(scaled, false))); - result.addState(new int[] { android.R.attr.state_pressed }, - new BitmapDrawable(createSelectedBitmap(scaled, true))); - result.addState(new int[0], new BitmapDrawable(scaled)); - - result.setBounds(0, 0, mIconTextureWidth, mIconTextureHeight); - return result; - } - /** * Returns a bitmap suitable for the all apps view. The bitmap will be a power * of two sized ARGB_8888 bitmap that can be used as a gl texture. @@ -150,15 +116,6 @@ public final class IconUtilities { final int left = (textureWidth-width) / 2; final int top = (textureHeight-height) / 2; - if (false) { - // draw a big box for the icon for debugging - canvas.drawColor(sColors[mColorIndex]); - if (++mColorIndex >= sColors.length) mColorIndex = 0; - Paint debugPaint = new Paint(); - debugPaint.setColor(0xffcccc00); - canvas.drawRect(left, top, left+width, top+height, debugPaint); - } - mOldBounds.set(icon.getBounds()); icon.setBounds(left, top, left+width, top+height); icon.draw(canvas); @@ -167,24 +124,28 @@ public final class IconUtilities { return bitmap; } - private Bitmap createSelectedBitmap(Bitmap src, boolean pressed) { - final Bitmap result = Bitmap.createBitmap(mIconTextureWidth, mIconTextureHeight, - Bitmap.Config.ARGB_8888); - final Canvas dest = new Canvas(result); - - dest.drawColor(0, PorterDuff.Mode.CLEAR); - - int[] xy = new int[2]; - Bitmap mask = src.extractAlpha(mBlurPaint, xy); - - dest.drawBitmap(mask, xy[0], xy[1], - pressed ? mGlowColorPressedPaint : mGlowColorFocusedPaint); - - mask.recycle(); - - dest.drawBitmap(src, 0, 0, mPaint); - dest.setBitmap(null); - - return result; + public ColorFilter getDisabledColorFilter() { + if (mDisabledColorFilter != null) { + return mDisabledColorFilter; + } + ColorMatrix brightnessMatrix = new ColorMatrix(); + float brightnessF = 0.5f; + int brightnessI = (int) (255 * brightnessF); + // Brightness: C-new = C-old*(1-amount) + amount + float scale = 1f - brightnessF; + float[] mat = brightnessMatrix.getArray(); + mat[0] = scale; + mat[6] = scale; + mat[12] = scale; + mat[4] = brightnessI; + mat[9] = brightnessI; + mat[14] = brightnessI; + + ColorMatrix filterMatrix = new ColorMatrix(); + filterMatrix.setSaturation(0); + filterMatrix.preConcat(brightnessMatrix); + + mDisabledColorFilter = new ColorMatrixColorFilter(filterMatrix); + return mDisabledColorFilter; } } diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java index cfce5cfdd801..c04c1fb4f786 100644 --- a/services/core/java/com/android/server/power/BatterySaverPolicy.java +++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java @@ -310,6 +310,11 @@ public class BatterySaverPolicy extends ContentObserver { return R.string.config_batterySaverDeviceSpecificConfig; } + @VisibleForTesting + boolean isAccessibilityEnabled() { + return mAccessibilityManager.isEnabled(); + } + @Override public void onChange(boolean selfChange, Uri uri) { refreshSettings(); @@ -403,7 +408,7 @@ public class BatterySaverPolicy extends ContentObserver { parser.getString(KEY_CPU_FREQ_NONINTERACTIVE, "")).toSysFileMap(); // Update the effective policy. - mAccessibilityEnabled = mAccessibilityManager.isEnabled(); + mAccessibilityEnabled = isAccessibilityEnabled(); mVibrationDisabledEffective = mVibrationDisabledConfig && !mAccessibilityEnabled; // Don't disable vibration when accessibility is on. diff --git a/services/core/java/com/android/server/slice/SlicePermissionManager.java b/services/core/java/com/android/server/slice/SlicePermissionManager.java index d25ec89e0057..c67f94b895fc 100644 --- a/services/core/java/com/android/server/slice/SlicePermissionManager.java +++ b/services/core/java/com/android/server/slice/SlicePermissionManager.java @@ -251,6 +251,9 @@ public class SlicePermissionManager implements DirtyTracker { } // Can't read or no permissions exist, create a clean object. client = new SliceClientPermissions(pkgUser, this); + synchronized (mCachedClients) { + mCachedClients.put(pkgUser, client); + } } return client; } @@ -278,6 +281,9 @@ public class SlicePermissionManager implements DirtyTracker { } // Can't read or no permissions exist, create a clean object. provider = new SliceProviderPermissions(pkgUser, this); + synchronized (mCachedProviders) { + mCachedProviders.put(pkgUser, provider); + } } return provider; } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 966ca4104710..e637df4db502 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -17,6 +17,7 @@ package com.android.server.wm; 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_UNDEFINED; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; @@ -31,9 +32,12 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS; +import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static android.view.WindowManager.TRANSIT_UNSET; +import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; @@ -919,10 +923,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } void detachChildren() { + SurfaceControl.openTransaction(); for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowState w = mChildren.get(i); w.mWinAnimator.detachChildren(); } + SurfaceControl.closeTransaction(); } void finishRelaunching() { @@ -1684,12 +1690,24 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } } + private boolean shouldAnimate(int transit) { + final boolean isSplitScreenPrimary = + getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; + final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN; + + // We animate always if it's not split screen primary, and only some special cases in split + // screen primary because it causes issues with stack clipping when we run an un-minimize + // animation at the same time. + return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation; + } + boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter, boolean isVoiceInteraction) { - if (mService.mDisableTransitionAnimation) { + if (mService.mDisableTransitionAnimation || !shouldAnimate(transit)) { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { - Slog.v(TAG_WM, "applyAnimation: transition animation is disabled. atoken=" + this); + Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped." + + " atoken=" + this); } cancelAnimation(); return false; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c0dc750949bc..f3423c63e270 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -390,6 +390,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ int mLayoutSeq = 0; + /** + * Specifies the count to determine whether to defer updating the IME target until ready. + */ + private int mDeferUpdateImeTargetCount; + /** Temporary float array to retrieve 3x3 matrix values. */ private final float[] mTmpFloats = new float[9]; @@ -2454,6 +2459,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return null; } + final WindowState curTarget = mService.mInputMethodTarget; + if (!canUpdateImeTarget()) { + if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target"); + return curTarget; + } + // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the // same display. Or even when the current IME/target are not on the same screen as the next // IME/target. For now only look for input windows on the main screen. @@ -2477,16 +2488,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM, "Proposed new IME target: " + target); - // Now, a special case -- if the last target's window is in the process of exiting, and is - // above the new target, keep on the last target to avoid flicker. Consider for example a - // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it - // until it is completely gone so it doesn't drop behind the dialog or its full-screen - // scrim. - final WindowState curTarget = mService.mInputMethodTarget; + // Now, a special case -- if the last target's window is in the process of exiting, and the + // new target is home, keep on the last target to avoid flicker. Home is a special case + // since its above other stacks in the ordering list, but layed out below the others. if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing() - && (target == null - || curTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer)) { - if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing"); + && (target == null || target.isActivityTypeHome())) { + if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "New target is home while current target is" + + "closing, not changing"); return curTarget; } @@ -3958,4 +3966,33 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void assignStackOrdering() { mTaskStackContainers.assignStackOrdering(getPendingTransaction()); } + + /** + * Increment the deferral count to determine whether to update the IME target. + */ + void deferUpdateImeTarget() { + mDeferUpdateImeTargetCount++; + } + + /** + * Decrement the deferral count to determine whether to update the IME target. If the count + * reaches 0, a new ime target will get computed. + */ + void continueUpdateImeTarget() { + if (mDeferUpdateImeTargetCount == 0) { + return; + } + + mDeferUpdateImeTargetCount--; + if (mDeferUpdateImeTargetCount == 0) { + computeImeTarget(true /* updateImeTarget */); + } + } + + /** + * @return Whether a new IME target should be computed. + */ + private boolean canUpdateImeTarget() { + return mDeferUpdateImeTargetCount == 0; + } } diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java index ba8ec69f3605..a1639c2dd892 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowController.java +++ b/services/core/java/com/android/server/wm/DisplayWindowController.java @@ -94,6 +94,31 @@ public class DisplayWindowController } } + /** + * Starts deferring the ability to update the IME target. This is needed when a call will + * attempt to update the IME target before all information about the Windows have been updated. + */ + public void deferUpdateImeTarget() { + synchronized (mWindowMap) { + final DisplayContent dc = mRoot.getDisplayContent(mDisplayId); + if (dc != null) { + dc.deferUpdateImeTarget(); + } + } + } + + /** + * Resumes updating the IME target after deferring. See {@link #deferUpdateImeTarget()} + */ + public void continueUpdateImeTarget() { + synchronized (mWindowMap) { + final DisplayContent dc = mRoot.getDisplayContent(mDisplayId); + if (dc != null) { + dc.continueUpdateImeTarget(); + } + } + } + @Override public String toString() { return "{DisplayWindowController displayId=" + mDisplayId + "}"; diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 553b4fe53115..27238017bb27 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -366,7 +366,7 @@ public class RecentsAnimationController implements DeathRecipient { && mTargetAppToken.findMainWindow() != null ? mTargetAppToken.findMainWindow().mContentInsets : null; - mRunner.onAnimationStart_New(mController, appTargets, contentInsets, + mRunner.onAnimationStart(mController, appTargets, contentInsets, minimizedHomeBounds); if (DEBUG_RECENTS_ANIMATIONS) { Slog.d(TAG, "startAnimation(): Notify animation start:"); @@ -426,9 +426,13 @@ public class RecentsAnimationController implements DeathRecipient { removeAnimation(taskAdapter); } + // Clear any pending failsafe runnables + mService.mH.removeCallbacks(mFailsafeRunnable); + // Clear references to the runner unlinkToDeathOfRunner(); mRunner = null; + mCanceled = true; // Clear associated input consumers mService.mInputMonitor.updateInputWindowsLw(true /*force*/); @@ -558,14 +562,17 @@ public class RecentsAnimationController implements DeathRecipient { } RemoteAnimationTarget createRemoteAnimationApp() { - final WindowState mainWindow = mTask.getTopVisibleAppMainWindow(); + final AppWindowToken topApp = mTask.getTopVisibleAppToken(); + final WindowState mainWindow = topApp != null + ? topApp.findMainWindow() + : null; if (mainWindow == null) { return null; } final Rect insets = new Rect(mainWindow.mContentInsets); InsetUtils.addInsets(insets, mainWindow.mAppToken.getLetterboxInsets()); mTarget = new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash, - !mTask.fillsParent(), mainWindow.mWinAnimator.mLastClipRect, + !topApp.fillsParent(), mainWindow.mWinAnimator.mLastClipRect, insets, mTask.getPrefixOrderIndex(), mPosition, mBounds, mTask.getWindowConfiguration(), mIsRecentTaskInvisible); return mTarget; diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index efc4e737b92c..f17bbb95cfe1 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -37,6 +37,7 @@ import android.view.DisplayListCanvas; import android.view.RenderNode; import android.view.SurfaceControl; import android.view.ThreadedRenderer; +import android.view.View; import android.view.WindowManager.LayoutParams; import com.android.internal.annotations.VisibleForTesting; @@ -274,7 +275,8 @@ class TaskSnapshotController { } return new TaskSnapshot(buffer, top.getConfiguration().orientation, getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */, - true /* isRealSnapshot */, task.getWindowingMode()); + true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task), + !top.fillsParent()); } private boolean shouldDisableSnapshots() { @@ -364,7 +366,8 @@ class TaskSnapshotController { return new TaskSnapshot(hwBitmap.createGraphicBufferHandle(), topChild.getConfiguration().orientation, mainWindow.mStableInsets, ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */, - false /* isRealSnapshot */, task.getWindowingMode()); + false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task), + !topChild.fillsParent()); } /** @@ -429,6 +432,21 @@ class TaskSnapshotController { }); } + /** + * @return The SystemUI visibility flags for the top fullscreen window in the given + * {@param task}. + */ + private int getSystemUiVisibility(Task task) { + final AppWindowToken topFullscreenToken = task.getTopFullscreenAppToken(); + final WindowState topFullscreenWindow = topFullscreenToken != null + ? topFullscreenToken.getTopFullscreenWindow() + : null; + if (topFullscreenWindow != null) { + return topFullscreenWindow.getSystemUiVisibility(); + } + return 0; + } + void dump(PrintWriter pw, String prefix) { mCache.dump(pw, prefix); } diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java index b682a3262da1..1410c21a1c81 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java @@ -90,7 +90,8 @@ class TaskSnapshotLoader { return new TaskSnapshot(buffer, proto.orientation, new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom), reducedResolution, reducedResolution ? REDUCED_SCALE : 1f, - proto.isRealSnapshot, proto.windowingMode); + proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility, + proto.isTranslucent); } catch (IOException e) { Slog.w(TAG, "Unable to load task snapshot data for taskId=" + taskId); return null; diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java index 408fb3ce36c9..a642e6ab744a 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java @@ -317,6 +317,8 @@ class TaskSnapshotPersister { proto.insetBottom = mSnapshot.getContentInsets().bottom; proto.isRealSnapshot = mSnapshot.isRealSnapshot(); proto.windowingMode = mSnapshot.getWindowingMode(); + proto.systemUiVisibility = mSnapshot.getSystemUiVisibility(); + proto.isTranslucent = mSnapshot.isTranslucent(); final byte[] bytes = TaskSnapshotProto.toByteArray(proto); final File file = getProtoFile(mTaskId, mUserId); final AtomicFile atomicFile = new AtomicFile(file); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c710c9789004..7883e2e63ebb 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2726,7 +2726,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean isClosing() { - return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); + return mAnimatingExit || (mAppToken.isAnimating() && mAppToken.hiddenRequested); } void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) { 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 1415ada5fc92..1ce41a641935 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java @@ -325,13 +325,12 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { } /** - * Verifies the correct activity is returned when querying the top running activity with an - * empty focused stack. + * Verifies the correct activity is returned when querying the top running activity. */ @Test - public void testNonFocusedTopRunningActivity() throws Exception { + public void testTopRunningActivity() throws Exception { // Create stack to hold focus - final ActivityStack focusedStack = mService.mStackSupervisor.getDefaultDisplay() + final ActivityStack emptyStack = mService.mStackSupervisor.getDefaultDisplay() .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); final KeyguardController keyguard = mSupervisor.getKeyguardController(); @@ -340,7 +339,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true) .setStack(stack).build(); - mSupervisor.mFocusedStack = focusedStack; + mSupervisor.mFocusedStack = emptyStack; doAnswer((InvocationOnMock invocationOnMock) -> { final SparseIntArray displayIds = invocationOnMock.<SparseIntArray>getArgument(0); @@ -359,6 +358,12 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked( true /* considerKeyguardState */)); + // Change focus to stack with activity. + mSupervisor.mFocusedStack = stack; + assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked()); + assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked( + true /* considerKeyguardState */)); + // Add activity that should be shown on the keyguard. final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService) .setCreateTask(true) @@ -370,6 +375,13 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked()); assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked( true /* considerKeyguardState */)); + + // Change focus back to empty stack + mSupervisor.mFocusedStack = emptyStack; + // Ensure the show when locked activity is returned when not the focused stack + assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked()); + assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked( + true /* considerKeyguardState */)); } /** diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java index a9d6c29e57ce..90947f44ef2b 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java @@ -503,7 +503,8 @@ public class KeySyncTaskTest { @Test public void run_sendsEncryptedKeysIfAvailableToSync_withRawPublicKey() throws Exception { mRecoverableKeyStoreDb.setRecoveryServiceCertPath( - TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS, TestData.CERT_PATH_1); + TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS, + TestData.getInsecureCertPathForEndpoint1()); mRecoverableKeyStoreDb.setServerParams( TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE); @@ -528,7 +529,8 @@ public class KeySyncTaskTest { lockScreenHash, keyChainSnapshot.getEncryptedRecoveryKeyBlob(), /*vaultParams=*/ KeySyncUtils.packVaultParams( - TestData.CERT_1_PUBLIC_KEY, + TestData.getInsecureCertPathForEndpoint1().getCertificates().get(0) + .getPublicKey(), counterId, /*maxAttempts=*/ 10, TEST_VAULT_HANDLE)); @@ -537,7 +539,7 @@ public class KeySyncTaskTest { assertThat(keyChainSnapshot.getCounterId()).isEqualTo(counterId); assertThat(keyChainSnapshot.getMaxAttempts()).isEqualTo(10); assertThat(keyChainSnapshot.getTrustedHardwareCertPath()) - .isEqualTo(TestData.CERT_PATH_1); + .isEqualTo(TestData.getInsecureCertPathForEndpoint1()); assertThat(keyChainSnapshot.getServerParams()).isEqualTo(TEST_VAULT_HANDLE); WrappedApplicationKey keyData = applicationKeys.get(0); assertEquals(TEST_APP_KEY_ALIAS, keyData.getAlias()); @@ -805,7 +807,7 @@ public class KeySyncTaskTest { private byte[] decryptThmEncryptedKey( byte[] lockScreenHash, byte[] encryptedKey, byte[] vaultParams) throws Exception { byte[] locallyEncryptedKey = SecureBox.decrypt( - TestData.CERT_1_PRIVATE_KEY, + TestData.getInsecurePrivateKeyForEndpoint1(), /*sharedSecret=*/ KeySyncUtils.calculateThmKfHash(lockScreenHash), /*header=*/ KeySyncUtils.concat(THM_ENCRYPTED_RECOVERY_KEY_HEADER, vaultParams), encryptedKey diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java index e82478fb68ba..8e86a87915e8 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java @@ -101,35 +101,22 @@ public class RecoverableKeyStoreManagerTest { private static final String INSECURE_CERTIFICATE_ALIAS = TrustedRootCertificates.TEST_ONLY_INSECURE_CERTIFICATE_ALIAS; private static final String TEST_SESSION_ID = "karlin"; - private static final byte[] TEST_PUBLIC_KEY = new byte[] { - (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06, - (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, - (byte) 0x01, (byte) 0x07, (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xb8, - (byte) 0x00, (byte) 0x11, (byte) 0x18, (byte) 0x98, (byte) 0x1d, (byte) 0xf0, (byte) 0x6e, - (byte) 0xb4, (byte) 0x94, (byte) 0xfe, (byte) 0x86, (byte) 0xda, (byte) 0x1c, (byte) 0x07, - (byte) 0x8d, (byte) 0x01, (byte) 0xb4, (byte) 0x3a, (byte) 0xf6, (byte) 0x8d, (byte) 0xdc, - (byte) 0x61, (byte) 0xd0, (byte) 0x46, (byte) 0x49, (byte) 0x95, (byte) 0x0f, (byte) 0x10, - (byte) 0x86, (byte) 0x93, (byte) 0x24, (byte) 0x66, (byte) 0xe0, (byte) 0x3f, (byte) 0xd2, - (byte) 0xdf, (byte) 0xf3, (byte) 0x79, (byte) 0x20, (byte) 0x1d, (byte) 0x91, (byte) 0x55, - (byte) 0xb0, (byte) 0xe5, (byte) 0xbd, (byte) 0x7a, (byte) 0x8b, (byte) 0x32, (byte) 0x7d, - (byte) 0x25, (byte) 0x53, (byte) 0xa2, (byte) 0xfc, (byte) 0xa5, (byte) 0x65, (byte) 0xe1, - (byte) 0xbd, (byte) 0x21, (byte) 0x44, (byte) 0x7e, (byte) 0x78, (byte) 0x52, (byte) 0xfa}; + private static final byte[] TEST_PUBLIC_KEY = TestData.CERT_1_PUBLIC_KEY.getEncoded(); private static final byte[] TEST_SALT = getUtf8Bytes("salt"); private static final byte[] TEST_SECRET = getUtf8Bytes("password1234"); private static final byte[] TEST_VAULT_CHALLENGE = getUtf8Bytes("vault_challenge"); private static final byte[] TEST_VAULT_PARAMS = new byte[] { // backend_key - (byte) 0x04, (byte) 0xb8, (byte) 0x00, (byte) 0x11, (byte) 0x18, (byte) 0x98, (byte) 0x1d, - (byte) 0xf0, (byte) 0x6e, (byte) 0xb4, (byte) 0x94, (byte) 0xfe, (byte) 0x86, (byte) 0xda, - (byte) 0x1c, (byte) 0x07, (byte) 0x8d, (byte) 0x01, (byte) 0xb4, (byte) 0x3a, (byte) 0xf6, - (byte) 0x8d, (byte) 0xdc, (byte) 0x61, (byte) 0xd0, (byte) 0x46, (byte) 0x49, (byte) 0x95, - (byte) 0x0f, (byte) 0x10, (byte) 0x86, (byte) 0x93, (byte) 0x24, (byte) 0x66, (byte) 0xe0, - (byte) 0x3f, (byte) 0xd2, (byte) 0xdf, (byte) 0xf3, (byte) 0x79, (byte) 0x20, (byte) 0x1d, - (byte) 0x91, (byte) 0x55, (byte) 0xb0, (byte) 0xe5, (byte) 0xbd, (byte) 0x7a, (byte) 0x8b, - (byte) 0x32, (byte) 0x7d, (byte) 0x25, (byte) 0x53, (byte) 0xa2, (byte) 0xfc, (byte) 0xa5, - (byte) 0x65, (byte) 0xe1, (byte) 0xbd, (byte) 0x21, (byte) 0x44, (byte) 0x7e, (byte) 0x78, - (byte) 0x52, (byte) 0xfa, + (byte) 0x04, (byte) 0x8e, (byte) 0x0c, (byte) 0x11, (byte) 0x4a, (byte) 0x79, (byte) 0x20, + (byte) 0x7c, (byte) 0x00, (byte) 0x4c, (byte) 0xd7, (byte) 0xe9, (byte) 0x06, (byte) 0xe2, + (byte) 0x58, (byte) 0x21, (byte) 0x45, (byte) 0xfa, (byte) 0x24, (byte) 0xcb, (byte) 0x07, + (byte) 0x66, (byte) 0xde, (byte) 0xfd, (byte) 0xf1, (byte) 0x83, (byte) 0xb4, (byte) 0x26, + (byte) 0x55, (byte) 0x98, (byte) 0xcb, (byte) 0xa9, (byte) 0xd5, (byte) 0x55, (byte) 0xad, + (byte) 0x65, (byte) 0xc5, (byte) 0xff, (byte) 0x5c, (byte) 0xfb, (byte) 0x1c, (byte) 0x4e, + (byte) 0x34, (byte) 0x98, (byte) 0x7e, (byte) 0x4f, (byte) 0x96, (byte) 0xa2, (byte) 0xa3, + (byte) 0x7e, (byte) 0xf4, (byte) 0x46, (byte) 0x52, (byte) 0x04, (byte) 0xba, (byte) 0x2a, + (byte) 0xb9, (byte) 0x47, (byte) 0xbb, (byte) 0xc2, (byte) 0x1e, (byte) 0xdd, (byte) 0x15, + (byte) 0x1a, (byte) 0xc0, // counter_id (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java index 64eb49bbb131..5d4be1bee105 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java @@ -29,6 +29,7 @@ import java.security.PublicKey; import java.security.cert.CertificateFactory; import java.security.cert.CertPath; import java.security.spec.ECPrivateKeySpec; +import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import javax.crypto.KeyGenerator; @@ -37,56 +38,56 @@ import javax.crypto.SecretKey; public final class TestData { private static final String KEY_ALGORITHM = "AES"; - private static final long DEFAULT_SERIAL = 1000; + private static final long DEFAULT_SERIAL = 10001; private static final String CERT_PATH_ENCODING = "PkiPath"; private static final String CERT_PATH_1_BASE64 = "" - + "MIIIPzCCBS8wggMXoAMCAQICAhAAMA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNVBAMM" - + "FUdvb2dsZSBDcnlwdEF1dGhWYXVsdDAeFw0xODAyMDMwMDQyMDNaFw0yODAyMDEw" - + "MDQyMDNaMC0xKzApBgNVBAMMIkdvb2dsZSBDcnlwdEF1dGhWYXVsdCBJbnRlcm1l" - + "ZGlhdGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDckHib0X6rQyDq" - + "k4519b5du0OrCPk30XXKwz+Hz5y4cGZaWKGcHOHWS2X9YApRzO00/EbvFkWVUTVG" - + "27wJ54V+C3HHSOAUWHhEgfFWvvHwfn9HTDx1BEk79aQqJ7DuJ06Sn/WOiMtKVAT5" - + "6Mi8mekBxpMOrdZqwlcLrUVsZxEHsw5/ceZu4cSWzc7SzlnbNK1cCgyRDGqWf6Gp" - + "3hGE86kUOtM1i95RgUIpw+w/z0wxpF6kIyQTjK+KjiYH/RBOJIEcm6sSWZlMotKL" - + "Sn2lhf+XL8yUxExIHTosfeb077QWW4w2BB2NZM4wPAO3w4aw33FNigDQc2SQYmnU" - + "EYmIcD8kx77+JWCgCxBJc2zTHXtBxWuXAQ+iegt8RO+QD97pd6XKM9xPsAOkcWLp" - + "79o+AJol4P5fwvgYM69mM4lwH12v86RI4aptPQOag0KDIHXyKbjaQyAgv30l4KkD" - + "pf2uWODhOOTwNbVPYUm3sYUlhBcbyhTk8YqN9sPU4QAao5sKTAYZgB/mlheQypTU" - + "wyvqz6bRzGehVB3ltP9gCyKdI04VXEUuUBWk3STyV2REQen5/LKAns6v11Cz22Zr" - + "EdCvNLgetnyV7CJsOa/wD/GiUWL2Ta7pzshi9ahJqrrcNPRbAzOLcNKZkFexhzPp" - + "onuo/pNrcaRda1frepXxVkmbsgOULwIDAQABo2YwZDAdBgNVHQ4EFgQUd6md2hCP" - + "lmf3VkEX5FfDxKBLbaAwHwYDVR0jBBgwFoAUm2X66jmB+eBCaZHSjGYzHM/x6fgw" - + "EgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL" - + "BQADggIBAFgShhuW+WVTowN080PLf0TWPlHACHHUPghf7rFGxgUjJypCloE84Beg" - + "3ROpP5l19CDqZ9OyPzA1z6VAzeGXyFhZvby7G2tZDBRP/v0u8pnSAdC5F8l8Vh2Y" - + "GdgE3sZD25vpdBi7P0Ef6LYQetOJXn86PqgmgW1F6lzxDjKCsi9kpeU0AWwDdOVg" - + "748wku50o8UEzsVwxzFd9toGlge/nn3FH5J7EuGzAlFwToHqpwTVEegaAd0l9mr5" - + "+rS7Urd3X80BHDqCBcXE7Uqbtzw5Y+lmowMCnW0kFN02dC9dLt2c9IxC+9sPIA5e" - + "TkrZBkrkTVRGLj2r29j7nC9m5VaKcBqcLZDWy8pRna8yaZprgNdE8d/WTY9nVsic" - + "09N8zNF5Q0bhhWa3QonlB9XW5ZqDguiclvn+5TtREzSAtSOyxM+gfG3l0wjOywIk" - + "1aFa52RaqAWPL67KOM6G3vKNpMnW5hrmHrijuKxiarGIoZfkZMR5ijK0uFgv3/p6" - + "NHL/YQBaHJJhkKet5ThiPxwW9+1k/ZcXVeY26Xh+22Gp/8to7ZW8guPPiN1hfpD+" - + "7f1IdSmHDrsZQQ7bfzV0bppsyNNB7e2Ecyw+GQny27nytBLJDGdRBurbwQvzppQO" - + "6Qmlk0rfCszh7bGCoCQNxXmuDsQ5BC+pQUqJplTqds1smyi29xs3MIIDCDCB8aAD" - + "AgECAgYBYVkuU0cwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAwwiR29vZ2xlIENy" - + "eXB0QXV0aFZhdWx0IEludGVybWVkaWF0ZTAeFw0xODAyMDIwMTAxMDNaFw0yMDAy" - + "MDMwMTAxMDNaMCkxJzAlBgNVBAMTHkdvb2dsZSBDcnlwdEF1dGhWYXVsdCBJbnN0" - + "YW5jZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLgAERiYHfButJT+htocB40B" - + "tDr2jdxh0EZJlQ8QhpMkZuA/0t/zeSAdkVWw5b16izJ9JVOi/KVl4b0hRH54Uvow" - + "DQYJKoZIhvcNAQELBQADggIBAJ3PM4GNTNYzMr8E/IGsWZkLx9ARAALqBXz7As59" - + "F8y5UcLMqkXD/ewOfBZgF5VzjlAePyE/wSw0wc3xzvrDVVDiZaMBW1DVtSlbn25q" - + "00m00mmcUeyyMc7vuRkPoDshIMQTc8+U3yyYsVScSV+B4TvSx6wPZ9FpwnSPjVPD" - + "2GkqeMTWszuxNVEWq0wmm0K5lMaX0hfiak+4/IZxOPPGIg2py1KLA/H2gdyeqyJR" - + "cAsyEkfwLlushR5T9abSiPsIRcYoX8Ck8Lt+gQ7RCMefnm8CoOBKIfcjuV4PGOoe" - + "Xrq57VR5SsOeT07bL+D7B+mohYFI1v2G3WClAE8XgM3q8NoFFvaYmoi0+UcTduil" - + "47qvozjdNmjRAgu5j6vMKXEdG5Rqsja8hy0LG1hwfnR0gNiwcZ5Le3GyFnwH1Igq" - + "vsGOUM0ohnDUAU0zJY7nG0QYrDYe5/QPRNhWDpYkwHDiqcG28wIQCOTPAZHU2EoS" - + "KjSqEG2l0S5JPcor2BEde9ikSkcmK8foxlOHIdFn+n7RNF3bSEfKn1IOuXoqPidm" - + "eBQLevqG8KTy/C9CHqlaCNlpbIA9h+WVfsjm2s6JXBu0YbcfoIbJAmSuZVeqB/+Z" - + "Vvpfiad/jQWzY49fRnsSmV7VveTFPGtJxC89EadbMAinMZo+72u59319RqN5wsP2" - + "Zus8"; - private static String CERT_PATH_2_BASE64 = "" + + "MIIIXTCCBRowggMCoAMCAQICEB35ZwzVpI9ssXg9SAehnU0wDQYJKoZIhvcNAQEL" + + "BQAwMTEvMC0GA1UEAxMmR29vZ2xlIENsb3VkIEtleSBWYXVsdCBTZXJ2aWNlIFJv" + + "b3QgQ0EwHhcNMTgwNTA3MTg1ODEwWhcNMjgwNTA4MTg1ODEwWjA5MTcwNQYDVQQD" + + "Ey5Hb29nbGUgQ2xvdWQgS2V5IFZhdWx0IFNlcnZpY2UgSW50ZXJtZWRpYXRlIENB" + + "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA73TrvH3j6zEimpcc32tx" + + "2iupWwfyzdE5l4Ejc5EBYzx0aZH6b/KDuutwustk0IoyjlGySMBz/21YgWejIm+n" + + "duAlpk7WY5kYHp0XWtzdmxZknmWTqugPeNZeiKEjoDmpyIbY6N+f13hQ2RVh+WDT" + + "EowQ/i04WBL75chshlIG+3A42g5Qr7DZEKdT9oJQqkntzj0cGyJ5X8BwjeTiJrvY" + + "k2Kn/0555/Kpp65G3Rf29VPPU3i67kthAT3SavLBpH03S4WZ+QlfrAiGQziydtz9" + + "t7mSk1xefjax5ZWAuJAfCbKfI3VWAcaUr4P57BzmDcSi0jgs1aM3t2BrPfAMRxWv" + + "35yDZnrC+HipzkjyDGBfHmFgoglyhc9e/Kj3mSusO0Rq1wguVXKs2hKXRoaGJuHt" + + "e3YIwTC1pLznqvolhD1nPoXf8rMzgHRzlc9H8iXsgB1p7975nh5WCPrMDX2eAmYd" + + "a0xTMccTeBzIM2ohxQsxlh5rsjXVNU3ihbWkHquzIiwFcAtldP3dMksj0dn/DnYD" + + "yokjEgU/z2I216E93x9hmKkEk6Pp7o8t/z6lwMT9FJIuzp7NREnWCSi+e5s2E7FD" + + "j6S7xY2zEIUHrmwuuJc0jzJnwdZ+0myinaTmBDvBXR5cU1cmEAZoheCAoRv9Z/6o" + + "ASczLF0C4uuVfA5GXcAm14cCAwEAAaMmMCQwDgYDVR0PAQH/BAQDAgGGMBIGA1Ud" + + "EwEB/wQIMAYBAf8CAQEwDQYJKoZIhvcNAQELBQADggIBAEPht79yQm8woQbPB1Bs" + + "eotkzJtTWTO9fnIWwNiRfQ3vJFXf69ghE77wUS13Ez3FlgNPj0Qxmg5ouE0d2yYV" + + "4AUrXnEGZELcyN2XHRXyNK0zXgnr3x6eZyY7QfgGKJgkyja5TS6ZPWGyaLKhClS0" + + "AYZSzWJtz0+AkGCdTbmyy7ShdXJ+GfnmssbndZA62VhcjeQmHsDq7V3PKAsp4/B9" + + "PzcnTrgkUFNnP1F1pr7JpUUX3xyRFy6gjIrUx1fcOFRxFYPWGLLMZ6P41rafm+M/" + + "CbBNr5CY7NrZjr34jLqWycfYes49o9OK44X/wPrxj0Sjg+VrW21+AJ9vrM7DS5hE" + + "QX1lDbDtQGkk3N1vgCTo6xt9LXsEu4xUT5bk7YAfpJqM0ltDFPwYAGCbjSkVT/M5" + + "JVZkKiUW668Us67x8yZc/5bxbvTA+5xrYhak/VYIBY6qub4J+bKwadw6uBgxnq4P" + + "hwgwjfaoJy9YAXCswjCtaE9GwkVmRnJE9vFjJ33IGf37hFTYEHBFy4FomVmQwRFZ" + + "TIe7tkKDq9i18F7lzBPJPO6wEG8bxi4csatrjcVHR9erpY5u6ebtkKG8qsan9qzh" + + "iWAgSytiT++HejZeoQ+RRgQWjupjdDo5/0oSdQqvaN8Ah6C2J+ecCZ12Lu0FwF+t" + + "t9Ie3pF6W8TzxzuMdFWq+afvMIIDOzCCASOgAwIBAgIRAOTj/iNQb6/Qit7zAW9n" + + "cL0wDQYJKoZIhvcNAQELBQAwOTE3MDUGA1UEAxMuR29vZ2xlIENsb3VkIEtleSBW" + + "YXVsdCBTZXJ2aWNlIEludGVybWVkaWF0ZSBDQTAeFw0xODA1MDcyMjE4MTFaFw0y" + + "MzA1MDgyMjE4MTFaMDIxMDAuBgNVBAMTJ0dvb2dsZSBDbG91ZCBLZXkgVmF1bHQg" + + "U2VydmljZSBFbmRwb2ludDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABI4MEUp5" + + "IHwATNfpBuJYIUX6JMsHZt798YO0JlWYy6nVVa1lxf9c+xxONJh+T5aio370RlIE" + + "uiq5R7vCHt0VGsCjEDAOMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB" + + "AGf6QU58lU+gGzy8hnp0suR/ixC++CExtf39pDHkdfU/e3ui4ROR+pjQ5F7okDFW" + + "eKSCNcJZ7tyXMJ9g7/I0qVY8Bj/gRnlVokdl/wD5PiL9GIzqWfnHNe3T+xrAAAgO" + + "D0bEmjgwNYmekfUIYQczd04d7ZMGnmAkpVH/0O2mf9q5x9fMlbKuAygUqQ/gmnlg" + + "xKfl9DSRWi4oMBOqlKlCRP1XAh3anu92+M/EhsFbyc07CWZY0SByX5M/cHVMLhUX" + + "jZHvcYLyOmJWJmXznidgyNeIR6t9yDB55iCt7WSn3qMY+9vA9ELzt8jYpBNaKc0G" + + "bWQkRzYWegkf4kMis98eQ3SnAKbRz6669nmuAdxKs9/LK6BlFOFw1xvsTRQ96dBa" + + "oiX2XGhou+Im0Td/AMs0Aigz2N+Ujq/yW//35GZQfdGGIYtFbkcltStygjIJyAM1" + + "pBhyBBkJhOhRpO4fXh98aq8H5J7R9i5A9WpnDstAxPxcNCDWn0O/WxhPvVZkFTpi" + + "NXh9dnlJ/kZe+j+z5ZMaxW435drLPx2AQKjXA9GgGrFPltTUyGycmEGtuxLvSnm/" + + "zPlmk5FUk7x2wEr0+bZ3cx0JHHgAtgXpe0jkDi8Bw8O3X7mUOjxVhYU6auiYJezW" + + "9LGmweaKwYvS04UCWOReolUVexob9LI/VX1JrrwD3s7k"; + private static final String CERT_PATH_2_BASE64 = "" + "MIIFMzCCBS8wggMXoAMCAQICAhAAMA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNVBAMM" + "FUdvb2dsZSBDcnlwdEF1dGhWYXVsdDAeFw0xODAyMDMwMDQyMDNaFw0yODAyMDEw" + "MDQyMDNaMC0xKzApBgNVBAMMIkdvb2dsZSBDcnlwdEF1dGhWYXVsdCBJbnRlcm1l" @@ -117,194 +118,44 @@ public final class TestData { + "6Qmlk0rfCszh7bGCoCQNxXmuDsQ5BC+pQUqJplTqds1smyi29xs3"; private static final String THM_CERT_XML_BEFORE_SERIAL = "" - + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - + "<certificates>\n" - + " <metadata>\n" - + " <serial>\n" - + " "; - private static final String THM_CERT_XML_AFTER_SERIAL = "\n" - + " </serial>\n" - + " <creation-time>\n" - + " 1515697631\n" - + " </creation-time>\n" - + " <refresh-interval>\n" - + " 2592000\n" - + " </refresh-interval>\n" + + "<certificate>\n" + + " <metadata>\n" + + " <serial>"; + private static final String THM_CERT_XML_AFTER_SERIAL = "" + + "</serial>\n" + + " <creation-time>1525817891</creation-time>\n" + + " <refresh-interval>2592000</refresh-interval>\n" + " <previous>\n" - + " <serial>\n" - + " 0\n" - + " </serial>\n" - + " <hash>\n" - + " 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\n" - + " </hash>\n" + + " <serial>10000</serial>\n" + + " <hash>ahyI+59KW2tVxi0inRdUSo1Y8kmx5xK1isDvYfzxWbo=</hash>\n" + " </previous>\n" + " </metadata>\n" + " <intermediates>\n" - + " <cert>\n" - + " MIIFLzCCAxegAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UEAwwVR29v\n" - + " Z2xlIENyeXB0QXV0aFZhdWx0MB4XDTE4MDIwMzAwNDIwM1oXDTI4MDIwMTAwNDIw\n" - + " M1owLTErMCkGA1UEAwwiR29vZ2xlIENyeXB0QXV0aFZhdWx0IEludGVybWVkaWF0\n" - + " ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANyQeJvRfqtDIOqTjnX1\n" - + " vl27Q6sI+TfRdcrDP4fPnLhwZlpYoZwc4dZLZf1gClHM7TT8Ru8WRZVRNUbbvAnn\n" - + " hX4LccdI4BRYeESB8Va+8fB+f0dMPHUESTv1pConsO4nTpKf9Y6Iy0pUBPnoyLyZ\n" - + " 6QHGkw6t1mrCVwutRWxnEQezDn9x5m7hxJbNztLOWds0rVwKDJEMapZ/oaneEYTz\n" - + " qRQ60zWL3lGBQinD7D/PTDGkXqQjJBOMr4qOJgf9EE4kgRybqxJZmUyi0otKfaWF\n" - + " /5cvzJTETEgdOix95vTvtBZbjDYEHY1kzjA8A7fDhrDfcU2KANBzZJBiadQRiYhw\n" - + " PyTHvv4lYKALEElzbNMde0HFa5cBD6J6C3xE75AP3ul3pcoz3E+wA6RxYunv2j4A\n" - + " miXg/l/C+Bgzr2YziXAfXa/zpEjhqm09A5qDQoMgdfIpuNpDICC/fSXgqQOl/a5Y\n" - + " 4OE45PA1tU9hSbexhSWEFxvKFOTxio32w9ThABqjmwpMBhmAH+aWF5DKlNTDK+rP\n" - + " ptHMZ6FUHeW0/2ALIp0jThVcRS5QFaTdJPJXZERB6fn8soCezq/XULPbZmsR0K80\n" - + " uB62fJXsImw5r/AP8aJRYvZNrunOyGL1qEmqutw09FsDM4tw0pmQV7GHM+mie6j+\n" - + " k2txpF1rV+t6lfFWSZuyA5QvAgMBAAGjZjBkMB0GA1UdDgQWBBR3qZ3aEI+WZ/dW\n" - + " QRfkV8PEoEttoDAfBgNVHSMEGDAWgBSbZfrqOYH54EJpkdKMZjMcz/Hp+DASBgNV\n" - + " HRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC\n" - + " AgEAWBKGG5b5ZVOjA3TzQ8t/RNY+UcAIcdQ+CF/usUbGBSMnKkKWgTzgF6DdE6k/\n" - + " mXX0IOpn07I/MDXPpUDN4ZfIWFm9vLsba1kMFE/+/S7ymdIB0LkXyXxWHZgZ2ATe\n" - + " xkPbm+l0GLs/QR/othB604lefzo+qCaBbUXqXPEOMoKyL2Sl5TQBbAN05WDvjzCS\n" - + " 7nSjxQTOxXDHMV322gaWB7+efcUfknsS4bMCUXBOgeqnBNUR6BoB3SX2avn6tLtS\n" - + " t3dfzQEcOoIFxcTtSpu3PDlj6WajAwKdbSQU3TZ0L10u3Zz0jEL72w8gDl5OStkG\n" - + " SuRNVEYuPavb2PucL2blVopwGpwtkNbLylGdrzJpmmuA10Tx39ZNj2dWyJzT03zM\n" - + " 0XlDRuGFZrdCieUH1dblmoOC6JyW+f7lO1ETNIC1I7LEz6B8beXTCM7LAiTVoVrn\n" - + " ZFqoBY8vrso4zobe8o2kydbmGuYeuKO4rGJqsYihl+RkxHmKMrS4WC/f+no0cv9h\n" - + " AFockmGQp63lOGI/HBb37WT9lxdV5jbpeH7bYan/y2jtlbyC48+I3WF+kP7t/Uh1\n" - + " KYcOuxlBDtt/NXRummzI00Ht7YRzLD4ZCfLbufK0EskMZ1EG6tvBC/OmlA7pCaWT\n" - + " St8KzOHtsYKgJA3Fea4OxDkEL6lBSommVOp2zWybKLb3Gzc=\n" - + " </cert>\n" + + " <cert>MIIFGjCCAwKgAwIBAgIQHflnDNWkj2yxeD1IB6GdTTANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDEyZHb29nbGUgQ2xvdWQgS2V5IFZhdWx0IFNlcnZpY2UgUm9vdCBDQTAeFw0xODA1MDcxODU4MTBaFw0yODA1MDgxODU4MTBaMDkxNzA1BgNVBAMTLkdvb2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDvdOu8fePrMSKalxzfa3HaK6lbB/LN0TmXgSNzkQFjPHRpkfpv8oO663C6y2TQijKOUbJIwHP/bViBZ6Mib6d24CWmTtZjmRgenRda3N2bFmSeZZOq6A941l6IoSOgOanIhtjo35/XeFDZFWH5YNMSjBD+LThYEvvlyGyGUgb7cDjaDlCvsNkQp1P2glCqSe3OPRwbInlfwHCN5OImu9iTYqf/Tnnn8qmnrkbdF/b1U89TeLruS2EBPdJq8sGkfTdLhZn5CV+sCIZDOLJ23P23uZKTXF5+NrHllYC4kB8Jsp8jdVYBxpSvg/nsHOYNxKLSOCzVoze3YGs98AxHFa/fnINmesL4eKnOSPIMYF8eYWCiCXKFz178qPeZK6w7RGrXCC5VcqzaEpdGhoYm4e17dgjBMLWkvOeq+iWEPWc+hd/yszOAdHOVz0fyJeyAHWnv3vmeHlYI+swNfZ4CZh1rTFMxxxN4HMgzaiHFCzGWHmuyNdU1TeKFtaQeq7MiLAVwC2V0/d0ySyPR2f8OdgPKiSMSBT/PYjbXoT3fH2GYqQSTo+nujy3/PqXAxP0Uki7Ons1ESdYJKL57mzYTsUOPpLvFjbMQhQeubC64lzSPMmfB1n7SbKKdpOYEO8FdHlxTVyYQBmiF4IChG/1n/qgBJzMsXQLi65V8DkZdwCbXhwIDAQABoyYwJDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBATANBgkqhkiG9w0BAQsFAAOCAgEAQ+G3v3JCbzChBs8HUGx6i2TMm1NZM71+chbA2JF9De8kVd/r2CETvvBRLXcTPcWWA0+PRDGaDmi4TR3bJhXgBStecQZkQtzI3ZcdFfI0rTNeCevfHp5nJjtB+AYomCTKNrlNLpk9YbJosqEKVLQBhlLNYm3PT4CQYJ1NubLLtKF1cn4Z+eayxud1kDrZWFyN5CYewOrtXc8oCynj8H0/NydOuCRQU2c/UXWmvsmlRRffHJEXLqCMitTHV9w4VHEVg9YYssxno/jWtp+b4z8JsE2vkJjs2tmOvfiMupbJx9h6zj2j04rjhf/A+vGPRKOD5WtbbX4An2+szsNLmERBfWUNsO1AaSTc3W+AJOjrG30tewS7jFRPluTtgB+kmozSW0MU/BgAYJuNKRVP8zklVmQqJRbrrxSzrvHzJlz/lvFu9MD7nGtiFqT9VggFjqq5vgn5srBp3Dq4GDGerg+HCDCN9qgnL1gBcKzCMK1oT0bCRWZGckT28WMnfcgZ/fuEVNgQcEXLgWiZWZDBEVlMh7u2QoOr2LXwXuXME8k87rAQbxvGLhyxq2uNxUdH16uljm7p5u2Qobyqxqf2rOGJYCBLK2JP74d6Nl6hD5FGBBaO6mN0Ojn/ShJ1Cq9o3wCHoLYn55wJnXYu7QXAX6230h7ekXpbxPPHO4x0Var5p+8=</cert>\n" + " </intermediates>\n" + " <endpoints>\n" - + " <cert>\n" - + " MIIDCDCB8aADAgECAgYBYVkuU0cwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAwwi\n" - + " R29vZ2xlIENyeXB0QXV0aFZhdWx0IEludGVybWVkaWF0ZTAeFw0xODAyMDIwMTAx\n" - + " MDNaFw0yMDAyMDMwMTAxMDNaMCkxJzAlBgNVBAMTHkdvb2dsZSBDcnlwdEF1dGhW\n" - + " YXVsdCBJbnN0YW5jZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLgAERiYHfBu\n" - + " tJT+htocB40BtDr2jdxh0EZJlQ8QhpMkZuA/0t/zeSAdkVWw5b16izJ9JVOi/KVl\n" - + " 4b0hRH54UvowDQYJKoZIhvcNAQELBQADggIBAJ3PM4GNTNYzMr8E/IGsWZkLx9AR\n" - + " AALqBXz7As59F8y5UcLMqkXD/ewOfBZgF5VzjlAePyE/wSw0wc3xzvrDVVDiZaMB\n" - + " W1DVtSlbn25q00m00mmcUeyyMc7vuRkPoDshIMQTc8+U3yyYsVScSV+B4TvSx6wP\n" - + " Z9FpwnSPjVPD2GkqeMTWszuxNVEWq0wmm0K5lMaX0hfiak+4/IZxOPPGIg2py1KL\n" - + " A/H2gdyeqyJRcAsyEkfwLlushR5T9abSiPsIRcYoX8Ck8Lt+gQ7RCMefnm8CoOBK\n" - + " IfcjuV4PGOoeXrq57VR5SsOeT07bL+D7B+mohYFI1v2G3WClAE8XgM3q8NoFFvaY\n" - + " moi0+UcTduil47qvozjdNmjRAgu5j6vMKXEdG5Rqsja8hy0LG1hwfnR0gNiwcZ5L\n" - + " e3GyFnwH1IgqvsGOUM0ohnDUAU0zJY7nG0QYrDYe5/QPRNhWDpYkwHDiqcG28wIQ\n" - + " COTPAZHU2EoSKjSqEG2l0S5JPcor2BEde9ikSkcmK8foxlOHIdFn+n7RNF3bSEfK\n" - + " n1IOuXoqPidmeBQLevqG8KTy/C9CHqlaCNlpbIA9h+WVfsjm2s6JXBu0YbcfoIbJ\n" - + " AmSuZVeqB/+ZVvpfiad/jQWzY49fRnsSmV7VveTFPGtJxC89EadbMAinMZo+72u5\n" - + " 9319RqN5wsP2Zus8\n" - + " </cert>\n" + // The public key is chosen by using the following hash as the first 32 bytes (x-axis) + // SHA256("Google Cloud Key Vault Service Test Endpoint") = 8e0c114a79207c004cd7e906e2582145fa24cb0766defdf183b4265598cba9d5 + // so its private key is unknown. + + " <cert>MIIDOzCCASOgAwIBAgIRAOTj/iNQb6/Qit7zAW9ncL0wDQYJKoZIhvcNAQELBQAwOTE3MDUGA1UEAxMuR29vZ2xlIENsb3VkIEtleSBWYXVsdCBTZXJ2aWNlIEludGVybWVkaWF0ZSBDQTAeFw0xODA1MDcyMjE4MTFaFw0yMzA1MDgyMjE4MTFaMDIxMDAuBgNVBAMTJ0dvb2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBFbmRwb2ludDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABI4MEUp5IHwATNfpBuJYIUX6JMsHZt798YO0JlWYy6nVVa1lxf9c+xxONJh+T5aio370RlIEuiq5R7vCHt0VGsCjEDAOMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAGf6QU58lU+gGzy8hnp0suR/ixC++CExtf39pDHkdfU/e3ui4ROR+pjQ5F7okDFWeKSCNcJZ7tyXMJ9g7/I0qVY8Bj/gRnlVokdl/wD5PiL9GIzqWfnHNe3T+xrAAAgOD0bEmjgwNYmekfUIYQczd04d7ZMGnmAkpVH/0O2mf9q5x9fMlbKuAygUqQ/gmnlgxKfl9DSRWi4oMBOqlKlCRP1XAh3anu92+M/EhsFbyc07CWZY0SByX5M/cHVMLhUXjZHvcYLyOmJWJmXznidgyNeIR6t9yDB55iCt7WSn3qMY+9vA9ELzt8jYpBNaKc0GbWQkRzYWegkf4kMis98eQ3SnAKbRz6669nmuAdxKs9/LK6BlFOFw1xvsTRQ96dBaoiX2XGhou+Im0Td/AMs0Aigz2N+Ujq/yW//35GZQfdGGIYtFbkcltStygjIJyAM1pBhyBBkJhOhRpO4fXh98aq8H5J7R9i5A9WpnDstAxPxcNCDWn0O/WxhPvVZkFTpiNXh9dnlJ/kZe+j+z5ZMaxW435drLPx2AQKjXA9GgGrFPltTUyGycmEGtuxLvSnm/zPlmk5FUk7x2wEr0+bZ3cx0JHHgAtgXpe0jkDi8Bw8O3X7mUOjxVhYU6auiYJezW9LGmweaKwYvS04UCWOReolUVexob9LI/VX1JrrwD3s7k</cert>\n" + " </endpoints>\n" - + "</certificates>\n"; + + "</certificate>\n"; private static final String THM_SIG_XML = "" - + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<signature>\n" - + " <intermediates>\n" - + " </intermediates>\n" - + " <certificate>\n" - + " MIIFLzCCAxegAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UEAwwVR29v\n" - + " Z2xlIENyeXB0QXV0aFZhdWx0MB4XDTE4MDIwMzAwNDIwM1oXDTI4MDIwMTAwNDIw\n" - + " M1owLTErMCkGA1UEAwwiR29vZ2xlIENyeXB0QXV0aFZhdWx0IEludGVybWVkaWF0\n" - + " ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANyQeJvRfqtDIOqTjnX1\n" - + " vl27Q6sI+TfRdcrDP4fPnLhwZlpYoZwc4dZLZf1gClHM7TT8Ru8WRZVRNUbbvAnn\n" - + " hX4LccdI4BRYeESB8Va+8fB+f0dMPHUESTv1pConsO4nTpKf9Y6Iy0pUBPnoyLyZ\n" - + " 6QHGkw6t1mrCVwutRWxnEQezDn9x5m7hxJbNztLOWds0rVwKDJEMapZ/oaneEYTz\n" - + " qRQ60zWL3lGBQinD7D/PTDGkXqQjJBOMr4qOJgf9EE4kgRybqxJZmUyi0otKfaWF\n" - + " /5cvzJTETEgdOix95vTvtBZbjDYEHY1kzjA8A7fDhrDfcU2KANBzZJBiadQRiYhw\n" - + " PyTHvv4lYKALEElzbNMde0HFa5cBD6J6C3xE75AP3ul3pcoz3E+wA6RxYunv2j4A\n" - + " miXg/l/C+Bgzr2YziXAfXa/zpEjhqm09A5qDQoMgdfIpuNpDICC/fSXgqQOl/a5Y\n" - + " 4OE45PA1tU9hSbexhSWEFxvKFOTxio32w9ThABqjmwpMBhmAH+aWF5DKlNTDK+rP\n" - + " ptHMZ6FUHeW0/2ALIp0jThVcRS5QFaTdJPJXZERB6fn8soCezq/XULPbZmsR0K80\n" - + " uB62fJXsImw5r/AP8aJRYvZNrunOyGL1qEmqutw09FsDM4tw0pmQV7GHM+mie6j+\n" - + " k2txpF1rV+t6lfFWSZuyA5QvAgMBAAGjZjBkMB0GA1UdDgQWBBR3qZ3aEI+WZ/dW\n" - + " QRfkV8PEoEttoDAfBgNVHSMEGDAWgBSbZfrqOYH54EJpkdKMZjMcz/Hp+DASBgNV\n" - + " HRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC\n" - + " AgEAWBKGG5b5ZVOjA3TzQ8t/RNY+UcAIcdQ+CF/usUbGBSMnKkKWgTzgF6DdE6k/\n" - + " mXX0IOpn07I/MDXPpUDN4ZfIWFm9vLsba1kMFE/+/S7ymdIB0LkXyXxWHZgZ2ATe\n" - + " xkPbm+l0GLs/QR/othB604lefzo+qCaBbUXqXPEOMoKyL2Sl5TQBbAN05WDvjzCS\n" - + " 7nSjxQTOxXDHMV322gaWB7+efcUfknsS4bMCUXBOgeqnBNUR6BoB3SX2avn6tLtS\n" - + " t3dfzQEcOoIFxcTtSpu3PDlj6WajAwKdbSQU3TZ0L10u3Zz0jEL72w8gDl5OStkG\n" - + " SuRNVEYuPavb2PucL2blVopwGpwtkNbLylGdrzJpmmuA10Tx39ZNj2dWyJzT03zM\n" - + " 0XlDRuGFZrdCieUH1dblmoOC6JyW+f7lO1ETNIC1I7LEz6B8beXTCM7LAiTVoVrn\n" - + " ZFqoBY8vrso4zobe8o2kydbmGuYeuKO4rGJqsYihl+RkxHmKMrS4WC/f+no0cv9h\n" - + " AFockmGQp63lOGI/HBb37WT9lxdV5jbpeH7bYan/y2jtlbyC48+I3WF+kP7t/Uh1\n" - + " KYcOuxlBDtt/NXRummzI00Ht7YRzLD4ZCfLbufK0EskMZ1EG6tvBC/OmlA7pCaWT\n" - + " St8KzOHtsYKgJA3Fea4OxDkEL6lBSommVOp2zWybKLb3Gzc=\n" - + " </certificate>\n" - + " <value>\n" - + " uKJ4W8BPCdVaIBe2ZiMxxk5L5vGBV9QwaOEGU80LgtA/gEqkiO2IMUBlQJFqvvhh6RSph5lWpLuv\n" - + " /Xt7WBzDsZOcxXNffg2+pWNpbpwZdHohlwQEI1OqiVYVnfG4euAkzeWZZLsRUuAjHfcWVIzDoSoK\n" - + " wC+gqdUQHBV+pWyn6PXVslS0JIldeegbiwF076M1D7ybeCABXoQelSZRHkx1szO8UnxSR3X7Cemu\n" - + " p9De/7z9+WPPclqybINVIPy6Kvl8mHrGSlzawQRDKtoMrJa8bo93PookF8sbg5EoGapV0yNpMEiA\n" - + " spq3DEcdXB6mGDGPnLbS2WXq4zjKopASRKkZvOMdgfS6NdUMDtKS1TsOrv2KKTkLnGYfvdAeWiMg\n" - + " oFbuyYQ0mnDlLH1UW6anI8RxXn+wmdyZA+/ksapGvRmkvz0Mb997WzqNl7v7UTr0SU3Ws01hFsm6\n" - + " lW++MsotkyfpR9mWB8/dqVNVShLmIlt7U/YFVfziYSrVdjcAdIlgJ6Ihxb92liQHOU+Qr1YDOmm1\n" - + " JSnhlQVvFxWZG7hm5laNL6lqXz5VV6Gk5IeLtMb8kdHz3zj4ascdldapVPLJIa5741GNNgQNU0nH\n" - + " FhAyKk0zN7PbL1/XGWPU+s5lai4HE6JM2CKA7jE7cYrdaDZxbba+9iWzQ4YEBDr5Z3OoloK5dvs=\n" - + " </value>\n" + + " <intermediates></intermediates>\n" + + " <certificate>MIIFGjCCAwKgAwIBAgIQHflnDNWkj2yxeD1IB6GdTTANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDEyZHb29nbGUgQ2xvdWQgS2V5IFZhdWx0IFNlcnZpY2UgUm9vdCBDQTAeFw0xODA1MDcxODU4MTBaFw0yODA1MDgxODU4MTBaMDkxNzA1BgNVBAMTLkdvb2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDvdOu8fePrMSKalxzfa3HaK6lbB/LN0TmXgSNzkQFjPHRpkfpv8oO663C6y2TQijKOUbJIwHP/bViBZ6Mib6d24CWmTtZjmRgenRda3N2bFmSeZZOq6A941l6IoSOgOanIhtjo35/XeFDZFWH5YNMSjBD+LThYEvvlyGyGUgb7cDjaDlCvsNkQp1P2glCqSe3OPRwbInlfwHCN5OImu9iTYqf/Tnnn8qmnrkbdF/b1U89TeLruS2EBPdJq8sGkfTdLhZn5CV+sCIZDOLJ23P23uZKTXF5+NrHllYC4kB8Jsp8jdVYBxpSvg/nsHOYNxKLSOCzVoze3YGs98AxHFa/fnINmesL4eKnOSPIMYF8eYWCiCXKFz178qPeZK6w7RGrXCC5VcqzaEpdGhoYm4e17dgjBMLWkvOeq+iWEPWc+hd/yszOAdHOVz0fyJeyAHWnv3vmeHlYI+swNfZ4CZh1rTFMxxxN4HMgzaiHFCzGWHmuyNdU1TeKFtaQeq7MiLAVwC2V0/d0ySyPR2f8OdgPKiSMSBT/PYjbXoT3fH2GYqQSTo+nujy3/PqXAxP0Uki7Ons1ESdYJKL57mzYTsUOPpLvFjbMQhQeubC64lzSPMmfB1n7SbKKdpOYEO8FdHlxTVyYQBmiF4IChG/1n/qgBJzMsXQLi65V8DkZdwCbXhwIDAQABoyYwJDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBATANBgkqhkiG9w0BAQsFAAOCAgEAQ+G3v3JCbzChBs8HUGx6i2TMm1NZM71+chbA2JF9De8kVd/r2CETvvBRLXcTPcWWA0+PRDGaDmi4TR3bJhXgBStecQZkQtzI3ZcdFfI0rTNeCevfHp5nJjtB+AYomCTKNrlNLpk9YbJosqEKVLQBhlLNYm3PT4CQYJ1NubLLtKF1cn4Z+eayxud1kDrZWFyN5CYewOrtXc8oCynj8H0/NydOuCRQU2c/UXWmvsmlRRffHJEXLqCMitTHV9w4VHEVg9YYssxno/jWtp+b4z8JsE2vkJjs2tmOvfiMupbJx9h6zj2j04rjhf/A+vGPRKOD5WtbbX4An2+szsNLmERBfWUNsO1AaSTc3W+AJOjrG30tewS7jFRPluTtgB+kmozSW0MU/BgAYJuNKRVP8zklVmQqJRbrrxSzrvHzJlz/lvFu9MD7nGtiFqT9VggFjqq5vgn5srBp3Dq4GDGerg+HCDCN9qgnL1gBcKzCMK1oT0bCRWZGckT28WMnfcgZ/fuEVNgQcEXLgWiZWZDBEVlMh7u2QoOr2LXwXuXME8k87rAQbxvGLhyxq2uNxUdH16uljm7p5u2Qobyqxqf2rOGJYCBLK2JP74d6Nl6hD5FGBBaO6mN0Ojn/ShJ1Cq9o3wCHoLYn55wJnXYu7QXAX6230h7ekXpbxPPHO4x0Var5p+8=</certificate>\n" + + " <value>WkmYBCY4heNutMf3tEbyg+Omm+MvWF4EoDmv2vCd259oy3t8URqDqu5vEi3TqQguX0GO3r5mRKCcEYged121xJltC6zShbDMZZNAlB6sqvS6/vIVBBx5jKecUaEpRuQ4ruTyF93YXDi7DgaCNGaYCjkDrnr8lSAyelZl2tfe2BbpOMiwH1fNvI6Xmb++iyMmZGoJo91ovucC635SnnULNUtivL2CjLgU3mKb2uZMB8XPr1t1FOTJEA81ghDU+p3ZrPLxLB3KBTtfAwPQyqStRuY8+3bnPqi7VWeZgfoesvJiPF6q1PraoaL/inlRFo7wr37CS9EtNR/k5cq1UJ4/4Ernvj5k2Zw/IclzYHUGSd3ljCOTJJB6cDtR7WDqprlr1J4nr9hf1Ya4DFJmlX3FXix43Dw6lfk/1gCiWu0y2i1A2NCn0QRxuPh5b385Epj98QlZnd2roB2GfzchJTAxI+oeLc3CowkyLDS5jjuTMERbKbPpkhQu9gtskYtB0I4fEGOMn17+ZrXRcTPJexCS2NGgSqiF4X9Fwe+9XRg3Nk+SoUj9gBCysP8UeSz1POZHQIlZ24mQzxOK2hwGwDtxVchGCrNyf8rh5bZE2hUKHYNH9UWQ+YWrieKeulfP+o1wL9NLZOTz3SHcV/kCv5WqgynzkrKf382FwunxF56NapA=</value>\n" + "</signature>\n"; - public static final PublicKey CERT_1_PUBLIC_KEY; - public static final PrivateKey CERT_1_PRIVATE_KEY; - - static { - try { - CERT_1_PUBLIC_KEY = - SecureBox.decodePublicKey( - new byte[] { - (byte) 0x04, (byte) 0xb8, (byte) 0x00, (byte) 0x11, (byte) 0x18, - (byte) 0x98, (byte) 0x1d, (byte) 0xf0, (byte) 0x6e, (byte) 0xb4, - (byte) 0x94, (byte) 0xfe, (byte) 0x86, (byte) 0xda, (byte) 0x1c, - (byte) 0x07, (byte) 0x8d, (byte) 0x01, (byte) 0xb4, (byte) 0x3a, - (byte) 0xf6, (byte) 0x8d, (byte) 0xdc, (byte) 0x61, (byte) 0xd0, - (byte) 0x46, (byte) 0x49, (byte) 0x95, (byte) 0x0f, (byte) 0x10, - (byte) 0x86, (byte) 0x93, (byte) 0x24, (byte) 0x66, (byte) 0xe0, - (byte) 0x3f, (byte) 0xd2, (byte) 0xdf, (byte) 0xf3, (byte) 0x79, - (byte) 0x20, (byte) 0x1d, (byte) 0x91, (byte) 0x55, (byte) 0xb0, - (byte) 0xe5, (byte) 0xbd, (byte) 0x7a, (byte) 0x8b, (byte) 0x32, - (byte) 0x7d, (byte) 0x25, (byte) 0x53, (byte) 0xa2, (byte) 0xfc, - (byte) 0xa5, (byte) 0x65, (byte) 0xe1, (byte) 0xbd, (byte) 0x21, - (byte) 0x44, (byte) 0x7e, (byte) 0x78, (byte) 0x52, (byte) 0xfa - }); - CERT_1_PRIVATE_KEY = - decodePrivateKey( - new byte[] { - (byte) 0x70, (byte) 0x01, (byte) 0xc7, (byte) 0x87, (byte) 0x32, - (byte) 0x2f, (byte) 0x1c, (byte) 0x9a, (byte) 0x6e, (byte) 0xb1, - (byte) 0x91, (byte) 0xca, (byte) 0x4e, (byte) 0xb5, (byte) 0x44, - (byte) 0xba, (byte) 0xc8, (byte) 0x68, (byte) 0xc6, (byte) 0x0a, - (byte) 0x76, (byte) 0xcb, (byte) 0xd3, (byte) 0x63, (byte) 0x67, - (byte) 0x7c, (byte) 0xb0, (byte) 0x11, (byte) 0x82, (byte) 0x65, - (byte) 0x77, (byte) 0x01 - }); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - public static byte[] getCertPath1Bytes() { - try { - return CertUtils.decodeBase64(CERT_PATH_1_BASE64); - } catch (Exception e){ - throw new RuntimeException(e); - } - } - - public static byte[] getCertPath2Bytes() { - try { - return CertUtils.decodeBase64(CERT_PATH_2_BASE64); - } catch (Exception e){ - throw new RuntimeException(e); - } - } - public static final CertPath CERT_PATH_1; public static final CertPath CERT_PATH_2; + public static final PublicKey CERT_1_PUBLIC_KEY; static { try { - CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); - CERT_PATH_1 = certFactory.generateCertPath( - new ByteArrayInputStream(getCertPath1Bytes()), CERT_PATH_ENCODING); - CERT_PATH_2 = certFactory.generateCertPath( - new ByteArrayInputStream(getCertPath2Bytes()), CERT_PATH_ENCODING); + CERT_PATH_1 = decodeCertPath(CERT_PATH_1_BASE64); + CERT_PATH_2 = decodeCertPath(CERT_PATH_2_BASE64); + CERT_1_PUBLIC_KEY = CERT_PATH_1.getCertificates().get(0).getPublicKey(); } catch (Exception e) { throw new RuntimeException(e); } @@ -323,13 +174,6 @@ public final class TestData { return THM_SIG_XML.getBytes(StandardCharsets.UTF_8); } - private static PrivateKey decodePrivateKey(byte[] keyBytes) throws Exception { - assertThat(keyBytes.length).isEqualTo(32); - BigInteger priv = new BigInteger(/*signum=*/ 1, keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance("EC"); - return keyFactory.generatePrivate(new ECPrivateKeySpec(priv, SecureBox.EC_PARAM_SPEC)); - } - public static SecretKey generateKey() throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM); keyGenerator.init(/*keySize=*/ 256); @@ -576,6 +420,10 @@ public final class TestData { + "2nxygOQKtfb0EPTvVYMErvWrA69rr+wPMSWPetvcDGEZ8hWFr3iRtduExC9sRqnV" + "5DhvZROQSZQtQ+Ja6g8BehUC9gPCES93EOQUYPpRQEeD1CE+1IKTyuH+ApynIKSj" + "5+U1x+OE3UZYTTzEck/TJxTm+Sv4FfCvpwdmDAMTjEZXfuFR+7+5Og=="; + private static final String INSECURE_PRIVATE_KEY_FOR_ENDPOINT1_BASE64 = "" + + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgdCqcARU7lWJVXKY/" + + "+DTlFC0dzcTvh1ufkfZdnoZoR7ShRANCAAS3S6JtfbCyXlLSA+WZHwk0Rr2hdjJX" + + "xGeJLnsAbVkESmoGL9wG2Qty2InpFQ9jFFJHvGR8a73RMQVqmNxwQvFh"; public static byte[] getInsecureCertXmlBytesWithEndpoint1(int serial) { String str = INSECURE_CERT_XML_HEADER; @@ -603,6 +451,13 @@ public final class TestData { return decodeCertPath(INSECURE_CERT_PATH_FOR_ENDPOINT2_BASE64); } + public static PrivateKey getInsecurePrivateKeyForEndpoint1() throws Exception { + byte[] keyBytes = Base64.getDecoder().decode(INSECURE_PRIVATE_KEY_FOR_ENDPOINT1_BASE64); + KeyFactory kf = KeyFactory.getInstance("EC"); + PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(keyBytes); + return kf.generatePrivate(skSpec); + } + private static CertPath decodeCertPath(String base64CertPath) throws Exception { byte[] certPathBytes = Base64.getDecoder().decode(base64CertPath); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); diff --git a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java index 20cf733a860b..761c1f1ea3a5 100644 --- a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java +++ b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java @@ -15,6 +15,7 @@ */ package com.android.server.power; +import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerSaveState; import android.os.Handler; @@ -41,7 +42,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase { private static final float DEFAULT_BRIGHTNESS_FACTOR = 0.5f; private static final float PRECISION = 0.001f; private static final int GPS_MODE = 0; - private static final int DEFAULT_GPS_MODE = 0; + private static final int DEFAULT_GPS_MODE = + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF; private static final String BATTERY_SAVER_CONSTANTS = "vibration_disabled=true," + "animation_disabled=false," + "soundtrigger_disabled=true," @@ -69,6 +71,10 @@ public class BatterySaverPolicyTest extends AndroidTestCase { return mDeviceSpecificConfigResId; } + @Override + boolean isAccessibilityEnabled() { + return mMockAccessibilityEnabled; + } @VisibleForTesting void onChange() { @@ -83,11 +89,15 @@ public class BatterySaverPolicyTest extends AndroidTestCase { private final ArrayMap<String, String> mMockGlobalSettings = new ArrayMap<>(); private int mDeviceSpecificConfigResId = R.string.config_batterySaverDeviceSpecificConfig_1; + private boolean mMockAccessibilityEnabled; + public void setUp() throws Exception { super.setUp(); MockitoAnnotations.initMocks(this); mBatterySaverPolicy = new BatterySaverPolicyForTest(mHandler); mBatterySaverPolicy.systemReady(getContext()); + + mMockAccessibilityEnabled = false; } @SmallTest @@ -101,6 +111,12 @@ public class BatterySaverPolicyTest extends AndroidTestCase { } @SmallTest + public void testGetBatterySaverPolicy_PolicyVibration_WithAccessibilityEnabled() { + mMockAccessibilityEnabled = true; + testServiceDefaultValue_unchanged(ServiceType.VIBRATION); + } + + @SmallTest public void testGetBatterySaverPolicy_PolicySound_DefaultValueCorrect() { testServiceDefaultValue(ServiceType.SOUND); } @@ -117,7 +133,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase { @SmallTest public void testGetBatterySaverPolicy_PolicyAnimation_DefaultValueCorrect() { - testServiceDefaultValue(ServiceType.ANIMATION); + testServiceDefaultValue_unchanged(ServiceType.ANIMATION); } @SmallTest @@ -144,11 +160,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase { @SmallTest public void testGetBatterySaverPolicy_PolicyScreenBrightness_DefaultValueCorrect() { - testServiceDefaultValue(ServiceType.SCREEN_BRIGHTNESS); - - PowerSaveState stateOn = - mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS, true); - assertThat(stateOn.brightnessFactor).isWithin(PRECISION).of(DEFAULT_BRIGHTNESS_FACTOR); + testServiceDefaultValue_unchanged(ServiceType.SCREEN_BRIGHTNESS); } @SmallTest @@ -222,6 +234,17 @@ public class BatterySaverPolicyTest extends AndroidTestCase { assertThat(batterySaverStateOff.batterySaverEnabled).isFalse(); } + private void testServiceDefaultValue_unchanged(@ServiceType int type) { + mBatterySaverPolicy.updateConstantsLocked("", ""); + final PowerSaveState batterySaverStateOn = + mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_ON); + assertThat(batterySaverStateOn.batterySaverEnabled).isFalse(); + + final PowerSaveState batterySaverStateOff = + mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_OFF); + assertThat(batterySaverStateOff.batterySaverEnabled).isFalse(); + } + public void testDeviceSpecific() { mDeviceSpecificConfigResId = R.string.config_batterySaverDeviceSpecificConfig_1; mMockGlobalSettings.put(Global.BATTERY_SAVER_CONSTANTS, ""); diff --git a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java index 6b52ee5f4408..84475bb365b7 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java @@ -19,6 +19,7 @@ package com.android.server.usage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.app.PendingIntent; import android.os.HandlerThread; @@ -49,9 +50,20 @@ public class AppTimeLimitControllerTests { private static final int OBS_ID1 = 1; private static final int OBS_ID2 = 2; private static final int OBS_ID3 = 3; + private static final int OBS_ID4 = 4; + private static final int OBS_ID5 = 5; + private static final int OBS_ID6 = 6; + private static final int OBS_ID7 = 7; + private static final int OBS_ID8 = 8; + private static final int OBS_ID9 = 9; + private static final int OBS_ID10 = 10; + private static final int OBS_ID11 = 11; - private static final long TIME_30_MIN = 30 * 60_1000L; - private static final long TIME_10_MIN = 10 * 60_1000L; + private static final long TIME_30_MIN = 30 * 60_000L; + private static final long TIME_10_MIN = 10 * 60_000L; + + private static final long MAX_OBSERVER_PER_UID = 10; + private static final long MIN_TIME_LIMIT = 4_000L; private static final String[] GROUP1 = { PKG_SOC1, PKG_GAME1, PKG_PROD @@ -93,6 +105,16 @@ public class AppTimeLimitControllerTests { protected long getUptimeMillis() { return mUptimeMillis; } + + @Override + protected long getObserverPerUidLimit() { + return MAX_OBSERVER_PER_UID; + } + + @Override + protected long getMinTimeLimit() { + return MIN_TIME_LIMIT; + } } @Before @@ -233,6 +255,47 @@ public class AppTimeLimitControllerTests { assertFalse(hasObserver(OBS_ID1)); } + /** Verify that App Time Limit Controller will limit the number of observerIds */ + @Test + public void testMaxObserverLimit() throws Exception { + boolean receivedException = false; + int ANOTHER_UID = UID + 1; + addObserver(OBS_ID1, GROUP1, TIME_30_MIN); + addObserver(OBS_ID2, GROUP1, TIME_30_MIN); + addObserver(OBS_ID3, GROUP1, TIME_30_MIN); + addObserver(OBS_ID4, GROUP1, TIME_30_MIN); + addObserver(OBS_ID5, GROUP1, TIME_30_MIN); + addObserver(OBS_ID6, GROUP1, TIME_30_MIN); + addObserver(OBS_ID7, GROUP1, TIME_30_MIN); + addObserver(OBS_ID8, GROUP1, TIME_30_MIN); + addObserver(OBS_ID9, GROUP1, TIME_30_MIN); + addObserver(OBS_ID10, GROUP1, TIME_30_MIN); + // Readding an observer should not cause an IllegalStateException + addObserver(OBS_ID5, GROUP1, TIME_30_MIN); + // Adding an observer for a different uid shouldn't cause an IllegalStateException + mController.addObserver(ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, null, USER_ID); + try { + addObserver(OBS_ID11, GROUP1, TIME_30_MIN); + } catch (IllegalStateException ise) { + receivedException = true; + } + assertTrue("Should have caused an IllegalStateException", receivedException); + } + + /** Verify that addObserver minimum time limit is one minute */ + @Test + public void testMinimumTimeLimit() throws Exception { + boolean receivedException = false; + // adding an observer with a one minute time limit should not cause an exception + addObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT); + try { + addObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1); + } catch (IllegalArgumentException iae) { + receivedException = true; + } + assertTrue("Should have caused an IllegalArgumentException", receivedException); + } + private void moveToForeground(String packageName) { mController.moveToForeground(packageName, "class", USER_ID); } diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java index fbf6691f5bd2..a2af9b80fe36 100644 --- a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -19,6 +19,9 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; +import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; @@ -82,6 +85,25 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { verifyNoMoreInteractionsExceptAsBinder(mMockRunner); } + @Test + public void testCancelAfterRemove_expectIgnored() throws Exception { + final AppWindowToken appWindow = createAppWindowToken(mDisplayContent, + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); + AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(), + false /* isRecentTaskInvisible */); + adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback); + + // Remove the app window so that the animation target can not be created + appWindow.removeImmediately(); + mController.startAnimation(); + mController.cleanupAnimation(REORDER_KEEP_IN_PLACE); + try { + mController.cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "test"); + } catch (Exception e) { + fail("Unexpected failure when canceling animation after finishing it"); + } + } + private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) { verify(binder, atLeast(0)).asBinder(); verifyNoMoreInteractions(binder); diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java index 13478dfded34..325d42aa6293 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java @@ -34,6 +34,7 @@ import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.util.ArraySet; +import android.view.View; import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem; import org.junit.Test; @@ -166,10 +167,12 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa @Test public void testIsRealSnapshotPersistAndLoadSnapshot() { - TaskSnapshot a = createSnapshot(1f /* scale */, true /* isRealSnapshot */, - WINDOWING_MODE_FULLSCREEN); - TaskSnapshot b = createSnapshot(1f /* scale */, false /* isRealSnapshot */, - WINDOWING_MODE_FULLSCREEN); + TaskSnapshot a = new TaskSnapshotBuilder() + .setIsRealSnapshot(true) + .build(); + TaskSnapshot b = new TaskSnapshotBuilder() + .setIsRealSnapshot(false) + .build(); assertTrue(a.isRealSnapshot()); assertFalse(b.isRealSnapshot()); mPersister.persistSnapshot(1, mTestUserId, a); @@ -185,10 +188,12 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa @Test public void testWindowingModePersistAndLoadSnapshot() { - TaskSnapshot a = createSnapshot(1f /* scale */, true /* isRealSnapshot */, - WINDOWING_MODE_FULLSCREEN); - TaskSnapshot b = createSnapshot(1f /* scale */, true /* isRealSnapshot */, - WINDOWING_MODE_PINNED); + TaskSnapshot a = new TaskSnapshotBuilder() + .setWindowingMode(WINDOWING_MODE_FULLSCREEN) + .build(); + TaskSnapshot b = new TaskSnapshotBuilder() + .setWindowingMode(WINDOWING_MODE_PINNED) + .build(); assertTrue(a.getWindowingMode() == WINDOWING_MODE_FULLSCREEN); assertTrue(b.getWindowingMode() == WINDOWING_MODE_PINNED); mPersister.persistSnapshot(1, mTestUserId, a); @@ -203,6 +208,50 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa } @Test + public void testIsTranslucentPersistAndLoadSnapshot() { + TaskSnapshot a = new TaskSnapshotBuilder() + .setIsTranslucent(true) + .build(); + TaskSnapshot b = new TaskSnapshotBuilder() + .setIsTranslucent(false) + .build(); + assertTrue(a.isTranslucent()); + assertFalse(b.isTranslucent()); + mPersister.persistSnapshot(1, mTestUserId, a); + mPersister.persistSnapshot(2, mTestUserId, b); + mPersister.waitForQueueEmpty(); + final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */); + final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */); + assertNotNull(snapshotA); + assertNotNull(snapshotB); + assertTrue(snapshotA.isTranslucent()); + assertFalse(snapshotB.isTranslucent()); + } + + @Test + public void testSystemUiVisibilityPersistAndLoadSnapshot() { + final int lightBarFlags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + TaskSnapshot a = new TaskSnapshotBuilder() + .setSystemUiVisibility(0) + .build(); + TaskSnapshot b = new TaskSnapshotBuilder() + .setSystemUiVisibility(lightBarFlags) + .build(); + assertTrue(a.getSystemUiVisibility() == 0); + assertTrue(b.getSystemUiVisibility() == lightBarFlags); + mPersister.persistSnapshot(1, mTestUserId, a); + mPersister.persistSnapshot(2, mTestUserId, b); + mPersister.waitForQueueEmpty(); + final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */); + final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */); + assertNotNull(snapshotA); + assertNotNull(snapshotB); + assertTrue(snapshotA.getSystemUiVisibility() == 0); + assertTrue(snapshotB.getSystemUiVisibility() == lightBarFlags); + } + + @Test public void testRemoveObsoleteFiles() { mPersister.persistSnapshot(1, mTestUserId, createSnapshot()); mPersister.persistSnapshot(2, mTestUserId, createSnapshot()); diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java index 6a4acbe47beb..8b8604365fa1 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java @@ -85,16 +85,57 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase { } TaskSnapshot createSnapshot(float scale) { - return createSnapshot(scale, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN); + return new TaskSnapshotBuilder() + .setScale(scale) + .build(); } - TaskSnapshot createSnapshot(float scale, boolean isRealSnapshot, int windowingMode) { - final GraphicBuffer buffer = GraphicBuffer.create(100, 100, PixelFormat.RGBA_8888, - USAGE_HW_TEXTURE | USAGE_SW_READ_RARELY | USAGE_SW_READ_RARELY); - Canvas c = buffer.lockCanvas(); - c.drawColor(Color.RED); - buffer.unlockCanvasAndPost(c); - return new TaskSnapshot(buffer, ORIENTATION_PORTRAIT, TEST_INSETS, - scale < 1f /* reducedResolution */, scale, isRealSnapshot, windowingMode); + /** + * Builds a TaskSnapshot. + */ + class TaskSnapshotBuilder { + + private float mScale = 1f; + private boolean mIsRealSnapshot = true; + private boolean mIsTranslucent = false; + private int mWindowingMode = WINDOWING_MODE_FULLSCREEN; + private int mSystemUiVisibility = 0; + + public TaskSnapshotBuilder setScale(float scale) { + mScale = scale; + return this; + } + + public TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) { + mIsRealSnapshot = isRealSnapshot; + return this; + } + + public TaskSnapshotBuilder setIsTranslucent(boolean isTranslucent) { + mIsTranslucent = isTranslucent; + return this; + } + + public TaskSnapshotBuilder setWindowingMode(int windowingMode) { + mWindowingMode = windowingMode; + return this; + } + + public TaskSnapshotBuilder setSystemUiVisibility(int systemUiVisibility) { + mSystemUiVisibility = systemUiVisibility; + return this; + } + + public TaskSnapshot build() { + final GraphicBuffer buffer = GraphicBuffer.create(100, 100, PixelFormat.RGBA_8888, + USAGE_HW_TEXTURE | USAGE_SW_READ_RARELY | USAGE_SW_READ_RARELY); + Canvas c = buffer.lockCanvas(); + c.drawColor(Color.RED); + buffer.unlockCanvasAndPost(c); + return new TaskSnapshot(buffer, ORIENTATION_PORTRAIT, TEST_INSETS, + mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot, mWindowingMode, + mSystemUiVisibility, mIsTranslucent); + } + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java index 54d02d4f2ad2..b19373efd1b0 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java @@ -62,7 +62,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase { GraphicBuffer.USAGE_SW_READ_NEVER | GraphicBuffer.USAGE_SW_WRITE_NEVER); final TaskSnapshot snapshot = new TaskSnapshot(buffer, ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */, - WINDOWING_MODE_FULLSCREEN); + WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */); mSurface = new TaskSnapshotSurface(sWm, new Window(), new Surface(), snapshot, "Test", Color.WHITE, Color.RED, Color.BLUE, sysuiVis, windowFlags, 0, taskBounds, ORIENTATION_PORTRAIT); diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java index 5443e73dd94f..dc057d564a84 100644 --- a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java +++ b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java @@ -26,7 +26,6 @@ import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; -import android.util.Log; import android.util.Xml.Encoding; import com.android.server.UiServiceTestCase; @@ -49,6 +48,20 @@ import java.io.IOException; public class SlicePermissionManagerTest extends UiServiceTestCase { @Test + public void testGrant() { + File sliceDir = new File(mContext.getDataDir(), "system/slices"); + SlicePermissionManager permissions = new SlicePermissionManager(mContext, + TestableLooper.get(this).getLooper(), sliceDir); + Uri uri = new Builder().scheme(ContentResolver.SCHEME_CONTENT) + .authority("authority") + .path("something").build(); + + permissions.grantSliceAccess("my.pkg", 0, "provider.pkg", 0, uri); + + assertTrue(permissions.hasPermission("my.pkg", 0, uri)); + } + + @Test public void testBackup() throws XmlPullParserException, IOException { File sliceDir = new File(mContext.getDataDir(), "system/slices"); Uri uri = new Builder().scheme(ContentResolver.SCHEME_CONTENT) diff --git a/services/usage/java/com/android/server/usage/AppTimeLimitController.java b/services/usage/java/com/android/server/usage/AppTimeLimitController.java index e20185114261..e7c54d8415d7 100644 --- a/services/usage/java/com/android/server/usage/AppTimeLimitController.java +++ b/services/usage/java/com/android/server/usage/AppTimeLimitController.java @@ -26,6 +26,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -58,6 +59,10 @@ public class AppTimeLimitController { private OnLimitReachedListener mListener; + private static final long MAX_OBSERVER_PER_UID = 1000; + + private static final long ONE_MINUTE = 60_000L; + @GuardedBy("mLock") private final SparseArray<UserData> mUsers = new SparseArray<>(); @@ -77,6 +82,9 @@ public class AppTimeLimitController { /** Map of observerId to details of the time limit group */ private SparseArray<TimeLimitGroup> groups = new SparseArray<>(); + /** Map of the number of observerIds registered by uid */ + private SparseIntArray observerIdCounts = new SparseIntArray(); + private UserData(@UserIdInt int userId) { this.userId = userId; } @@ -147,6 +155,18 @@ public class AppTimeLimitController { return SystemClock.uptimeMillis(); } + /** Overrideable for testing purposes */ + @VisibleForTesting + protected long getObserverPerUidLimit() { + return MAX_OBSERVER_PER_UID; + } + + /** Overrideable for testing purposes */ + @VisibleForTesting + protected long getMinTimeLimit() { + return ONE_MINUTE; + } + /** Returns an existing UserData object for the given userId, or creates one */ private UserData getOrCreateUserDataLocked(int userId) { UserData userData = mUsers.get(userId); @@ -171,10 +191,20 @@ public class AppTimeLimitController { */ public void addObserver(int requestingUid, int observerId, String[] packages, long timeLimit, PendingIntent callbackIntent, @UserIdInt int userId) { + + if (timeLimit < getMinTimeLimit()) { + throw new IllegalArgumentException("Time limit must be >= " + getMinTimeLimit()); + } synchronized (mLock) { UserData user = getOrCreateUserDataLocked(userId); + removeObserverLocked(user, requestingUid, observerId, /*readding =*/ true); - removeObserverLocked(user, requestingUid, observerId); + final int observerIdCount = user.observerIdCounts.get(requestingUid, 0); + if (observerIdCount >= getObserverPerUidLimit()) { + throw new IllegalStateException( + "Too many observers added by uid " + requestingUid); + } + user.observerIdCounts.put(requestingUid, observerIdCount + 1); TimeLimitGroup group = new TimeLimitGroup(); group.observerId = observerId; @@ -216,7 +246,7 @@ public class AppTimeLimitController { public void removeObserver(int requestingUid, int observerId, @UserIdInt int userId) { synchronized (mLock) { UserData user = getOrCreateUserDataLocked(userId); - removeObserverLocked(user, requestingUid, observerId); + removeObserverLocked(user, requestingUid, observerId, /*readding =*/ false); } } @@ -232,12 +262,19 @@ public class AppTimeLimitController { } @GuardedBy("mLock") - private void removeObserverLocked(UserData user, int requestingUid, int observerId) { + private void removeObserverLocked(UserData user, int requestingUid, int observerId, + boolean readding) { TimeLimitGroup group = user.groups.get(observerId); if (group != null && group.requestingUid == requestingUid) { removeGroupFromPackageMapLocked(user, group); user.groups.remove(observerId); mHandler.removeMessages(MyHandler.MSG_CHECK_TIMEOUT, group); + final int observerIdCount = user.observerIdCounts.get(requestingUid); + if (observerIdCount <= 1 && !readding) { + user.observerIdCounts.delete(requestingUid); + } else { + user.observerIdCounts.put(requestingUid, observerIdCount - 1); + } } } @@ -321,7 +358,7 @@ public class AppTimeLimitController { // Unregister since the limit has been met and observer was informed. synchronized (mLock) { UserData user = getOrCreateUserDataLocked(group.userId); - removeObserverLocked(user, group.requestingUid, group.observerId); + removeObserverLocked(user, group.requestingUid, group.observerId, false); } } diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index f777f1da47b2..243718a526e9 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -115,6 +115,7 @@ public class UsageStatsService extends SystemService implements PackageManagerInternal mPackageManagerInternal; PackageMonitor mPackageMonitor; IDeviceIdleController mDeviceIdleController; + // Do not use directly. Call getDpmInternal() instead DevicePolicyManagerInternal mDpmInternal; private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>(); @@ -159,7 +160,6 @@ public class UsageStatsService extends SystemService implements mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); - mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class); mHandler = new H(BackgroundThread.get().getLooper()); mAppStandby = new AppStandbyController(getContext(), BackgroundThread.get().getLooper()); @@ -209,6 +209,8 @@ public class UsageStatsService extends SystemService implements public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { mAppStandby.onBootPhase(phase); + // initialize mDpmInternal + getDpmInternal(); mDeviceIdleController = IDeviceIdleController.Stub.asInterface( ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); @@ -228,6 +230,13 @@ public class UsageStatsService extends SystemService implements } } + private DevicePolicyManagerInternal getDpmInternal() { + if (mDpmInternal == null) { + mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class); + } + return mDpmInternal; + } + private class UserActionsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -675,9 +684,10 @@ public class UsageStatsService extends SystemService implements private boolean hasObserverPermission(String callingPackage) { final int callingUid = Binder.getCallingUid(); + DevicePolicyManagerInternal dpmInternal = getDpmInternal(); if (callingUid == Process.SYSTEM_UID - || (mDpmInternal != null - && mDpmInternal.isActiveAdminWithPolicy(callingUid, + || (dpmInternal != null + && dpmInternal.isActiveAdminWithPolicy(callingUid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))) { // Caller is the system or the profile owner, so proceed. return true; @@ -1042,9 +1052,6 @@ public class UsageStatsService extends SystemService implements if (packages == null || packages.length == 0) { throw new IllegalArgumentException("Must specify at least one package"); } - if (timeLimitMs <= 0) { - throw new IllegalArgumentException("Time limit must be > 0"); - } if (callbackIntent == null) { throw new NullPointerException("callbackIntent can't be null"); } diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 165702ca42cd..bfff1487d4be 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -275,6 +275,23 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, options_.version_code_default.value()}); } } + + if (el->FindAttribute("", "platformBuildVersionCode") == nullptr) { + auto versionCode = el->FindAttribute(xml::kSchemaAndroid, "versionCode"); + if (versionCode != nullptr) { + el->attributes.push_back(xml::Attribute{"", "platformBuildVersionCode", + versionCode->value}); + } + } + + if (el->FindAttribute("", "platformBuildVersionName") == nullptr) { + auto versionName = el->FindAttribute(xml::kSchemaAndroid, "versionName"); + if (versionName != nullptr) { + el->attributes.push_back(xml::Attribute{"", "platformBuildVersionName", + versionName->value}); + } + } + return true; }); diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp index 8db937439c55..5f406e81f65d 100644 --- a/tools/aapt2/link/ManifestFixer_test.cpp +++ b/tools/aapt2/link/ManifestFixer_test.cpp @@ -556,6 +556,58 @@ TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) { ASSERT_THAT(manifest, IsNull()); } +TEST_F(ManifestFixerTest, InsertPlatformBuildVersions) { + // Test for insertion when versionCode and versionName are included in the manifest + { + std::string input = R"( + <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" + android:versionCode="27" android:versionName="O"/>)"; + std::unique_ptr<xml::XmlResource> manifest = Verify(input); + ASSERT_THAT(manifest, NotNull()); + + xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode"); + ASSERT_THAT(attr, NotNull()); + EXPECT_THAT(attr->value, StrEq("27")); + attr = manifest->root->FindAttribute("", "platformBuildVersionName"); + ASSERT_THAT(attr, NotNull()); + EXPECT_THAT(attr->value, StrEq("O")); + } + + // Test for insertion when versionCode and versionName defaults are specified + { + std::string input = R"( + <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"/>)"; + ManifestFixerOptions options; + options.version_code_default = {"27"}; + options.version_name_default = {"O"}; + std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options); + ASSERT_THAT(manifest, NotNull()); + + xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode"); + ASSERT_THAT(attr, NotNull()); + EXPECT_THAT(attr->value, StrEq("27")); + attr = manifest->root->FindAttribute("", "platformBuildVersionName"); + ASSERT_THAT(attr, NotNull()); + EXPECT_THAT(attr->value, StrEq("O")); + } + + // Test that the platform build version attributes are not changed if they are currently present + { + std::string input = R"( + <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" + android:versionCode="28" android:versionName="P" + platformBuildVersionCode="27" platformBuildVersionName="O"/>)"; + std::unique_ptr<xml::XmlResource> manifest = Verify(input); + ASSERT_THAT(manifest, NotNull()); + + xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode"); + ASSERT_THAT(attr, NotNull()); + EXPECT_THAT(attr->value, StrEq("27")); + attr = manifest->root->FindAttribute("", "platformBuildVersionName"); + ASSERT_THAT(attr, NotNull()); + EXPECT_THAT(attr->value, StrEq("O")); + } +} TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) { std::string input = R"( |