diff options
106 files changed, 1479 insertions, 1428 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index f0017b93fa81..ba2e4ecd53be 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -232,6 +232,7 @@ package android.content { package android.content.pm { public class ActivityInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable { + method public static boolean isTranslucentOrFloating(android.content.res.TypedArray); field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2 } diff --git a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java index 37b7acfaf5e6..8683ca163fb6 100644 --- a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java +++ b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java @@ -211,10 +211,10 @@ public class RequestSync { mExtras.putBoolean(key, Boolean.valueOf(value)); } else if (opt.equals("-f") || opt.equals("--foreground")) { - mExemptionFlag = ContentResolver.SYNC_EXEMPTION_ACTIVE; + mExemptionFlag = ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET; } else if (opt.equals("-F") || opt.equals("--top")) { - mExemptionFlag = ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP; + mExemptionFlag = ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP; } else { System.err.println("Error: Unknown option: " + opt); diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 49096904735b..9355862fa6a3 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -741,6 +741,7 @@ Landroid/app/IWallpaperManager;->getHeightHint()I Landroid/app/IWallpaperManager;->getWallpaper(Ljava/lang/String;Landroid/app/IWallpaperManagerCallback;ILandroid/os/Bundle;I)Landroid/os/ParcelFileDescriptor; Landroid/app/IWallpaperManager;->getWallpaperInfo(I)Landroid/app/WallpaperInfo; Landroid/app/IWallpaperManager;->getWidthHint()I +Landroid/app/IWallpaperManager;->hasNamedWallpaper(Ljava/lang/String;)Z Landroid/app/IWallpaperManager;->setWallpaperComponent(Landroid/content/ComponentName;)V Landroid/app/IWallpaperManagerCallback$Stub;-><init>()V Landroid/app/IWallpaperManagerCallback;->onWallpaperChanged()V @@ -923,6 +924,7 @@ Landroid/app/Service;->setForeground(Z)V Landroid/app/ServiceConnectionLeaked;-><init>(Ljava/lang/String;)V Landroid/app/SharedPreferencesImpl;-><init>(Ljava/io/File;I)V Landroid/app/SharedPreferencesImpl;->mFile:Ljava/io/File; +Landroid/app/SharedPreferencesImpl;->startLoadFromDisk()V Landroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V Landroid/app/StatusBarManager;-><init>(Landroid/content/Context;)V Landroid/app/StatusBarManager;->collapsePanels()V @@ -5116,6 +5118,7 @@ Landroid/service/wallpaper/IWallpaperService$Stub;->asInterface(Landroid/os/IBin Landroid/service/wallpaper/WallpaperService$Engine;->mPendingXOffset:F Landroid/service/wallpaper/WallpaperService$Engine;->setFixedSizeAllowed(Z)V Landroid/service/wallpaper/WallpaperService;->MSG_WINDOW_RESIZED:I +Landroid/speech/IRecognitionListener;->onEvent(ILandroid/os/Bundle;)V Landroid/speech/tts/TextToSpeech;->getCurrentEngine()Ljava/lang/String; Landroid/speech/tts/TextToSpeech;->mConnectingServiceConnection:Landroid/speech/tts/TextToSpeech$Connection; Landroid/speech/tts/TextToSpeech;->mCurrentEngine:Ljava/lang/String; @@ -5433,6 +5436,7 @@ Landroid/telephony/SmsMessage;->mWrappedSmsMessage:Lcom/android/internal/telepho Landroid/telephony/SmsMessage;->setSubId(I)V Landroid/telephony/SmsMessage;->useCdmaFormatForMoSms()Z Landroid/telephony/SmsMessage;->useCdmaFormatForMoSms(I)Z +Landroid/telephony/SubscriptionInfo;->getNameSource()I Landroid/telephony/SubscriptionManager;-><init>(Landroid/content/Context;)V Landroid/telephony/SubscriptionManager;->CONTENT_URI:Landroid/net/Uri; Landroid/telephony/SubscriptionManager;->DEFAULT_SUBSCRIPTION_ID:I @@ -5469,6 +5473,8 @@ Landroid/telephony/TelephonyManager;->getDefault()Landroid/telephony/TelephonyMa Landroid/telephony/TelephonyManager;->getDeviceSoftwareVersion(I)Ljava/lang/String; Landroid/telephony/TelephonyManager;->getGroupIdLevel1(I)Ljava/lang/String; Landroid/telephony/TelephonyManager;->getIccAuthentication(IIILjava/lang/String;)Ljava/lang/String; +Landroid/telephony/TelephonyManager;->getImsConfig(II)Landroid/telephony/ims/aidl/IImsConfig; +Landroid/telephony/TelephonyManager;->getImsRegistration(II)Landroid/telephony/ims/aidl/IImsRegistration; Landroid/telephony/TelephonyManager;->getIsimImpi()Ljava/lang/String; Landroid/telephony/TelephonyManager;->getIsimImpu()[Ljava/lang/String; Landroid/telephony/TelephonyManager;->getIsimPcscf()[Ljava/lang/String; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index fcab8c10db9e..c58b91e39d0f 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1555,6 +1555,7 @@ public class AppOpsManager { private final long[] mRejectTimes; private final int mDuration; private final int mProxyUid; + private final boolean mRunning; private final String mProxyPackageName; public OpEntry(int op, int mode, long time, long rejectTime, int duration, @@ -1566,12 +1567,13 @@ public class AppOpsManager { mTimes[0] = time; mRejectTimes[0] = rejectTime; mDuration = duration; + mRunning = duration == -1; mProxyUid = proxyUid; mProxyPackageName = proxyPackage; } public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration, - int proxyUid, String proxyPackage) { + boolean running, int proxyUid, String proxyPackage) { mOp = op; mMode = mode; mTimes = new long[_NUM_UID_STATE]; @@ -1579,10 +1581,16 @@ public class AppOpsManager { System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE); System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE); mDuration = duration; + mRunning = running; mProxyUid = proxyUid; mProxyPackageName = proxyPackage; } + public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration, + int proxyUid, String proxyPackage) { + this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage); + } + public int getOp() { return mOp; } @@ -1632,7 +1640,7 @@ public class AppOpsManager { } public boolean isRunning() { - return mDuration == -1; + return mRunning; } public int getDuration() { @@ -1659,6 +1667,7 @@ public class AppOpsManager { dest.writeLongArray(mTimes); dest.writeLongArray(mRejectTimes); dest.writeInt(mDuration); + dest.writeBoolean(mRunning); dest.writeInt(mProxyUid); dest.writeString(mProxyPackageName); } @@ -1669,6 +1678,7 @@ public class AppOpsManager { mTimes = source.createLongArray(); mRejectTimes = source.createLongArray(); mDuration = source.readInt(); + mRunning = source.readBoolean(); mProxyUid = source.readInt(); mProxyPackageName = source.readString(); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 54cb09596479..8d56c3ecec15 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6601,22 +6601,33 @@ public class Notification implements Parcelable * Helper class for generating large-format notifications that include multiple back-and-forth * messages of varying types between any number of people. * - * <br> + * <p> * If the platform does not provide large-format notifications, this method has no effect. The * user will always see the normal notification view. - * <br> - * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like - * so: + * + * <p> + * If the app is targeting Android P and above, it is required to use the {@link Person} + * class in order to get an optimal rendering of the notification and its avatars. For + * conversations involving multiple people, the app should also make sure that it marks the + * conversation as a group with {@link #setGroupConversation(boolean)}. + * + * <p> + * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior. + * Here's an example of how this may be used: * <pre class="prettyprint"> * + * Person user = new Person.Builder().setIcon(userIcon).setName(userName).build(); + * MessagingStyle style = new MessagingStyle(user) + * .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson()) + * .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson()) + * .setGroupConversation(hasMultiplePeople()); + * * Notification noti = new Notification.Builder() - * .setContentTitle("2 new messages wtih " + sender.toString()) + * .setContentTitle("2 new messages with " + sender.toString()) * .setContentText(subject) * .setSmallIcon(R.drawable.new_message) * .setLargeIcon(aBitmap) - * .setStyle(new Notification.MessagingStyle(resources.getString(R.string.reply_name)) - * .addMessage(messages[0].getText(), messages[0].getTime(), messages[0].getSender()) - * .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getSender())) + * .setStyle(style) * .build(); * </pre> */ @@ -6826,7 +6837,9 @@ public class Notification implements Parcelable } /** - * Sets whether this conversation notification represents a group. + * Sets whether this conversation notification represents a group. If the app is targeting + * Android P, this is required if the app wants to display the largeIcon set with + * {@link Notification.Builder#setLargeIcon(Bitmap)}, otherwise it will be hidden. * * @param isGroupConversation {@code true} if the conversation represents a group, * {@code false} otherwise. @@ -7048,12 +7061,21 @@ public class Notification implements Parcelable CharSequence conversationTitle = !TextUtils.isEmpty(super.mBigContentTitle) ? super.mBigContentTitle : mConversationTitle; - boolean isOneToOne = TextUtils.isEmpty(conversationTitle); + boolean atLeastP = mBuilder.mContext.getApplicationInfo().targetSdkVersion + >= Build.VERSION_CODES.P; + boolean isOneToOne; CharSequence nameReplacement = null; - if (hasOnlyWhiteSpaceSenders()) { - isOneToOne = true; - nameReplacement = conversationTitle; - conversationTitle = null; + Icon avatarReplacement = null; + if (!atLeastP) { + isOneToOne = TextUtils.isEmpty(conversationTitle); + avatarReplacement = mBuilder.mN.mLargeIcon; + if (hasOnlyWhiteSpaceSenders()) { + isOneToOne = true; + nameReplacement = conversationTitle; + conversationTitle = null; + } + } else { + isOneToOne = !isGroupConversation(); } TemplateBindResult bindResult = new TemplateBindResult(); RemoteViews contentView = mBuilder.applyStandardTemplateWithActions( @@ -7076,8 +7098,8 @@ public class Notification implements Parcelable mBuilder.getSecondaryTextColor()); contentView.setBoolean(R.id.status_bar_latest_event_content, "setDisplayImagesAtEnd", displayImagesAtEnd); - contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon", - mBuilder.mN.mLargeIcon); + contentView.setIcon(R.id.status_bar_latest_event_content, "setAvatarReplacement", + avatarReplacement); contentView.setCharSequence(R.id.status_bar_latest_event_content, "setNameReplacement", nameReplacement); contentView.setBoolean(R.id.status_bar_latest_event_content, "setIsOneToOne", diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java index 2d007adf86e6..60e8a121dc45 100644 --- a/core/java/android/app/WallpaperColors.java +++ b/core/java/android/app/WallpaperColors.java @@ -144,13 +144,6 @@ public final class WallpaperColors implements Parcelable { * @param bitmap Source where to extract from. */ public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap) { - return fromBitmap(bitmap, false /* computeHints */); - } - - /** - * @hide - */ - public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap, boolean computeHints) { if (bitmap == null) { throw new IllegalArgumentException("Bitmap can't be null"); } @@ -200,7 +193,7 @@ public final class WallpaperColors implements Parcelable { } } - int hints = computeHints ? calculateDarkHints(bitmap) : 0; + int hints = calculateDarkHints(bitmap); if (shouldRecycle) { bitmap.recycle(); diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index 5e7584122dd6..4c22c94266d7 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -15,6 +15,8 @@ */ package android.app.slice; +import static android.app.slice.Slice.SUBTYPE_COLOR; + import android.annotation.NonNull; import android.app.PendingIntent; import android.content.ComponentName; @@ -29,6 +31,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ProviderInfo; import android.database.ContentObserver; import android.database.Cursor; +import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -39,6 +42,8 @@ import android.os.StrictMode; import android.os.StrictMode.ThreadPolicy; import android.util.ArraySet; import android.util.Log; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; import java.util.ArrayList; import java.util.Arrays; @@ -472,12 +477,25 @@ public abstract class SliceProvider extends ContentProvider { } Slice.Builder parent = new Slice.Builder(sliceUri); Slice.Builder childAction = new Slice.Builder(parent) + .addIcon(Icon.createWithResource(context, + com.android.internal.R.drawable.ic_permission), null, + Collections.emptyList()) .addHints(Arrays.asList(Slice.HINT_TITLE, Slice.HINT_SHORTCUT)) .addAction(action, new Slice.Builder(parent).build(), null); + TypedValue tv = new TypedValue(); + new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light) + .getTheme().resolveAttribute(android.R.attr.colorAccent, tv, true); + int deviceDefaultAccent = tv.data; + parent.addSubSlice(new Slice.Builder(sliceUri.buildUpon().appendPath("permission").build()) + .addIcon(Icon.createWithResource(context, + com.android.internal.R.drawable.ic_arrow_forward), null, + Collections.emptyList()) .addText(getPermissionString(context, callingPackage), null, Collections.emptyList()) + .addInt(deviceDefaultAccent, SUBTYPE_COLOR, + Collections.emptyList()) .addSubSlice(childAction.build(), null) .build(), null); return parent.addHints(Arrays.asList(Slice.HINT_PERMISSION_REQUEST)).build(); diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 503ca6c3712d..3e90af356da0 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -399,16 +399,20 @@ public final class UsageEvents implements Parcelable { * {@hide} */ public UsageEvents(Parcel in) { - mEventCount = in.readInt(); - mIndex = in.readInt(); + byte[] bytes = in.readBlob(); + Parcel data = Parcel.obtain(); + data.unmarshall(bytes, 0, bytes.length); + data.setDataPosition(0); + mEventCount = data.readInt(); + mIndex = data.readInt(); if (mEventCount > 0) { - mStringPool = in.createStringArray(); + mStringPool = data.createStringArray(); - final int listByteLength = in.readInt(); - final int positionInParcel = in.readInt(); + final int listByteLength = data.readInt(); + final int positionInParcel = data.readInt(); mParcel = Parcel.obtain(); mParcel.setDataPosition(0); - mParcel.appendFrom(in, in.dataPosition(), listByteLength); + mParcel.appendFrom(data, data.dataPosition(), listByteLength); mParcel.setDataSize(mParcel.dataPosition()); mParcel.setDataPosition(positionInParcel); } @@ -586,10 +590,11 @@ public final class UsageEvents implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mEventCount); - dest.writeInt(mIndex); + Parcel data = Parcel.obtain(); + data.writeInt(mEventCount); + data.writeInt(mIndex); if (mEventCount > 0) { - dest.writeStringArray(mStringPool); + data.writeStringArray(mStringPool); if (mEventsToWrite != null) { // Write out the events @@ -604,31 +609,34 @@ public final class UsageEvents implements Parcelable { final int listByteLength = p.dataPosition(); // Write the total length of the data. - dest.writeInt(listByteLength); + data.writeInt(listByteLength); // Write our current position into the data. - dest.writeInt(0); + data.writeInt(0); // Write the data. - dest.appendFrom(p, 0, listByteLength); + data.appendFrom(p, 0, listByteLength); } finally { p.recycle(); } } else if (mParcel != null) { // Write the total length of the data. - dest.writeInt(mParcel.dataSize()); + data.writeInt(mParcel.dataSize()); // Write out current position into the data. - dest.writeInt(mParcel.dataPosition()); + data.writeInt(mParcel.dataPosition()); // Write the data. - dest.appendFrom(mParcel, 0, mParcel.dataSize()); + data.appendFrom(mParcel, 0, mParcel.dataSize()); } else { throw new IllegalStateException( "Either mParcel or mEventsToWrite must not be null"); } } + // Data can be too large for a transact. Write the data as a Blob, which will be written to + // ashmem if too large. + dest.writeBlob(data.marshall()); } public static final Creator<UsageEvents> CREATOR = new Creator<UsageEvents>() { diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 1b07784e4cee..72d209abda16 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -184,7 +184,11 @@ public final class UsageStatsManager { /** @hide */ public static final int REASON_SUB_USAGE_SLICE_PINNED_PRIV = 0x000A; /** @hide */ - public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000B; + public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE = 0x000B; + /** @hide */ + public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C; + /** @hide */ + public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D; /** @hide */ public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001; @@ -669,13 +673,19 @@ public final class UsageStatsManager { sb.append("-sa"); break; case REASON_SUB_USAGE_SLICE_PINNED: - sb.append("slp"); + sb.append("-lp"); break; case REASON_SUB_USAGE_SLICE_PINNED_PRIV: - sb.append("slpp"); + sb.append("-lv"); + break; + case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE: + sb.append("-en"); + break; + case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE: + sb.append("-ed"); break; case REASON_SUB_USAGE_EXEMPTED_SYNC_START: - sb.append("es"); + sb.append("-es"); break; } break; diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java index b8628a4d446b..1a656ab39373 100644 --- a/core/java/android/app/usage/UsageStatsManagerInternal.java +++ b/core/java/android/app/usage/UsageStatsManagerInternal.java @@ -245,7 +245,15 @@ public abstract class UsageStatsManagerInternal { int numDeferredJobs, long timeSinceLastJobRun); /** - * Report a sync that was scheduled by an active app is about to be executed. + * Report a sync is scheduled by a foreground app. + * + * @param packageName name of the package that owns the sync adapter. + * @param userId which user the app is associated with + */ + public abstract void reportExemptedSyncScheduled(String packageName, @UserIdInt int userId); + + /** + * Report a sync that was scheduled by a foreground app is about to be executed. * * @param packageName name of the package that owns the sync adapter. * @param userId which user the app is associated with diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index f7908b699d56..32a674363535 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -520,27 +520,36 @@ public abstract class ContentResolver { public static final int SYNC_EXEMPTION_NONE = 0; /** - * When executing a sync with this exemption, we'll put the target app in the ACTIVE bucket - * for 10 minutes. This will allow the sync adapter to schedule/run further syncs and jobs. + * Exemption given to a sync request made by a foreground app (including + * PROCESS_STATE_IMPORTANT_FOREGROUND). + * + * At the schedule time, we promote the sync adapter app for a higher bucket: + * - If the device is not dozing (so the sync will start right away) + * promote to ACTIVE for 1 hour. + * - If the device is dozing (so the sync *won't* start right away), + * promote to WORKING_SET for 4 hours, so it'll get a higher chance to be started once the + * device comes out of doze. + * - When the sync actually starts, we promote the sync adapter app to ACTIVE for 10 minutes, + * so it can schedule and start more syncs without getting throttled, even when the first + * operation was canceled and now we're retrying. + * * - * Note this will still *not* let RARE apps to run syncs, because they still won't get network - * connection. * @hide */ - public static final int SYNC_EXEMPTION_ACTIVE = 1; + public static final int SYNC_EXEMPTION_PROMOTE_BUCKET = 1; /** - * In addition to {@link #SYNC_EXEMPTION_ACTIVE}, we put the sync adapter app in the + * In addition to {@link #SYNC_EXEMPTION_PROMOTE_BUCKET}, we put the sync adapter app in the * temp whitelist for 10 minutes, so that even RARE apps can run syncs right away. * @hide */ - public static final int SYNC_EXEMPTION_ACTIVE_WITH_TEMP = 2; + public static final int SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP = 2; /** @hide */ @IntDef(flag = false, prefix = { "SYNC_EXEMPTION_" }, value = { SYNC_EXEMPTION_NONE, - SYNC_EXEMPTION_ACTIVE, - SYNC_EXEMPTION_ACTIVE_WITH_TEMP, + SYNC_EXEMPTION_PROMOTE_BUCKET, + SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP, }) @Retention(RetentionPolicy.SOURCE) public @interface SyncExemption {} diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 14617116bc7f..0e91a2927c79 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1188,6 +1188,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { * Determines whether the {@link Activity} is considered translucent or floating. * @hide */ + @TestApi public static boolean isTranslucentOrFloating(TypedArray attributes) { final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 15aedd7cf502..63de8bf49f8b 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1664,7 +1664,8 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device includes at least one form of audio - * output, such as speakers, audio jack or streaming over bluetooth + * output, as defined in the Android Compatibility Definition Document (CDD) + * <a href="https://source.android.com/compatibility/android-cdd#7_8_audio">section 7.8 Audio</a>. */ @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output"; diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index 262de15a94d2..1275a852ee2b 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -813,6 +813,10 @@ public abstract class CameraMetadata<TKey> { /** * <p>The camera device is a logical camera backed by two or more physical cameras that are * also exposed to the application.</p> + * <p>Camera application shouldn't assume that there are at most 1 rear camera and 1 front + * camera in the system. For an application that switches between front and back cameras, + * the recommendation is to switch between the first rear camera and the first front + * camera in the list of supported camera devices.</p> * <p>This capability requires the camera device to support the following:</p> * <ul> * <li>This camera device must list the following static metadata entries in {@link android.hardware.camera2.CameraCharacteristics }:<ul> diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 0ae5394e6cb9..3d76c2501440 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -138,6 +138,15 @@ public class Binder implements IBinder { } /** + * Dump proxy debug information. + * + * @hide + */ + public static void dumpProxyDebugInfo() { + BinderProxy.dumpProxyDebugInfo(); + } + + /** * Check if binder transaction tracing is enabled. * * @hide @@ -941,8 +950,7 @@ final class BinderProxy implements IBinder { // about to crash. final int totalUnclearedSize = unclearedSize(); if (totalUnclearedSize >= CRASH_AT_SIZE) { - dumpProxyInterfaceCounts(); - dumpPerUidProxyCounts(); + dumpProxyDebugInfo(); Runtime.getRuntime().gc(); throw new AssertionError("Binder ProxyMap has too many entries: " + totalSize + " (total), " + totalUnclearedSize + " (uncleared), " @@ -1027,6 +1035,14 @@ final class BinderProxy implements IBinder { private static ProxyMap sProxyMap = new ProxyMap(); /** + * @hide + */ + public static void dumpProxyDebugInfo() { + sProxyMap.dumpProxyInterfaceCounts(); + sProxyMap.dumpPerUidProxyCounts(); + } + + /** * Return a BinderProxy for IBinder. * This method is thread-hostile! The (native) caller serializes getInstance() calls using * gProxyLock. diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java index 105cd3867463..0257891e5f38 100644 --- a/core/java/android/service/autofill/FillCallback.java +++ b/core/java/android/service/autofill/FillCallback.java @@ -70,7 +70,7 @@ public final class FillCallback { assertNotCalled(); mCalled = true; try { - mCallback.onFailure(message); + mCallback.onFailure(mRequestId, message); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } diff --git a/core/java/android/service/autofill/IFillCallback.aidl b/core/java/android/service/autofill/IFillCallback.aidl index 2bb3e9acd3e1..1bad1d7f474a 100644 --- a/core/java/android/service/autofill/IFillCallback.aidl +++ b/core/java/android/service/autofill/IFillCallback.aidl @@ -28,5 +28,5 @@ import android.service.autofill.FillResponse; interface IFillCallback { void onCancellable(in ICancellationSignal cancellation); void onSuccess(in FillResponse response); - void onFailure(CharSequence message); + void onFailure(int requestId, CharSequence message); } diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index 2d8b4d482b21..c86149907323 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -43,7 +43,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_bluetooth_while_driving", "false"); DEFAULT_FLAGS.put("settings_data_usage_v2", "true"); DEFAULT_FLAGS.put("settings_audio_switcher", "true"); - DEFAULT_FLAGS.put("settings_systemui_theme", "false"); + DEFAULT_FLAGS.put("settings_systemui_theme", "true"); } /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 7c814f4a5773..ed67075d38d6 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1630,6 +1630,8 @@ public final class ViewRootImpl implements ViewParent, contentInsets.top + outsets.top, contentInsets.right + outsets.right, contentInsets.bottom + outsets.bottom); } + contentInsets = ensureInsetsNonNegative(contentInsets, "content"); + stableInsets = ensureInsetsNonNegative(stableInsets, "stable"); mLastWindowInsets = new WindowInsets(contentInsets, null /* windowDecorInsets */, stableInsets, mContext.getResources().getConfiguration().isScreenRound(), @@ -1638,6 +1640,17 @@ public final class ViewRootImpl implements ViewParent, return mLastWindowInsets; } + private Rect ensureInsetsNonNegative(Rect insets, String kind) { + if (insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0) { + Log.wtf(mTag, "Negative " + kind + "Insets: " + insets + ", mFirst=" + mFirst); + return new Rect(Math.max(0, insets.left), + Math.max(0, insets.top), + Math.max(0, insets.right), + Math.max(0, insets.bottom)); + } + return insets; + } + void dispatchApplyInsets(View host) { WindowInsets insets = getWindowInsets(true /* forceConstruct */); final boolean dispatchCutout = (mWindowAttributes.layoutInDisplayCutoutMode diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 4c7dc116d167..7555ffff3e38 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -1899,10 +1899,20 @@ public final class AutofillManager { } private LogMaker newLog(int category) { - return new LogMaker(category) - .setPackageName(mContext.getPackageName()) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, - isCompatibilityModeEnabledLocked() ? 1 : 0); + final LogMaker log = new LogMaker(category) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SESSION_ID, mSessionId); + + if (isCompatibilityModeEnabledLocked()) { + log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1); + } + final AutofillClient client = getClient(); + if (client == null) { + // Client should never be null here, but it doesn't hurt to check... + log.setPackageName(mContext.getPackageName()); + } else { + log.setComponentName(client.autofillClientGetComponentName()); + } + return log; } /** diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index d22b1e66b596..6cb0eaa7f47d 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -285,10 +285,14 @@ public final class SelectionActionModeHelper { final Layout layout = mTextView.getLayout(); final Runnable onAnimationEndCallback = () -> { - if (result.mStart >= 0 && result.mEnd <= getText(mTextView).length() + final SelectionResult startSelectionResult; + if (result != null && result.mStart >= 0 && result.mEnd <= getText(mTextView).length() && result.mStart <= result.mEnd) { - startSelectionActionMode(result); + startSelectionResult = result; + } else { + startSelectionResult = null; } + startSelectionActionMode(startSelectionResult); }; // TODO do not trigger the animation if the change included only non-printable characters final boolean didSelectionChange = diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index 294007946c77..9171959537c8 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -156,9 +156,12 @@ public class AssistUtils { if (activeServiceSupportsAssistGesture()) { return getActiveServiceComponentName(); } - - Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) - .getAssistIntent(false); + final SearchManager searchManager = + (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); + if (searchManager == null) { + return null; + } + final Intent intent = searchManager.getAssistIntent(false); PackageManager pm = mContext.getPackageManager(); ResolveInfo info = pm.resolveActivityAsUser(intent, PackageManager.MATCH_DEFAULT_ONLY, userId); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 571878d183ee..4f567d239896 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -76,6 +76,7 @@ import android.widget.Space; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.ResolverActivity; import com.android.internal.app.ResolverActivity.TargetInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -932,7 +933,7 @@ public class ChooserActivity extends ResolverActivity { public static final int TARGET_SERVICE = 1; public static final int TARGET_STANDARD = 2; - private static final int MAX_SERVICE_TARGETS = 8; + private static final int MAX_SERVICE_TARGETS = 4; private static final int MAX_TARGETS_PER_SERVICE = 4; private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>(); @@ -1189,123 +1190,20 @@ public class ChooserActivity extends ResolverActivity { } } - static class RowScale { - private static final int DURATION = 400; - - float mScale; - ChooserRowAdapter mAdapter; - private final ObjectAnimator mAnimator; - - public static final FloatProperty<RowScale> PROPERTY = - new FloatProperty<RowScale>("scale") { - @Override - public void setValue(RowScale object, float value) { - object.mScale = value; - object.mAdapter.notifyDataSetChanged(); - } - - @Override - public Float get(RowScale object) { - return object.mScale; - } - }; - - public RowScale(@NonNull ChooserRowAdapter adapter, float from, float to) { - mAdapter = adapter; - mScale = from; - if (from == to) { - mAnimator = null; - return; - } - - mAnimator = ObjectAnimator.ofFloat(this, PROPERTY, from, to) - .setDuration(DURATION); - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - mAdapter.onAnimationStart(); - } - @Override - public void onAnimationEnd(Animator animation) { - mAdapter.onAnimationEnd(); - } - }); - } - - public RowScale setInterpolator(Interpolator interpolator) { - if (mAnimator != null) { - mAnimator.setInterpolator(interpolator); - } - return this; - } - - public float get() { - return mScale; - } - - public void startAnimation() { - if (mAnimator != null) { - mAnimator.start(); - } - } - - public void cancelAnimation() { - if (mAnimator != null) { - mAnimator.cancel(); - } - } - } - class ChooserRowAdapter extends BaseAdapter { private ChooserListAdapter mChooserListAdapter; private final LayoutInflater mLayoutInflater; private final int mColumnCount = 4; - private RowScale[] mServiceTargetScale; - private final Interpolator mInterpolator; private int mAnimationCount = 0; public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) { mChooserListAdapter = wrappedAdapter; mLayoutInflater = LayoutInflater.from(ChooserActivity.this); - mInterpolator = AnimationUtils.loadInterpolator(ChooserActivity.this, - android.R.interpolator.decelerate_quint); - wrappedAdapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { super.onChanged(); - final int rcount = getServiceTargetRowCount(); - if (mServiceTargetScale == null - || mServiceTargetScale.length != rcount) { - RowScale[] old = mServiceTargetScale; - int oldRCount = old != null ? old.length : 0; - mServiceTargetScale = new RowScale[rcount]; - if (old != null && rcount > 0) { - System.arraycopy(old, 0, mServiceTargetScale, 0, - Math.min(old.length, rcount)); - } - - for (int i = rcount; i < oldRCount; i++) { - old[i].cancelAnimation(); - } - - for (int i = oldRCount; i < rcount; i++) { - final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f) - .setInterpolator(mInterpolator); - mServiceTargetScale[i] = rs; - } - - // Start the animations in a separate loop. - // The process of starting animations will result in - // binding views to set up initial values, and we must - // have ALL of the new RowScale objects created above before - // we get started. - for (int i = oldRCount; i < rcount; i++) { - mServiceTargetScale[i].startAnimation(); - } - } - notifyDataSetChanged(); } @@ -1313,39 +1211,10 @@ public class ChooserActivity extends ResolverActivity { public void onInvalidated() { super.onInvalidated(); notifyDataSetInvalidated(); - if (mServiceTargetScale != null) { - for (RowScale rs : mServiceTargetScale) { - rs.cancelAnimation(); - } - } } }); } - private float getRowScale(int rowPosition) { - final int start = getCallerTargetRowCount(); - final int end = start + getServiceTargetRowCount(); - if (rowPosition >= start && rowPosition < end) { - return mServiceTargetScale[rowPosition - start].get(); - } - return 1.f; - } - - public void onAnimationStart() { - final boolean lock = mAnimationCount == 0; - mAnimationCount++; - if (lock) { - mResolverDrawerLayout.setDismissLocked(true); - } - } - - public void onAnimationEnd() { - mAnimationCount--; - if (mAnimationCount == 0) { - mResolverDrawerLayout.setDismissLocked(false); - } - } - @Override public int getCount() { return (int) ( @@ -1360,9 +1229,9 @@ public class ChooserActivity extends ResolverActivity { (float) mChooserListAdapter.getCallerTargetCount() / mColumnCount); } + // There can be at most one row of service targets. public int getServiceTargetRowCount() { - return (int) Math.ceil( - (float) mChooserListAdapter.getServiceTargetCount() / mColumnCount); + return (int) mChooserListAdapter.getServiceTargetCount() == 0 ? 0 : 1; } @Override @@ -1485,8 +1354,7 @@ public class ChooserActivity extends ResolverActivity { } final int oldHeight = holder.row.getLayoutParams().height; - holder.row.getLayoutParams().height = Math.max(1, - (int) (holder.measuredRowHeight * getRowScale(rowPosition))); + holder.row.getLayoutParams().height = Math.max(1, holder.measuredRowHeight); if (holder.row.getLayoutParams().height != oldHeight) { holder.row.requestLayout(); } @@ -1728,7 +1596,7 @@ public class ChooserActivity extends ResolverActivity { final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView); int height = ((RowViewHolder) (v.getTag())).measuredRowHeight; - offset += (int) (height * mChooserRowAdapter.getRowScale(pos)); + offset += (int) (height); if (vt >= 0) { mCachedViewType = vt; diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java index d468ce38709f..03a734d8537e 100644 --- a/core/java/com/android/internal/widget/MessagingLayout.java +++ b/core/java/com/android/internal/widget/MessagingLayout.java @@ -82,7 +82,7 @@ public class MessagingLayout extends FrameLayout { private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint mTextPaint = new Paint(); private CharSequence mConversationTitle; - private Icon mLargeIcon; + private Icon mAvatarReplacement; private boolean mIsOneToOne; private ArrayList<MessagingGroup> mAddedGroups = new ArrayList<>(); private Person mUser; @@ -125,8 +125,8 @@ public class MessagingLayout extends FrameLayout { } @RemotableViewMethod - public void setLargeIcon(Icon icon) { - mLargeIcon = icon; + public void setAvatarReplacement(Icon icon) { + mAvatarReplacement = icon; } @RemotableViewMethod @@ -228,7 +228,7 @@ public class MessagingLayout extends FrameLayout { boolean isOwnMessage = group.getSender() == mUser; CharSequence senderName = group.getSenderName(); if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName) - || (mIsOneToOne && mLargeIcon != null && !isOwnMessage)) { + || (mIsOneToOne && mAvatarReplacement != null && !isOwnMessage)) { continue; } String symbol = uniqueNames.get(senderName); @@ -246,8 +246,8 @@ public class MessagingLayout extends FrameLayout { if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName)) { continue; } - if (mIsOneToOne && mLargeIcon != null && group.getSender() != mUser) { - group.setAvatar(mLargeIcon); + if (mIsOneToOne && mAvatarReplacement != null && group.getSender() != mUser) { + group.setAvatar(mAvatarReplacement); } else { Icon cachedIcon = cachedAvatars.get(senderName); if (cachedIcon == null) { diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index 418e15be8504..9d2458863c9f 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -117,6 +117,7 @@ message ActivityRecordProto { optional bool visible = 4; optional bool front_of_task = 5; optional int32 proc_id = 6; + optional bool translucent = 7; } message KeyguardControllerProto { diff --git a/core/proto/android/server/forceappstandbytracker.proto b/core/proto/android/server/forceappstandbytracker.proto index 1113d6a9ef39..8c71b0ba27eb 100644 --- a/core/proto/android/server/forceappstandbytracker.proto +++ b/core/proto/android/server/forceappstandbytracker.proto @@ -25,7 +25,7 @@ option java_multiple_files = true; // Dump from com.android.server.ForceAppStandbyTracker. // -// Next ID: 12 +// Next ID: 13 message ForceAppStandbyTrackerProto { option (.android.msg_privacy).dest = DEST_AUTOMATIC; @@ -41,6 +41,9 @@ message ForceAppStandbyTrackerProto { // App ids that are in power-save whitelist. repeated int32 power_save_whitelist_app_ids = 3; + // App ids that are in power-save user whitelist. + repeated int32 power_save_user_whitelist_app_ids = 12; + // App ids that are in temporary power-save whitelist. repeated int32 temp_power_save_whitelist_app_ids = 4; diff --git a/core/res/res/drawable/ic_arrow_forward.xml b/core/res/res/drawable/ic_arrow_forward.xml new file mode 100644 index 000000000000..f1085703ef13 --- /dev/null +++ b/core/res/res/drawable/ic_arrow_forward.xml @@ -0,0 +1,24 @@ +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M12.0,4.0l-1.41,1.41L16.17,11.0L4.0,11.0l0.0,2.0l12.17,0.0l-5.58,5.59L12.0,20.0l8.0,-8.0z"/> +</vector> diff --git a/core/res/res/drawable/ic_permission.xml b/core/res/res/drawable/ic_permission.xml new file mode 100644 index 000000000000..00523509fcae --- /dev/null +++ b/core/res/res/drawable/ic_permission.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="16.0" + android:viewportHeight="16.0"> + <path + android:fillColor="#FF000000" + android:pathData=" + M9.0,12l-2.0,0.0l0.0,-2.0l2.0,0.0l0.0,2.0z + m0.0,-4.0l-2.0,0.0l0.0,-4.0l2.0,0.0l0.0,4.0z"/> +</vector> diff --git a/core/res/res/drawable/perm_group_camera.xml b/core/res/res/drawable/perm_group_camera.xml index 61903a55361f..db7833f63faf 100644 --- a/core/res/res/drawable/perm_group_camera.xml +++ b/core/res/res/drawable/perm_group_camera.xml @@ -22,10 +22,8 @@ <path android:fillColor="#000000" - android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z" /> + android:pathData="M20,5h-3.17L15,3H9L7.17,5H4C2.9,5 2,5.9 2,7v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM20,19H4V7h16V19z"/> <path android:fillColor="#000000" - android:pathData="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1 0 2-.9 -2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 -5-2.24 5-5 5z" /> -</vector>
\ No newline at end of file + android:pathData="M12,9c-2.21,0 -4,1.79 -4,4c0,2.21 1.79,4 4,4s4,-1.79 4,-4C16,10.79 14.21,9 12,9z"/> +</vector> diff --git a/core/res/res/drawable/perm_group_contacts.xml b/core/res/res/drawable/perm_group_contacts.xml index 8f9dc3e0d178..b834a27bac4b 100644 --- a/core/res/res/drawable/perm_group_contacts.xml +++ b/core/res/res/drawable/perm_group_contacts.xml @@ -22,8 +22,14 @@ <path android:fillColor="#000000" - android:pathData="M20 0H4v2h16V0zM4 24h16v-2H4v2zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1 -0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 2.75c1.24 0 2.25 1.01 2.25 2.25s-1.01 2.25-2.25 -2.25S9.75 10.24 9.75 9 10.76 6.75 12 6.75zM17 17H7v-1.5c0-1.67 3.33-2.5 5-2.5s5 -.83 5 2.5V17z" /> -</vector>
\ No newline at end of file + android:pathData="M4,1h16v2h-16z"/> + <path + android:fillColor="#000000" + android:pathData="M4,21h16v2h-16z"/> + <path + android:fillColor="#000000" + android:pathData="M20,5H4C2.9,5 2,5.9 2,7v10c0,1.1 0.9,2 2,2h2h12h2c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM8.21,17c0.7,-0.47 2.46,-1 3.79,-1s3.09,0.53 3.79,1H8.21zM20,17h-2c0,-1.99 -4,-3 -6,-3s-6,1.01 -6,3H4V7h16V17z"/> + <path + android:fillColor="#000000" + android:pathData="M12,13.5c1.66,0 3,-1.34 3,-3c0,-1.66 -1.34,-3 -3,-3s-3,1.34 -3,3C9,12.16 10.34,13.5 12,13.5zM12,9.5c0.55,0 1,0.45 1,1s-0.45,1 -1,1s-1,-0.45 -1,-1S11.45,9.5 12,9.5z"/> +</vector> diff --git a/core/res/res/drawable/perm_group_location.xml b/core/res/res/drawable/perm_group_location.xml index cc1ec90eca4c..a7fa52471ab4 100644 --- a/core/res/res/drawable/perm_group_location.xml +++ b/core/res/res/drawable/perm_group_location.xml @@ -22,6 +22,8 @@ <path android:fillColor="#000000" - android:pathData="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 -9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" /> -</vector>
\ No newline at end of file + android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/> + <path + android:fillColor="#000000" + android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/> +</vector> diff --git a/core/res/res/drawable/perm_group_microphone.xml b/core/res/res/drawable/perm_group_microphone.xml index d494e67c63ad..9b532c1a7376 100644 --- a/core/res/res/drawable/perm_group_microphone.xml +++ b/core/res/res/drawable/perm_group_microphone.xml @@ -22,7 +22,8 @@ <path android:fillColor="#000000" - android:pathData="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 -3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 -6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z" /> -</vector>
\ No newline at end of file + android:pathData="M12,14c1.66,0 3,-1.34 3,-3V5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6C9,12.66 10.34,14 12,14zM11,5c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v6c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V5z"/> + <path + android:fillColor="#000000" + android:pathData="M17,11c0,2.76 -2.24,5 -5,5s-5,-2.24 -5,-5H5c0,3.53 2.61,6.43 6,6.92V21h2v-3.08c3.39,-0.49 6,-3.39 6,-6.92H17z"/> +</vector> diff --git a/core/res/res/drawable/perm_group_sms.xml b/core/res/res/drawable/perm_group_sms.xml index 47bca19edcc5..ebcf3d1fcd82 100644 --- a/core/res/res/drawable/perm_group_sms.xml +++ b/core/res/res/drawable/perm_group_sms.xml @@ -22,6 +22,5 @@ <path android:fillColor="#000000" - android:pathData="M20 2H4c-1.1 0-1.99 .9 -1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 -11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z" /> -</vector>
\ No newline at end of file + android:pathData="M20,2H4C2.9,2 2,2.9 2,4v18l4.75,-4h14C21.1,18 22,17.1 22,16V4C22,2.9 21.1,2 20,2zM20,16H4V4h16V16zM9,11H7V9h2V11zM17,11h-2V9h2V11zM13,11h-2V9h2V11z"/> +</vector> diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml index 1ff169350d40..4b8965bd9ef8 100644 --- a/core/res/res/drawable/perm_group_storage.xml +++ b/core/res/res/drawable/perm_group_storage.xml @@ -22,6 +22,5 @@ <path android:fillColor="#000000" - android:pathData="M10 4H4c-1.1 0-1.99 .9 -1.99 2L2 18c0 1.1 .9 2 2 2h16c1.1 0 2-.9 -2-2V8c0-1.1-.9-2-2-2h-8l-2-2z" /> -</vector>
\ No newline at end of file + android:pathData="M20,6h-8l-2,-2H4C2.9,4 2.01,4.9 2.01,6L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8C22,6.9 21.1,6 20,6zM20,18H4V8h16V18z"/> +</vector> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 770891184049..f7ff37738256 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3383,4 +3383,6 @@ <java-symbol type="string" name="battery_saver_description_with_learn_more" /> <java-symbol type="drawable" name="ic_lock_lockdown" /> + <java-symbol type="drawable" name="ic_arrow_forward" /> + <java-symbol type="drawable" name="ic_permission" /> </resources> diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java new file mode 100644 index 000000000000..c8e46fcdf3fd --- /dev/null +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import android.content.Context; +import android.graphics.Rect; +import android.platform.test.annotations.Presubmit; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +@Presubmit +@SmallTest +@RunWith(AndroidJUnit4.class) +public class ViewRootImplTest { + + private Context mContext; + private ViewRootImplAccessor mViewRootImpl; + + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getContext(); + + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + mViewRootImpl = new ViewRootImplAccessor( + new ViewRootImpl(mContext, mContext.getDisplay())); + }); + } + + @Test + public void negativeInsets_areSetToZero() throws Exception { + mViewRootImpl.getAttachInfo().getContentInsets().set(-10, -20, -30 , -40); + mViewRootImpl.getAttachInfo().getStableInsets().set(-10, -20, -30 , -40); + final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */); + + assertThat(insets.getSystemWindowInsets(), equalTo(new Rect())); + assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(), + insets.getStableInsetRight(), insets.getStableInsetBottom()), equalTo(new Rect())); + } + + @Test + public void negativeInsets_areSetToZero_positiveAreLeftAsIs() throws Exception { + mViewRootImpl.getAttachInfo().getContentInsets().set(-10, 20, -30 , 40); + mViewRootImpl.getAttachInfo().getStableInsets().set(10, -20, 30 , -40); + final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */); + + assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(0, 20, 0, 40))); + assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(), + insets.getStableInsetRight(), insets.getStableInsetBottom()), + equalTo(new Rect(10, 0, 30, 0))); + } + + @Test + public void positiveInsets_areLeftAsIs() throws Exception { + mViewRootImpl.getAttachInfo().getContentInsets().set(10, 20, 30 , 40); + mViewRootImpl.getAttachInfo().getStableInsets().set(10, 20, 30 , 40); + final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */); + + assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(10, 20, 30, 40))); + assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(), + insets.getStableInsetRight(), insets.getStableInsetBottom()), + equalTo(new Rect(10, 20, 30, 40))); + } + + private static class ViewRootImplAccessor { + + private final ViewRootImpl mViewRootImpl; + + ViewRootImplAccessor(ViewRootImpl viewRootImpl) { + mViewRootImpl = viewRootImpl; + } + + public ViewRootImpl get() { + return mViewRootImpl; + } + + AttachInfoAccessor getAttachInfo() throws Exception { + return new AttachInfoAccessor( + getField(mViewRootImpl, ViewRootImpl.class.getDeclaredField("mAttachInfo"))); + } + + WindowInsets getWindowInsets(boolean forceConstruct) throws Exception { + return (WindowInsets) invokeMethod(mViewRootImpl, + ViewRootImpl.class.getDeclaredMethod("getWindowInsets", boolean.class), + forceConstruct); + } + + class AttachInfoAccessor { + + private final Class<?> mClass; + private final Object mAttachInfo; + + AttachInfoAccessor(Object attachInfo) throws Exception { + mAttachInfo = attachInfo; + mClass = ViewRootImpl.class.getClassLoader().loadClass( + "android.view.View$AttachInfo"); + } + + Rect getContentInsets() throws Exception { + return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mContentInsets")); + } + + Rect getStableInsets() throws Exception { + return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mStableInsets")); + } + } + + private static Object getField(Object o, Field field) throws Exception { + field.setAccessible(true); + return field.get(o); + } + + private static Object invokeMethod(Object o, Method method, Object... args) + throws Exception { + method.setAccessible(true); + return method.invoke(o, args); + } + } +} diff --git a/docs/html/reference/_book.yaml b/docs/html/reference/_book.yaml deleted file mode 100644 index b902a61a6501..000000000000 --- a/docs/html/reference/_book.yaml +++ /dev/null @@ -1,853 +0,0 @@ -reference: -- title: Class Index - path: /reference/classes.html - status_text: no-toggle -- title: Package Index - path: /reference/packages.html - status_text: no-toggle -- title: android - path: /reference/android/package-summary.html - status_text: apilevel-1 -- title: android.accessibilityservice - path: /reference/android/accessibilityservice/package-summary.html - status_text: apilevel-4 -- title: android.accounts - path: /reference/android/accounts/package-summary.html - status_text: apilevel-5 -- title: android.animation - path: /reference/android/animation/package-summary.html - status_text: apilevel-11 -- title: android.annotation - path: /reference/android/annotation/package-summary.html - status_text: apilevel-16 -- title: android.app - path: /reference/android/app/package-summary.html - status_text: apilevel-1 -- title: android.app.admin - path: /reference/android/app/admin/package-summary.html - status_text: apilevel-8 -- title: android.app.assist - path: /reference/android/app/assist/package-summary.html - status_text: apilevel-23 -- title: android.app.backup - path: /reference/android/app/backup/package-summary.html - status_text: apilevel-8 -- title: android.app.job - path: /reference/android/app/job/package-summary.html - status_text: apilevel-21 -- title: android.app.usage - path: /reference/android/app/usage/package-summary.html - status_text: apilevel-21 -- title: android.appwidget - path: /reference/android/appwidget/package-summary.html - status_text: apilevel-3 -- title: android.bluetooth - path: /reference/android/bluetooth/package-summary.html - status_text: apilevel-5 -- title: android.bluetooth.le - path: /reference/android/bluetooth/le/package-summary.html - status_text: apilevel-21 -- title: android.companion - path: /reference/android/companion/package-summary.html - status_text: apilevel-O -- title: android.content - path: /reference/android/content/package-summary.html - status_text: apilevel-1 -- title: android.content.pm - path: /reference/android/content/pm/package-summary.html - status_text: apilevel-1 -- title: android.content.res - path: /reference/android/content/res/package-summary.html - status_text: apilevel-1 -- title: android.database - path: /reference/android/database/package-summary.html - status_text: apilevel-1 -- title: android.database.sqlite - path: /reference/android/database/sqlite/package-summary.html - status_text: apilevel-1 -- title: android.databinding - path: /reference/android/databinding/package-summary.html - status_text: apilevel- -- title: android.drm - path: /reference/android/drm/package-summary.html - status_text: apilevel-11 -- title: android.gesture - path: /reference/android/gesture/package-summary.html - status_text: apilevel-4 -- title: android.graphics - path: /reference/android/graphics/package-summary.html - status_text: apilevel-1 -- title: android.graphics.drawable - path: /reference/android/graphics/drawable/package-summary.html - status_text: apilevel-1 -- title: android.graphics.drawable.shapes - path: /reference/android/graphics/drawable/shapes/package-summary.html - status_text: apilevel-1 -- title: android.graphics.fonts - path: /reference/android/graphics/fonts/package-summary.html - status_text: apilevel-O -- title: android.graphics.pdf - path: /reference/android/graphics/pdf/package-summary.html - status_text: apilevel-19 -- title: android.hardware - path: /reference/android/hardware/package-summary.html - status_text: apilevel-1 -- title: android.hardware.camera2 - path: /reference/android/hardware/camera2/package-summary.html - status_text: apilevel-21 -- title: android.hardware.camera2.params - path: /reference/android/hardware/camera2/params/package-summary.html - status_text: apilevel-21 -- title: android.hardware.display - path: /reference/android/hardware/display/package-summary.html - status_text: apilevel-17 -- title: android.hardware.fingerprint - path: /reference/android/hardware/fingerprint/package-summary.html - status_text: apilevel-23 -- title: android.hardware.input - path: /reference/android/hardware/input/package-summary.html - status_text: apilevel-16 -- title: android.hardware.usb - path: /reference/android/hardware/usb/package-summary.html - status_text: apilevel-12 -- title: android.icu.lang - path: /reference/android/icu/lang/package-summary.html - status_text: apilevel-24 -- title: android.icu.math - path: /reference/android/icu/math/package-summary.html - status_text: apilevel-24 -- title: android.icu.text - path: /reference/android/icu/text/package-summary.html - status_text: apilevel-24 -- title: android.icu.util - path: /reference/android/icu/util/package-summary.html - status_text: apilevel-24 -- title: android.inputmethodservice - path: /reference/android/inputmethodservice/package-summary.html - status_text: apilevel-3 -- title: android.location - path: /reference/android/location/package-summary.html - status_text: apilevel-1 -- title: android.media - path: /reference/android/media/package-summary.html - status_text: apilevel-1 -- title: android.media.audiofx - path: /reference/android/media/audiofx/package-summary.html - status_text: apilevel-9 -- title: android.media.browse - path: /reference/android/media/browse/package-summary.html - status_text: apilevel-21 -- title: android.media.effect - path: /reference/android/media/effect/package-summary.html - status_text: apilevel-14 -- title: android.media.midi - path: /reference/android/media/midi/package-summary.html - status_text: apilevel-23 -- title: android.media.projection - path: /reference/android/media/projection/package-summary.html - status_text: apilevel-21 -- title: android.media.session - path: /reference/android/media/session/package-summary.html - status_text: apilevel-21 -- title: android.media.tv - path: /reference/android/media/tv/package-summary.html - status_text: apilevel-21 -- title: android.mtp - path: /reference/android/mtp/package-summary.html - status_text: apilevel-12 -- title: android.net - path: /reference/android/net/package-summary.html - status_text: apilevel-1 -- title: android.net.http - path: /reference/android/net/http/package-summary.html - status_text: apilevel-1 -- title: android.net.nsd - path: /reference/android/net/nsd/package-summary.html - status_text: apilevel-16 -- title: android.net.rtp - path: /reference/android/net/rtp/package-summary.html - status_text: apilevel-12 -- title: android.net.sip - path: /reference/android/net/sip/package-summary.html - status_text: apilevel-9 -- title: android.net.wifi - path: /reference/android/net/wifi/package-summary.html - status_text: apilevel-1 -- title: android.net.wifi.aware - path: /reference/android/net/wifi/aware/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.hotspot2 - path: /reference/android/net/wifi/hotspot2/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.hotspot2.omadm - path: /reference/android/net/wifi/hotspot2/omadm/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.hotspot2.pps - path: /reference/android/net/wifi/hotspot2/pps/package-summary.html - status_text: apilevel-O -- title: android.net.wifi.p2p - path: /reference/android/net/wifi/p2p/package-summary.html - status_text: apilevel-14 -- title: android.net.wifi.p2p.nsd - path: /reference/android/net/wifi/p2p/nsd/package-summary.html - status_text: apilevel-16 -- title: android.nfc - path: /reference/android/nfc/package-summary.html - status_text: apilevel-9 -- title: android.nfc.cardemulation - path: /reference/android/nfc/cardemulation/package-summary.html - status_text: apilevel-19 -- title: android.nfc.tech - path: /reference/android/nfc/tech/package-summary.html - status_text: apilevel-10 -- title: android.opengl - path: /reference/android/opengl/package-summary.html - status_text: apilevel-1 -- title: android.os - path: /reference/android/os/package-summary.html - status_text: apilevel-1 -- title: android.os.health - path: /reference/android/os/health/package-summary.html - status_text: apilevel-24 -- title: android.os.storage - path: /reference/android/os/storage/package-summary.html - status_text: apilevel-9 -- title: android.preference - path: /reference/android/preference/package-summary.html - status_text: apilevel-1 -- title: android.print - path: /reference/android/print/package-summary.html - status_text: apilevel-19 -- title: android.print.pdf - path: /reference/android/print/pdf/package-summary.html - status_text: apilevel-19 -- title: android.printservice - path: /reference/android/printservice/package-summary.html - status_text: apilevel-19 -- title: android.provider - path: /reference/android/provider/package-summary.html - status_text: apilevel-1 -- title: android.renderscript - path: /reference/android/renderscript/package-summary.html - status_text: apilevel-11 -- title: android.sax - path: /reference/android/sax/package-summary.html - status_text: apilevel-1 -- title: android.security - path: /reference/android/security/package-summary.html - status_text: apilevel-14 -- title: android.security.keystore - path: /reference/android/security/keystore/package-summary.html - status_text: apilevel-23 -- title: android.service.autofill - path: /reference/android/service/autofill/package-summary.html - status_text: apilevel-O -- title: android.service.carrier - path: /reference/android/service/carrier/package-summary.html - status_text: apilevel-22 -- title: android.service.chooser - path: /reference/android/service/chooser/package-summary.html - status_text: apilevel-23 -- title: android.service.dreams - path: /reference/android/service/dreams/package-summary.html - status_text: apilevel-17 -- title: android.service.media - path: /reference/android/service/media/package-summary.html - status_text: apilevel-21 -- title: android.service.notification - path: /reference/android/service/notification/package-summary.html - status_text: apilevel-18 -- title: android.service.quicksettings - path: /reference/android/service/quicksettings/package-summary.html - status_text: apilevel-24 -- title: android.service.restrictions - path: /reference/android/service/restrictions/package-summary.html - status_text: apilevel-21 -- title: android.service.textservice - path: /reference/android/service/textservice/package-summary.html - status_text: apilevel-14 -- title: android.service.voice - path: /reference/android/service/voice/package-summary.html - status_text: apilevel-21 -- title: android.service.vr - path: /reference/android/service/vr/package-summary.html - status_text: apilevel-24 -- title: android.service.wallpaper - path: /reference/android/service/wallpaper/package-summary.html - status_text: apilevel-7 -- title: android.speech - path: /reference/android/speech/package-summary.html - status_text: apilevel-3 -- title: android.speech.tts - path: /reference/android/speech/tts/package-summary.html - status_text: apilevel-4 -- title: android.support.animation - path: /reference/android/support/animation/package-summary.html - status_text: apilevel-25.3.0 -- title: android.support.annotation - path: /reference/android/support/annotation/package-summary.html - status_text: apilevel- -- title: android.support.app.recommendation - path: /reference/android/support/app/recommendation/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.compat - path: /reference/android/support/compat/package-summary.html - status_text: apilevel- -- title: android.support.coreui - path: /reference/android/support/coreui/package-summary.html - status_text: apilevel- -- title: android.support.coreutils - path: /reference/android/support/coreutils/package-summary.html - status_text: apilevel- -- title: android.support.customtabs - path: /reference/android/support/customtabs/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.design - path: /reference/android/support/design/package-summary.html - status_text: apilevel- -- title: android.support.design.widget - path: /reference/android/support/design/widget/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.dynamicanimation - path: /reference/android/support/dynamicanimation/package-summary.html - status_text: apilevel- -- title: android.support.exifinterface - path: /reference/android/support/exifinterface/package-summary.html - status_text: apilevel- -- title: android.support.fragment - path: /reference/android/support/fragment/package-summary.html - status_text: apilevel- -- title: android.support.graphics.drawable - path: /reference/android/support/graphics/drawable/package-summary.html - status_text: apilevel-23.2.0 -- title: android.support.graphics.drawable.animated - path: /reference/android/support/graphics/drawable/animated/package-summary.html - status_text: apilevel- -- title: android.support.media - path: /reference/android/support/media/package-summary.html - status_text: apilevel-25.1.0 -- title: android.support.media.instantvideo - path: /reference/android/support/media/instantvideo/package-summary.html - status_text: apilevel- -- title: android.support.media.instantvideo.preload - path: /reference/android/support/media/instantvideo/preload/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.media.instantvideo.widget - path: /reference/android/support/media/instantvideo/widget/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.media.tv - path: /reference/android/support/media/tv/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.mediacompat - path: /reference/android/support/mediacompat/package-summary.html - status_text: apilevel- -- title: android.support.multidex - path: /reference/android/support/multidex/package-summary.html - status_text: apilevel- -- title: android.support.percent - path: /reference/android/support/percent/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.recommendation - path: /reference/android/support/recommendation/package-summary.html - status_text: apilevel- -- title: android.support.transition - path: /reference/android/support/transition/package-summary.html - status_text: apilevel-24.2.0 -- title: android.support.v13 - path: /reference/android/support/v13/package-summary.html - status_text: apilevel- -- title: android.support.v13.app - path: /reference/android/support/v13/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v13.view - path: /reference/android/support/v13/view/package-summary.html - status_text: apilevel-24.0.0 -- title: android.support.v13.view.inputmethod - path: /reference/android/support/v13/view/inputmethod/package-summary.html - status_text: apilevel-25.0.0 -- title: android.support.v14.preference - path: /reference/android/support/v14/preference/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v17.leanback - path: /reference/android/support/v17/leanback/package-summary.html - status_text: apilevel- -- title: android.support.v17.leanback.app - path: /reference/android/support/v17/leanback/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.database - path: /reference/android/support/v17/leanback/database/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.graphics - path: /reference/android/support/v17/leanback/graphics/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.media - path: /reference/android/support/v17/leanback/media/package-summary.html - status_text: apilevel-25.1.0 -- title: android.support.v17.leanback.system - path: /reference/android/support/v17/leanback/system/package-summary.html - status_text: apilevel-22.2.1 -- title: android.support.v17.leanback.widget - path: /reference/android/support/v17/leanback/widget/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v17.leanback.widget.picker - path: /reference/android/support/v17/leanback/widget/picker/package-summary.html - status_text: apilevel-23.2.0 -- title: android.support.v17.preference - path: /reference/android/support/v17/preference/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v4 - path: /reference/android/support/v4/package-summary.html - status_text: apilevel- -- title: android.support.v4.accessibilityservice - path: /reference/android/support/v4/accessibilityservice/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.app - path: /reference/android/support/v4/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.content - path: /reference/android/support/v4/content/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.content.pm - path: /reference/android/support/v4/content/pm/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v4.content.res - path: /reference/android/support/v4/content/res/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v4.database - path: /reference/android/support/v4/database/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.graphics - path: /reference/android/support/v4/graphics/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.graphics.drawable - path: /reference/android/support/v4/graphics/drawable/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.hardware.display - path: /reference/android/support/v4/hardware/display/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.hardware.fingerprint - path: /reference/android/support/v4/hardware/fingerprint/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v4.math - path: /reference/android/support/v4/math/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.support.v4.media - path: /reference/android/support/v4/media/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.media.session - path: /reference/android/support/v4/media/session/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.net - path: /reference/android/support/v4/net/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.os - path: /reference/android/support/v4/os/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.print - path: /reference/android/support/v4/print/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.provider - path: /reference/android/support/v4/provider/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.text - path: /reference/android/support/v4/text/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.text.util - path: /reference/android/support/v4/text/util/package-summary.html - status_text: apilevel-24.2.0 -- title: android.support.v4.util - path: /reference/android/support/v4/util/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.view - path: /reference/android/support/v4/view/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.view.accessibility - path: /reference/android/support/v4/view/accessibility/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v4.view.animation - path: /reference/android/support/v4/view/animation/package-summary.html - status_text: apilevel-22.1.0 -- title: android.support.v4.widget - path: /reference/android/support/v4/widget/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.app - path: /reference/android/support/v7/app/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.appcompat - path: /reference/android/support/v7/appcompat/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v7.cardview - path: /reference/android/support/v7/cardview/package-summary.html - status_text: apilevel- -- title: android.support.v7.content.res - path: /reference/android/support/v7/content/res/package-summary.html - status_text: apilevel-24.0.0 -- title: android.support.v7.graphics - path: /reference/android/support/v7/graphics/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.graphics.drawable - path: /reference/android/support/v7/graphics/drawable/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v7.gridlayout - path: /reference/android/support/v7/gridlayout/package-summary.html - status_text: apilevel- -- title: android.support.v7.media - path: /reference/android/support/v7/media/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.mediarouter - path: /reference/android/support/v7/mediarouter/package-summary.html - status_text: apilevel- -- title: android.support.v7.palette - path: /reference/android/support/v7/palette/package-summary.html - status_text: apilevel- -- title: android.support.v7.preference - path: /reference/android/support/v7/preference/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.v7.recyclerview - path: /reference/android/support/v7/recyclerview/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v7.util - path: /reference/android/support/v7/util/package-summary.html - status_text: apilevel-22.1.0 -- title: android.support.v7.view - path: /reference/android/support/v7/view/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.widget - path: /reference/android/support/v7/widget/package-summary.html - status_text: apilevel-22.0.0 -- title: android.support.v7.widget.helper - path: /reference/android/support/v7/widget/helper/package-summary.html - status_text: apilevel-22.2.0 -- title: android.support.v7.widget.util - path: /reference/android/support/v7/widget/util/package-summary.html - status_text: apilevel-22.1.0 -- title: android.support.v8.renderscript - path: /reference/android/support/v8/renderscript/package-summary.html - status_text: apilevel-23.0.0 -- title: android.support.wearable - path: /reference/android/support/wearable/package-summary.html - status_text: apilevel- -- title: android.support.wearable.view - path: /reference/android/support/wearable/view/package-summary.html - status_text: apilevel-26.0.0-alpha1 -- title: android.system - path: /reference/android/system/package-summary.html - status_text: apilevel-21 -- title: android.telecom - path: /reference/android/telecom/package-summary.html - status_text: apilevel-21 -- title: android.telephony - path: /reference/android/telephony/package-summary.html - status_text: apilevel-1 -- title: android.telephony.cdma - path: /reference/android/telephony/cdma/package-summary.html - status_text: apilevel-5 -- title: android.telephony.gsm - path: /reference/android/telephony/gsm/package-summary.html - status_text: apilevel-1 -- title: android.test - path: /reference/android/test/package-summary.html - status_text: apilevel-1 -- title: android.test.mock - path: /reference/android/test/mock/package-summary.html - status_text: apilevel-1 -- title: android.test.suitebuilder - path: /reference/android/test/suitebuilder/package-summary.html - status_text: apilevel-1 -- title: android.test.suitebuilder.annotation - path: /reference/android/test/suitebuilder/annotation/package-summary.html - status_text: apilevel-1 -- title: android.text - path: /reference/android/text/package-summary.html - status_text: apilevel-1 -- title: android.text.format - path: /reference/android/text/format/package-summary.html - status_text: apilevel-3 -- title: android.text.method - path: /reference/android/text/method/package-summary.html - status_text: apilevel-1 -- title: android.text.style - path: /reference/android/text/style/package-summary.html - status_text: apilevel-1 -- title: android.text.util - path: /reference/android/text/util/package-summary.html - status_text: apilevel-1 -- title: android.transition - path: /reference/android/transition/package-summary.html - status_text: apilevel-19 -- title: android.util - path: /reference/android/util/package-summary.html - status_text: apilevel-1 -- title: android.view - path: /reference/android/view/package-summary.html - status_text: apilevel-1 -- title: android.view.accessibility - path: /reference/android/view/accessibility/package-summary.html - status_text: apilevel-4 -- title: android.view.animation - path: /reference/android/view/animation/package-summary.html - status_text: apilevel-1 -- title: android.view.autofill - path: /reference/android/view/autofill/package-summary.html - status_text: apilevel-O -- title: android.view.inputmethod - path: /reference/android/view/inputmethod/package-summary.html - status_text: apilevel-3 -- title: android.view.textclassifier - path: /reference/android/view/textclassifier/package-summary.html - status_text: apilevel-O -- title: android.view.textservice - path: /reference/android/view/textservice/package-summary.html - status_text: apilevel-14 -- title: android.webkit - path: /reference/android/webkit/package-summary.html - status_text: apilevel-1 -- title: android.widget - path: /reference/android/widget/package-summary.html - status_text: apilevel-1 -- title: com.android.test.runner - path: /reference/com/android/test/runner/package-summary.html - status_text: apilevel- -- title: dalvik.annotation - path: /reference/dalvik/annotation/package-summary.html - status_text: apilevel-1 -- title: dalvik.bytecode - path: /reference/dalvik/bytecode/package-summary.html - status_text: apilevel-1 -- title: dalvik.system - path: /reference/dalvik/system/package-summary.html - status_text: apilevel-1 -- title: java.awt.font - path: /reference/java/awt/font/package-summary.html - status_text: apilevel-1 -- title: java.beans - path: /reference/java/beans/package-summary.html - status_text: apilevel-3 -- title: java.io - path: /reference/java/io/package-summary.html - status_text: apilevel-1 -- title: java.lang - path: /reference/java/lang/package-summary.html - status_text: apilevel-1 -- title: java.lang.annotation - path: /reference/java/lang/annotation/package-summary.html - status_text: apilevel-1 -- title: java.lang.invoke - path: /reference/java/lang/invoke/package-summary.html - status_text: apilevel-O -- title: java.lang.ref - path: /reference/java/lang/ref/package-summary.html - status_text: apilevel-1 -- title: java.lang.reflect - path: /reference/java/lang/reflect/package-summary.html - status_text: apilevel-1 -- title: java.math - path: /reference/java/math/package-summary.html - status_text: apilevel-1 -- title: java.net - path: /reference/java/net/package-summary.html - status_text: apilevel-1 -- title: java.nio - path: /reference/java/nio/package-summary.html - status_text: apilevel-1 -- title: java.nio.channels - path: /reference/java/nio/channels/package-summary.html - status_text: apilevel-1 -- title: java.nio.channels.spi - path: /reference/java/nio/channels/spi/package-summary.html - status_text: apilevel-1 -- title: java.nio.charset - path: /reference/java/nio/charset/package-summary.html - status_text: apilevel-1 -- title: java.nio.charset.spi - path: /reference/java/nio/charset/spi/package-summary.html - status_text: apilevel-1 -- title: java.nio.file - path: /reference/java/nio/file/package-summary.html - status_text: apilevel-O -- title: java.nio.file.attribute - path: /reference/java/nio/file/attribute/package-summary.html - status_text: apilevel-O -- title: java.nio.file.spi - path: /reference/java/nio/file/spi/package-summary.html - status_text: apilevel-O -- title: java.security - path: /reference/java/security/package-summary.html - status_text: apilevel-1 -- title: java.security.acl - path: /reference/java/security/acl/package-summary.html - status_text: apilevel-1 -- title: java.security.cert - path: /reference/java/security/cert/package-summary.html - status_text: apilevel-1 -- title: java.security.interfaces - path: /reference/java/security/interfaces/package-summary.html - status_text: apilevel-1 -- title: java.security.spec - path: /reference/java/security/spec/package-summary.html - status_text: apilevel-1 -- title: java.sql - path: /reference/java/sql/package-summary.html - status_text: apilevel-1 -- title: java.text - path: /reference/java/text/package-summary.html - status_text: apilevel-1 -- title: java.time - path: /reference/java/time/package-summary.html - status_text: apilevel-O -- title: java.time.chrono - path: /reference/java/time/chrono/package-summary.html - status_text: apilevel-O -- title: java.time.format - path: /reference/java/time/format/package-summary.html - status_text: apilevel-O -- title: java.time.temporal - path: /reference/java/time/temporal/package-summary.html - status_text: apilevel-O -- title: java.time.zone - path: /reference/java/time/zone/package-summary.html - status_text: apilevel-O -- title: java.util - path: /reference/java/util/package-summary.html - status_text: apilevel-1 -- title: java.util.concurrent - path: /reference/java/util/concurrent/package-summary.html - status_text: apilevel-1 -- title: java.util.concurrent.atomic - path: /reference/java/util/concurrent/atomic/package-summary.html - status_text: apilevel-1 -- title: java.util.concurrent.locks - path: /reference/java/util/concurrent/locks/package-summary.html - status_text: apilevel-1 -- title: java.util.function - path: /reference/java/util/function/package-summary.html - status_text: apilevel-24 -- title: java.util.jar - path: /reference/java/util/jar/package-summary.html - status_text: apilevel-1 -- title: java.util.logging - path: /reference/java/util/logging/package-summary.html - status_text: apilevel-1 -- title: java.util.prefs - path: /reference/java/util/prefs/package-summary.html - status_text: apilevel-1 -- title: java.util.regex - path: /reference/java/util/regex/package-summary.html - status_text: apilevel-1 -- title: java.util.stream - path: /reference/java/util/stream/package-summary.html - status_text: apilevel-24 -- title: java.util.zip - path: /reference/java/util/zip/package-summary.html - status_text: apilevel-1 -- title: javax.crypto - path: /reference/javax/crypto/package-summary.html - status_text: apilevel-1 -- title: javax.crypto.interfaces - path: /reference/javax/crypto/interfaces/package-summary.html - status_text: apilevel-1 -- title: javax.crypto.spec - path: /reference/javax/crypto/spec/package-summary.html - status_text: apilevel-1 -- title: javax.microedition.khronos.egl - path: /reference/javax/microedition/khronos/egl/package-summary.html - status_text: apilevel-1 -- title: javax.microedition.khronos.opengles - path: /reference/javax/microedition/khronos/opengles/package-summary.html - status_text: apilevel-1 -- title: javax.net - path: /reference/javax/net/package-summary.html - status_text: apilevel-1 -- title: javax.net.ssl - path: /reference/javax/net/ssl/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth - path: /reference/javax/security/auth/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth.callback - path: /reference/javax/security/auth/callback/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth.login - path: /reference/javax/security/auth/login/package-summary.html - status_text: apilevel-1 -- title: javax.security.auth.x500 - path: /reference/javax/security/auth/x500/package-summary.html - status_text: apilevel-1 -- title: javax.security.cert - path: /reference/javax/security/cert/package-summary.html - status_text: apilevel-1 -- title: javax.sql - path: /reference/javax/sql/package-summary.html - status_text: apilevel-1 -- title: javax.xml - path: /reference/javax/xml/package-summary.html - status_text: apilevel-1 -- title: javax.xml.datatype - path: /reference/javax/xml/datatype/package-summary.html - status_text: apilevel-8 -- title: javax.xml.namespace - path: /reference/javax/xml/namespace/package-summary.html - status_text: apilevel-8 -- title: javax.xml.parsers - path: /reference/javax/xml/parsers/package-summary.html - status_text: apilevel-1 -- title: javax.xml.transform - path: /reference/javax/xml/transform/package-summary.html - status_text: apilevel-8 -- title: javax.xml.transform.dom - path: /reference/javax/xml/transform/dom/package-summary.html - status_text: apilevel-8 -- title: javax.xml.transform.sax - path: /reference/javax/xml/transform/sax/package-summary.html - status_text: apilevel-8 -- title: javax.xml.transform.stream - path: /reference/javax/xml/transform/stream/package-summary.html - status_text: apilevel-8 -- title: javax.xml.validation - path: /reference/javax/xml/validation/package-summary.html - status_text: apilevel-8 -- title: javax.xml.xpath - path: /reference/javax/xml/xpath/package-summary.html - status_text: apilevel-8 -- title: junit.framework - path: /reference/junit/framework/package-summary.html - status_text: apilevel-1 -- title: junit.runner - path: /reference/junit/runner/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.conn - path: /reference/org/apache/http/conn/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.conn.scheme - path: /reference/org/apache/http/conn/scheme/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.conn.ssl - path: /reference/org/apache/http/conn/ssl/package-summary.html - status_text: apilevel-1 -- title: org.apache.http.params - path: /reference/org/apache/http/params/package-summary.html - status_text: apilevel-1 -- title: org.json - path: /reference/org/json/package-summary.html - status_text: apilevel-1 -- title: org.w3c.dom - path: /reference/org/w3c/dom/package-summary.html - status_text: apilevel-1 -- title: org.w3c.dom.ls - path: /reference/org/w3c/dom/ls/package-summary.html - status_text: apilevel-8 -- title: org.xml.sax - path: /reference/org/xml/sax/package-summary.html - status_text: apilevel-1 -- title: org.xml.sax.ext - path: /reference/org/xml/sax/ext/package-summary.html - status_text: apilevel-1 -- title: org.xml.sax.helpers - path: /reference/org/xml/sax/helpers/package-summary.html - status_text: apilevel-1 -- title: org.xmlpull.v1 - path: /reference/org/xmlpull/v1/package-summary.html - status_text: apilevel-1 -- title: org.xmlpull.v1.sax2 - path: /reference/org/xmlpull/v1/sax2/package-summary.html - status_text: apilevel-1 diff --git a/docs/html/reference/_project.yaml b/docs/html/reference/_project.yaml deleted file mode 100644 index e5c26e7fdd8f..000000000000 --- a/docs/html/reference/_project.yaml +++ /dev/null @@ -1,6 +0,0 @@ -name: "Reference" -home_url: /reference/ -description: "API Reference packages and classes." -content_license: cc3-apache2 -buganizer_id: 30209417 -parent_project_metadata_path: /develop/_project.yaml diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml index 3185ea215262..e50a3757d14f 100644 --- a/media/tests/MediaFrameworkTest/AndroidManifest.xml +++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml @@ -24,7 +24,7 @@ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> - <application> + <application android:networkSecurityConfig="@xml/network_security_config"> <uses-library android:name="android.test.runner" /> <activity android:label="@string/app_name" android:name="MediaFrameworkTest" diff --git a/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml b/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml new file mode 100644 index 000000000000..c15c09cbf2d5 --- /dev/null +++ b/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<network-security-config> + <base-config cleartextTrafficPermitted="true"/> +</network-security-config> diff --git a/packages/SettingsLib/res/drawable/ic_signal_location.xml b/packages/SettingsLib/res/drawable/ic_signal_location.xml index 2f605805eba2..11870933b8bb 100644 --- a/packages/SettingsLib/res/drawable/ic_signal_location.xml +++ b/packages/SettingsLib/res/drawable/ic_signal_location.xml @@ -19,11 +19,10 @@ android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> - <group - android:translateX="0.02" - android:translateY="0.82"> - <path - android:pathData="M12,2C8.13,2 5,5.13 5,9c0,4.17 4.42,9.92 6.24,12.11 0.4,0.48 1.13,0.48 1.53,0C14.58,18.92 19,13.17 19,9c0,-3.87 -3.13,-7 -7,-7zM12,11.5a2.5,2.5 0,0 1,0 -5,2.5 2.5,0 0,1 0,5z" - android:fillColor="#FFFFFFFF"/> - </group> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/> </vector> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 85bbd59081a9..fbe52d191c30 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 = 167; + private static final int SETTINGS_VERSION = 168; private final int mUserId; @@ -3792,6 +3792,19 @@ public class SettingsProvider extends ContentProvider { currentVersion = 167; } + if (currentVersion == 167) { + // Version 167: by default, vibrate for wireless charging + final SettingsState globalSettings = getGlobalSettingsLocked(); + final Setting currentSetting = globalSettings.getSettingLocked( + Global.CHARGING_VIBRATION_ENABLED); + if (currentSetting.isNull()) { + globalSettings.insertSettingLocked( + Global.CHARGING_VIBRATION_ENABLED, "1", + null, true, SettingsState.SYSTEM_PACKAGE_NAME); + } + currentVersion = 168; + } + // vXXX: Add new settings above this point. if (currentVersion != newVersion) { diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 88edd12ab2f4..7871020a92aa 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -211,6 +211,8 @@ <!-- Permission necessary to change car audio volume through CarAudioManager --> <uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" /> + <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" /> + <application android:name=".SystemUIApplication" android:persistent="true" diff --git a/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..0899d3515f1b --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..22664496db76 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..3328add435fb --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..ed651da88800 --- /dev/null +++ b/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png Binary files differnew file mode 100644 index 000000000000..06e120239eb2 --- /dev/null +++ b/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png diff --git a/packages/SystemUI/res/drawable/car_add_circle_round.xml b/packages/SystemUI/res/drawable/car_add_circle_round.xml index 5cf0c31384f9..13c7dd12f940 100644 --- a/packages/SystemUI/res/drawable/car_add_circle_round.xml +++ b/packages/SystemUI/res/drawable/car_add_circle_round.xml @@ -1,4 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="oval"> diff --git a/packages/SystemUI/res/drawable/car_ic_add_white.xml b/packages/SystemUI/res/drawable/car_ic_add_white.xml index f24771dd3184..d6818607ec08 100644 --- a/packages/SystemUI/res/drawable/car_ic_add_white.xml +++ b/packages/SystemUI/res/drawable/car_ic_add_white.xml @@ -1,3 +1,17 @@ +<!-- Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="@dimen/car_touch_target_size" android:height="@dimen/car_touch_target_size" diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml index 907be01be508..2cd788303279 100644 --- a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml +++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml @@ -21,10 +21,12 @@ android:height="21dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> - <group android:name="icon" android:pivotX="12" android:pivotY="12"> + <!-- Use scaleX to flip icon so arrows always point in the direction of motion --> + <group android:name="icon" android:pivotX="12" android:pivotY="12" + android:scaleX="?attr/rotateButtonScaleX"> <!-- Tint color to be set directly --> <path android:fillColor="#FFFFFFFF" - android:pathData="M12,4c-0.06,0 -0.12,0.01 -0.18,0.01l1.09,-1.09L11.5,1.5L8,5l3.5,3.5l1.41,-1.41l-1.08,-1.08C11.89,6.01 11.95,6 12,6c3.31,0 6,2.69 6,6c0,1.7 -0.71,3.23 -1.85,4.32l1.41,1.41C19.06,16.28 20,14.25 20,12C20,7.59 16.41,4 12,4zM16,19l-3.5,3.5l-1.41,-1.41l1.1,-1.1C12.13,19.98 12.06,20 12,20c-4.41,0 -8,-3.59 -8,-8c0,-2.25 0.94,-4.28 2.43,-5.73l1.41,1.41C6.71,8.77 6,10.3 6,12c0,3.31 2.69,6 6,6c0.05,0 0.11,-0.01 0.16,-0.01l-1.07,-1.07l1.41,-1.41L16,19z"/> + android:pathData="M19,12c0,1.72 -0.63,3.3 -1.66,4.52l-1.44,-1.44C16.58,14.23 17,13.17 17,12c0,-2.76 -2.24,-5 -5,-5c-0.06,0 -0.11,0.01 -0.17,0.01l1.08,1.08L11.5,9.5L8,6l3.5,-3.5l1.41,1.42l-1.09,1.09C11.88,5.01 11.94,5 12,5C15.87,5 19,8.13 19,12zM12.5,14.51l-1.41,1.41l1.06,1.06C12.1,16.99 12.05,17 12,17c-2.76,0 -5,-2.24 -5,-5c0,-1.17 0.42,-2.23 1.09,-3.08L6.66,7.48C5.62,8.7 5,10.28 5,12c0,3.87 3.13,7 7,7c0.06,0 0.13,-0.01 0.19,-0.01v0l-1.1,1.1l1.41,1.41L16,18L12.5,14.51z"/> </group> </vector> </aapt:attr> diff --git a/packages/SystemUI/res/drawable/stat_sys_location.xml b/packages/SystemUI/res/drawable/stat_sys_location.xml index 33ac5cd9e34e..bdb0b0c2c29f 100644 --- a/packages/SystemUI/res/drawable/stat_sys_location.xml +++ b/packages/SystemUI/res/drawable/stat_sys_location.xml @@ -19,11 +19,13 @@ <vector android:width="17dp" android:height="17dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/> </vector> </inset>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/recents_onboarding.xml b/packages/SystemUI/res/layout/recents_onboarding.xml index 093a7ce176d9..adf1e742d08a 100644 --- a/packages/SystemUI/res/layout/recents_onboarding.xml +++ b/packages/SystemUI/res/layout/recents_onboarding.xml @@ -23,7 +23,7 @@ <LinearLayout android:layout_width="wrap_content" - android:layout_height="40dp" + android:layout_height="wrap_content" android:paddingStart="24dp" android:paddingEnd="4dp" android:background="@drawable/recents_onboarding_toast_rounded_background" @@ -33,8 +33,9 @@ <TextView android:id="@+id/onboarding_text" - android:layout_width="wrap_content" + android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_weight="1" android:layout_gravity="center_vertical" android:textColor="@android:color/white" android:textSize="16sp"/> 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 7931dfe74587..8b56b6806db2 100644 --- a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml +++ b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml @@ -29,7 +29,6 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" - android:paddingStart="2dp" android:orientation="horizontal" > <FrameLayout diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml index c70e8296340e..e67bb60555f3 100644 --- a/packages/SystemUI/res/layout/volume_dialog.xml +++ b/packages/SystemUI/res/layout/volume_dialog.xml @@ -93,7 +93,7 @@ android:layout_gravity="center" android:contentDescription="@string/accessibility_volume_settings" android:background="@drawable/ripple_drawable_20dp" - android:tint="?android:attr/textColorHint" + android:tint="?android:attr/textColorSecondary" android:soundEffectsEnabled="false" /> </FrameLayout> </LinearLayout> diff --git a/packages/SystemUI/res/values-ldrtl/strings.xml b/packages/SystemUI/res/values-ldrtl/strings.xml new file mode 100644 index 000000000000..c93da69b9941 --- /dev/null +++ b/packages/SystemUI/res/values-ldrtl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources> + <!-- Recents: Text that shows above the navigation bar after launching several apps. [CHAR LIMIT=NONE] --> + <string name="recents_quick_scrub_onboarding">Drag left to quickly switch apps</string> +</resources> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index 2ce9bfc8ae7c..3f63f2283ba8 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -141,5 +141,7 @@ <!-- Used to style rotate suggestion button AVD animations --> <attr name="rotateButtonStartAngle" format="float" /> <attr name="rotateButtonEndAngle" format="float" /> + <attr name="rotateButtonScaleX" format="float" /> + </resources> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index d8607ccf0f37..975055ce72e6 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -125,9 +125,6 @@ <color name="light_mode_icon_color_dual_tone_background">#4dffffff</color> <color name="light_mode_icon_color_dual_tone_fill">#ffffff</color> - <color name="volume_settings_icon_color">#7fffffff</color> - <color name="volume_slider_inactive">@*android:color/quaternary_device_default_settings</color> - <color name="docked_divider_background">#ff000000</color> <color name="docked_divider_handle">#ffffff</color> <drawable name="forced_resizable_background">#59000000</drawable> @@ -141,7 +138,7 @@ <color name="remote_input_accent">#eeeeee</color> <color name="quick_step_track_background_dark">#61000000</color> - <color name="quick_step_track_background_light">#4DFFFFFF</color> + <color name="quick_step_track_background_light">#33FFFFFF</color> <!-- Keyboard shortcuts colors --> <color name="ksh_application_group_color">#fff44336</color> diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/SystemUI/res/values/colors_car.xml index cb3abb957f0c..49bfb250acab 100644 --- a/packages/SystemUI/res/values/colors_car.xml +++ b/packages/SystemUI/res/values/colors_car.xml @@ -25,4 +25,7 @@ <color name="car_user_switcher_name_text_color">@color/car_body1_light</color> <color name="car_user_switcher_add_user_background_color">@color/car_dark_blue_grey_600</color> <color name="car_user_switcher_add_user_add_sign_color">@color/car_body1_light</color> + + <!-- colors for volume dialog tint --> + <color name="car_volume_dialog_tint">@color/car_tint</color> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 82869caba668..9a3bdf271dc0 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -201,7 +201,7 @@ <dimen name="status_bar_padding_start">6dp</dimen> <!-- the padding on the end of the statusbar --> - <dimen name="status_bar_padding_end">8dp</dimen> + <dimen name="status_bar_padding_end">6dp</dimen> <!-- the radius of the overflow dot in the status bar --> <dimen name="overflow_dot_radius">1dp</dimen> @@ -867,6 +867,8 @@ <!-- The size of corner radius of the arrow in the onboarding toast. --> <dimen name="recents_onboarding_toast_arrow_corner_radius">2dp</dimen> + <!-- The start margin of quick scrub onboarding toast. --> + <dimen name="recents_quick_scrub_onboarding_margin_start">8dp</dimen> <!-- The min alpha to apply to a task affiliation group color. --> <item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item> @@ -939,7 +941,7 @@ <dimen name="rounded_corner_content_padding">0dp</dimen> <dimen name="nav_content_padding">0dp</dimen> <dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen> - <dimen name="nav_quick_scrub_track_thickness">2dp</dimen> + <dimen name="nav_quick_scrub_track_thickness">10dp</dimen> <!-- Navigation bar shadow params. --> <dimen name="nav_key_button_shadow_offset_x">0dp</dimen> @@ -1007,4 +1009,7 @@ <dimen name="logout_button_margin_bottom">12dp</dimen> <dimen name="logout_button_corner_radius">2dp</dimen> + <!-- How much into a DisplayCutout's bounds we can go, on each side --> + <dimen name="display_cutout_margin_consumption">0px</dimen> + </resources> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index b3f4534853c4..e4f59892f79b 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -506,21 +506,25 @@ <style name="RotateButtonCCWStart0"> <item name="rotateButtonStartAngle">0</item> <item name="rotateButtonEndAngle">-90</item> + <item name="rotateButtonScaleX">1</item> </style> <style name="RotateButtonCCWStart90"> <item name="rotateButtonStartAngle">90</item> <item name="rotateButtonEndAngle">0</item> + <item name="rotateButtonScaleX">1</item> </style> <style name="RotateButtonCWStart0"> <item name="rotateButtonStartAngle">0</item> <item name="rotateButtonEndAngle">90</item> + <item name="rotateButtonScaleX">-1</item> </style> <style name="RotateButtonCWStart90"> <item name="rotateButtonStartAngle">90</item> <item name="rotateButtonEndAngle">180</item> + <item name="rotateButtonScaleX">-1</item> </style> </resources> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java index 52e1c167ffc8..24875d7dadf8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java @@ -58,7 +58,7 @@ import java.util.function.Consumer; import androidx.slice.Slice; import androidx.slice.SliceItem; -import androidx.slice.SliceManager; +import androidx.slice.SliceViewManager; import androidx.slice.core.SliceQuery; import androidx.slice.widget.ListContent; import androidx.slice.widget.RowContent; @@ -373,7 +373,7 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe } public void refresh() { - Slice slice = SliceManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri); + Slice slice = SliceViewManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri); onChanged(slice); } diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 2746a71e3316..e347a144dc9c 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -196,6 +196,9 @@ public class ScreenDecorations extends SystemUI implements Tunable { @Override protected void onConfigurationChanged(Configuration newConfig) { updateOrientation(); + if (shouldDrawCutout() && mOverlay == null) { + setupDecorations(); + } } protected void updateOrientation() { @@ -207,10 +210,6 @@ public class ScreenDecorations extends SystemUI implements Tunable { updateLayoutParams(); updateViews(); } - - if (shouldDrawCutout() && mOverlay == null) { - setupDecorations(); - } } } diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java index 56cb88870d65..19f8416860a2 100644 --- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java @@ -14,6 +14,8 @@ package com.android.systemui; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; + import android.app.Activity; import android.app.AlertDialog; import android.app.slice.SliceManager; @@ -61,7 +63,9 @@ public class SlicePermissionActivity extends Activity implements OnClickListener .setNegativeButton(R.string.slice_permission_deny, this) .setPositiveButton(R.string.slice_permission_allow, this) .setOnDismissListener(this) - .show(); + .create(); + dialog.getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); + dialog.show(); TextView t1 = dialog.getWindow().getDecorView().findViewById(R.id.text1); t1.setText(getString(R.string.slice_permission_text_1, app2)); TextView t2 = dialog.getWindow().getDecorView().findViewById(R.id.text2); diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java index fec76f266c09..8d8e20669a1f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java @@ -173,7 +173,7 @@ public class RecentsOnboarding { : SWIPE_UP_SHOW_ON_APP_LAUNCH_AFTER_DISMISS_BACK_OFF; mNumAppsLaunchedSinceSwipeUpTipDismiss++; if (mNumAppsLaunchedSinceSwipeUpTipDismiss - == swipeUpShowOnAppLauncherAfterDismiss) { + >= swipeUpShowOnAppLauncherAfterDismiss) { mNumAppsLaunchedSinceSwipeUpTipDismiss = 0; shouldLog = show(R.string.recents_swipe_up_onboarding); } @@ -188,7 +188,7 @@ public class RecentsOnboarding { if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) { if (mHasDismissedQuickScrubTip) { if (mOverviewOpenedCountSinceQuickScrubTipDismiss - == QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) { + >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) { mOverviewOpenedCountSinceQuickScrubTipDismiss = 0; shouldLog = show(R.string.recents_quick_scrub_onboarding); } @@ -393,7 +393,20 @@ public class RecentsOnboarding { if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) { mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); - mWindowManager.addView(mLayout, getWindowLayoutParams()); + final int gravity; + final int x; + if (stringRes == R.string.recents_swipe_up_onboarding) { + gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + x = 0; + } else { + int layoutDirection = + mContext.getResources().getConfiguration().getLayoutDirection(); + gravity = Gravity.BOTTOM | (layoutDirection == View.LAYOUT_DIRECTION_LTR + ? Gravity.LEFT : Gravity.RIGHT); + x = mContext.getResources().getDimensionPixelSize( + R.dimen.recents_quick_scrub_onboarding_margin_start); + } + mWindowManager.addView(mLayout, getWindowLayoutParams(gravity, x)); mLayout.setAlpha(0); mLayout.animate() .alpha(1f) @@ -459,19 +472,19 @@ public class RecentsOnboarding { pw.println(" }"); } - private WindowManager.LayoutParams getWindowLayoutParams() { + private WindowManager.LayoutParams getWindowLayoutParams(int gravity, int x) { int flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, - 0, -mNavBarHeight / 2, + ViewGroup.LayoutParams.WRAP_CONTENT, + x, -mNavBarHeight / 2, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; lp.setTitle("RecentsOnboarding"); - lp.gravity = Gravity.BOTTOM; + lp.gravity = gravity; return lp; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java index 3c0b22660c17..894ea62b1b61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java @@ -114,6 +114,10 @@ public class ButtonDispatcher { return mVisibility != null ? mVisibility : View.VISIBLE; } + public boolean isVisible() { + return getVisibility() == View.VISIBLE; + } + public float getAlpha() { return mAlpha != null ? mAlpha : 1; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index 58d3b9a2bf33..0bd3cc795bc3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -90,6 +90,11 @@ public class KeyguardStatusBarView extends RelativeLayout private ViewGroup mStatusIconArea; private int mLayoutState = LAYOUT_NONE; + /** + * Draw this many pixels into the left/right side of the cutout to optimally use the space + */ + private int mCutoutSideNudge = 0; + public KeyguardStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); } @@ -158,6 +163,8 @@ public class KeyguardStatusBarView extends RelativeLayout R.dimen.system_icons_switcher_hidden_expanded_margin); mSystemIconsBaseMargin = res.getDimensionPixelSize( R.dimen.system_icons_super_container_avatarless_margin_end); + mCutoutSideNudge = getResources().getDimensionPixelSize( + R.dimen.display_cutout_margin_consumption); } private void updateVisibilities() { @@ -266,6 +273,8 @@ public class KeyguardStatusBarView extends RelativeLayout mCutoutSpace.setVisibility(View.VISIBLE); RelativeLayout.LayoutParams lp = (LayoutParams) mCutoutSpace.getLayoutParams(); + bounds.left = bounds.left + mCutoutSideNudge; + bounds.right = bounds.right - mCutoutSideNudge; lp.width = bounds.width(); lp.height = bounds.height(); lp.addRule(RelativeLayout.CENTER_IN_PARENT); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 68359bf309eb..9acac22c9e90 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -1144,6 +1144,8 @@ public class NavigationBarFragment extends Fragment implements Callbacks { mRoot.postOnAnimationDelayed(mRipple, RIPPLE_OFFSET_MS); mRoot.postOnAnimationDelayed(mRipple, RIPPLE_INTERVAL_MS); mRoot.postOnAnimationDelayed(mRipple, 2*RIPPLE_INTERVAL_MS); + mRoot.postOnAnimationDelayed(mRipple, 3*RIPPLE_INTERVAL_MS); + mRoot.postOnAnimationDelayed(mRipple, 4*RIPPLE_INTERVAL_MS); } public void stop() { 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 6c66cabf0da8..0fd8df09eaaa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -336,13 +336,14 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav int x = (int) event.getX(); int y = (int) event.getY(); mDownHitTarget = HIT_TARGET_NONE; - if (mBackButtonBounds.contains(x, y)) { + if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_BACK; - } else if (mHomeButtonBounds.contains(x, y)) { + } else if (getHomeButton().isVisible() && mHomeButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_HOME; - } else if (mRecentsButtonBounds.contains(x, y)) { + } else if (getRecentsButton().isVisible() && mRecentsButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_OVERVIEW; - } else if (mRotationButtonBounds.contains(x, y)) { + } else if (getRotateSuggestionButton().isVisible() + && mRotationButtonBounds.contains(x, y)) { mDownHitTarget = HIT_TARGET_ROTATION; } break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 01582d090999..5477f882e5f9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -74,6 +74,10 @@ public class PhoneStatusBarView extends PanelBar { private View mCutoutSpace; @Nullable private DisplayCutout mDisplayCutout; + /** + * Draw this many pixels into the left/right side of the cutout to optimally use the space + */ + private int mCutoutSideNudge = 0; public PhoneStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); @@ -98,6 +102,8 @@ public class PhoneStatusBarView extends PanelBar { mBarTransitions.init(); mBattery = findViewById(R.id.battery); mCutoutSpace = findViewById(R.id.cutout_space_view); + + updateResources(); } @Override @@ -280,6 +286,9 @@ public class PhoneStatusBarView extends PanelBar { } public void updateResources() { + mCutoutSideNudge = getResources().getDimensionPixelSize( + R.dimen.display_cutout_margin_consumption); + ViewGroup.LayoutParams layoutParams = getLayoutParams(); layoutParams.height = getResources().getDimensionPixelSize( R.dimen.status_bar_height); @@ -311,6 +320,8 @@ public class PhoneStatusBarView extends PanelBar { Rect bounds = new Rect(); boundsFromDirection(mDisplayCutout, Gravity.TOP, bounds); + bounds.left = bounds.left + mCutoutSideNudge; + bounds.right = bounds.right - mCutoutSideNudge; lp.width = bounds.width(); lp.height = bounds.height(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java index b55fe47f1f2d..860b77e1b251 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java @@ -29,14 +29,13 @@ import android.animation.AnimatorSet; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Matrix; -import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.RemoteException; import android.util.FloatProperty; @@ -55,6 +54,7 @@ import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.shared.system.NavigationBarCompat; +import com.android.internal.graphics.ColorUtils; /** * Class to detect gestures on the navigation bar and implement quick scrub. @@ -63,7 +63,8 @@ public class QuickStepController implements GestureHelper { private static final String TAG = "QuickStepController"; private static final int ANIM_IN_DURATION_MS = 150; - private static final int ANIM_OUT_DURATION_MS = 100; + private static final int ANIM_OUT_DURATION_MS = 134; + private static final float TRACK_SCALE = 0.95f; private NavigationBarView mNavigationBarView; @@ -76,6 +77,7 @@ public class QuickStepController implements GestureHelper { private boolean mIsVertical; private boolean mIsRTL; private float mTrackAlpha; + private float mTrackScale = TRACK_SCALE; private int mLightTrackColor; private int mDarkTrackColor; private float mDarkIntensity; @@ -85,7 +87,7 @@ public class QuickStepController implements GestureHelper { private final Handler mHandler = new Handler(); private final Rect mTrackRect = new Rect(); - private final Paint mTrackPaint = new Paint(); + private final Drawable mTrackDrawable; private final OverviewProxyService mOverviewEventSender; private final int mTrackThickness; private final int mTrackEndPadding; @@ -108,6 +110,20 @@ public class QuickStepController implements GestureHelper { } }; + private final FloatProperty<QuickStepController> mTrackScaleProperty = + new FloatProperty<QuickStepController>("TrackScale") { + @Override + public void setValue(QuickStepController controller, float scale) { + mTrackScale = scale; + mNavigationBarView.invalidate(); + } + + @Override + public Float get(QuickStepController controller) { + return mTrackScale; + } + }; + private final FloatProperty<QuickStepController> mNavBarAlphaProperty = new FloatProperty<QuickStepController>("NavBarAlpha") { @Override @@ -139,7 +155,7 @@ public class QuickStepController implements GestureHelper { mOverviewEventSender = Dependency.get(OverviewProxyService.class); mTrackThickness = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_thickness); mTrackEndPadding = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding); - mTrackPaint.setAlpha(0); + mTrackDrawable = context.getDrawable(R.drawable.qs_scrubber_track).mutate(); } public void setComponents(NavigationBarView navigationBarView) { @@ -296,9 +312,17 @@ public class QuickStepController implements GestureHelper { } int color = (int) mTrackColorEvaluator.evaluate(mDarkIntensity, mLightTrackColor, mDarkTrackColor); - mTrackPaint.setColor(color); - mTrackPaint.setAlpha((int) (mTrackPaint.getAlpha() * mTrackAlpha)); - canvas.drawRect(mTrackRect, mTrackPaint); + int colorAlpha = ColorUtils.setAlphaComponent(color, + (int) (Color.alpha(color) * mTrackAlpha)); + mTrackDrawable.setTint(colorAlpha); + + // Scale the track, but apply the inverse scale from the nav bar + canvas.save(); + canvas.scale(mTrackScale / mNavigationBarView.getScaleX(), + 1f / mNavigationBarView.getScaleY(), + mTrackRect.centerX(), mTrackRect.centerY()); + mTrackDrawable.draw(canvas); + canvas.restore(); } @Override @@ -322,6 +346,7 @@ public class QuickStepController implements GestureHelper { x2 = x1 + width - 2 * mTrackEndPadding; } mTrackRect.set(x1, y1, x2, y2); + mTrackDrawable.setBounds(mTrackRect); } @Override @@ -387,7 +412,9 @@ public class QuickStepController implements GestureHelper { mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light); mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark); - ObjectAnimator trackAnimator = ObjectAnimator.ofFloat(this, mTrackAlphaProperty, 1f); + ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this, + PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 1f), + PropertyValuesHolder.ofFloat(mTrackScaleProperty, 1f)); trackAnimator.setInterpolator(ALPHA_IN); trackAnimator.setDuration(ANIM_IN_DURATION_MS); ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 0f); @@ -438,7 +465,9 @@ public class QuickStepController implements GestureHelper { mTrackAnimator.cancel(); } - ObjectAnimator trackAnimator = ObjectAnimator.ofFloat(this, mTrackAlphaProperty, 0f); + ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this, + PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 0f), + PropertyValuesHolder.ofFloat(mTrackScaleProperty, TRACK_SCALE)); trackAnimator.setInterpolator(ALPHA_OUT); trackAnimator.setDuration(ANIM_OUT_DURATION_MS); ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 1f); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index 7cd433a3868e..384a6e7068f4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -148,16 +148,31 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba boolean in = activityIn && mActivityEnabled && visible; boolean out = activityOut && mActivityEnabled && visible; - mWifiIconState.visible = visible; - mWifiIconState.resId = statusIcon.icon; - mWifiIconState.activityIn = in; - mWifiIconState.activityOut = out; - mWifiIconState.slot = mSlotWifi; - mWifiIconState.airplaneSpacerVisible = mIsAirplaneMode; - mWifiIconState.contentDescription = statusIcon.contentDescription; - - if (mWifiIconState.visible && mWifiIconState.resId > 0) { - mIconController.setSignalIcon(mSlotWifi, mWifiIconState.copy()); + WifiIconState newState = mWifiIconState.copy(); + + newState.visible = visible; + newState.resId = statusIcon.icon; + newState.activityIn = in; + newState.activityOut = out; + newState.slot = mSlotWifi; + newState.airplaneSpacerVisible = mIsAirplaneMode; + newState.contentDescription = statusIcon.contentDescription; + + MobileIconState first = getFirstMobileState(); + newState.signalSpacerVisible = first != null && first.typeId != 0; + + updateWifiIconWithState(newState); + mWifiIconState = newState; + } + + private void updateShowWifiSignalSpacer(WifiIconState state) { + MobileIconState first = getFirstMobileState(); + state.signalSpacerVisible = first != null && first.typeId != 0; + } + + private void updateWifiIconWithState(WifiIconState state) { + if (state.visible && state.resId > 0) { + mIconController.setSignalIcon(mSlotWifi, state); mIconController.setIconVisibility(mSlotWifi, true); } else { mIconController.setIconVisibility(mSlotWifi, false); @@ -173,6 +188,9 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba return; } + // Visibility of the data type indicator changed + boolean typeChanged = statusType != state.typeId && (statusType == 0 || state.typeId == 0); + state.visible = statusIcon.visible && !mBlockMobile; state.strengthId = statusIcon.icon; state.typeId = statusType; @@ -184,6 +202,15 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba // Always send a copy to maintain value type semantics mIconController.setMobileIcons(mSlotMobile, MobileIconState.copyStates(mMobileStates)); + + if (typeChanged) { + WifiIconState wifiCopy = mWifiIconState.copy(); + updateShowWifiSignalSpacer(wifiCopy); + if (!Objects.equals(wifiCopy, mWifiIconState)) { + updateWifiIconWithState(wifiCopy); + mWifiIconState = wifiCopy; + } + } } private MobileIconState getState(int subId) { @@ -196,6 +223,14 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba return null; } + private MobileIconState getFirstMobileState() { + if (mMobileStates.size() > 0) { + return mMobileStates.get(0); + } + + return null; + } + /** * It is expected that a call to setSubs will be immediately followed by setMobileDataIndicators 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 4ec9ae883a2b..b81447816aec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -565,10 +565,12 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { - mRemoteInputView.mRemoteInputQuickSettingsDisabler.setRemoteInputActive(false); + // When BACK key is pressed, this method would be invoked twice. + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && + event.getAction() == KeyEvent.ACTION_UP) { + defocusIfNeeded(true /* animate */); } - return super.dispatchKeyEvent(event); + return super.onKeyPreIme(keyCode, event); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java index 8034345c37a7..bf962b818997 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java @@ -344,13 +344,17 @@ public class CarVolumeDialogImpl implements VolumeDialog { int supplementalIconId, @Nullable View.OnClickListener supplementalIconOnClickListener) { SeekbarListItem listItem = new SeekbarListItem(mContext); listItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId)); + int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint); int progress = getSeekbarValue(mCarAudioManager, volumeGroupId); listItem.setProgress(progress); listItem.setOnSeekBarChangeListener( new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId, mCarAudioManager)); - listItem.setPrimaryActionIcon(mContext.getResources().getDrawable(volumeItem.icon)); + Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon); + primaryIcon.setTint(color); + listItem.setPrimaryActionIcon(primaryIcon); if (supplementalIconId != 0) { Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId); + supplementalIcon.setTint(color); listItem.setSupplementalIcon(supplementalIcon, true, supplementalIconOnClickListener); } else { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 03474a8c3385..ed243ef6a417 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -43,8 +43,10 @@ import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PixelFormat; +import android.graphics.PorterDuff; import android.graphics.drawable.ColorDrawable; import android.media.AudioManager; import android.media.AudioSystem; @@ -90,6 +92,7 @@ import com.android.systemui.plugins.VolumeDialog; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.VolumeDialogController.State; import com.android.systemui.plugins.VolumeDialogController.StreamState; +import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -131,8 +134,10 @@ public class VolumeDialogImpl implements VolumeDialog { private final AccessibilityManagerWrapper mAccessibilityMgr; private final Object mSafetyWarningLock = new Object(); private final Accessibility mAccessibility = new Accessibility(); - private final ColorStateList mActiveTint; - private final ColorStateList mInactiveTint; + private ColorStateList mActiveTint; + private int mActiveAlpha; + private ColorStateList mInactiveTint; + private int mInactiveAlpha; private boolean mShowing; private boolean mShowA11yStream; @@ -150,8 +155,6 @@ public class VolumeDialogImpl implements VolumeDialog { mController = Dependency.get(VolumeDialogController.class); mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class); - mActiveTint = ColorStateList.valueOf(Utils.getColorAccent(mContext)); - mInactiveTint = loadColorStateList(R.color.volume_slider_inactive); mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); } @@ -224,6 +227,12 @@ public class VolumeDialogImpl implements VolumeDialog { return true; }); + mActiveTint = ColorStateList.valueOf(Utils.getColorAccent(mContext)); + mActiveAlpha = Color.alpha(mActiveTint.getDefaultColor()); + mInactiveTint = ColorStateList.valueOf( + Utils.getColorAttr(mContext, android.R.attr.colorForeground)); + mInactiveAlpha = getAlphaAttr(android.R.attr.secondaryContentAlpha); + mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows); mRinger = mDialog.findViewById(R.id.ringer); mRingerIcon = mRinger.findViewById(R.id.ringer_icon); @@ -263,8 +272,11 @@ public class VolumeDialogImpl implements VolumeDialog { return mDialogView; } - private ColorStateList loadColorStateList(int colorResId) { - return ColorStateList.valueOf(mContext.getColor(colorResId)); + private int getAlphaAttr(int attr) { + TypedArray ta = mContext.obtainStyledAttributes(new int[]{attr}); + float alpha = ta.getFloat(0, 0); + ta.recycle(); + return (int) (alpha * 255); } private boolean isLandscape() { @@ -890,12 +902,16 @@ public class VolumeDialogImpl implements VolumeDialog { if (isActive) { row.slider.requestFocus(); } - final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveTint - : mInactiveTint; + boolean useActiveColoring = isActive && row.slider.isEnabled(); + final ColorStateList tint = useActiveColoring ? mActiveTint : mInactiveTint; + final int alpha = useActiveColoring ? mActiveAlpha : mInactiveAlpha; if (tint == row.cachedTint) return; row.slider.setProgressTintList(tint); row.slider.setThumbTintList(tint); + row.slider.setProgressBackgroundTintList(tint); + row.slider.setAlpha(((float) alpha) / 255); row.icon.setImageTintList(tint); + row.icon.setImageAlpha(alpha); row.cachedTint = tint; } diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index d06410597391..4328d94275e9 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -3986,27 +3986,44 @@ message MetricsEvent { // OS: O APP_TRANSITION_IS_EPHEMERAL = 905; - // An autofill session was started + // An autofill session was started. + // OS: O // Package: Package of app that is autofilled // NOTE: starting on OS MR1, it also added the following field: // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // NOTE: starting on OS P, it also added the following field: - // Tag FIELD_FLAGS - Flags used to start the session - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFIL_FLAGS: flags used to start the session. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session started. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SESSION_STARTED = 906; // An autofill request was processed by a service - // Type TYPE_SUCCESS: The request succeeded - // Type TYPE_FAILURE: The request failed + // Type TYPE_SUCCESS: service called FillCalback.onSuccess() + // Type TYPE_FAILURE: service called FillCallback.onFailure() // Package: Package of app that is autofilled // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets returned in the response, or -1 if - // the service returned a null response. - // NOTE: starting on OS P, it also added: - // Type TYPE_CLOSE: Service returned a null response. + // the service returned a null response + // NOTE: starting on OS P, it also added the following fields: + // TYPE_CLOSE: request timed out before service called a FillCallback method + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_REQUEST_ORDINAL: sequence number of the request inside a session; starts + // with 1. + // Tag FIELD_AUTOFILL_FLAGS: flags used to request autofill + // Tag FIELD_AUTOFILL_DURATION: how long it took (in ms) to show the autofill UI after a field + // was focused. + // Tag FIELD_AUTOFILL_AUTHENTICATION_STATUS: status of authenticated datasets or responses. // Tag FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS: if service requested field classification, - // number of entries field ids in the request. - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // number of entries field ids in the request. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: Prior to P, some of the fields above were logged by 5 different metrics: + // - AUTOFILL_UI_LATENCY + // - AUTOFILL_AUTHENTICATED; + // - AUTOFILL_DATASET_AUTHENTICATED + // - AUTOFILL_INVALID_AUTHENTICATION + // - AUTOFILL_INVALID_DATASET_AUTHENTICATION AUTOFILL_REQUEST = 907; // Tag of a field for a package of an autofill service @@ -4023,9 +4040,11 @@ message MetricsEvent { // Package: Package of app that was autofilled // Tag FIELD_AUTOFILL_FILTERTEXT_LEN: The length of the filter text // Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets shown - // NOTE: starting on OS P, it also added the following field: + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_FILL_UI = 910; // Tag of a field for the length of the filter text @@ -4034,16 +4053,17 @@ message MetricsEvent { // An autofill authentication succeeded // Package: Package of app that was autofilled // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_AUTHENTICATED = 912; // An activity was autofilled and all values could be applied // Package: Package of app that is autofilled // Tag FIELD_AUTOFILL_NUM_VALUES: Number of values that were suggested to be autofilled // Tag FIELD_AUTOFILL_NUM_VIEWS_FILLED: Number of views that could be filled - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_DATASET_APPLIED = 913; // Tag of a field for the number values to be filled in @@ -4058,28 +4078,37 @@ message MetricsEvent { // Type TYPE_ACTION: data was saved // Package: Package of app that was autofilled // Tag FIELD_AUTOFILL_NUM_IDS: The number of ids that are saved - // NOTE: starting on OS P, it also added the following field: + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_UI = 916; // Tag of a field for the number of saveable ids FIELD_AUTOFILL_NUM_IDS = 917; - // ACTION: An autofill service was reqiested to save data + // ACTION: An autofill service was requested to save data // Type TYPE_SUCCESS: The request succeeded right away // Type TYPE_OPEN: The request succeeded but the service launched an IntentSender // Type TYPE_FAILURE: The request failed // Package: Package of app that was autofilled // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_DATA_SAVE_REQUEST = 918; // An auto-fill session was finished + // OS: O // Package: Package of app that was autofilled - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_NUMBER_REQUESTS: number of requests made to the service (each request + // is logged by a separate AUTOFILL_REQUEST metric) AUTOFILL_SESSION_FINISHED = 919; // meta-event: a reader has checkpointed the log here. @@ -4206,7 +4235,7 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of the autofill service that processed the request // TAG FIELD_AUTOFILL_FORGED_COMPONENT_NAME: Component name being forged // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_FORGED_COMPONENT_ATTEMPT = 948; // FIELD - The component that an app tried tro forged. @@ -4664,8 +4693,10 @@ message MetricsEvent { // OS: O MR // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_PREVIOUS_LENGTH: the previous length of the value - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_VALUE_RESET = 1124; // Tag of AUTOFILL_VALUE_RESET @@ -4675,25 +4706,21 @@ message MetricsEvent { // An autofill dataset authentication succeeded // Package: Package of app that was autofilled // OS: O MR - // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_DATASET_AUTHENTICATED = 1126; // An autofill service provided an invalid dataset authentication // Package: Package of app that was autofilled // OS: O MR // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_INVALID_DATASET_AUTHENTICATION = 1127; // An autofill service provided an invalid authentication extra // Package: Package of app that was autofilled // OS: O MR // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS AUTOFILL_INVALID_AUTHENTICATION = 1128; // An autofill service used a custom description (using RemoteViews) in the autofill save UI @@ -4701,8 +4728,10 @@ message MetricsEvent { // OS: O MR // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_CUSTOM_DESCRIPTION = 1129; // FIELD - Type of save object passed by the service when the Save UI is shown @@ -4714,8 +4743,10 @@ message MetricsEvent { // OS: O MR // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_CUSTOM_SUBTITLE = 1131; // User tapped a link in the custom description of the autofill save UI provided by an autofill service @@ -4726,8 +4757,10 @@ message MetricsEvent { // Type TYPE_FAILURE: The link could not launc an activity // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_LINK_TAPPED = 1132; // Result of the validation on save when an autofill service provided a validator @@ -4738,8 +4771,10 @@ message MetricsEvent { // Type TYPE_DISMISS: The validation failed // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_VALIDATION = 1133; // Result of an operation in the autofill save UI after the user tapped a link in the custom description @@ -4749,8 +4784,10 @@ message MetricsEvent { // Type TYPE_OPEN: The autofill save UI was restored // Type TYPE_DISMISS: The autofill save UI was destroyed // Type TYPE_FAILURE: An invalid opperation was reported by the app's AutofillManager - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // NOTE: starting on OS P, it also added the following fields: + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_PENDING_SAVE_UI_OPERATION = 1134; // Autofill service called API that disables itself @@ -4758,13 +4795,12 @@ message MetricsEvent { // OS: O MR AUTOFILL_SERVICE_DISABLED_SELF = 1135; + // DEPRECATED - on P it was merged with AUTOFILL_REQUEST // Reports how long it took to show the autofill UI after a field was focused // Tag FIELD_AUTOFILL_DURATION: Duration in ms // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Package: Package of the autofill service // OS: O MR - // NOTE: starting on OS P, it also added the following field: - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_UI_LATENCY = 1136; // Action: the snooze leave-behind was shown after the user clicked the snooze icon @@ -4931,15 +4967,19 @@ message MetricsEvent { // An autofill service explicitly defined which view should commit the autofill context // Package: Package of app that is autofilled // OS: P + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION = 1228; // The autofill context was commited when the user clicked a view explicitly marked by the // service as committing it // Package: Package of app that is autofilled // OS: P - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SAVE_EXPLICITLY_TRIGGERED = 1229; // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling @@ -4952,7 +4992,8 @@ message MetricsEvent { // OS: P // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SERVICE_DISABLED_APP = 1231; // An autofill service asked to disable autofill for a given activity. @@ -4961,7 +5002,8 @@ message MetricsEvent { // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_CLASS_NAME: Class name of the activity that is being disabled for autofill // Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_SERVICE_DISABLED_ACTIVITY = 1232; // ACTION: Stop an app and turn on background check @@ -5171,9 +5213,11 @@ message MetricsEvent { // Package: Package of app that is autofilled // Counter: number of matches found // OS: P + // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled. // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request // Tag FIELD_AUTOFILL_MATCH_SCORE: Average score of the matches, in the range of 0 to 100 - // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. + // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric. + // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode. AUTOFILL_FIELD_CLASSIFICATION_MATCHES = 1273; // Tag used to report autofill field classification scores @@ -5840,6 +5884,7 @@ message MetricsEvent { ACTION_STORAGE_MIGRATE_LATER = 1413; // Tag used to report whether an activity is being autofilled on compatibility mode. + // OS: P FIELD_AUTOFILL_COMPAT_MODE = 1414; // OPEN: Settings > Sound > Switch a2dp devices dialog @@ -6045,6 +6090,32 @@ message MetricsEvent { // OS: P ACTION_BATTERY_CAUSED_SHUTDOWN = 1451; + // FIELD: Flags used on autofill-related metrics + // OS: P + FIELD_AUTOFILL_FLAGS = 1452; + + // Tag used when the service returned an authenticated dataset or response. + // Used to replace the following individual metrics, which now are logged as the value of this + // field in the AUTOFILL_REQUEST metric: + // - AUTOFILL_AUTHENTICATED; + // - AUTOFILL_DATASET_AUTHENTICATED + // - AUTOFILL_INVALID_AUTHENTICATION + // - AUTOFILL_INVALID_DATASET_AUTHENTICATION + // OS: P + FIELD_AUTOFILL_AUTHENTICATION_STATUS = 1453; + + // FIELD: Index of the autofill request inside of a session. + // OS: P + FIELD_AUTOFILL_REQUEST_ORDINAL = 1454; + + // FIELD: Number of requests made to an autofill service during a session. + // OS: P + FIELD_AUTOFILL_NUMBER_REQUESTS = 1455; + + // FIELD: Id of the autofill session associated with this metric. + // OS: P + FIELD_AUTOFILL_SESSION_ID = 1456; + // ---- End P Constants, all P constants go above this line ---- // Add new aosp constants above this line. // END OF AOSP CONSTANTS diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index d97253e1f5a8..1ccce177bca8 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -537,11 +537,17 @@ final class AutofillManagerServiceImpl { final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid; Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid + ") passed component (" + componentName + ") owned by UID " + packageUid); - mMetricsLogger.write( - Helper.newLogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT, - callingPackage, getServicePackageName(), compatMode) + + // NOTE: not using Helper.newLogMaker() because we don't have the session id + final LogMaker log = new LogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT) + .setPackageName(callingPackage) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName()) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME, - componentName == null ? "null" : componentName.flattenToShortString())); + componentName == null ? "null" : componentName.flattenToShortString()); + if (compatMode) { + log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1); + } + mMetricsLogger.write(log); throw new SecurityException("Invalid component: " + componentName); } @@ -780,10 +786,10 @@ final class AutofillManagerServiceImpl { @Nullable ArrayList<String> changedDatasetIds, @Nullable ArrayList<AutofillId> manuallyFilledFieldIds, @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds, - @NonNull String appPackageName, boolean compatMode) { + @NonNull ComponentName appComponentName, boolean compatMode) { logContextCommittedLocked(sessionId, clientState, selectedDatasets, ignoredDatasets, changedFieldIds, changedDatasetIds, manuallyFilledFieldIds, - manuallyFilledDatasetIds, null, null, appPackageName, compatMode); + manuallyFilledDatasetIds, null, null, appComponentName, compatMode); } @GuardedBy("mLock") @@ -796,7 +802,7 @@ final class AutofillManagerServiceImpl { @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds, @Nullable ArrayList<AutofillId> detectedFieldIdsList, @Nullable ArrayList<FieldClassification> detectedFieldClassificationsList, - @NonNull String appPackageName, boolean compatMode) { + @NonNull ComponentName appComponentName, boolean compatMode) { if (isValidEventLocked("logDatasetNotSelected()", sessionId)) { if (sVerbose) { Slog.v(TAG, "logContextCommitted() with FieldClassification: id=" + sessionId @@ -807,6 +813,7 @@ final class AutofillManagerServiceImpl { + ", manuallyFilledFieldIds=" + manuallyFilledFieldIds + ", detectedFieldIds=" + detectedFieldIdsList + ", detectedFieldClassifications=" + detectedFieldClassificationsList + + ", appComponentName=" + appComponentName.toShortString() + ", compatMode=" + compatMode); } AutofillId[] detectedFieldsIds = null; @@ -834,7 +841,7 @@ final class AutofillManagerServiceImpl { final int averageScore = (int) ((totalScore * 100) / totalSize); mMetricsLogger.write(Helper .newLogMaker(MetricsEvent.AUTOFILL_FIELD_CLASSIFICATION_MATCHES, - appPackageName, getServicePackageName(), compatMode) + appComponentName, getServicePackageName(), sessionId, compatMode) .setCounterValue(numberFields) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_MATCH_SCORE, averageScore)); @@ -889,9 +896,11 @@ final class AutofillManagerServiceImpl { } mUserData = userData; // Log it - int numberFields = mUserData == null ? 0: mUserData.getCategoryIds().length; - mMetricsLogger.write(Helper.newLogMaker(MetricsEvent.AUTOFILL_USERDATA_UPDATED, - getServicePackageName(), null) + final int numberFields = mUserData == null ? 0: mUserData.getCategoryIds().length; + // NOTE: contrary to most metrics, the service name is logged as the main package name + // here, not as MetricsEvent.FIELD_AUTOFILL_SERVICE + mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_USERDATA_UPDATED) + .setPackageName(getServicePackageName()) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, numberFields)); } } @@ -1130,7 +1139,8 @@ final class AutofillManagerServiceImpl { /** * Called by {@link Session} when service asked to disable autofill for an app. */ - void disableAutofillForApp(@NonNull String packageName, long duration, boolean compatMode) { + void disableAutofillForApp(@NonNull String packageName, long duration, int sessionId, + boolean compatMode) { synchronized (mLock) { if (mDisabledApps == null) { mDisabledApps = new ArrayMap<>(1); @@ -1143,7 +1153,7 @@ final class AutofillManagerServiceImpl { mDisabledApps.put(packageName, expiration); int intDuration = duration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) duration; mMetricsLogger.write(Helper.newLogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_APP, - packageName, getServicePackageName(), compatMode) + packageName, getServicePackageName(), sessionId, compatMode) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, intDuration)); } } @@ -1152,7 +1162,7 @@ final class AutofillManagerServiceImpl { * Called by {@link Session} when service asked to disable autofill an app. */ void disableAutofillForActivity(@NonNull ComponentName componentName, long duration, - boolean compatMode) { + int sessionId, boolean compatMode) { synchronized (mLock) { if (mDisabledActivities == null) { mDisabledActivities = new ArrayMap<>(1); @@ -1163,14 +1173,20 @@ final class AutofillManagerServiceImpl { expiration = Long.MAX_VALUE; } mDisabledActivities.put(componentName, expiration); - final int intDuration = duration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) duration; + final int intDuration = duration > Integer.MAX_VALUE + ? Integer.MAX_VALUE + : (int) duration; // NOTE: not using Helper.newLogMaker() because we're setting the componentName instead // of package name - mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_ACTIVITY) + final LogMaker log = new LogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_ACTIVITY) .setComponentName(componentName) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName()) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, intDuration) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, compatMode ? 1 : 0)); + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SESSION_ID, sessionId); + if (compatMode) { + log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1); + } + mMetricsLogger.write(log); } } diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java index f78101338d2e..cf310e9598f7 100644 --- a/services/autofill/java/com/android/server/autofill/Helper.java +++ b/services/autofill/java/com/android/server/autofill/Helper.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.assist.AssistStructure; import android.app.assist.AssistStructure.ViewNode; +import android.content.ComponentName; import android.metrics.LogMaker; import android.service.autofill.Dataset; import android.util.ArrayMap; @@ -109,20 +110,29 @@ public final class Helper { } @NonNull - public static LogMaker newLogMaker(int category, String packageName, - String servicePackageName) { - final LogMaker log = new LogMaker(category).setPackageName(packageName); - if (servicePackageName != null) { - log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName); + private static LogMaker newLogMaker(int category, @NonNull String servicePackageName, + int sessionId, boolean compatMode) { + final LogMaker log = new LogMaker(category) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SESSION_ID, sessionId); + if (compatMode) { + log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1); } return log; } @NonNull - public static LogMaker newLogMaker(int category, String packageName, - String servicePackageName, boolean compatMode) { - return newLogMaker(category, packageName, servicePackageName) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, compatMode ? 1 : 0); + public static LogMaker newLogMaker(int category, @NonNull String packageName, + @NonNull String servicePackageName, int sessionId, boolean compatMode) { + return newLogMaker(category, servicePackageName, sessionId, compatMode) + .setPackageName(packageName); + } + + @NonNull + public static LogMaker newLogMaker(int category, @NonNull ComponentName componentName, + @NonNull String servicePackageName, int sessionId, boolean compatMode) { + return newLogMaker(category, servicePackageName, sessionId, compatMode) + .setComponentName(componentName); } public static void printlnRedactedText(@NonNull PrintWriter pw, @Nullable CharSequence text) { @@ -193,6 +203,18 @@ public final class Helper { return urlBarNode; } + /** + * Gets the value of a metric tag, or {@code 0} if not found or NaN. + */ + static int getNumericValue(@NonNull LogMaker log, int tag) { + final Object value = log.getTaggedData(tag); + if (!(value instanceof Number)) { + return 0; + } else { + return ((Number) value).intValue(); + } + } + private interface ViewNodeFilter { boolean matches(ViewNode node); } diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java index 4ded3fe29f2a..3e932e8d6daf 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java @@ -99,12 +99,14 @@ final class RemoteFillService implements DeathRecipient { private PendingRequest mPendingRequest; public interface FillServiceCallbacks { - void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response, - @NonNull String servicePackageName); - void onFillRequestFailure(@Nullable CharSequence message, + void onFillRequestSuccess(int requestId, @Nullable FillResponse response, + @NonNull String servicePackageName, int requestFlags); + void onFillRequestFailure(int requestId, @Nullable CharSequence message, @NonNull String servicePackageName); + void onFillRequestTimeout(int requestId, @NonNull String servicePackageName); void onSaveRequestSuccess(@NonNull String servicePackageName, @Nullable IntentSender intentSender); + // TODO(b/80093094): add timeout here too? void onSaveRequestFailure(@Nullable CharSequence message, @NonNull String servicePackageName); void onServiceDied(RemoteFillService service); @@ -301,21 +303,31 @@ final class RemoteFillService implements DeathRecipient { mContext.unbindService(mServiceConnection); } - private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest, int requestFlags, - FillResponse response) { + private void dispatchOnFillRequestSuccess(@NonNull PendingFillRequest pendingRequest, + @Nullable FillResponse response, int requestFlags) { mHandler.post(() -> { if (handleResponseCallbackCommon(pendingRequest)) { - mCallbacks.onFillRequestSuccess(requestFlags, response, - mComponentName.getPackageName()); + mCallbacks.onFillRequestSuccess(pendingRequest.mRequest.getId(), response, + mComponentName.getPackageName(), requestFlags); } }); } - private void dispatchOnFillRequestFailure(PendingRequest pendingRequest, + private void dispatchOnFillRequestFailure(@NonNull PendingFillRequest pendingRequest, @Nullable CharSequence message) { mHandler.post(() -> { if (handleResponseCallbackCommon(pendingRequest)) { - mCallbacks.onFillRequestFailure(message, mComponentName.getPackageName()); + mCallbacks.onFillRequestFailure(pendingRequest.mRequest.getId(), message, + mComponentName.getPackageName()); + } + }); + } + + private void dispatchOnFillRequestTimeout(@NonNull PendingFillRequest pendingRequest) { + mHandler.post(() -> { + if (handleResponseCallbackCommon(pendingRequest)) { + mCallbacks.onFillRequestTimeout(pendingRequest.mRequest.getId(), + mComponentName.getPackageName()); } }); } @@ -538,18 +550,18 @@ final class RemoteFillService implements DeathRecipient { final RemoteFillService remoteService = getService(); if (remoteService != null) { remoteService.dispatchOnFillRequestSuccess(PendingFillRequest.this, - request.getFlags(), response); + response, request.getFlags()); } } @Override - public void onFailure(CharSequence message) { + public void onFailure(int requestId, CharSequence message) { if (!finish()) return; final RemoteFillService remoteService = getService(); if (remoteService != null) { - remoteService.dispatchOnFillRequestFailure( - PendingFillRequest.this, message); + remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, + message); } } }; @@ -566,7 +578,7 @@ final class RemoteFillService implements DeathRecipient { if (cancellation != null) { remoteService.dispatchOnFillTimeout(cancellation); } - remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null); + remoteService.dispatchOnFillRequestTimeout(PendingFillRequest.this); } @Override diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 73c71725200c..fbbb76cc412c 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -27,6 +27,7 @@ import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED; import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; +import static com.android.server.autofill.Helper.getNumericValue; import static com.android.server.autofill.Helper.sDebug; import static com.android.server.autofill.Helper.sPartitionMaxCount; import static com.android.server.autofill.Helper.sVerbose; @@ -93,6 +94,7 @@ import com.android.server.autofill.ui.AutoFillUI; import com.android.server.autofill.ui.PendingUi; import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -176,7 +178,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState /** * Contexts read from the app; they will be updated (sanitized, change values for save) before - * sent to {@link AutofillService}. Ordered by the time they we read. + * sent to {@link AutofillService}. Ordered by the time they were read. */ @GuardedBy("mLock") private ArrayList<FillContext> mContexts; @@ -231,6 +233,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState private final LocalLog mWtfHistory; /** + * Map of {@link MetricsEvent#AUTOFILL_REQUEST} metrics, keyed by fill request id. + */ + @GuardedBy("mLock") + private final SparseArray<LogMaker> mRequestLogs = new SparseArray<>(1); + + /** * Receiver of assist data from the app's {@link Activity}. */ private final IAssistDataReceiver mAssistReceiver = new IAssistDataReceiver.Stub() { @@ -483,8 +491,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState requestId = sIdCounter.getAndIncrement(); } while (requestId == INVALID_REQUEST_ID); + // Create a metrics log for the request + final int ordinal = mRequestLogs.size() + 1; + final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_REQUEST_ORDINAL, ordinal); + if (flags != 0) { + log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags); + } + mRequestLogs.put(requestId, log); + if (sVerbose) { - Slog.v(TAG, "Requesting structure for requestId=" + requestId + ", flags=" + flags); + Slog.v(TAG, "Requesting structure for request #" + ordinal + " ,requestId=" + + requestId + ", flags=" + flags); } // If the focus changes very quickly before the first request is returned each focus change @@ -537,7 +555,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState setClientLocked(client); mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED) - .addTaggedData(MetricsEvent.FIELD_FLAGS, flags)); + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags)); } /** @@ -604,21 +622,30 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // FillServiceCallbacks @Override - public void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response, - @NonNull String servicePackageName) { + public void onFillRequestSuccess(int requestId, @Nullable FillResponse response, + @NonNull String servicePackageName, int requestFlags) { final AutofillId[] fieldClassificationIds; + final LogMaker requestLog; + synchronized (mLock) { if (mDestroyed) { Slog.w(TAG, "Call to Session#onFillRequestSuccess() rejected - session: " + id + " destroyed"); return; } + + requestLog = mRequestLogs.get(requestId); + if (requestLog != null) { + requestLog.setType(MetricsEvent.TYPE_SUCCESS); + } else { + Slog.w(TAG, "onFillRequestSuccess(): no request log for id " + requestId); + } if (response == null) { + if (requestLog != null) { + requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1); + } processNullResponseLocked(requestFlags); - mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName) - .setType(MetricsEvent.TYPE_SUCCESS) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1)); return; } @@ -645,10 +672,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.d(TAG, message.toString()); } if ((flags & FillResponse.FLAG_DISABLE_ACTIVITY_ONLY) != 0) { - mService.disableAutofillForActivity(mComponentName, disableDuration, mCompatMode); + mService.disableAutofillForActivity(mComponentName, disableDuration, + id, mCompatMode); } else { mService.disableAutofillForApp(mComponentName.getPackageName(), disableDuration, - mCompatMode); + id, mCompatMode); } sessionFinishedState = AutofillManager.STATE_DISABLED_BY_SERVICE; } @@ -659,38 +687,54 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // Response is "empty" from an UI point of view, need to notify client. notifyUnavailableToClient(sessionFinishedState); } - synchronized (mLock) { - processResponseLocked(response, null, requestFlags); + + if (requestLog != null) { + requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, + response.getDatasets() == null ? 0 : response.getDatasets().size()); + if (fieldClassificationIds != null) { + requestLog.addTaggedData( + MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS, + fieldClassificationIds.length); + } } - final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName) - .setType(MetricsEvent.TYPE_SUCCESS) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, - response.getDatasets() == null ? 0 : response.getDatasets().size()); - if (fieldClassificationIds != null) { - log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS, - fieldClassificationIds.length); + synchronized (mLock) { + processResponseLocked(response, null, requestFlags); } - mMetricsLogger.write(log); } // FillServiceCallbacks @Override - public void onFillRequestFailure(@Nullable CharSequence message, + public void onFillRequestFailure(int requestId, @Nullable CharSequence message, @NonNull String servicePackageName) { + onFillRequestFailureOrTimeout(requestId, false, message, servicePackageName); + } + + // FillServiceCallbacks + @Override + public void onFillRequestTimeout(int requestId, @NonNull String servicePackageName) { + onFillRequestFailureOrTimeout(requestId, true, null, servicePackageName); + } + + private void onFillRequestFailureOrTimeout(int requestId, boolean timedOut, + @Nullable CharSequence message, @NonNull String servicePackageName) { synchronized (mLock) { if (mDestroyed) { - Slog.w(TAG, "Call to Session#onFillRequestFailure() rejected - session: " - + id + " destroyed"); + Slog.w(TAG, "Call to Session#onFillRequestFailureOrTimeout(req=" + requestId + + ") rejected - session: " + id + " destroyed"); return; } mService.resetLastResponse(); + final LogMaker requestLog = mRequestLogs.get(requestId); + if (requestLog == null) { + Slog.w(TAG, "onFillRequestFailureOrTimeout(): no log for id " + requestId); + } else { + requestLog.setType(timedOut ? MetricsEvent.TYPE_CLOSE : MetricsEvent.TYPE_FAILURE); + } + } + if (message != null) { + getUiForShowing().showError(message, this); } - LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName) - .setType(MetricsEvent.TYPE_FAILURE); - mMetricsLogger.write(log); - - getUiForShowing().showError(message, this); removeSelf(); } @@ -973,11 +1017,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState + ", clientState=" + newClientState); } if (result instanceof FillResponse) { - writeLog(MetricsEvent.AUTOFILL_AUTHENTICATED); + logAuthenticationStatusLocked(requestId, MetricsEvent.AUTOFILL_AUTHENTICATED); replaceResponseLocked(authenticatedResponse, (FillResponse) result, newClientState); } else if (result instanceof Dataset) { if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) { - writeLog(MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED); + logAuthenticationStatusLocked(requestId, + MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED); if (newClientState != null) { if (sDebug) Slog.d(TAG, "Updating client state from auth dataset"); mClientState = newClientState; @@ -986,13 +1031,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState authenticatedResponse.getDatasets().set(datasetIdx, dataset); autoFill(requestId, datasetIdx, dataset, false); } else { - writeLog(MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION); + logAuthenticationStatusLocked(requestId, + MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION); } } else { if (result != null) { Slog.w(TAG, "service returned invalid auth type: " + result); } - writeLog(MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION); + logAuthenticationStatusLocked(requestId, + MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION); processNullResponseLocked(0); } } @@ -1253,7 +1300,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds, ignoredDatasets, changedFieldIds, changedDatasetIds, manuallyFilledFieldIds, manuallyFilledDatasetIds, - mComponentName.getPackageName(), mCompatMode); + mComponentName, mCompatMode); } } @@ -1308,7 +1355,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds, ignoredDatasets, changedFieldIds, changedDatasetIds, manuallyFilledFieldIds, manuallyFilledDatasetIds, - mComponentName.getPackageName(), mCompatMode); + mComponentName, mCompatMode); return; } final Scores scores = result.getParcelable(EXTRA_SCORES); @@ -1373,7 +1420,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds, ignoredDatasets, changedFieldIds, changedDatasetIds, manuallyFilledFieldIds, manuallyFilledDatasetIds, detectedFieldIds, detectedFieldClassifications, - mComponentName.getPackageName(), mCompatMode); + mComponentName, mCompatMode); }); fcStrategy.getScores(callback, algorithm, algorithmArgs, currentValues, userValues); @@ -1404,7 +1451,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState * the current values of all fields in the screen. */ if (saveInfo == null) { - if (sVerbose) Slog.w(TAG, "showSaveLocked(): no saveInfo from service"); + if (sVerbose) Slog.v(TAG, "showSaveLocked(): no saveInfo from service"); return true; } @@ -1603,8 +1650,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mPendingSaveUi = new PendingUi(mActivityToken, id, client); getUiForShowing().showSaveUi(mService.getServiceLabel(), mService.getServiceIcon(), mService.getServicePackageName(), saveInfo, this, - mComponentName.getPackageName(), this, - mPendingSaveUi, mCompatMode); + mComponentName, this, mPendingSaveUi, mCompatMode); if (client != null) { try { client.setSaveUiState(id, true); @@ -2065,7 +2111,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } @Override - public void onFillReady(FillResponse response, AutofillId filledId, + public void onFillReady(@NonNull FillResponse response, @NonNull AutofillId filledId, @Nullable AutofillValue value) { synchronized (mLock) { if (mDestroyed) { @@ -2081,8 +2127,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } getUiForShowing().showFillUi(filledId, response, filterText, - mService.getServicePackageName(), mComponentName.getPackageName(), - mService.getServiceLabel(), mService.getServiceIcon(), this, mCompatMode); + mService.getServicePackageName(), mComponentName, + mService.getServiceLabel(), mService.getServiceIcon(), this, id, mCompatMode); synchronized (mLock) { if (mUiShownTime == 0) { @@ -2103,9 +2149,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState TimeUtils.formatDuration(duration, historyLog); mUiLatencyHistory.log(historyLog.toString()); - final LogMaker metricsLog = newLogMaker(MetricsEvent.AUTOFILL_UI_LATENCY) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, duration); - mMetricsLogger.write(metricsLog); + addTaggedDataToRequestLogLocked(response.getRequestId(), + MetricsEvent.FIELD_AUTOFILL_DURATION, duration); } } } @@ -2474,6 +2519,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState TimeUtils.formatDuration(mUiShownTime - mStartTime, pw); pw.println(); } + final int requestLogsSizes = mRequestLogs.size(); + pw.print(prefix); pw.print("mSessionLogs: "); pw.println(requestLogsSizes); + for (int i = 0; i < requestLogsSizes; i++) { + final int requestId = mRequestLogs.keyAt(i); + final LogMaker log = mRequestLogs.valueAt(i); + pw.print(prefix2); pw.print('#'); pw.print(i); pw.print(": req="); + pw.print(requestId); pw.print(", log=" ); dumpRequestLog(pw, log); pw.println(); + } pw.print(prefix); pw.print("mResponses: "); if (mResponses == null) { pw.println("null"); @@ -2532,6 +2585,56 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mRemoteFillService.dump(prefix, pw); } + private static void dumpRequestLog(@NonNull PrintWriter pw, @NonNull LogMaker log) { + pw.print("CAT="); pw.print(log.getCategory()); + pw.print(", TYPE="); + final int type = log.getType(); + switch (type) { + case MetricsEvent.TYPE_SUCCESS: pw.print("SUCCESS"); break; + case MetricsEvent.TYPE_FAILURE: pw.print("FAILURE"); break; + case MetricsEvent.TYPE_CLOSE: pw.print("CLOSE"); break; + default: pw.print("UNSUPPORTED"); + } + pw.print('('); pw.print(type); pw.print(')'); + pw.print(", PKG="); pw.print(log.getPackageName()); + pw.print(", SERVICE="); pw.print(log + .getTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE)); + pw.print(", ORDINAL="); pw.print(log + .getTaggedData(MetricsEvent.FIELD_AUTOFILL_REQUEST_ORDINAL)); + dumpNumericValue(pw, log, "FLAGS", MetricsEvent.FIELD_AUTOFILL_FLAGS); + dumpNumericValue(pw, log, "NUM_DATASETS", MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS); + dumpNumericValue(pw, log, "UI_LATENCY", MetricsEvent.FIELD_AUTOFILL_DURATION); + final int authStatus = + getNumericValue(log, MetricsEvent.FIELD_AUTOFILL_AUTHENTICATION_STATUS); + if (authStatus != 0) { + pw.print(", AUTH_STATUS="); + switch (authStatus) { + case MetricsEvent.AUTOFILL_AUTHENTICATED: + pw.print("AUTHENTICATED"); break; + case MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED: + pw.print("DATASET_AUTHENTICATED"); break; + case MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION: + pw.print("INVALID_AUTHENTICATION"); break; + case MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION: + pw.print("INVALID_DATASET_AUTHENTICATION"); break; + default: pw.print("UNSUPPORTED"); + } + pw.print('('); pw.print(authStatus); pw.print(')'); + } + dumpNumericValue(pw, log, "FC_IDS", + MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS); + dumpNumericValue(pw, log, "COMPAT_MODE", + MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE); + } + + private static void dumpNumericValue(@NonNull PrintWriter pw, @NonNull LogMaker log, + @NonNull String field, int tag) { + final int value = getNumericValue(log, tag); + if (value != 0) { + pw.print(", "); pw.print(field); pw.print('='); pw.print(value); + } + } + void autoFillApp(Dataset dataset) { synchronized (mLock) { if (mDestroyed) { @@ -2610,7 +2713,19 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mUi.destroyAll(mPendingSaveUi, this, true); mUi.clearCallback(this); mDestroyed = true; - writeLog(MetricsEvent.AUTOFILL_SESSION_FINISHED); + + // Log metrics + final int totalRequests = mRequestLogs.size(); + if (totalRequests > 0) { + if (sVerbose) Slog.v(TAG, "destroyLocked(): logging " + totalRequests + " requests"); + for (int i = 0; i < totalRequests; i++) { + final LogMaker log = mRequestLogs.valueAt(i); + mMetricsLogger.write(log); + } + } + mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_FINISHED) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUMBER_REQUESTS, totalRequests)); + return mRemoteFillService; } @@ -2719,14 +2834,36 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } private LogMaker newLogMaker(int category, String servicePackageName) { - return Helper.newLogMaker(category, mComponentName.getPackageName(), servicePackageName, - mCompatMode); + return Helper.newLogMaker(category, mComponentName, servicePackageName, id, mCompatMode); } private void writeLog(int category) { mMetricsLogger.write(newLogMaker(category)); } + private void logAuthenticationStatusLocked(int requestId, int status) { + addTaggedDataToRequestLogLocked(requestId, + MetricsEvent.FIELD_AUTOFILL_AUTHENTICATION_STATUS, status); + } + + private void addTaggedDataToRequestLogLocked(int requestId, int tag, @Nullable Object value) { + final LogMaker requestLog = mRequestLogs.get(requestId); + if (requestLog == null) { + Slog.w(TAG, + "addTaggedDataToRequestLogLocked(tag=" + tag + "): no log for id " + requestId); + return; + } + requestLog.addTaggedData(tag, value); + } + + private static String requestLogToString(@NonNull LogMaker log) { + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw); + dumpRequestLog(pw, log); + pw.flush(); + return sw.toString(); + } + private void wtf(@Nullable Exception e, String fmt, Object...args) { final String message = String.format(fmt, args); mWtfHistory.log(message); diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java index cff1a84ceafe..bb97e4a97c97 100644 --- a/services/autofill/java/com/android/server/autofill/ViewState.java +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -19,6 +19,7 @@ package com.android.server.autofill; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static com.android.server.autofill.Helper.sDebug; +import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import android.service.autofill.FillResponse; @@ -40,7 +41,7 @@ final class ViewState { /** * Called when the fill UI is ready to be shown for this view. */ - void onFillReady(FillResponse fillResponse, AutofillId focusedId, + void onFillReady(@NonNull FillResponse fillResponse, @NonNull AutofillId focusedId, @Nullable AutofillValue value); } diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java index 811d87beaaa5..c5e838aaa85e 100644 --- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java +++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java @@ -20,6 +20,7 @@ import static com.android.server.autofill.Helper.sVerbose; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.ComponentName; import android.content.Context; import android.content.IntentSender; import android.graphics.drawable.Drawable; @@ -162,22 +163,25 @@ public final class AutoFillUI { * @param response the current fill response * @param filterText text of the view to be filled * @param servicePackageName package name of the autofill service filling the activity - * @param packageName package name of the activity that is filled + * @param componentName component name of the activity that is filled * @param serviceLabel label of autofill service * @param serviceIcon icon of autofill service - * @param callback Identifier for the caller + * @param callback identifier for the caller + * @param sessionId id of the autofill session + * @param compatMode whether the app is being autofilled in compatibility mode. */ public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response, @Nullable String filterText, @Nullable String servicePackageName, - @NonNull String packageName, @NonNull CharSequence serviceLabel, - @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback, boolean compatMode) { + @NonNull ComponentName componentName, @NonNull CharSequence serviceLabel, + @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback, int sessionId, + boolean compatMode) { if (sDebug) { final int size = filterText == null ? 0 : filterText.length(); Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + size + " chars"); } final LogMaker log = Helper - .newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, packageName, servicePackageName, - compatMode) + .newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, componentName, servicePackageName, + sessionId, compatMode) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FILTERTEXT_LEN, filterText == null ? 0 : filterText.length()) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, @@ -262,17 +266,19 @@ public final class AutoFillUI { */ public void showSaveUi(@NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon, @Nullable String servicePackageName, @NonNull SaveInfo info, - @NonNull ValueFinder valueFinder, @NonNull String packageName, + @NonNull ValueFinder valueFinder, @NonNull ComponentName componentName, @NonNull AutoFillUiCallback callback, @NonNull PendingUi pendingSaveUi, boolean compatMode) { - if (sVerbose) Slog.v(TAG, "showSaveUi() for " + packageName + ": " + info); + if (sVerbose) { + Slog.v(TAG, "showSaveUi() for " + componentName.toShortString() + ": " + info); + } int numIds = 0; numIds += info.getRequiredIds() == null ? 0 : info.getRequiredIds().length; numIds += info.getOptionalIds() == null ? 0 : info.getOptionalIds().length; final LogMaker log = Helper - .newLogMaker(MetricsEvent.AUTOFILL_SAVE_UI, packageName, servicePackageName, - compatMode) + .newLogMaker(MetricsEvent.AUTOFILL_SAVE_UI, componentName, servicePackageName, + pendingSaveUi.sessionId, compatMode) .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_IDS, numIds); mHandler.post(() -> { @@ -281,7 +287,7 @@ public final class AutoFillUI { } hideAllUiThread(callback); mSaveUi = new SaveUi(mContext, pendingSaveUi, serviceLabel, serviceIcon, - servicePackageName, packageName, info, valueFinder, mOverlayControl, + servicePackageName, componentName, info, valueFinder, mOverlayControl, new SaveUi.OnSaveListener() { @Override public void onSave() { @@ -409,7 +415,7 @@ public final class AutoFillUI { if (pendingSaveUi != null && notifyClient) { try { if (sDebug) Slog.d(TAG, "destroySaveUiUiThread(): notifying client"); - pendingSaveUi.client.setSaveUiState(pendingSaveUi.id, false); + pendingSaveUi.client.setSaveUiState(pendingSaveUi.sessionId, false); } catch (RemoteException e) { Slog.e(TAG, "Error notifying client to set save UI state to hidden: " + e); } diff --git a/services/autofill/java/com/android/server/autofill/ui/PendingUi.java b/services/autofill/java/com/android/server/autofill/ui/PendingUi.java index d1dfb5c04316..091208bc8f7a 100644 --- a/services/autofill/java/com/android/server/autofill/ui/PendingUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/PendingUi.java @@ -35,7 +35,7 @@ public final class PendingUi { private final IBinder mToken; private int mState; - public final int id; + public final int sessionId; public final IAutoFillManagerClient client; /** @@ -43,10 +43,11 @@ public final class PendingUi { * * @param token token used to identify this pending UI. */ - public PendingUi(@NonNull IBinder token, int id, @NonNull IAutoFillManagerClient client) { + public PendingUi(@NonNull IBinder token, int sessionId, + @NonNull IAutoFillManagerClient client) { mToken = token; mState = STATE_CREATED; - this.id = id; + this.sessionId = sessionId; this.client = client; } @@ -81,7 +82,7 @@ public final class PendingUi { @Override public String toString() { - return "PendingUi: [token=" + mToken + ", id=" + id + ", state=" + return "PendingUi: [token=" + mToken + ", sessionId=" + sessionId + ", state=" + DebugUtils.flagsToString(PendingUi.class, "STATE_", mState) + "]"; } } diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index a5311b28c32e..dc84498353ea 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Dialog; import android.app.PendingIntent; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentSender; @@ -133,14 +134,14 @@ final class SaveUi { private final CharSequence mSubTitle; private final PendingUi mPendingUi; private final String mServicePackageName; - private final String mPackageName; + private final ComponentName mComponentName; private final boolean mCompatMode; private boolean mDestroyed; SaveUi(@NonNull Context context, @NonNull PendingUi pendingUi, @NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon, - @Nullable String servicePackageName, @NonNull String packageName, + @Nullable String servicePackageName, @NonNull ComponentName componentName, @NonNull SaveInfo info, @NonNull ValueFinder valueFinder, @NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener, boolean compatMode) { @@ -148,7 +149,7 @@ final class SaveUi { mListener = new OneTimeListener(listener); mOverlayControl = overlayControl; mServicePackageName = servicePackageName; - mPackageName = packageName; + mComponentName = componentName; mCompatMode = compatMode; context = new ContextThemeWrapper(context, THEME_ID); @@ -412,12 +413,12 @@ final class SaveUi { } private LogMaker newLogMaker(int category, int saveType) { - return Helper.newLogMaker(category, mPackageName, mServicePackageName, mCompatMode) - .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SAVE_TYPE, saveType); + return newLogMaker(category).addTaggedData(MetricsEvent.FIELD_AUTOFILL_SAVE_TYPE, saveType); } private LogMaker newLogMaker(int category) { - return Helper.newLogMaker(category, mPackageName, mServicePackageName, mCompatMode); + return Helper.newLogMaker(category, mComponentName, mServicePackageName, + mPendingUi.sessionId, mCompatMode); } private void writeLog(int category, int saveType) { @@ -505,7 +506,7 @@ final class SaveUi { pw.print(prefix); pw.print("subtitle: "); pw.println(mSubTitle); pw.print(prefix); pw.print("pendingUi: "); pw.println(mPendingUi); pw.print(prefix); pw.print("service: "); pw.println(mServicePackageName); - pw.print(prefix); pw.print("app: "); pw.println(mPackageName); + pw.print(prefix); pw.print("app: "); pw.println(mComponentName.toShortString()); pw.print(prefix); pw.print("compat mode: "); pw.println(mCompatMode); final View view = mDialog.getWindow().getDecorView(); diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 0775abf574b5..f79a51b13afd 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -1776,7 +1776,7 @@ class AlarmManagerService extends SystemService { } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID || UserHandle.isSameApp(callingUid, mSystemUiUid) || ((mAppStateTracker != null) - && mAppStateTracker.isUidPowerSaveWhitelisted(callingUid)))) { + && mAppStateTracker.isUidPowerSaveUserWhitelisted(callingUid)))) { flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; } diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 3beebcba6c5d..aa86ea8b03e2 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -812,11 +812,12 @@ public class AppOpsService extends IAppOpsService.Stub { resOps = new ArrayList<>(); for (int j=0; j<pkgOps.size(); j++) { Op curOp = pkgOps.valueAt(j); - long duration = curOp.duration == -1 + final boolean running = curOp.duration == -1; + long duration = running ? (elapsedNow - curOp.startRealtime) : curOp.duration; resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, - curOp.rejectTime, (int) duration, curOp.proxyUid, + curOp.rejectTime, (int) duration, running, curOp.proxyUid, curOp.proxyPackageName)); } } else { @@ -826,11 +827,12 @@ public class AppOpsService extends IAppOpsService.Stub { if (resOps == null) { resOps = new ArrayList<>(); } - long duration = curOp.duration == -1 + final boolean running = curOp.duration == -1; + final long duration = running ? (elapsedNow - curOp.startRealtime) : curOp.duration; resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, - curOp.rejectTime, (int) duration, curOp.proxyUid, + curOp.rejectTime, (int) duration, running, curOp.proxyUid, curOp.proxyPackageName)); } } diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java index 9b001ce3f917..3a7b5d683507 100644 --- a/services/core/java/com/android/server/AppStateTracker.java +++ b/services/core/java/com/android/server/AppStateTracker.java @@ -117,6 +117,12 @@ public class AppStateTracker { @GuardedBy("mLock") private int[] mPowerWhitelistedAllAppIds = new int[0]; + /** + * User whitelisted apps in the device idle controller. + */ + @GuardedBy("mLock") + private int[] mPowerWhitelistedUserAppIds = new int[0]; + @GuardedBy("mLock") private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds; @@ -983,13 +989,16 @@ public class AppStateTracker { * Called by device idle controller to update the power save whitelists. */ public void setPowerSaveWhitelistAppIds( - int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) { + int[] powerSaveWhitelistExceptIdleAppIdArray, + int[] powerSaveWhitelistUserAppIdArray, + int[] tempWhitelistAppIdArray) { synchronized (mLock) { final int[] previousWhitelist = mPowerWhitelistedAllAppIds; final int[] previousTempWhitelist = mTempWhitelistedAppIds; - mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray; + mPowerWhitelistedAllAppIds = powerSaveWhitelistExceptIdleAppIdArray; mTempWhitelistedAppIds = tempWhitelistAppIdArray; + mPowerWhitelistedUserAppIds = powerSaveWhitelistUserAppIdArray; if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) { mHandler.notifyAllUnwhitelisted(); @@ -1194,6 +1203,16 @@ public class AppStateTracker { } /** + * @param uid the uid to check for + * @return whether a UID is in the user defined power-save whitelist or not. + */ + public boolean isUidPowerSaveUserWhitelisted(int uid) { + synchronized (mLock) { + return ArrayUtils.contains(mPowerWhitelistedUserAppIds, UserHandle.getAppId(uid)); + } + } + + /** * @return whether a UID is in the temp power-save whitelist or not. * * Note clients normally shouldn't need to access it. It's only for dumpsys. @@ -1231,9 +1250,12 @@ public class AppStateTracker { pw.print("Foreground uids: "); dumpUids(pw, mForegroundUids); - pw.print("Whitelist appids: "); + pw.print("Except-idle + user whitelist appids: "); pw.println(Arrays.toString(mPowerWhitelistedAllAppIds)); + pw.print("User whitelist appids: "); + pw.println(Arrays.toString(mPowerWhitelistedUserAppIds)); + pw.print("Temp whitelist appids: "); pw.println(Arrays.toString(mTempWhitelistedAppIds)); @@ -1311,6 +1333,10 @@ public class AppStateTracker { proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId); } + for (int appId : mPowerWhitelistedUserAppIds) { + proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_USER_WHITELIST_APP_IDS, appId); + } + for (int appId : mTempWhitelistedAppIds) { proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId); } diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 74b45436aabd..0f4702cb8cde 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -1540,7 +1540,7 @@ public class DeviceIdleController extends SystemService mLocalActivityManager.registerScreenObserver(mScreenObserver); - passWhiteListToForceAppStandbyTrackerLocked(); + passWhiteListsToForceAppStandbyTrackerLocked(); updateInteractivityLocked(); } updateConnectivityState(null); @@ -1631,7 +1631,7 @@ public class DeviceIdleController extends SystemService mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds); - passWhiteListToForceAppStandbyTrackerLocked(); + passWhiteListsToForceAppStandbyTrackerLocked(); } return true; } catch (PackageManager.NameNotFoundException e) { @@ -1650,7 +1650,7 @@ public class DeviceIdleController extends SystemService mPowerSaveWhitelistExceptIdleAppIds); mPowerSaveWhitelistUserAppsExceptIdle.clear(); - passWhiteListToForceAppStandbyTrackerLocked(); + passWhiteListsToForceAppStandbyTrackerLocked(); } } } @@ -2589,7 +2589,7 @@ public class DeviceIdleController extends SystemService } mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); } - passWhiteListToForceAppStandbyTrackerLocked(); + passWhiteListsToForceAppStandbyTrackerLocked(); } private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) { @@ -2615,7 +2615,7 @@ public class DeviceIdleController extends SystemService } mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray); } - passWhiteListToForceAppStandbyTrackerLocked(); + passWhiteListsToForceAppStandbyTrackerLocked(); } private void reportPowerSaveWhitelistChangedLocked() { @@ -2630,9 +2630,10 @@ public class DeviceIdleController extends SystemService getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); } - private void passWhiteListToForceAppStandbyTrackerLocked() { + private void passWhiteListsToForceAppStandbyTrackerLocked() { mAppStateTracker.setPowerSaveWhitelistAppIds( mPowerSaveWhitelistExceptIdleAppIdArray, + mPowerSaveWhitelistUserAppIdArray, mTempWhitelistAppIdArray); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c25f8ff843a8..e95a9327cfb3 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -15305,6 +15305,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void onLimitReached(int uid) { Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " + Process.myUid()); + Binder.dumpProxyDebugInfo(); if (uid == Process.SYSTEM_UID) { Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); } else { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index ef5a5a322aa8..d456f6255426 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -115,6 +115,7 @@ import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK; import static com.android.server.am.ActivityRecordProto.IDENTIFIER; import static com.android.server.am.ActivityRecordProto.PROC_ID; import static com.android.server.am.ActivityRecordProto.STATE; +import static com.android.server.am.ActivityRecordProto.TRANSLUCENT; import static com.android.server.am.ActivityRecordProto.VISIBLE; import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT; import static com.android.server.wm.IdentifierProto.HASH_CODE; @@ -2412,11 +2413,16 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } // Compute configuration based on max supported width and height. - outBounds.set(0, 0, maxActivityWidth, maxActivityHeight); - // Position the activity frame on the opposite side of the nav bar. - final int navBarPosition = service.mWindowManager.getNavBarPosition(); - final int left = navBarPosition == NAV_BAR_LEFT ? appBounds.right - outBounds.width() : 0; - outBounds.offsetTo(left, 0 /* top */); + // Also account for the left / top insets (e.g. from display cutouts), which will be clipped + // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app + // bounds would end up too small. + outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top); + + if (service.mWindowManager.getNavBarPosition() == NAV_BAR_LEFT) { + // Position the activity frame on the opposite side of the nav bar. + outBounds.left = appBounds.right - maxActivityWidth; + outBounds.right = appBounds.right; + } } boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) { @@ -2980,6 +2986,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo if (app != null) { proto.write(PROC_ID, app.pid); } + proto.write(TRANSLUCENT, !fullscreen); proto.end(token); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index afad0b1df5f2..7310fab72cf8 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2554,6 +2554,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D final int displayId = mTmpOrderedDisplayIds.get(i); // If a display is registered in WM, it must also be available in AM. final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId); + if (display == null) { + // Looks like the display no longer exists in the system... + continue; + } for (int j = display.getChildCount() - 1; j >= 0; --j) { final ActivityStack stack = display.getChildAt(j); if (ignoreCurrent && stack == currentFocus) { diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index d7057f45e135..2c9a494dbecd 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -1310,10 +1310,10 @@ public final class ContentService extends IContentService.Stub { : ActivityManager.PROCESS_STATE_NONEXISTENT; if (procState <= ActivityManager.PROCESS_STATE_TOP) { - return ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP; + return ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP; } if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { - return ContentResolver.SYNC_EXEMPTION_ACTIVE; + return ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET; } return ContentResolver.SYNC_EXEMPTION_NONE; } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 33cf11b86650..0a640b8a76c6 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -1656,7 +1656,7 @@ public class SyncManager { } if (syncOperation.syncExemptionFlag - == ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP) { + == ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP) { DeviceIdleController.LocalService dic = LocalServices.getService(DeviceIdleController.LocalService.class); if (dic != null) { @@ -1668,6 +1668,15 @@ public class SyncManager { } } + if (syncOperation.isAppStandbyExempted()) { + final UsageStatsManagerInternal usmi = LocalServices.getService( + UsageStatsManagerInternal.class); + if (usmi != null) { + usmi.reportExemptedSyncScheduled(syncOperation.owningPackage, + UserHandle.getUserId(syncOperation.owningUid)); + } + } + getJobScheduler().scheduleAsPackage(b.build(), syncOperation.owningPackage, syncOperation.target.userId, syncOperation.wakeLockName()); } diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java index d0975637e686..25edf4070689 100644 --- a/services/core/java/com/android/server/content/SyncOperation.java +++ b/services/core/java/com/android/server/content/SyncOperation.java @@ -390,10 +390,10 @@ public class SyncOperation { switch (syncExemptionFlag) { case ContentResolver.SYNC_EXEMPTION_NONE: break; - case ContentResolver.SYNC_EXEMPTION_ACTIVE: + case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET: sb.append(" STANDBY-EXEMPTED"); break; - case ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP: + case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP: sb.append(" STANDBY-EXEMPTED(TOP)"); break; default: diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index 6a343f88a273..11f07015ef12 100644 --- a/services/core/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java @@ -341,6 +341,7 @@ public class SyncStorageEngine { boolean initialization; Bundle extras; int reason; + int syncExemptionFlag; } public static class DayStats { @@ -1142,6 +1143,7 @@ public class SyncStorageEngine { item.reason = op.reason; item.extras = op.extras; item.event = EVENT_START; + item.syncExemptionFlag = op.syncExemptionFlag; mSyncHistory.add(0, item); while (mSyncHistory.size() > MAX_HISTORY) { mSyncHistory.remove(mSyncHistory.size()-1); @@ -1262,6 +1264,20 @@ public class SyncStorageEngine { SyncManager.formatDurationHMS(event, elapsedTime); event.append(" Reason="); event.append(SyncOperation.reasonToString(null, item.reason)); + if (item.syncExemptionFlag != ContentResolver.SYNC_EXEMPTION_NONE) { + event.append(" Exemption="); + switch (item.syncExemptionFlag) { + case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET: + event.append("fg"); + break; + case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP: + event.append("top"); + break; + default: + event.append(item.syncExemptionFlag); + break; + } + } event.append(" Extras="); SyncOperation.extrasToStringBuilder(item.extras, event); diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 4e6307dbca8a..0f8c5269a95c 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -1015,26 +1015,25 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt locationListener = mFusedLocationListener; } - if (!locationManager.isProviderEnabled(provider)) { - Log.w(TAG, "Unable to request location since " + provider - + " provider does not exist or is not enabled."); - return; - } - Log.i(TAG, String.format( "GNSS HAL Requesting location updates from %s provider for %d millis.", provider, durationMillis)); - locationManager.requestLocationUpdates(provider, - LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0, - locationListener, mHandler.getLooper()); - locationListener.numLocationUpdateRequest++; - mHandler.postDelayed(() -> { - if (--locationListener.numLocationUpdateRequest == 0) { - Log.i(TAG, String.format("Removing location updates from %s provider.", provider)); - locationManager.removeUpdates(locationListener); - } - }, durationMillis); + try { + locationManager.requestLocationUpdates(provider, + LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0, + locationListener, mHandler.getLooper()); + locationListener.numLocationUpdateRequest++; + mHandler.postDelayed(() -> { + if (--locationListener.numLocationUpdateRequest == 0) { + Log.i(TAG, + String.format("Removing location updates from %s provider.", provider)); + locationManager.removeUpdates(locationListener); + } + }, durationMillis); + } catch (IllegalArgumentException e) { + Log.w(TAG, "Unable to request location.", e); + } } private void injectBestLocation(Location location) { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index a735297b06c2..7ffd5ed07a31 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -6161,7 +6161,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { sendSystemKeyToStatusBarAsync(event.getKeyCode()); TelecomManager telecomManager = getTelecommService(); - if (telecomManager != null) { + if (telecomManager != null && !mHandleVolumeKeysInWM) { + // When {@link #mHandleVolumeKeysInWM} is set, volume key events + // should be dispatched to WM. if (telecomManager.isRinging()) { // If an incoming call is ringing, either VOLUME key means // "silence ringer". We handle these keys here, rather than diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 288612621f2c..547ab0ed443d 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -557,7 +557,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (cropFile != null) { Bitmap bitmap = BitmapFactory.decodeFile(cropFile); if (bitmap != null) { - colors = WallpaperColors.fromBitmap(bitmap, true /* computeHints */); + colors = WallpaperColors.fromBitmap(bitmap); bitmap.recycle(); } } diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index b8431b1d8ad8..65c8e96a0774 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -22,7 +22,9 @@ import static com.android.server.wm.AlphaAnimationSpecProto.TO; import static com.android.server.wm.AnimationSpecProto.ALPHA; import android.graphics.Rect; +import android.util.Log; import android.util.proto.ProtoOutputStream; +import android.view.Surface; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; @@ -171,14 +173,18 @@ class Dimmer { */ private DimState getDimState(WindowContainer container) { if (mDimState == null) { - final SurfaceControl ctl = makeDimLayer(); - mDimState = new DimState(ctl); - /** - * See documentation on {@link #dimAbove} to understand lifecycle management of Dim's - * via state resetting for Dim's with containers. - */ - if (container == null) { - mDimState.mDontReset = true; + try { + final SurfaceControl ctl = makeDimLayer(); + mDimState = new DimState(ctl); + /** + * See documentation on {@link #dimAbove} to understand lifecycle management of + * Dim's via state resetting for Dim's with containers. + */ + if (container == null) { + mDimState.mDontReset = true; + } + } catch (Surface.OutOfResourcesException e) { + Log.w(TAG, "OutOfResourcesException creating dim surface"); } } @@ -189,6 +195,11 @@ class Dimmer { private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer, float alpha) { final DimState d = getDimState(container); + + if (d == null) { + return; + } + if (container != null) { // The dim method is called from WindowState.prepareSurfaces(), which is always called // in the correct Z from lowest Z to highest. This ensures that the dim layer is always @@ -208,10 +219,11 @@ class Dimmer { * @param t A Transaction in which to finish the dim. */ void stopDim(SurfaceControl.Transaction t) { - DimState d = getDimState(null); - t.hide(d.mDimLayer); - d.isVisible = false; - d.mDontReset = false; + if (mDimState != null) { + t.hide(mDimState.mDimLayer); + mDimState.isVisible = false; + mDimState.mDontReset = false; + } } /** diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 7211533c1b44..2bfff269e457 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -206,6 +206,9 @@ class SurfaceAnimationRunner { } } }); + a.mAnim = anim; + mRunningAnimations.put(a.mLeash, a); + anim.start(); if (a.mAnimSpec.canSkipFirstFrame()) { // If we can skip the first frame, we start one frame later. @@ -215,8 +218,6 @@ class SurfaceAnimationRunner { // Immediately start the animation by manually applying an animation frame. Otherwise, the // start time would only be set in the next frame, leading to a delay. anim.doAnimationFrame(mChoreographer.getFrameTime()); - a.mAnim = anim; - mRunningAnimations.put(a.mLeash, a); } private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) { diff --git a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java index 5daacd73c915..933b3d6b4b6c 100644 --- a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java @@ -445,7 +445,7 @@ public class AppStateTrackerTest { areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS); areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE); - instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {UID_2}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {}, new int[] {UID_2}); areRestricted(instance, UID_1, PACKAGE_1, NONE); areRestricted(instance, UID_10_1, PACKAGE_1, NONE); @@ -482,6 +482,15 @@ public class AppStateTrackerTest { } @Test + public void testPowerSaveUserWhitelist() throws Exception { + final AppStateTrackerTestable instance = newInstance(); + instance.setPowerSaveWhitelistAppIds(new int[] {}, new int[] {UID_1, UID_2}, new int[] {}); + assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_1)); + assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_2)); + assertFalse(instance.isUidPowerSaveUserWhitelisted(UID_3)); + } + + @Test public void testUidStateForeground() throws Exception { final AppStateTrackerTestable instance = newInstance(); callStart(instance); @@ -861,7 +870,7 @@ public class AppStateTrackerTest { // ------------------------------------------------------------------------- // Tests with system/user/temp whitelist. - instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {}); waitUntilMainHandlerDrain(); verify(l, times(1)).updateAllJobs(); @@ -873,7 +882,7 @@ public class AppStateTrackerTest { verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); reset(l); - instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {}); waitUntilMainHandlerDrain(); verify(l, times(1)).updateAllJobs(); @@ -886,7 +895,8 @@ public class AppStateTrackerTest { reset(l); // Update temp whitelist. - instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, + new int[] {UID_1, UID_3}); waitUntilMainHandlerDrain(); verify(l, times(1)).updateAllJobs(); @@ -898,7 +908,7 @@ public class AppStateTrackerTest { verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); reset(l); - instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3}); waitUntilMainHandlerDrain(); verify(l, times(1)).updateAllJobs(); @@ -924,7 +934,7 @@ public class AppStateTrackerTest { verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); reset(l); - instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {}); waitUntilMainHandlerDrain(); // Called once for updating all whitelist and once for updating temp whitelist @@ -937,7 +947,7 @@ public class AppStateTrackerTest { verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); reset(l); - instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {}); waitUntilMainHandlerDrain(); verify(l, times(1)).updateAllJobs(); @@ -950,7 +960,8 @@ public class AppStateTrackerTest { reset(l); // Update temp whitelist. - instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, + new int[] {UID_1, UID_3}); waitUntilMainHandlerDrain(); verify(l, times(1)).updateAllJobs(); @@ -962,7 +973,7 @@ public class AppStateTrackerTest { verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString()); reset(l); - instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3}); + instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3}); waitUntilMainHandlerDrain(); verify(l, times(1)).updateAllJobs(); diff --git a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java index ea0fe455672b..7f397d6a2cfc 100644 --- a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java @@ -18,6 +18,8 @@ package com.android.server.appops; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; @@ -36,6 +38,8 @@ import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.List; + /** * Tests app ops version upgrades */ @@ -107,6 +111,46 @@ public class AppOpsActiveWatcherTest { verifyNoMoreInteractions(listener); } + @Test + public void testIsRunning() throws Exception { + final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); + // Start the op + appOpsManager.startOp(AppOpsManager.OP_CAMERA); + + assertTrue("Camera should be running", isCameraOn(appOpsManager)); + + // Finish the op + appOpsManager.finishOp(AppOpsManager.OP_CAMERA); + + assertFalse("Camera should not be running", isCameraOn(appOpsManager)); + } + + private boolean isCameraOn(AppOpsManager appOpsManager) { + List<AppOpsManager.PackageOps> packages + = appOpsManager.getPackagesForOps(new int[] {AppOpsManager.OP_CAMERA}); + // AppOpsManager can return null when there is no requested data. + if (packages != null) { + final int numPackages = packages.size(); + for (int packageInd = 0; packageInd < numPackages; packageInd++) { + AppOpsManager.PackageOps packageOp = packages.get(packageInd); + List<AppOpsManager.OpEntry> opEntries = packageOp.getOps(); + if (opEntries != null) { + final int numOps = opEntries.size(); + for (int opInd = 0; opInd < numOps; opInd++) { + AppOpsManager.OpEntry opEntry = opEntries.get(opInd); + if (opEntry.getOp() == AppOpsManager.OP_CAMERA) { + if (opEntry.isRunning()) { + return true; + } + } + } + } + } + } + + return false; + } + private static Context getContext() { return InstrumentationRegistry.getContext(); } diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index dee25569705b..84611667d113 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -218,6 +218,11 @@ public class AppStandbyControllerTests { + "stable_charging_threshold=" + STABLE_CHARGING_THRESHOLD; } + @Override + public boolean isDeviceIdleMode() { + return false; + } + // Internal methods void setDisplayOn(boolean on) { diff --git a/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java b/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java index 4d99b3208720..9c010a07135d 100644 --- a/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java @@ -20,8 +20,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import android.app.WallpaperColors; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; import android.os.Handler; import android.os.Message; import android.os.SystemClock; @@ -87,17 +85,4 @@ public class WallpaperServiceTests { assertEquals("OnComputeColors should have been deferred.", 0, eventCountdown.getCount()); } - - @Test - public void testFromDrawableTest_doesntComputeHints() { - WallpaperColors wallpaperColors = WallpaperColors.fromDrawable( - new ColorDrawable(Color.BLACK)); - assertEquals("WallpaperColors should not support dark theme.", 0, - wallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME); - - wallpaperColors = WallpaperColors.fromDrawable( - new ColorDrawable(Color.WHITE)); - assertEquals("WallpaperColors should not support dark text.", 0, - wallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT); - } } diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java index 3378897858d3..9c62700a9118 100644 --- a/services/usage/java/com/android/server/usage/AppStandbyController.java +++ b/services/usage/java/com/android/server/usage/AppStandbyController.java @@ -24,6 +24,8 @@ import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT; import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE; import static android.app.usage.UsageStatsManager.REASON_SUB_PREDICTED_RESTORED; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_ACTIVE_TIMEOUT; +import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE; +import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_START; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND; @@ -194,8 +196,9 @@ public class AppStandbyController { static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10; /** Check the state of one app: arg1 = userId, arg2 = uid, obj = (String) packageName */ static final int MSG_CHECK_PACKAGE_IDLE_STATE = 11; - static final int MSG_REPORT_EXEMPTED_SYNC_START = 12; - static final int MSG_UPDATE_STABLE_CHARGING= 13; + static final int MSG_REPORT_EXEMPTED_SYNC_SCHEDULED = 12; + static final int MSG_REPORT_EXEMPTED_SYNC_START = 13; + static final int MSG_UPDATE_STABLE_CHARGING= 14; long mCheckIdleIntervalMillis; long mAppIdleParoleIntervalMillis; @@ -213,8 +216,20 @@ public class AppStandbyController { long mPredictionTimeoutMillis; /** Maximum time a sync adapter associated with a CP should keep the buckets elevated. */ long mSyncAdapterTimeoutMillis; - /** Maximum time an exempted sync should keep the buckets elevated. */ - long mExemptedSyncAdapterTimeoutMillis; + /** + * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in + * non-doze + */ + long mExemptedSyncScheduledNonDozeTimeoutMillis; + /** + * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in + * doze + */ + long mExemptedSyncScheduledDozeTimeoutMillis; + /** + * Maximum time an exempted sync should keep the buckets elevated, when sync is started. + */ + long mExemptedSyncStartTimeoutMillis; /** Maximum time a system interaction should keep the buckets elevated. */ long mSystemInteractionTimeoutMillis; /** The length of time phone must be charging before considered stable enough to run jobs */ @@ -393,6 +408,37 @@ public class AppStandbyController { } } + void reportExemptedSyncScheduled(String packageName, int userId) { + if (!mAppIdleEnabled) return; + + final int bucketToPromote; + final int usageReason; + final long durationMillis; + + if (!mInjector.isDeviceIdleMode()) { + // Not dozing. + bucketToPromote = STANDBY_BUCKET_ACTIVE; + usageReason = REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE; + durationMillis = mExemptedSyncScheduledNonDozeTimeoutMillis; + } else { + // Dozing. + bucketToPromote = STANDBY_BUCKET_WORKING_SET; + usageReason = REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE; + durationMillis = mExemptedSyncScheduledDozeTimeoutMillis; + } + + final long elapsedRealtime = mInjector.elapsedRealtime(); + + synchronized (mAppIdleLock) { + AppUsageHistory appUsage = mAppIdleHistory.reportUsage(packageName, userId, + bucketToPromote, usageReason, + 0, + elapsedRealtime + durationMillis); + maybeInformListeners(packageName, userId, elapsedRealtime, + appUsage.currentBucket, appUsage.bucketingReason, false); + } + } + void reportExemptedSyncStart(String packageName, int userId) { if (!mAppIdleEnabled) return; @@ -402,7 +448,7 @@ public class AppStandbyController { AppUsageHistory appUsage = mAppIdleHistory.reportUsage(packageName, userId, STANDBY_BUCKET_ACTIVE, REASON_SUB_USAGE_EXEMPTED_SYNC_START, 0, - elapsedRealtime + mExemptedSyncAdapterTimeoutMillis); + elapsedRealtime + mExemptedSyncStartTimeoutMillis); maybeInformListeners(packageName, userId, elapsedRealtime, appUsage.currentBucket, appUsage.bucketingReason, false); } @@ -1365,6 +1411,11 @@ public class AppStandbyController { .sendToTarget(); } + void postReportExemptedSyncScheduled(String packageName, int userId) { + mHandler.obtainMessage(MSG_REPORT_EXEMPTED_SYNC_SCHEDULED, userId, 0, packageName) + .sendToTarget(); + } + void postReportExemptedSyncStart(String packageName, int userId) { mHandler.obtainMessage(MSG_REPORT_EXEMPTED_SYNC_START, userId, 0, packageName) .sendToTarget(); @@ -1401,6 +1452,16 @@ public class AppStandbyController { TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw); pw.println(); + pw.print(" mExemptedSyncScheduledNonDozeTimeoutMillis="); + TimeUtils.formatDuration(mExemptedSyncScheduledNonDozeTimeoutMillis, pw); + pw.println(); + pw.print(" mExemptedSyncScheduledDozeTimeoutMillis="); + TimeUtils.formatDuration(mExemptedSyncScheduledDozeTimeoutMillis, pw); + pw.println(); + pw.print(" mExemptedSyncStartTimeoutMillis="); + TimeUtils.formatDuration(mExemptedSyncStartTimeoutMillis, pw); + pw.println(); + pw.println(); pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled); pw.print(" mAppIdleTempParoled="); pw.print(mAppIdleTempParoled); @@ -1429,6 +1490,7 @@ public class AppStandbyController { private IBatteryStats mBatteryStats; private PackageManagerInternal mPackageManagerInternal; private DisplayManager mDisplayManager; + private PowerManager mPowerManager; int mBootPhase; Injector(Context context, Looper looper) { @@ -1453,6 +1515,7 @@ public class AppStandbyController { mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mDisplayManager = (DisplayManager) mContext.getSystemService( Context.DISPLAY_SERVICE); + mPowerManager = mContext.getSystemService(PowerManager.class); } mBootPhase = phase; } @@ -1532,6 +1595,11 @@ public class AppStandbyController { return Global.getString(mContext.getContentResolver(), Global.APP_IDLE_CONSTANTS); } + + /** Whether the device is in doze or not. */ + public boolean isDeviceIdleMode() { + return mPowerManager.isDeviceIdleMode(); + } } class AppStandbyHandler extends Handler { @@ -1595,6 +1663,10 @@ public class AppStandbyController { mInjector.elapsedRealtime()); break; + case MSG_REPORT_EXEMPTED_SYNC_SCHEDULED: + reportExemptedSyncScheduled((String) msg.obj, msg.arg1); + break; + case MSG_REPORT_EXEMPTED_SYNC_START: reportExemptedSyncStart((String) msg.obj, msg.arg1); break; @@ -1684,7 +1756,12 @@ public class AppStandbyController { "system_update_usage_duration"; private static final String KEY_PREDICTION_TIMEOUT = "prediction_timeout"; private static final String KEY_SYNC_ADAPTER_HOLD_DURATION = "sync_adapter_duration"; - private static final String KEY_EXEMPTED_SYNC_HOLD_DURATION = "exempted_sync_duration"; + private static final String KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION + = "exempted_sync_scheduled_nd_duration"; + private static final String KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION + = "exempted_sync_scheduled_d_duration"; + private static final String KEY_EXEMPTED_SYNC_START_HOLD_DURATION + = "exempted_sync_start_duration"; private static final String KEY_SYSTEM_INTERACTION_HOLD_DURATION = "system_interaction_duration"; private static final String KEY_STABLE_CHARGING_THRESHOLD = "stable_charging_threshold"; @@ -1693,7 +1770,9 @@ public class AppStandbyController { public static final long DEFAULT_SYSTEM_UPDATE_TIMEOUT = 2 * ONE_HOUR; public static final long DEFAULT_SYSTEM_INTERACTION_TIMEOUT = 10 * ONE_MINUTE; public static final long DEFAULT_SYNC_ADAPTER_TIMEOUT = 10 * ONE_MINUTE; - public static final long DEFAULT_EXEMPTED_SYNC_TIMEOUT = 10 * ONE_MINUTE; + public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT = 10 * ONE_MINUTE; + public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT = 4 * ONE_HOUR; + public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = 10 * ONE_MINUTE; public static final long DEFAULT_STABLE_CHARGING_THRESHOLD = 10 * ONE_MINUTE; private final KeyValueListParser mParser = new KeyValueListParser(','); @@ -1778,9 +1857,22 @@ public class AppStandbyController { mSyncAdapterTimeoutMillis = mParser.getDurationMillis (KEY_SYNC_ADAPTER_HOLD_DURATION, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYNC_ADAPTER_TIMEOUT); - mExemptedSyncAdapterTimeoutMillis = mParser.getDurationMillis - (KEY_EXEMPTED_SYNC_HOLD_DURATION, - COMPRESS_TIME ? ONE_MINUTE : DEFAULT_EXEMPTED_SYNC_TIMEOUT); + + mExemptedSyncScheduledNonDozeTimeoutMillis = mParser.getDurationMillis + (KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION, + COMPRESS_TIME ? (ONE_MINUTE / 2) + : DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT); + + mExemptedSyncScheduledDozeTimeoutMillis = mParser.getDurationMillis + (KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION, + COMPRESS_TIME ? ONE_MINUTE + : DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT); + + mExemptedSyncStartTimeoutMillis = mParser.getDurationMillis + (KEY_EXEMPTED_SYNC_START_HOLD_DURATION, + COMPRESS_TIME ? ONE_MINUTE + : DEFAULT_EXEMPTED_SYNC_START_TIMEOUT); + mSystemInteractionTimeoutMillis = mParser.getDurationMillis (KEY_SYSTEM_INTERACTION_HOLD_DURATION, COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYSTEM_INTERACTION_TIMEOUT); diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 6311127a1ffe..a7d3f78c66f0 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -1371,6 +1371,11 @@ public class UsageStatsService extends SystemService implements } @Override + public void reportExemptedSyncScheduled(String packageName, int userId) { + mAppStandby.postReportExemptedSyncScheduled(packageName, userId); + } + + @Override public void reportExemptedSyncStart(String packageName, int userId) { mAppStandby.postReportExemptedSyncStart(packageName, userId); } |