diff options
165 files changed, 2100 insertions, 2257 deletions
diff --git a/StubLibraries.bp b/StubLibraries.bp index 6927f4449054..0f805655b33d 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -340,7 +340,7 @@ java_library_static { } java_library_static { - name: "framework_module_app_stubs_current", + name: "android_module_app_stubs_current", srcs: [ ":module-app-api-stubs-docs", ], @@ -355,7 +355,7 @@ java_library_static { } java_library_static { - name: "framework_module_lib_stubs_current", + name: "android_module_lib_stubs_current", srcs: [ ":module-lib-api-stubs-docs", ], diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index ed5626a1acbc..69f4748548a7 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -77,7 +77,6 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; -import android.util.StatsLog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; @@ -85,6 +84,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.AppStateTracker; import com.android.server.DeviceIdleInternal; @@ -1171,9 +1171,9 @@ public class JobSchedulerService extends com.android.server.SystemService jobStatus.enqueueWorkLocked(work); } - StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, uId, null, jobStatus.getBatteryName(), - StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED, + FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED, JobProtoEnums.STOP_REASON_CANCELLED, jobStatus.getStandbyBucket(), jobStatus.getJobId()); @@ -2567,7 +2567,8 @@ public class JobSchedulerService extends com.android.server.SystemService BatteryStatsInternal mBatteryStatsInternal = LocalServices.getService (BatteryStatsInternal.class); mBatteryStatsInternal.noteJobsDeferred(uid, counter.numDeferred(), sinceLast); - StatsLog.write_non_chained(StatsLog.DEFERRED_JOB_STATS_REPORTED, uid, null, + FrameworkStatsLog.write_non_chained( + FrameworkStatsLog.DEFERRED_JOB_STATS_REPORTED, uid, null, counter.numDeferred(), sinceLast); } } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index dbdce70dda03..f706260edec2 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -32,10 +32,10 @@ import android.text.format.DateFormat; import android.util.ArraySet; import android.util.Pair; import android.util.Slog; -import android.util.StatsLog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.LocalServices; import com.android.server.job.GrantedUriPermissions; import com.android.server.job.JobSchedulerInternal; @@ -1059,10 +1059,12 @@ public final class JobStatus { mReadyDynamicSatisfied = mDynamicConstraints == (satisfiedConstraints & mDynamicConstraints); if (STATS_LOG_ENABLED && (STATSD_CONSTRAINTS_TO_LOG & constraint) != 0) { - StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED, + FrameworkStatsLog.write_non_chained( + FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED, sourceUid, null, getBatteryName(), getProtoConstraint(constraint), - state ? StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED - : StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED); + state ? FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED + : FrameworkStatsLog + .SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED); } return true; } diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp index f66f0340edab..231c91026bb6 100644 --- a/apex/statsd/framework/Android.bp +++ b/apex/statsd/framework/Android.bp @@ -34,9 +34,8 @@ java_library { ], libs: [ "framework-annotations-lib", - // TODO(b/146230220): Use framework-system-stubs instead. - //"android_system_stubs_current", - //"framework_module_lib_stubs_current", + // TODO(b/146230220): Use android_module_lib_stubs_current instead. + //"android_module_lib_stubs_current", "framework-all", ], hostdex: true, // for hiddenapi check diff --git a/api/current.txt b/api/current.txt index 32fb1e7e8bfd..510db01940cd 100644 --- a/api/current.txt +++ b/api/current.txt @@ -47070,8 +47070,8 @@ package android.telephony { } public class MmsManager { - method public void downloadMultimediaMessage(int, @NonNull String, @NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent); - method public void sendMultimediaMessage(int, @NonNull android.net.Uri, @Nullable String, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent); + method public void downloadMultimediaMessage(int, @NonNull String, @NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent, long); + method public void sendMultimediaMessage(int, @NonNull android.net.Uri, @Nullable String, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent, long); } @Deprecated public class NeighboringCellInfo implements android.os.Parcelable { @@ -51776,7 +51776,7 @@ package android.view { method public int getFlags(); method public android.view.Display.HdrCapabilities getHdrCapabilities(); method @Deprecated public int getHeight(); - method public void getMetrics(android.util.DisplayMetrics); + method @Deprecated public void getMetrics(android.util.DisplayMetrics); method public android.view.Display.Mode getMode(); method public String getName(); method @Deprecated public int getOrientation(); @@ -51785,10 +51785,10 @@ package android.view { method public long getPresentationDeadlineNanos(); method public void getRealMetrics(android.util.DisplayMetrics); method public void getRealSize(android.graphics.Point); - method public void getRectSize(android.graphics.Rect); + method @Deprecated public void getRectSize(android.graphics.Rect); method public float getRefreshRate(); method public int getRotation(); - method public void getSize(android.graphics.Point); + method @Deprecated public void getSize(android.graphics.Point); method public int getState(); method public android.view.Display.Mode[] getSupportedModes(); method @Deprecated public float[] getSupportedRefreshRates(); diff --git a/api/system-current.txt b/api/system-current.txt index e3c61c89dcb9..b99ddb313ce0 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -7580,7 +7580,7 @@ package android.net.wifi { method public boolean isEphemeral(); method public boolean isOsuAp(); method public boolean isPasspointAp(); - method @Nullable public static String removeDoubleQuotes(@Nullable String); + method @Nullable public static String sanitizeSsid(@Nullable String); field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00"; field public static final int INVALID_RSSI = -127; // 0xffffff81 } @@ -7622,7 +7622,6 @@ package android.net.wifi { method public boolean isApMacRandomizationSupported(); method public boolean isConnectedMacRandomizationSupported(); method @Deprecated public boolean isDeviceToDeviceRttSupported(); - method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported(); method public boolean isPortableHotspotSupported(); method public boolean isVerboseLoggingEnabled(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled(); diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 0906b359e9b9..94bda7b0b622 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -226,12 +226,12 @@ message Atom { GnssNfwNotificationReported gnss_nfw_notification_reported = 131 [(module) = "framework"]; GnssConfigurationReported gnss_configuration_reported = 132 [(module) = "framework"]; UsbPortOverheatEvent usb_port_overheat_event_reported = 133; - NfcErrorOccurred nfc_error_occurred = 134; - NfcStateChanged nfc_state_changed = 135; - NfcBeamOccurred nfc_beam_occurred = 136; - NfcCardemulationOccurred nfc_cardemulation_occurred = 137; - NfcTagOccurred nfc_tag_occurred = 138; - NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139; + NfcErrorOccurred nfc_error_occurred = 134 [(module) = "nfc"]; + NfcStateChanged nfc_state_changed = 135 [(module) = "nfc"]; + NfcBeamOccurred nfc_beam_occurred = 136 [(module) = "nfc"]; + NfcCardemulationOccurred nfc_cardemulation_occurred = 137 [(module) = "nfc"]; + NfcTagOccurred nfc_tag_occurred = 138 [(module) = "nfc"]; + NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139 [(module) = "nfc"]; SeStateChanged se_state_changed = 140; SeOmapiReported se_omapi_reported = 141; BroadcastDispatchLatencyReported broadcast_dispatch_latency_reported = diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 5f3bad6ad1a8..cb6a476fb617 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -287,7 +287,7 @@ interface IActivityManager { void killApplicationProcess(in String processName, int uid); // Special low-level communication with activity manager. boolean handleApplicationWtf(in IBinder app, in String tag, boolean system, - in ApplicationErrorReport.ParcelableCrashInfo crashInfo); + in ApplicationErrorReport.ParcelableCrashInfo crashInfo, int immediateCallerPid); @UnsupportedAppUsage void killBackgroundProcesses(in String packageName, int userId); boolean isUserAMonkey(); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 35d26aba9094..576b56fa33f6 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2487,6 +2487,20 @@ public class Notification implements Parcelable if (extras.containsKey(EXTRA_BACKGROUND_IMAGE_URI)) { visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI))); } + + ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST); + if (people != null && !people.isEmpty()) { + for (Person p : people) { + if (p.getIconUri() != null) { + visitor.accept(p.getIconUri()); + } + } + } + + final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON); + if (person != null && person.getIconUri() != null) { + visitor.accept(person.getIconUri()); + } } if (MessagingStyle.class.equals(getNotificationStyle()) && extras != null) { @@ -2495,6 +2509,11 @@ public class Notification implements Parcelable for (MessagingStyle.Message message : MessagingStyle.Message .getMessagesFromBundleArray(messages)) { visitor.accept(message.getDataUri()); + + Person senderPerson = message.getSenderPerson(); + if (senderPerson != null && senderPerson.getIconUri() != null) { + visitor.accept(senderPerson.getIconUri()); + } } } @@ -2503,6 +2522,11 @@ public class Notification implements Parcelable for (MessagingStyle.Message message : MessagingStyle.Message .getMessagesFromBundleArray(historic)) { visitor.accept(message.getDataUri()); + + Person senderPerson = message.getSenderPerson(); + if (senderPerson != null && senderPerson.getIconUri() != null) { + visitor.accept(senderPerson.getIconUri()); + } } } } diff --git a/core/java/android/app/Person.java b/core/java/android/app/Person.java index 14a5589c04c2..63ef2484ca1d 100644 --- a/core/java/android/app/Person.java +++ b/core/java/android/app/Person.java @@ -19,6 +19,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.drawable.Icon; +import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -122,6 +123,20 @@ public final class Person implements Parcelable { return ""; } + /** + * @return the URI associated with the {@link #getIcon()} for this person, iff the icon exists + * and is URI based. + * @hide + */ + @Nullable + public Uri getIconUri() { + if (mIcon != null && (mIcon.getType() == Icon.TYPE_URI + || mIcon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) { + return mIcon.getUri(); + } + return null; + } + @Override public boolean equals(Object obj) { if (obj instanceof Person) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d1b5a83e7142..f71d78b40242 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -7028,21 +7028,28 @@ public class DevicePolicyManager { } /** - * Called by a device owner to set the default SMS application. + * Must be called by a device owner or a profile owner of an organization-owned managed profile + * to set the default SMS application. * <p> - * The calling device admin must be a device owner. If it is not, a security exception will be - * thrown. + * This method can be called on the {@link DevicePolicyManager} instance, returned by + * {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner + * of an organization-owned managed profile and the package must be a pre-installed system + * package. If called on the parent instance, then the default SMS application is set on the + * personal profile. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param packageName The name of the package to set as the default SMS application. - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException if {@code admin} is not a device or profile owner or if + * called on the parent profile and the {@code admin} is not a + * profile owner of an organization-owned managed profile. + * @throws IllegalArgumentException if called on the parent profile and the package + * provided is not a pre-installed system package. */ public void setDefaultSmsApplication(@NonNull ComponentName admin, @NonNull String packageName) { - throwIfParentInstance("setDefaultSmsApplication"); if (mService != null) { try { - mService.setDefaultSmsApplication(admin, packageName); + mService.setDefaultSmsApplication(admin, packageName, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index e3dba310ab44..7fd0ae4a1a00 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -202,7 +202,7 @@ interface IDevicePolicyManager { void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity); void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName); - void setDefaultSmsApplication(in ComponentName admin, String packageName); + void setDefaultSmsApplication(in ComponentName admin, String packageName, boolean parent); void setApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName, in Bundle settings); Bundle getApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName); diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 01800c6751fb..14442a2088cd 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -539,13 +539,13 @@ public class NetworkPolicyManager { /** @hide */ public static String resolveNetworkId(WifiConfiguration config) { - return WifiInfo.removeDoubleQuotes(config.isPasspoint() + return WifiInfo.sanitizeSsid(config.isPasspoint() ? config.providerFriendlyName : config.SSID); } /** @hide */ public static String resolveNetworkId(String ssid) { - return WifiInfo.removeDoubleQuotes(ssid); + return WifiInfo.sanitizeSsid(ssid); } /** @hide */ diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 5e6c47a47a8e..5498f74ba2cc 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -32,7 +32,7 @@ import static android.net.NetworkStats.METERED_YES; import static android.net.NetworkStats.ROAMING_ALL; import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_YES; -import static android.net.wifi.WifiInfo.removeDoubleQuotes; +import static android.net.wifi.WifiInfo.sanitizeSsid; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; @@ -401,7 +401,7 @@ public class NetworkTemplate implements Parcelable { switch (ident.mType) { case TYPE_WIFI: return Objects.equals( - removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId)); + sanitizeSsid(mNetworkId), sanitizeSsid(ident.mNetworkId)); default: return false; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9666c12699e8..605c585215a6 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8711,6 +8711,14 @@ public final class Settings { "back_gesture_inset_scale_right"; /** + * Current provider of proximity-based sharing services. + * Default value in @string/config_defaultNearbySharingComponent. + * No VALIDATOR as this setting will not be backed up. + * @hide + */ + public static final String NEARBY_SHARING_COMPONENT = "nearby_sharing_component"; + + /** * Controls whether aware is enabled. * @hide */ diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index c5d97b718ff0..74b913645ad4 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -35,6 +35,7 @@ import android.os.Parcelable; import android.os.UserHandle; import android.text.TextUtils; +import com.android.internal.logging.InstanceId; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -68,6 +69,8 @@ public class StatusBarNotification implements Parcelable { private final UserHandle user; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final long postTime; + // A small per-notification ID, used for statsd logging. + private InstanceId mInstanceId; // Not final, see setInstanceId() private Context mContext; // used for inflation & icon expansion @@ -131,8 +134,9 @@ public class StatusBarNotification implements Parcelable { this.postTime = in.readLong(); if (in.readInt() != 0) { this.overrideGroupKey = in.readString(); - } else { - this.overrideGroupKey = null; + } + if (in.readInt() != 0) { + this.mInstanceId = InstanceId.CREATOR.createFromParcel(in); } this.key = key(); this.groupKey = groupKey(); @@ -196,7 +200,6 @@ public class StatusBarNotification implements Parcelable { out.writeInt(this.initialPid); this.notification.writeToParcel(out, flags); user.writeToParcel(out, flags); - out.writeLong(this.postTime); if (this.overrideGroupKey != null) { out.writeInt(1); @@ -204,6 +207,12 @@ public class StatusBarNotification implements Parcelable { } else { out.writeInt(0); } + if (this.mInstanceId != null) { + out.writeInt(1); + mInstanceId.writeToParcel(out, flags); + } else { + out.writeInt(0); + } } public int describeContents() { @@ -390,6 +399,20 @@ public class StatusBarNotification implements Parcelable { /** * @hide */ + public InstanceId getInstanceId() { + return mInstanceId; + } + + /** + * @hide + */ + public void setInstanceId(InstanceId instanceId) { + mInstanceId = instanceId; + } + + /** + * @hide + */ @UnsupportedAppUsage public Context getPackageContext(Context context) { if (mContext == null) { diff --git a/core/java/android/service/quickaccesswallet/TEST_MAPPING b/core/java/android/service/quickaccesswallet/TEST_MAPPING new file mode 100644 index 000000000000..4d97ab6e612d --- /dev/null +++ b/core/java/android/service/quickaccesswallet/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "CtsQuickAccessWalletTestCases" + } + ] +} diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 0304328f734a..d79fc9a48116 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -57,8 +57,8 @@ import java.util.List; * <li>The application display area specifies the part of the display that may contain * an application window, excluding the system decorations. The application display area may * be smaller than the real display area because the system subtracts the space needed - * for decor elements such as the status bar. Use the following methods to query the - * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li> + * for decor elements such as the status bar. Use {@link WindowMetrics#getSize()} to query the + * application window size.</li> * <li>The real display area specifies the part of the display that contains content * including the system decorations. Even so, the real display area may be smaller than the * physical size of the display if the window manager is emulating a smaller display @@ -97,7 +97,7 @@ public final class Display { // We cache the app width and height properties briefly between calls // to getHeight() and getWidth() to ensure that applications perceive // consistent results when the size changes (most of the time). - // Applications should now be using getSize() instead. + // Applications should now be using WindowMetrics instead. private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20; private long mLastCachedAppSizeUpdate; private int mCachedAppWidthCompat; @@ -674,7 +674,10 @@ public final class Display { * </p> * * @param outSize A {@link Point} object to receive the size information. + * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to obtain an instance of + * {@link WindowMetrics} and use {@link WindowMetrics#getSize()} instead. */ + @Deprecated public void getSize(Point outSize) { synchronized (this) { updateDisplayInfoLocked(); @@ -688,8 +691,10 @@ public final class Display { * Gets the size of the display as a rectangle, in pixels. * * @param outSize A {@link Rect} object to receive the size information. - * @see #getSize(Point) + * @deprecated Use {@link WindowMetrics#getSize()} to get the dimensions of the application + * window area. */ + @Deprecated public void getRectSize(Rect outSize) { synchronized (this) { updateDisplayInfoLocked(); @@ -752,7 +757,7 @@ public final class Display { } /** - * @deprecated Use {@link #getSize(Point)} instead. + * @deprecated Use {@link WindowMetrics#getSize()} instead. */ @Deprecated public int getWidth() { @@ -763,7 +768,7 @@ public final class Display { } /** - * @deprecated Use {@link #getSize(Point)} instead. + * @deprecated Use {@link WindowMetrics#getSize()} instead. */ @Deprecated public int getHeight() { @@ -1102,7 +1107,10 @@ public final class Display { * </p> * * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. + * @deprecated Use {@link WindowMetrics#getSize()} to get the dimensions of the application + * window area, and {@link Configuration#densityDpi} to get the current density. */ + @Deprecated public void getMetrics(DisplayMetrics outMetrics) { synchronized (this) { updateDisplayInfoLocked(); diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java index ddfd38c0320b..9901d053184c 100644 --- a/core/java/android/view/InsetsSourceConsumer.java +++ b/core/java/android/view/InsetsSourceConsumer.java @@ -181,8 +181,9 @@ public class InsetsSourceConsumer { } private void applyHiddenToControl() { - if (mSourceControl == null || mSourceControl.getLeash() == null - || mController.getAnimationType(mType) != ANIMATION_TYPE_NONE) { + + // TODO: Handle case properly when animation is running already (it shouldn't!) + if (mSourceControl == null || mSourceControl.getLeash() == null) { return; } diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index 77d8e0290f20..ab8c19ea8861 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -18,7 +18,9 @@ package com.android.internal.app; import android.annotation.IntDef; import android.annotation.Nullable; import android.content.Context; +import android.content.pm.ResolveInfo; import android.os.UserHandle; +import android.os.UserManager; import android.view.View; import android.view.ViewGroup; @@ -27,6 +29,7 @@ import com.android.internal.widget.PagerAdapter; import com.android.internal.widget.ViewPager; import java.util.HashSet; +import java.util.List; import java.util.Objects; import java.util.Set; @@ -46,11 +49,17 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private int mCurrentPage; private OnProfileSelectedListener mOnProfileSelectedListener; private Set<Integer> mLoadedPages; + private final UserHandle mPersonalProfileUserHandle; + private final UserHandle mWorkProfileUserHandle; - AbstractMultiProfilePagerAdapter(Context context, int currentPage) { + AbstractMultiProfilePagerAdapter(Context context, int currentPage, + UserHandle personalProfileUserHandle, + UserHandle workProfileUserHandle) { mContext = Objects.requireNonNull(context); mCurrentPage = currentPage; mLoadedPages = new HashSet<>(); + mPersonalProfileUserHandle = personalProfileUserHandle; + mWorkProfileUserHandle = workProfileUserHandle; } void setOnProfileSelectedListener(OnProfileSelectedListener listener) { @@ -72,7 +81,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { public void onPageSelected(int position) { mCurrentPage = position; if (!mLoadedPages.contains(position)) { - getActiveListAdapter().rebuildList(); + rebuildActiveTab(true); mLoadedPages.add(position); } if (mOnProfileSelectedListener != null) { @@ -85,6 +94,13 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { mLoadedPages.add(mCurrentPage); } + void clearInactiveProfileCache() { + if (mLoadedPages.size() == 1) { + return; + } + mLoadedPages.remove(1 - mCurrentPage); + } + @Override public ViewGroup instantiateItem(ViewGroup container, int position) { final ProfileDescriptor profileDescriptor = getItem(position); @@ -187,12 +203,53 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { @VisibleForTesting public abstract @Nullable ResolverListAdapter getInactiveListAdapter(); + public abstract ResolverListAdapter getPersonalListAdapter(); + + public abstract @Nullable ResolverListAdapter getWorkListAdapter(); + abstract Object getCurrentRootAdapter(); abstract ViewGroup getActiveAdapterView(); abstract @Nullable ViewGroup getInactiveAdapterView(); + boolean rebuildActiveTab(boolean post) { + return rebuildTab(getActiveListAdapter(), post); + } + + boolean rebuildInactiveTab(boolean post) { + if (getItemCount() == 1) { + return false; + } + return rebuildTab(getInactiveListAdapter(), post); + } + + private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) { + UserHandle listUserHandle = activeListAdapter.getUserHandle(); + if (UserHandle.myUserId() != listUserHandle.getIdentifier() && + !hasAppsInOtherProfile(activeListAdapter)) { + // TODO(arangelov): Show empty state UX here + return false; + } else { + return activeListAdapter.rebuildList(doPostProcessing); + } + } + + private boolean hasAppsInOtherProfile(ResolverListAdapter adapter) { + if (mWorkProfileUserHandle == null) { + return false; + } + List<ResolverActivity.ResolvedComponentInfo> resolversForIntent = + adapter.getResolversForUser(UserHandle.of(UserHandle.myUserId())); + for (ResolverActivity.ResolvedComponentInfo info : resolversForIntent) { + ResolveInfo resolveInfo = info.getResolveInfoAt(0); + if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) { + return true; + } + } + return false; + } + protected class ProfileDescriptor { final ViewGroup rootView; ProfileDescriptor(ViewGroup rootView) { diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 65128e4a2eda..a43e4fe118a9 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -53,6 +53,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.content.res.Configuration; +import android.content.res.Resources; import android.database.Cursor; import android.database.DataSetObserver; import android.graphics.Bitmap; @@ -81,6 +82,7 @@ import android.provider.DeviceConfig; import android.provider.DocumentsContract; import android.provider.Downloads; import android.provider.OpenableColumns; +import android.provider.Settings; import android.service.chooser.ChooserTarget; import android.service.chooser.ChooserTargetService; import android.service.chooser.IChooserTargetResult; @@ -101,6 +103,7 @@ import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; +import android.widget.Button; import android.widget.ImageView; import android.widget.Space; import android.widget.TextView; @@ -131,6 +134,7 @@ import java.io.File; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.net.URISyntaxException; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; @@ -166,6 +170,9 @@ public class ChooserActivity extends ResolverActivity implements private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions"; + private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label"; + private static final String CHIP_ICON_METADATA_KEY = "android.service.chooser.chip_icon"; + private static final boolean DEBUG = true; private static final boolean USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES = true; @@ -527,6 +534,15 @@ public class ChooserActivity extends ResolverActivity implements mIsSuccessfullySelected = false; Intent intent = getIntent(); Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT); + if (targetParcelable instanceof Uri) { + try { + targetParcelable = Intent.parseUri(targetParcelable.toString(), + Intent.URI_INTENT_SCHEME); + } catch (URISyntaxException ex) { + // doesn't parse as an intent; let the next test fail and error out + } + } + if (!(targetParcelable instanceof Intent)) { Log.w("ChooserActivity", "Target is not an intent: " + targetParcelable); finish(); @@ -777,7 +793,9 @@ public class ChooserActivity extends ResolverActivity implements /* userHandle */ UserHandle.of(UserHandle.myUserId())); return new ChooserMultiProfilePagerAdapter( /* context */ this, - adapter); + adapter, + getPersonalProfileUserHandle(), + /* workProfileUserHandle= */ null); } private ChooserMultiProfilePagerAdapter createChooserMultiProfilePagerAdapterForTwoProfiles( @@ -804,7 +822,9 @@ public class ChooserActivity extends ResolverActivity implements /* context */ this, personalAdapter, workAdapter, - /* defaultProfile */ getCurrentProfile()); + /* defaultProfile */ getCurrentProfile(), + getPersonalProfileUserHandle(), + getWorkProfileUserHandle()); } @Override @@ -856,11 +876,11 @@ public class ChooserActivity extends ResolverActivity implements } @Override - protected PackageMonitor createPackageMonitor() { + protected PackageMonitor createPackageMonitor(ResolverListAdapter listAdapter) { return new PackageMonitor() { @Override public void onSomePackagesChanged() { - handlePackagesChanged(); + handlePackagesChanged(listAdapter); } }; } @@ -869,9 +889,19 @@ public class ChooserActivity extends ResolverActivity implements * Update UI to reflect changes in data. */ public void handlePackagesChanged() { - // TODO(arangelov): Dispatch this to all adapters when we have the helper methods - // in a follow-up CL - mChooserMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); + handlePackagesChanged(/* listAdapter */ null); + } + + /** + * Update UI to reflect changes in data. + * <p>If {@code listAdapter} is {@code null}, both profile list adapters are updated. + */ + private void handlePackagesChanged(@Nullable ResolverListAdapter listAdapter) { + if (listAdapter == null) { + mChooserMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); + } else { + listAdapter.handlePackagesChanged(); + } updateProfileViewButton(); } @@ -965,6 +995,108 @@ public class ChooserActivity extends ResolverActivity implements return displayContentPreview(previewType, targetIntent, getLayoutInflater(), parent); } + private ComponentName getNearbySharingComponent() { + String nearbyComponent = Settings.Secure.getString( + getContentResolver(), + Settings.Secure.NEARBY_SHARING_COMPONENT); + if (TextUtils.isEmpty(nearbyComponent)) { + nearbyComponent = getString(R.string.config_defaultNearbySharingComponent); + } + if (TextUtils.isEmpty(nearbyComponent)) { + return null; + } + return ComponentName.unflattenFromString(nearbyComponent); + } + + private TargetInfo getNearbySharingTarget(Intent originalIntent) { + final ComponentName cn = getNearbySharingComponent(); + if (cn == null) return null; + + final Intent resolveIntent = new Intent(); + resolveIntent.setComponent(cn); + final ResolveInfo ri = getPackageManager().resolveActivity( + resolveIntent, PackageManager.GET_META_DATA); + if (ri == null || ri.activityInfo == null) { + Log.e(TAG, "Device-specified nearby sharing component (" + cn + + ") not available"); + return null; + } + + // Allow the nearby sharing component to provide a more appropriate icon and label + // for the chip. + CharSequence name = null; + Drawable icon = null; + final Bundle metaData = ri.activityInfo.metaData; + if (metaData != null) { + try { + final Resources pkgRes = getPackageManager().getResourcesForActivity(cn); + final int nameResId = metaData.getInt(CHIP_LABEL_METADATA_KEY); + name = pkgRes.getString(nameResId); + final int resId = metaData.getInt(CHIP_ICON_METADATA_KEY); + icon = pkgRes.getDrawable(resId); + } catch (Resources.NotFoundException ex) { + } catch (NameNotFoundException ex) { + } + } + if (TextUtils.isEmpty(name)) { + name = ri.loadLabel(getPackageManager()); + } + if (icon == null) { + icon = ri.loadIcon(getPackageManager()); + } + + final DisplayResolveInfo dri = new DisplayResolveInfo( + originalIntent, ri, name, "", resolveIntent, null); + dri.setDisplayIcon(icon); + return dri; + } + + private Button createActionButton(Drawable icon, CharSequence title, View.OnClickListener r) { + Button b = (Button) LayoutInflater.from(this).inflate(R.layout.chooser_action_button, null); + if (icon != null) { + final int size = getResources() + .getDimensionPixelSize(R.dimen.chooser_action_button_icon_size); + icon.setBounds(0, 0, size, size); + b.setCompoundDrawablesRelative(icon, null, null, null); + } + b.setText(title); + b.setOnClickListener(r); + return b; + } + + private Button createCopyButton() { + final Button b = createActionButton( + getDrawable(R.drawable.ic_menu_copy_material), + getString(R.string.copy), this::onCopyButtonClicked); + b.setId(R.id.chooser_copy_button); + return b; + } + + private @Nullable Button createNearbyButton(Intent originalIntent) { + final TargetInfo ti = getNearbySharingTarget(originalIntent); + if (ti == null) return null; + + return createActionButton( + ti.getDisplayIcon(this), + ti.getDisplayLabel(), + (View unused) -> { + safelyStartActivity(ti); + finish(); + } + ); + } + + private void addActionButton(ViewGroup parent, Button b) { + if (b == null) return; + final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT + ); + final int gap = getResources().getDimensionPixelSize(R.dimen.resolver_icon_margin) / 2; + lp.setMarginsRelative(gap, 0, gap, 0); + parent.addView(b, lp); + } + private ViewGroup displayContentPreview(@ContentPreviewType int previewType, Intent targetIntent, LayoutInflater layoutInflater, ViewGroup parent) { ViewGroup layout = null; @@ -995,8 +1127,10 @@ public class ChooserActivity extends ResolverActivity implements ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate( R.layout.chooser_grid_preview_text, parent, false); - contentPreviewLayout.findViewById(R.id.copy_button).setOnClickListener( - this::onCopyButtonClicked); + final ViewGroup actionRow = + (ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row); + addActionButton(actionRow, createCopyButton()); + addActionButton(actionRow, createNearbyButton(targetIntent)); CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT); if (sharingText == null) { @@ -1154,7 +1288,8 @@ public class ChooserActivity extends ResolverActivity implements // TODO(b/120417119): Disable file copy until after moving to sysui, // due to permissions issues - contentPreviewLayout.findViewById(R.id.file_copy_button).setVisibility(View.GONE); + //((ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row)) + // .addView(createCopyButton()); String action = targetIntent.getAction(); if (Intent.ACTION_SEND.equals(action)) { @@ -1680,7 +1815,7 @@ public class ChooserActivity extends ResolverActivity implements } return intentFilter; } catch (Exception e) { - Log.e(TAG, "failed to get target intent filter " + e); + Log.e(TAG, "failed to get target intent filter", e); return null; } } @@ -2337,10 +2472,10 @@ public class ChooserActivity extends ResolverActivity implements } @Override // ResolverListCommunicator - public void onHandlePackagesChanged() { + public void onHandlePackagesChanged(ResolverListAdapter listAdapter) { mServicesRequested.clear(); mChooserMultiProfilePagerAdapter.getActiveListAdapter().notifyDataSetChanged(); - super.onHandlePackagesChanged(); + super.onHandlePackagesChanged(listAdapter); } @Override // SelectableTargetInfoCommunicator diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java index ca3b7e7a7837..74ae29117b59 100644 --- a/core/java/com/android/internal/app/ChooserListAdapter.java +++ b/core/java/com/android/internal/app/ChooserListAdapter.java @@ -19,7 +19,6 @@ package com.android.internal.app; import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_PREDICTION_SERVICE; import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER; -import android.annotation.Nullable; import android.app.ActivityManager; import android.app.prediction.AppPredictor; import android.content.ComponentName; @@ -176,7 +175,7 @@ public class ChooserListAdapter extends ResolverListAdapter { Log.d(TAG, "clearing queryTargets on package change"); } createPlaceHolders(); - mChooserListCommunicator.onHandlePackagesChanged(); + mChooserListCommunicator.onHandlePackagesChanged(this); } @@ -541,7 +540,7 @@ public class ChooserListAdapter extends ResolverListAdapter { @Override AsyncTask<List<ResolvedComponentInfo>, Void, - List<ResolvedComponentInfo>> createSortingTask() { + List<ResolvedComponentInfo>> createSortingTask(boolean doPostProcessing) { return new AsyncTask<List<ResolvedComponentInfo>, Void, List<ResolvedComponentInfo>>() { @@ -554,9 +553,11 @@ public class ChooserListAdapter extends ResolverListAdapter { } @Override protected void onPostExecute(List<ResolvedComponentInfo> sortedComponents) { - processSortedList(sortedComponents); - mChooserListCommunicator.updateProfileViewButton(); - notifyDataSetChanged(); + processSortedList(sortedComponents, doPostProcessing); + if (doPostProcessing) { + mChooserListCommunicator.updateProfileViewButton(); + notifyDataSetChanged(); + } } }; } diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java index 663e0255feb9..e3501422f915 100644 --- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java @@ -38,8 +38,10 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd private final ChooserProfileDescriptor[] mItems; ChooserMultiProfilePagerAdapter(Context context, - ChooserActivity.ChooserGridAdapter adapter) { - super(context, /* currentPage */ 0); + ChooserActivity.ChooserGridAdapter adapter, + UserHandle personalProfileUserHandle, + UserHandle workProfileUserHandle) { + super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle); mItems = new ChooserProfileDescriptor[] { createProfileDescriptor(adapter) }; @@ -48,8 +50,11 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd ChooserMultiProfilePagerAdapter(Context context, ChooserActivity.ChooserGridAdapter personalAdapter, ChooserActivity.ChooserGridAdapter workAdapter, - @Profile int defaultProfile) { - super(context, /* currentPage */ defaultProfile); + @Profile int defaultProfile, + UserHandle personalProfileUserHandle, + UserHandle workProfileUserHandle) { + super(context, /* currentPage */ defaultProfile, personalProfileUserHandle, + workProfileUserHandle); mItems = new ChooserProfileDescriptor[] { createProfileDescriptor(personalAdapter), createProfileDescriptor(workAdapter) @@ -131,6 +136,17 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd } @Override + public ResolverListAdapter getPersonalListAdapter() { + return getAdapterForIndex(PROFILE_PERSONAL).getListAdapter(); + } + + @Override + @Nullable + public ResolverListAdapter getWorkListAdapter() { + return getAdapterForIndex(PROFILE_WORK).getListAdapter(); + } + + @Override ChooserActivity.ChooserGridAdapter getCurrentRootAdapter() { return getAdapterForIndex(getCurrentPage()); } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 30a41d338806..051534cc3eb1 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -16,7 +16,9 @@ package com.android.internal.app; +import static android.Manifest.permission.INTERACT_ACROSS_PROFILES; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.content.PermissionChecker.PID_UNKNOWN; import static com.android.internal.app.AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL; import static com.android.internal.app.AbstractMultiProfilePagerAdapter.PROFILE_WORK; @@ -36,6 +38,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.PermissionChecker; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -157,7 +160,8 @@ public class ResolverActivity extends Activity implements private static final String TAB_TAG_PERSONAL = "personal"; private static final String TAB_TAG_WORK = "work"; - private final PackageMonitor mPackageMonitor = createPackageMonitor(); + private PackageMonitor mPersonalPackageMonitor; + private PackageMonitor mWorkPackageMonitor; @VisibleForTesting protected AbstractMultiProfilePagerAdapter mMultiProfilePagerAdapter; @@ -243,11 +247,11 @@ public class ResolverActivity extends Activity implements } } - protected PackageMonitor createPackageMonitor() { + protected PackageMonitor createPackageMonitor(ResolverListAdapter listAdapter) { return new PackageMonitor() { @Override public void onSomePackagesChanged() { - mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); + listAdapter.handlePackagesChanged(); updateProfileViewButton(); } @@ -327,8 +331,6 @@ public class ResolverActivity extends Activity implements mPm = getPackageManager(); - mPackageMonitor.register(this, getMainLooper(), false); - mRegistered = true; mReferrerPackage = getReferrerPackageName(); // Add our initial intent as the first item, regardless of what else has already been added. @@ -353,6 +355,18 @@ public class ResolverActivity extends Activity implements return; } + mPersonalPackageMonitor = createPackageMonitor( + mMultiProfilePagerAdapter.getPersonalListAdapter()); + mPersonalPackageMonitor.register( + this, getMainLooper(), getPersonalProfileUserHandle(), false); + if (hasWorkProfile()) { + mWorkPackageMonitor = createPackageMonitor( + mMultiProfilePagerAdapter.getWorkListAdapter()); + mWorkPackageMonitor.register(this, getMainLooper(), getWorkProfileUserHandle(), false); + } + + mRegistered = true; + final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel); if (rdl != null) { rdl.setOnDismissedListener(new ResolverDrawerLayout.OnDismissedListener() { @@ -419,7 +433,9 @@ public class ResolverActivity extends Activity implements /* userHandle */ UserHandle.of(UserHandle.myUserId())); return new ResolverMultiProfilePagerAdapter( /* context */ this, - adapter); + adapter, + getPersonalProfileUserHandle(), + /* workProfileUserHandle= */ null); } private ResolverMultiProfilePagerAdapter createResolverMultiProfilePagerAdapterForTwoProfiles( @@ -438,20 +454,23 @@ public class ResolverActivity extends Activity implements == getPersonalProfileUserHandle().getIdentifier()), mUseLayoutForBrowsables, /* userHandle */ getPersonalProfileUserHandle()); + UserHandle workProfileUserHandle = getWorkProfileUserHandle(); ResolverListAdapter workAdapter = createResolverListAdapter( /* context */ this, /* payloadIntents */ mIntents, initialIntents, rList, (filterLastUsed && UserHandle.myUserId() - == getWorkProfileUserHandle().getIdentifier()), + == workProfileUserHandle.getIdentifier()), mUseLayoutForBrowsables, - /* userHandle */ getWorkProfileUserHandle()); + /* userHandle */ workProfileUserHandle); return new ResolverMultiProfilePagerAdapter( /* context */ this, personalAdapter, workAdapter, - /* defaultProfile */ getCurrentProfile()); + /* defaultProfile */ getCurrentProfile(), + getPersonalProfileUserHandle(), + getWorkProfileUserHandle()); } protected @Profile int getCurrentProfile() { @@ -543,9 +562,6 @@ public class ResolverActivity extends Activity implements public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); - if (mMultiProfilePagerAdapter.getInactiveListAdapter() != null) { - mMultiProfilePagerAdapter.getInactiveListAdapter().handlePackagesChanged(); - } if (mSystemWindowInsets != null) { mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top, @@ -707,7 +723,16 @@ public class ResolverActivity extends Activity implements protected void onRestart() { super.onRestart(); if (!mRegistered) { - mPackageMonitor.register(this, getMainLooper(), false); + mPersonalPackageMonitor.register(this, getMainLooper(), + getPersonalProfileUserHandle(), false); + if (hasWorkProfile()) { + if (mWorkPackageMonitor == null) { + mWorkPackageMonitor = createPackageMonitor( + mMultiProfilePagerAdapter.getWorkListAdapter()); + } + mWorkPackageMonitor.register(this, getMainLooper(), + getWorkProfileUserHandle(), false); + } mRegistered = true; } mMultiProfilePagerAdapter.getActiveListAdapter().handlePackagesChanged(); @@ -718,7 +743,10 @@ public class ResolverActivity extends Activity implements protected void onStop() { super.onStop(); if (mRegistered) { - mPackageMonitor.unregister(); + mPersonalPackageMonitor.unregister(); + if (mWorkPackageMonitor != null) { + mWorkPackageMonitor.unregister(); + } mRegistered = false; } final Intent intent = getIntent(); @@ -913,26 +941,21 @@ public class ResolverActivity extends Activity implements } @Override // ResolverListCommunicator - public void onPostListReady(ResolverListAdapter listAdapter) { - if (mMultiProfilePagerAdapter.getCurrentUserHandle().getIdentifier() - == UserHandle.myUserId()) { - setHeader(); + public void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing) { + if (isAutolaunching() || maybeAutolaunchActivity()) { + return; } - resetButtonBar(); - onListRebuilt(listAdapter); - } - - protected void onListRebuilt(ResolverListAdapter listAdapter) { - int count = listAdapter.getUnfilteredCount(); - if (count == 1 && listAdapter.getOtherProfile() == null) { - // Only one target, so we're a candidate to auto-launch! - final TargetInfo target = listAdapter.targetInfoForPosition(0, false); - if (shouldAutoLaunchSingleChoice(target)) { - safelyStartActivity(target); - finish(); + if (doPostProcessing) { + if (mMultiProfilePagerAdapter.getCurrentUserHandle().getIdentifier() + == UserHandle.myUserId()) { + setHeader(); } + resetButtonBar(); + onListRebuilt(listAdapter); } + } + protected void onListRebuilt(ResolverListAdapter listAdapter) { final ItemClickListener listener = new ItemClickListener(); setupAdapterListView((ListView) mMultiProfilePagerAdapter.getActiveAdapterView(), listener); } @@ -1132,6 +1155,11 @@ public class ResolverActivity extends Activity implements } private void safelyStartActivityInternal(TargetInfo cti) { + mPersonalPackageMonitor.unregister(); + if (mWorkPackageMonitor != null) { + mWorkPackageMonitor.unregister(); + } + mRegistered = false; // If needed, show that intent is forwarded // from managed profile to owner or other way around. if (mProfileSwitchMessageId != -1) { @@ -1247,7 +1275,11 @@ public class ResolverActivity extends Activity implements throw new IllegalStateException("mMultiProfilePagerAdapter.getCurrentListAdapter() " + "cannot be null."); } - boolean rebuildCompleted = mMultiProfilePagerAdapter.getActiveListAdapter().rebuildList(); + boolean rebuildCompleted = mMultiProfilePagerAdapter.rebuildActiveTab(true); + + // We partially rebuild the inactive adapter to determine if we should auto launch + mMultiProfilePagerAdapter.rebuildInactiveTab(false); + if (useLayoutWithDefault()) { mLayoutId = R.layout.resolver_list_with_default; } else { @@ -1274,25 +1306,12 @@ public class ResolverActivity extends Activity implements * @return <code>true</code> if the activity is finishing and creation should halt. */ final boolean postRebuildListInternal(boolean rebuildCompleted) { - int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount(); // We only rebuild asynchronously when we have multiple elements to sort. In the case where // we're already done, we can check if we should auto-launch immediately. - if (rebuildCompleted) { - if (count == 1 - && mMultiProfilePagerAdapter.getActiveListAdapter().getOtherProfile() == null) { - // Only one target, so we're a candidate to auto-launch! - final TargetInfo target = mMultiProfilePagerAdapter.getActiveListAdapter() - .targetInfoForPosition(0, false); - if (shouldAutoLaunchSingleChoice(target)) { - safelyStartActivity(target); - mPackageMonitor.unregister(); - mRegistered = false; - finish(); - return true; - } - } + if (rebuildCompleted && maybeAutolaunchActivity()) { + return true; } setupViewVisibilities(); @@ -1304,6 +1323,129 @@ public class ResolverActivity extends Activity implements return false; } + private int isPermissionGranted(String permission, int uid) { + return ActivityManager.checkComponentPermission(permission, uid, + /* owningUid= */-1, /* exported= */ true); + } + + /** + * @return {@code true} if a resolved target is autolaunched, otherwise {@code false} + */ + private boolean maybeAutolaunchActivity() { + int numberOfProfiles = mMultiProfilePagerAdapter.getItemCount(); + if (numberOfProfiles == 1 && maybeAutolaunchIfSingleTarget()) { + return true; + } else if (numberOfProfiles == 2 && maybeAutolaunchIfCrossProfileSupported()) { + // note that autolaunching when we have 2 profiles, 1 resolved target on the active + // tab and 0 resolved targets on the inactive tab, is already handled before launching + // ResolverActivity + return true; + } + return false; + } + + private boolean maybeAutolaunchIfSingleTarget() { + int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount(); + if (count != 1) { + return false; + } + + // Only one target, so we're a candidate to auto-launch! + final TargetInfo target = mMultiProfilePagerAdapter.getActiveListAdapter() + .targetInfoForPosition(0, false); + if (shouldAutoLaunchSingleChoice(target)) { + safelyStartActivity(target); + finish(); + return true; + } + return false; + } + + /** + * When we have a personal and a work profile, we auto launch in the following scenario: + * - There is 1 resolved target on each profile + * - That target is the same app on both profiles + * - The target app has permission to communicate cross profiles + * - The target app has declared it supports cross-profile communication via manifest metadata + */ + private boolean maybeAutolaunchIfCrossProfileSupported() { + int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount(); + if (count != 1) { + return false; + } + ResolverListAdapter inactiveListAdapter = + mMultiProfilePagerAdapter.getInactiveListAdapter(); + if (inactiveListAdapter.getUnfilteredCount() != 1) { + return false; + } + TargetInfo activeProfileTarget = mMultiProfilePagerAdapter.getActiveListAdapter() + .targetInfoForPosition(0, false); + TargetInfo inactiveProfileTarget = inactiveListAdapter.targetInfoForPosition(0, false); + if (!Objects.equals(activeProfileTarget.getResolvedComponentName(), + inactiveProfileTarget.getResolvedComponentName())) { + return false; + } + if (!shouldAutoLaunchSingleChoice(activeProfileTarget)) { + return false; + } + String packageName = activeProfileTarget.getResolvedComponentName().getPackageName(); + if (!canAppInteractCrossProfiles(packageName)) { + return false; + } + + safelyStartActivity(activeProfileTarget); + finish(); + return true; + } + + /** + * Returns whether the package has the necessary permissions to interact across profiles on + * behalf of a given user. + * + * <p>This means meeting the following condition: + * <ul> + * <li>The app's {@link ApplicationInfo#crossProfile} flag must be true, and at least + * one of the following conditions must be fulfilled</li> + * <li>{@code Manifest.permission.INTERACT_ACROSS_USERS_FULL} granted.</li> + * <li>{@code Manifest.permission.INTERACT_ACROSS_USERS} granted.</li> + * <li>{@code Manifest.permission.INTERACT_ACROSS_PROFILES} granted, or the corresponding + * AppOps {@code android:interact_across_profiles} is set to "allow".</li> + * </ul> + * + */ + private boolean canAppInteractCrossProfiles(String packageName) { + ApplicationInfo applicationInfo; + try { + applicationInfo = getPackageManager().getApplicationInfo(packageName, 0); + } catch (NameNotFoundException e) { + Log.e(TAG, "Package " + packageName + " does not exist on current user."); + return false; + } + if (!applicationInfo.crossProfile) { + return false; + } + + int packageUid = applicationInfo.uid; + + if (isPermissionGranted(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, + packageUid) == PackageManager.PERMISSION_GRANTED) { + return true; + } + if (isPermissionGranted(android.Manifest.permission.INTERACT_ACROSS_USERS, packageUid) + == PackageManager.PERMISSION_GRANTED) { + return true; + } + if (PermissionChecker.checkPermissionForPreflight(this, INTERACT_ACROSS_PROFILES, + PID_UNKNOWN, packageUid, packageName) == PackageManager.PERMISSION_GRANTED) { + return true; + } + return false; + } + + private boolean isAutolaunching() { + return !mRegistered && isFinishing(); + } + private void setupProfileTabs() { TabHost tabHost = findViewById(R.id.profile_tabhost); tabHost.setup(); @@ -1499,12 +1641,20 @@ public class ResolverActivity extends Activity implements } @Override // ResolverListCommunicator - public void onHandlePackagesChanged() { - ResolverListAdapter activeListAdapter = mMultiProfilePagerAdapter.getActiveListAdapter(); - activeListAdapter.rebuildList(); - if (activeListAdapter.getCount() == 0) { - // We no longer have any items... just finish the activity. - finish(); + public void onHandlePackagesChanged(ResolverListAdapter listAdapter) { + if (listAdapter == mMultiProfilePagerAdapter.getActiveListAdapter()) { + boolean listRebuilt = mMultiProfilePagerAdapter.rebuildActiveTab(true); + if (listRebuilt) { + ResolverListAdapter activeListAdapter = + mMultiProfilePagerAdapter.getActiveListAdapter(); + activeListAdapter.notifyDataSetChanged(); + if (activeListAdapter.getCount() == 0) { + // We no longer have any items... just finish the activity. + finish(); + } + } + } else { + mMultiProfilePagerAdapter.clearInactiveProfileCache(); } } diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java index 405112d99fe7..2321da14cebe 100644 --- a/core/java/com/android/internal/app/ResolverListAdapter.java +++ b/core/java/com/android/internal/app/ResolverListAdapter.java @@ -113,7 +113,7 @@ public class ResolverListAdapter extends BaseAdapter { } public void handlePackagesChanged() { - mResolverListCommunicator.onHandlePackagesChanged(); + mResolverListCommunicator.onHandlePackagesChanged(this); } public void setPlaceholderCount(int count) { @@ -176,9 +176,14 @@ public class ResolverListAdapter extends BaseAdapter { * Rebuild the list of resolvers. In some cases some parts will need some asynchronous work * to complete. * + * The {@code doPostProcessing } parameter is used to specify whether to update the UI and + * load additional targets (e.g. direct share) after the list has been rebuilt. This is used + * in the case where we want to load the inactive profile's resolved apps to know the + * number of targets. + * * @return Whether or not the list building is completed. */ - protected boolean rebuildList() { + protected boolean rebuildList(boolean doPostProcessing) { List<ResolvedComponentInfo> currentResolveList = null; // Clear the value of mOtherProfile from previous call. mOtherProfile = null; @@ -186,6 +191,7 @@ public class ResolverListAdapter extends BaseAdapter { mLastChosenPosition = -1; mAllTargetsAreBrowsers = false; mDisplayList.clear(); + if (mBaseResolveList != null) { currentResolveList = mUnfilteredResolveList = new ArrayList<>(); mResolverListController.addResolveListDedupe(currentResolveList, @@ -198,7 +204,7 @@ public class ResolverListAdapter extends BaseAdapter { mResolverListCommunicator.shouldGetActivityMetadata(), mIntents); if (currentResolveList == null) { - processSortedList(currentResolveList); + processSortedList(currentResolveList, doPostProcessing); return true; } List<ResolvedComponentInfo> originalList = @@ -256,22 +262,22 @@ public class ResolverListAdapter extends BaseAdapter { --placeholderCount; } setPlaceholderCount(placeholderCount); - createSortingTask().execute(currentResolveList); - postListReadyRunnable(); + createSortingTask(doPostProcessing).execute(currentResolveList); + postListReadyRunnable(doPostProcessing); return false; } else { - processSortedList(currentResolveList); + processSortedList(currentResolveList, doPostProcessing); return true; } } else { - processSortedList(currentResolveList); + processSortedList(currentResolveList, doPostProcessing); return true; } } AsyncTask<List<ResolvedComponentInfo>, Void, - List<ResolvedComponentInfo>> createSortingTask() { + List<ResolvedComponentInfo>> createSortingTask(boolean doPostProcessing) { return new AsyncTask<List<ResolvedComponentInfo>, Void, List<ResolvedComponentInfo>>() { @@ -283,15 +289,17 @@ public class ResolverListAdapter extends BaseAdapter { } @Override protected void onPostExecute(List<ResolvedComponentInfo> sortedComponents) { - processSortedList(sortedComponents); - mResolverListCommunicator.updateProfileViewButton(); + processSortedList(sortedComponents, doPostProcessing); notifyDataSetChanged(); + if (doPostProcessing) { + mResolverListCommunicator.updateProfileViewButton(); + } } }; } - - protected void processSortedList(List<ResolvedComponentInfo> sortedComponents) { + protected void processSortedList(List<ResolvedComponentInfo> sortedComponents, + boolean doPostProcessing) { int n; if (sortedComponents != null && (n = sortedComponents.size()) != 0) { mAllTargetsAreBrowsers = mUseLayoutForBrowsables; @@ -343,20 +351,23 @@ public class ResolverListAdapter extends BaseAdapter { } mResolverListCommunicator.sendVoiceChoicesIfNeeded(); - postListReadyRunnable(); + postListReadyRunnable(doPostProcessing); } /** * Some necessary methods for creating the list are initiated in onCreate and will also * determine the layout known. We therefore can't update the UI inline and post to the * handler thread to update after the current task is finished. + * @param doPostProcessing Whether to update the UI and load additional direct share targets + * after the list has been rebuilt */ - void postListReadyRunnable() { + void postListReadyRunnable(boolean doPostProcessing) { if (mPostListReadyRunnable == null) { mPostListReadyRunnable = new Runnable() { @Override public void run() { - mResolverListCommunicator.onPostListReady(ResolverListAdapter.this); + mResolverListCommunicator.onPostListReady(ResolverListAdapter.this, + doPostProcessing); mPostListReadyRunnable = null; } }; @@ -590,6 +601,12 @@ public class ResolverListAdapter extends BaseAdapter { return mResolverListController.getUserHandle(); } + protected List<ResolvedComponentInfo> getResolversForUser(UserHandle userHandle) { + return mResolverListController.getResolversForIntentAsUser(true, + mResolverListCommunicator.shouldGetActivityMetadata(), + mIntents, userHandle); + } + /** * Necessary methods to communicate between {@link ResolverListAdapter} * and {@link ResolverActivity}. @@ -600,7 +617,7 @@ public class ResolverListAdapter extends BaseAdapter { Intent getReplacementIntent(ActivityInfo activityInfo, Intent defIntent); - void onPostListReady(ResolverListAdapter listAdapter); + void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi); void sendVoiceChoicesIfNeeded(); @@ -612,7 +629,7 @@ public class ResolverListAdapter extends BaseAdapter { Intent getTargetIntent(); - void onHandlePackagesChanged(); + void onHandlePackagesChanged(ResolverListAdapter listAdapter); } static class ViewHolder { diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 0bfe9eb04d28..022aded188fa 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -111,6 +111,15 @@ public class ResolverListController { boolean shouldGetResolvedFilter, boolean shouldGetActivityMetadata, List<Intent> intents) { + return getResolversForIntentAsUser(shouldGetResolvedFilter, shouldGetActivityMetadata, + intents, mUserHandle); + } + + public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntentAsUser( + boolean shouldGetResolvedFilter, + boolean shouldGetActivityMetadata, + List<Intent> intents, + UserHandle userHandle) { List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null; for (int i = 0, N = intents.size(); i < N; i++) { final Intent intent = intents.get(i); @@ -122,7 +131,7 @@ public class ResolverListController { flags |= PackageManager.MATCH_INSTANT; } final List<ResolveInfo> infos = mpm.queryIntentActivitiesAsUser(intent, flags, - mUserHandle); + userHandle); if (infos != null) { if (resolvedComponents == null) { resolvedComponents = new ArrayList<>(); diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java index 9d3c6c9ad8b1..96dc83a3f683 100644 --- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java @@ -36,8 +36,10 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA private final ResolverProfileDescriptor[] mItems; ResolverMultiProfilePagerAdapter(Context context, - ResolverListAdapter adapter) { - super(context, /* currentPage */ 0); + ResolverListAdapter adapter, + UserHandle personalProfileUserHandle, + UserHandle workProfileUserHandle) { + super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle); mItems = new ResolverProfileDescriptor[] { createProfileDescriptor(adapter) }; @@ -46,8 +48,11 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA ResolverMultiProfilePagerAdapter(Context context, ResolverListAdapter personalAdapter, ResolverListAdapter workAdapter, - @Profile int defaultProfile) { - super(context, /* currentPage */ defaultProfile); + @Profile int defaultProfile, + UserHandle personalProfileUserHandle, + UserHandle workProfileUserHandle) { + super(context, /* currentPage */ defaultProfile, personalProfileUserHandle, + workProfileUserHandle); mItems = new ResolverProfileDescriptor[] { createProfileDescriptor(personalAdapter), createProfileDescriptor(workAdapter) @@ -116,6 +121,17 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA } @Override + public ResolverListAdapter getPersonalListAdapter() { + return getAdapterForIndex(PROFILE_PERSONAL); + } + + @Override + @Nullable + public ResolverListAdapter getWorkListAdapter() { + return getAdapterForIndex(PROFILE_WORK); + } + + @Override ResolverListAdapter getCurrentRootAdapter() { return getActiveListAdapter(); } diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java index e0eb9af8b228..c50ff356f935 100644 --- a/core/java/com/android/internal/compat/ChangeReporter.java +++ b/core/java/com/android/internal/compat/ChangeReporter.java @@ -18,10 +18,10 @@ package com.android.internal.compat; import android.util.Log; import android.util.Slog; -import android.util.StatsLog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.FrameworkStatsLog; import java.util.HashMap; import java.util.HashSet; @@ -85,8 +85,8 @@ public final class ChangeReporter { */ public void reportChange(int uid, long changeId, int state) { if (shouldWriteToStatsLog(uid, changeId, state)) { - StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId, - state, mSource); + FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, + changeId, state, mSource); } if (shouldWriteToDebug(uid, changeId, state)) { debugLog(uid, changeId, state); @@ -174,7 +174,7 @@ public final class ChangeReporter { private void debugLog(int uid, long changeId, int state) { String message = String.format("Compat change id reported: %d; UID %d; state: %s", changeId, uid, stateToString(state)); - if (mSource == StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER) { + if (mSource == FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER) { Slog.d(TAG, message); } else { Log.d(TAG, message); @@ -183,18 +183,18 @@ public final class ChangeReporter { } /** - * Transforms StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE enum to a string. + * Transforms FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE enum to a string. * * @param state to transform * @return a string representing the state */ private static String stateToString(int state) { switch (state) { - case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED: + case FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED: return "LOGGED"; - case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED: + case FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED: return "ENABLED"; - case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED: + case FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED: return "DISABLED"; default: return "UNKNOWN"; diff --git a/core/java/com/android/internal/logging/InstanceId.java b/core/java/com/android/internal/logging/InstanceId.java index 85dbac3f59bb..85643fcffa2f 100644 --- a/core/java/com/android/internal/logging/InstanceId.java +++ b/core/java/com/android/internal/logging/InstanceId.java @@ -16,20 +16,33 @@ package com.android.internal.logging; +import static java.lang.Math.max; +import static java.lang.Math.min; + import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; /** * An opaque identifier used to disambiguate which logs refer to a particular instance of some * UI element. Useful when there might be multiple instances simultaneously active. - * Obtain from InstanceIdSequence. + * Obtain from InstanceIdSequence. Clipped to range [0, INSTANCE_ID_MAX]. */ -public class InstanceId { - private int mId; - protected InstanceId(int id) { - mId = id; +public final class InstanceId implements Parcelable { + // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values + static final int INSTANCE_ID_MAX = 1 << 20; + + private final int mId; + InstanceId(int id) { + mId = min(max(0, id), INSTANCE_ID_MAX); + } + + private InstanceId(Parcel in) { + this(in.readInt()); } + @VisibleForTesting public int getId() { return mId; @@ -47,4 +60,28 @@ public class InstanceId { } return mId == ((InstanceId) obj).mId; } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mId); + } + + public static final Parcelable.Creator<InstanceId> CREATOR = + new Parcelable.Creator<InstanceId>() { + @Override + public InstanceId createFromParcel(Parcel in) { + return new InstanceId(in); + } + + @Override + public InstanceId[] newArray(int size) { + return new InstanceId[size]; + } + }; + } diff --git a/core/java/com/android/internal/logging/InstanceIdSequence.java b/core/java/com/android/internal/logging/InstanceIdSequence.java index 2e78ed8c5185..aa507e538944 100644 --- a/core/java/com/android/internal/logging/InstanceIdSequence.java +++ b/core/java/com/android/internal/logging/InstanceIdSequence.java @@ -19,6 +19,8 @@ package com.android.internal.logging; import static java.lang.Math.max; import static java.lang.Math.min; +import com.android.internal.annotations.VisibleForTesting; + import java.security.SecureRandom; import java.util.Random; @@ -28,8 +30,6 @@ import java.util.Random; * first use; try to give it a long lifetime. Safe for concurrent use. */ public class InstanceIdSequence { - // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values - private static final int INSTANCE_ID_MAX = 1 << 20; protected final int mInstanceIdMax; private final Random mRandom = new SecureRandom(); @@ -39,7 +39,7 @@ public class InstanceIdSequence { * an all-zero sequence. */ public InstanceIdSequence(int instanceIdMax) { - mInstanceIdMax = min(max(0, instanceIdMax), INSTANCE_ID_MAX); + mInstanceIdMax = min(max(0, instanceIdMax), InstanceId.INSTANCE_ID_MAX); } /** @@ -47,6 +47,16 @@ public class InstanceIdSequence { * @return new InstanceId */ public InstanceId newInstanceId() { - return new InstanceId(mRandom.nextInt(mInstanceIdMax)); + return newInstanceIdInternal(mRandom.nextInt(mInstanceIdMax)); + } + + /** + * Factory function for instance IDs, used for testing. + * @param id + * @return new InstanceId(id) + */ + @VisibleForTesting + protected InstanceId newInstanceIdInternal(int id) { + return new InstanceId(id); } } diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index 7adb27cd9e36..db009f68d28a 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -468,7 +468,8 @@ public class RuntimeInit { try { if (ActivityManager.getService().handleApplicationWtf( mApplicationObject, tag, system, - new ApplicationErrorReport.ParcelableCrashInfo(t))) { + new ApplicationErrorReport.ParcelableCrashInfo(t), + Process.myPid())) { // The Activity Manager has already written us off -- now exit. Process.killProcess(Process.myPid()); System.exit(10); diff --git a/core/res/res/drawable/chooser_action_button_bg.xml b/core/res/res/drawable/chooser_action_button_bg.xml new file mode 100644 index 000000000000..a434c0b9b6a9 --- /dev/null +++ b/core/res/res/drawable/chooser_action_button_bg.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 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 + --> +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="@color/lighter_gray"> + <item> + <inset + android:insetLeft="0dp" + android:insetTop="8dp" + android:insetRight="0dp" + android:insetBottom="8dp"> + <shape android:shape="rectangle"> + <corners android:radius="16dp"></corners> + <stroke android:width="1dp" + android:color="?attr/textColorSecondary" /> + <solid android:color="?attr/colorBackground" /> + </shape> + </inset> + </item> +</ripple> diff --git a/core/res/res/drawable/ic_content_copy_gm2.xml b/core/res/res/drawable/ic_content_copy_gm2.xml deleted file mode 100644 index ee58738b75d0..000000000000 --- a/core/res/res/drawable/ic_content_copy_gm2.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 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="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - <path - android:fillColor="?android:attr/textColorSecondary" - android:pathData="M18,21L4,21L4,7L2,7v14c0,1.1 0.9,2 2,2h14v-2zM21,17L21,3c0,-1.1 -0.9,-2 -2,-2L8,1c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2zM19,17L8,17L8,3h11v14z"/> -</vector> diff --git a/core/res/res/drawable/ic_menu_copy_material.xml b/core/res/res/drawable/ic_menu_copy_material.xml index c03723b1fb33..8c9f1c514b97 100644 --- a/core/res/res/drawable/ic_menu_copy_material.xml +++ b/core/res/res/drawable/ic_menu_copy_material.xml @@ -1,26 +1,27 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 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 + 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 + 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. + 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="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:autoMirrored="true" - android:tint="?attr/colorControlNormal"> - <path - android:pathData="M16,1L4,1C2.9,1 2,1.9 2,3l0,14l2,0L4,3l12,0L16,1zM19,5L8,5C6.9,5 6,5.9 6,7l0,14c0,1.1 0.9,2 2,2l11,0c1.1,0 2,-0.9 2,-2L21,7C21,5.9 20.1,5 19,5zM19,21L8,21L8,7l11,0L19,21z" - android:fillColor="@color/white"/> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:autoMirrored="true" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@color/white" + android:pathData="M18,21L4,21L4,7L2,7v14c0,1.1 0.9,2 2,2h14v-2zM21,17L21,3c0,-1.1 -0.9,-2 -2,-2L8,1c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2zM19,17L8,17L8,3h11v14z"/> </vector> diff --git a/core/res/res/layout/chooser_action_button.xml b/core/res/res/layout/chooser_action_button.xml new file mode 100644 index 000000000000..119b2e90292d --- /dev/null +++ b/core/res/res/layout/chooser_action_button.xml @@ -0,0 +1,30 @@ +<!-- + ~ Copyright (C) 2019 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 + --> + +<Button xmlns:android="http://schemas.android.com/apk/res/android" + android:gravity="center_vertical|start" + android:paddingStart="12dp" + android:paddingEnd="12dp" + android:drawablePadding="8dp" + android:textColor="?android:textColorSecondary" + android:textSize="12sp" + android:maxWidth="192dp" + android:singleLine="true" + android:clickable="true" + android:background="@drawable/chooser_action_button_bg" + android:drawableTint="?android:attr/colorControlNormal" + android:drawableTintMode="src_in" + /> diff --git a/core/res/res/layout/chooser_action_row.xml b/core/res/res/layout/chooser_action_row.xml new file mode 100644 index 000000000000..ea7561124181 --- /dev/null +++ b/core/res/res/layout/chooser_action_row.xml @@ -0,0 +1,26 @@ +<!-- + ~ Copyright (C) 2019 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 + --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingLeft="@dimen/chooser_edge_margin_normal" + android:paddingRight="@dimen/chooser_edge_margin_normal" + android:gravity="center" + > + +</LinearLayout> diff --git a/core/res/res/layout/chooser_grid_preview_file.xml b/core/res/res/layout/chooser_grid_preview_file.xml index f7d60c91052d..2a39215a4bd8 100644 --- a/core/res/res/layout/chooser_grid_preview_file.xml +++ b/core/res/res/layout/chooser_grid_preview_file.xml @@ -65,13 +65,15 @@ android:gravity="start|top" android:paddingRight="24dp" android:singleLine="true"/> - <Button - android:id="@+id/file_copy_button" - android:layout_width="24dp" - android:layout_height="24dp" - android:gravity="center" - android:layout_gravity="center_vertical" - android:background="@drawable/ic_content_copy_gm2"/> </LinearLayout> + + <include + android:id="@+id/chooser_action_row" + layout="@layout/chooser_action_row" + android:layout_width="@dimen/chooser_preview_width" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/chooser_view_spacing" + android:layout_gravity="center" + /> </LinearLayout> diff --git a/core/res/res/layout/chooser_grid_preview_image.xml b/core/res/res/layout/chooser_grid_preview_image.xml index 79a0de4b271f..62df1650612a 100644 --- a/core/res/res/layout/chooser_grid_preview_image.xml +++ b/core/res/res/layout/chooser_grid_preview_image.xml @@ -78,5 +78,15 @@ android:scaleType="centerCrop"/> </RelativeLayout> + + <include + android:id="@+id/chooser_action_row" + layout="@layout/chooser_action_row" + android:layout_width="@dimen/chooser_preview_width" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/chooser_view_spacing" + android:layout_gravity="center" + /> + </LinearLayout> diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml index 4d7846dfb9cc..002917463ab3 100644 --- a/core/res/res/layout/chooser_grid_preview_text.xml +++ b/core/res/res/layout/chooser_grid_preview_text.xml @@ -37,10 +37,9 @@ <TextView android:id="@+id/content_preview_text" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentStart="true" - android:layout_toStartOf="@id/copy_button" android:layout_centerVertical="true" android:ellipsize="end" android:fontFamily="@android:string/config_headlineFontFamily" @@ -48,40 +47,17 @@ android:maxLines="2" android:focusable="true"/> - <LinearLayout - android:id="@+id/copy_button" - android:orientation="vertical" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerVertical="true" - android:layout_alignParentEnd="true" - android:layout_marginStart="@dimen/chooser_view_spacing" - android:gravity="center" - android:minWidth="48dp" - android:minHeight="48dp" - android:clickable="true" - style="?attr/borderlessButtonStyle"> - - <ImageView - android:layout_width="24dp" - android:layout_height="24dp" - android:gravity="top|center_horizontal" - android:src="@drawable/ic_content_copy_gm2" /> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="4dp" - android:gravity="center_horizontal" - android:text="@string/copy" - android:textColor="?android:textColorSecondary" - android:textSize="12sp" - android:maxWidth="72dp" - android:maxLines="2" - android:ellipsize="end" /> - </LinearLayout> </RelativeLayout> + <include + android:id="@+id/chooser_action_row" + layout="@layout/chooser_action_row" + android:layout_width="@dimen/chooser_preview_width" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/chooser_view_spacing" + android:layout_gravity="center" + /> + <!-- Required sub-layout so we can get the nice rounded corners--> <!-- around this section --> <LinearLayout diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index e98f8ba3cda7..52b92d2660da 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4323,4 +4323,12 @@ <item>4</item> <!-- PROCESS_STATE_FOREGROUND_SERVICE --> <item>12</item> <!-- PROCESS_STATE_TOP_SLEEPING --> </integer-array> + + <!-- Component name that accepts ACTION_SEND intents for nearby (proximity-based) sharing. + Used by ChooserActivity. --> + <string translatable="false" name="config_defaultNearbySharingComponent"></string> + + <!-- Boolean indicating whether frameworks needs to reset cell broadcast geo-fencing + check after reboot or airplane mode toggling --> + <bool translatable="false" name="reset_geo_fencing_check_after_boot_or_apm">false</bool> </resources> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index d437aa1c340c..0b5082cdaf94 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -774,6 +774,8 @@ <dimen name="resolver_edge_margin">24dp</dimen> <dimen name="resolver_elevation">1dp</dimen> + <dimen name="chooser_action_button_icon_size">18dp</dimen> + <!-- Assistant handles --> <dimen name="assist_handle_shadow_radius">2dp</dimen> diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index ddd9ba43fe09..51ed08b88111 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -194,6 +194,9 @@ <!-- A tag used to save the index where the custom view is stored --> <item type="id" name="notification_custom_view_index_tag" /> + <!-- Marks the "copy to clipboard" button in the ChooserActivity --> + <item type="id" name="chooser_copy_button" /> + <!-- Accessibility action identifier for {@link android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK}. --> <item type="id" name="accessibilitySystemActionBack" /> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e4717f817688..21128e33b6e5 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -66,8 +66,7 @@ <java-symbol type="id" name="content_preview_text_layout" /> <java-symbol type="id" name="content_preview_title" /> <java-symbol type="id" name="content_preview_title_layout" /> - <java-symbol type="id" name="copy_button" /> - <java-symbol type="id" name="file_copy_button" /> + <java-symbol type="id" name="chooser_action_row" /> <java-symbol type="id" name="current_scene" /> <java-symbol type="id" name="scene_layoutid_cache" /> <java-symbol type="id" name="customPanel" /> @@ -3783,6 +3782,11 @@ <java-symbol type="string" name="config_factoryResetPackage" /> <java-symbol type="array" name="config_highRefreshRateBlacklist" /> + <java-symbol type="id" name="chooser_copy_button" /> + <java-symbol type="layout" name="chooser_action_button" /> + <java-symbol type="dimen" name="chooser_action_button_icon_size" /> + <java-symbol type="string" name="config_defaultNearbySharingComponent" /> + <java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" /> <java-symbol type="bool" name="config_showBuiltinWirelessChargingAnim" /> diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index d4c362143bf0..df6b9066ea5c 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -64,7 +64,6 @@ import android.graphics.Paint; import android.graphics.drawable.Icon; import android.metrics.LogMaker; import android.net.Uri; -import android.os.Bundle; import android.os.UserHandle; import android.service.chooser.ChooserTarget; @@ -77,9 +76,6 @@ import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; @@ -482,8 +478,8 @@ public class ChooserActivityTest { .launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - onView(withId(R.id.copy_button)).check(matches(isDisplayed())); - onView(withId(R.id.copy_button)).perform(click()); + onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed())); + onView(withId(R.id.chooser_copy_button)).perform(click()); ClipboardManager clipboard = (ClipboardManager) activity.getSystemService( Context.CLIPBOARD_SERVICE); ClipData clipData = clipboard.getPrimaryClip(); @@ -510,8 +506,8 @@ public class ChooserActivityTest { .launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - onView(withId(R.id.copy_button)).check(matches(isDisplayed())); - onView(withId(R.id.copy_button)).perform(click()); + onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed())); + onView(withId(R.id.chooser_copy_button)).perform(click()); verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture()); // First is Activity shown, Second is "with preview" diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java index 42f7736d37b0..911490f30799 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java @@ -27,12 +27,14 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText; import static com.android.internal.app.MatcherUtils.first; import static com.android.internal.app.ResolverDataProvider.createPackageManagerMockedInfo; +import static com.android.internal.app.ResolverDataProvider.createResolvedComponentInfoWithOtherId; import static com.android.internal.app.ResolverWrapperActivity.sOverrides; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import android.content.Intent; @@ -465,14 +467,33 @@ public class ResolverActivityTest { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; List<ResolvedComponentInfo> personalResolvedComponentInfos = - createResolvedComponentsForTest(3); + createResolvedComponentsForTestWithOtherProfile(3); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + when(sOverrides.resolverListController.getResolversForIntentAsUser( Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos); + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.resolverListController.getResolversForIntentAsUser( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + Intent sendIntent = createSendImageIntent(); markWorkProfileUserAvailable(); @@ -502,9 +523,9 @@ public class ResolverActivityTest { final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); waitForIdle(); + onView(withText(R.string.resolver_work_tab)) .perform(click()); - waitForIdle(); assertThat(activity.getWorkListAdapter().getCount(), is(4)); } @@ -553,10 +574,35 @@ public class ResolverActivityTest { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(1); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); + + when(sOverrides.resolverListController.getResolversForIntentAsUser( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.resolverListController.getResolversForIntentAsUser( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(sOverrides.workProfileUserHandle))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); + Intent sendIntent = createSendImageIntent(); final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 7c0efe16838e..58cc08bc2d73 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -479,6 +479,14 @@ bool Bitmap::compress(JavaCompressFormat format, int32_t quality, SkWStream* str bool Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format, int32_t quality, SkWStream* stream) { + if (bitmap.colorType() == kAlpha_8_SkColorType) { + // None of the JavaCompressFormats have a sensible way to compress an + // ALPHA_8 Bitmap. SkPngEncoder will compress one, but it uses a non- + // standard format that most decoders do not understand, so this is + // likely not useful. + return false; + } + SkEncodedImageFormat fm; switch (format) { case JavaCompressFormat::Jpeg: diff --git a/mms/java/android/telephony/MmsManager.java b/mms/java/android/telephony/MmsManager.java index cf55eba6e5ba..f07cd5e34062 100644 --- a/mms/java/android/telephony/MmsManager.java +++ b/mms/java/android/telephony/MmsManager.java @@ -55,10 +55,12 @@ public class MmsManager { * sending the message. * @param sentIntent if not NULL this <code>PendingIntent</code> is broadcast when the message * is successfully sent, or failed + * @param messageId an id that uniquely identifies the message requested to be sent. + * Used for logging and diagnostics purposes. The id may be 0. */ public void sendMultimediaMessage(int subId, @NonNull Uri contentUri, @Nullable String locationUrl, @Nullable Bundle configOverrides, - @Nullable PendingIntent sentIntent) { + @Nullable PendingIntent sentIntent, long messageId) { try { final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); if (iMms == null) { @@ -66,7 +68,7 @@ public class MmsManager { } iMms.sendMessage(subId, ActivityThread.currentPackageName(), contentUri, - locationUrl, configOverrides, sentIntent); + locationUrl, configOverrides, sentIntent, messageId); } catch (RemoteException e) { // Ignore it } @@ -83,18 +85,22 @@ public class MmsManager { * downloading the message. * @param downloadedIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is downloaded, or the download is failed + * @param messageId an id that uniquely identifies the message requested to be downloaded. + * Used for logging and diagnostics purposes. The id may be 0. + * downloaded. * @throws IllegalArgumentException if locationUrl or contentUri is empty */ public void downloadMultimediaMessage(int subId, @NonNull String locationUrl, @NonNull Uri contentUri, @Nullable Bundle configOverrides, - @Nullable PendingIntent downloadedIntent) { + @Nullable PendingIntent downloadedIntent, long messageId) { try { final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); if (iMms == null) { return; } iMms.downloadMessage(subId, ActivityThread.currentPackageName(), - locationUrl, contentUri, configOverrides, downloadedIntent); + locationUrl, contentUri, configOverrides, downloadedIntent, + messageId); } catch (RemoteException e) { // Ignore it } diff --git a/mms/java/com/android/internal/telephony/IMms.aidl b/mms/java/com/android/internal/telephony/IMms.aidl index 8be511186800..e0e0a4a812e4 100644 --- a/mms/java/com/android/internal/telephony/IMms.aidl +++ b/mms/java/com/android/internal/telephony/IMms.aidl @@ -37,9 +37,11 @@ interface IMms { * sending the message. See {@link android.telephony.SmsManager} for the value names and types. * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is successfully sent, or failed + * @param messageId An id that uniquely identifies the message requested to be sent. */ void sendMessage(int subId, String callingPkg, in Uri contentUri, - String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent); + String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent, + in long messageId); /** * Download an MMS message using known location and transaction id @@ -54,10 +56,11 @@ interface IMms { * types. * @param downloadedIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is downloaded, or the download is failed - */ + * @param messageId An id that uniquely identifies the message requested to be downloaded. + */ void downloadMessage(int subId, String callingPkg, String locationUrl, in Uri contentUri, in Bundle configOverrides, - in PendingIntent downloadedIntent); + in PendingIntent downloadedIntent, in long messageId); /** * Import a text message into system's SMS store diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml index 851a3d8f136a..d65d821e71ab 100644 --- a/packages/SettingsLib/res/values-ar/arrays.xml +++ b/packages/SettingsLib/res/values-ar/arrays.xml @@ -252,7 +252,7 @@ <item msgid="3474333938380896988">"عرض مناطق العجز في رؤية اللونين الأخضر والأحمر"</item> </string-array> <string-array name="app_process_limit_entries"> - <item msgid="794656271086646068">"الحد القياسي"</item> + <item msgid="794656271086646068">"الحدّ العادي"</item> <item msgid="8628438298170567201">"ليست هناك عمليات بالخلفية"</item> <item msgid="915752993383950932">"عملية واحدة بحد أقصى"</item> <item msgid="8554877790859095133">"عمليتان بحد أقصى"</item> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 54856566e021..5103345401f4 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -124,7 +124,7 @@ <string name="bluetooth_talkback_headset" msgid="3406852564400882682">"سماعة رأس"</string> <string name="bluetooth_talkback_phone" msgid="868393783858123880">"هاتف"</string> <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"تصوير"</string> - <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"سماعة أذن"</string> + <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"السمّاعة"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"جهاز إدخال طرفي"</string> <string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"بلوتوث"</string> <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"جارٍ إقران سماعة الأذن الطبية اليسرى…"</string> @@ -157,7 +157,7 @@ <string name="tts_settings" msgid="8130616705989351312">"إعدادات تحويل النص إلى كلام"</string> <string name="tts_settings_title" msgid="7602210956640483039">"تحويل النص إلى كلام"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"معدل سرعة الكلام"</string> - <string name="tts_default_rate_summary" msgid="3781937042151716987">"سرعة نطق الكلام"</string> + <string name="tts_default_rate_summary" msgid="3781937042151716987">"سرعة قول الكلام"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"درجة الصوت"</string> <string name="tts_default_pitch_summary" msgid="9132719475281551884">"للتأثير في نبرة الكلام المُرَكَّب"</string> <string name="tts_default_lang_title" msgid="4698933575028098940">"اللغة"</string> @@ -181,7 +181,7 @@ <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"المحرّك المفضّل"</string> <string name="tts_general_section_title" msgid="8919671529502364567">"عامة"</string> <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"إعادة ضبط طبقة صوت الكلام"</string> - <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"إعادة ضبط طبقة الصوت التي يتم نطق النص بها على الإعداد التلقائي."</string> + <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"إعادة ضبط طبقة الصوت التي يتم قول النص بها على الإعداد التلقائي."</string> <string-array name="tts_rate_entries"> <item msgid="9004239613505400644">"بطيء جدًا"</item> <item msgid="1815382991399815061">"بطيء"</item> @@ -353,7 +353,7 @@ <string-array name="color_mode_names"> <item msgid="3836559907767149216">"نابض بالحياة (تلقائي)"</item> <item msgid="9112200311983078311">"طبيعي"</item> - <item msgid="6564241960833766170">"قياسي"</item> + <item msgid="6564241960833766170">"عادي"</item> </string-array> <string-array name="color_mode_descriptions"> <item msgid="6828141153199944847">"ألوان محسَّنة"</item> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index cda42d348c45..5bcff5ad27b2 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -201,7 +201,7 @@ <string name="development_settings_summary" msgid="8718917813868735095">"Đặt tùy chọn cho phát triển ứng dụng"</string> <string name="development_settings_not_available" msgid="355070198089140951">"Tùy chọn dành cho nhà phát triển không khả dụng cho người dùng này"</string> <string name="vpn_settings_not_available" msgid="2894137119965668920">"Cài đặt VPN không khả dụng cho người dùng này"</string> - <string name="tethering_settings_not_available" msgid="266821736434699780">"Cài đặt chia sẻ kết nối không khả dụng cho người dùng này"</string> + <string name="tethering_settings_not_available" msgid="266821736434699780">"Cài đặt cách chia sẻ kết nối không khả dụng cho người dùng này"</string> <string name="apn_settings_not_available" msgid="1147111671403342300">"Cài đặt tên điểm truy cập không khả dụng cho người dùng này"</string> <string name="enable_adb" msgid="8072776357237289039">"Gỡ lỗi qua USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Bật chế độ gỡ lỗi khi kết nối USB"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java index b01fc8541957..f5aa652f3194 100644 --- a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java +++ b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java @@ -216,7 +216,7 @@ public class NetworkPolicyEditor { private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) { if (template == null) return null; final String networkId = template.getNetworkId(); - final String strippedNetworkId = WifiInfo.removeDoubleQuotes(networkId); + final String strippedNetworkId = WifiInfo.sanitizeSsid(networkId); if (!TextUtils.equals(strippedNetworkId, networkId)) { return new NetworkTemplate( template.getMatchRule(), template.getSubscriberId(), strippedNetworkId); diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 65269c9d5a89..dee1d7eced66 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -728,6 +728,7 @@ public class SettingsBackupTest { Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE, Settings.Secure.FACE_UNLOCK_RE_ENROLL, Settings.Secure.TAP_GESTURE, + Settings.Secure.NEARBY_SHARING_COMPONENT, // not user configurable Settings.Secure.WINDOW_MAGNIFICATION, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER, Settings.Secure.SUPPRESS_DOZE); diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index c238d7d49f9b..de174b13a459 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -69,10 +69,6 @@ android_library { ], manifest: "AndroidManifest.xml", - libs: [ - "telephony-common", - ], - kotlincflags: ["-Xjvm-default=enable"], plugins: ["dagger2-compiler-2.19"], @@ -136,7 +132,6 @@ android_library { ], libs: [ "android.test.runner", - "telephony-common", "android.test.base", ], kotlincflags: ["-Xjvm-default=enable"], @@ -163,10 +158,6 @@ android_app { proguard_flags_files: ["proguard.flags"], }, - libs: [ - "telephony-common", - ], - kotlincflags: ["-Xjvm-default=enable"], dxflags: ["--multi-dex"], diff --git a/packages/SystemUI/docs/plugin_hooks.md b/packages/SystemUI/docs/plugin_hooks.md index 2fb0c996111a..9fe2e181971a 100644 --- a/packages/SystemUI/docs/plugin_hooks.md +++ b/packages/SystemUI/docs/plugin_hooks.md @@ -56,11 +56,6 @@ Expected interface: [ClockPlugin](/packages/SystemUI/plugin/src/com/android/syst Use: Allows replacement of the keyguard main clock. -### Action: com.android.systemui.action.PLUGIN_NPV -Expected interface: [NPVPlugin](/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java) - -Use: Attach a view under QQS for prototyping. - # Global plugin dependencies These classes can be accessed by any plugin using PluginDependency as long as they @Requires them. diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java deleted file mode 100644 index c1d4b03b6620..000000000000 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/HomeControlsPlugin.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.systemui.plugins; - -import android.view.ViewGroup; - -import com.android.systemui.plugins.annotations.ProvidesInterface; - -/** - * Test plugin for home controls - */ -@ProvidesInterface(action = HomeControlsPlugin.ACTION, version = HomeControlsPlugin.VERSION) -public interface HomeControlsPlugin extends Plugin { - - String ACTION = "com.android.systemui.action.PLUGIN_HOME_CONTROLS"; - int VERSION = 1; - - /** - * Pass the container for the plugin to use however it wants. Ideally the plugin impl - * will add home controls to this space. - */ - void sendParentGroup(ViewGroup group); - - /** - * When visible, will poll for updates. - */ - void setVisible(boolean visible); -} diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java deleted file mode 100644 index 1426266a7048..000000000000 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NPVPlugin.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.plugins; - -import android.view.View; -import android.widget.FrameLayout; - -import com.android.systemui.plugins.annotations.ProvidesInterface; - -/** - * Plugin to attach custom views under QQS. - * - * A parent view is provided to the plugin to which they can add Views. - * <br> - * The parent is a {@link FrameLayout} with same background as QS and 96dp height. - * - * {@see NPVPluginManager} - * {@see status_bar_expanded_plugin_frame} - */ -@ProvidesInterface(action = NPVPlugin.ACTION, version = NPVPlugin.VERSION) -public interface NPVPlugin extends Plugin { - String ACTION = "com.android.systemui.action.PLUGIN_NPV"; - int VERSION = 1; - - /** - * Attach views to the parent. - * - * @param parent a {@link FrameLayout} to which to attach views. Preferably a root view. - * @return a view attached to parent. - */ - View attachToRoot(FrameLayout parent); - - /** - * Indicate to the plugin when it is listening (QS expanded) - * @param listening - */ - default void setListening(boolean listening) {}; -} diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java index 17f2f476c9f2..6518924ca0c2 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java @@ -133,7 +133,6 @@ public interface QSTile { public CharSequence label; public CharSequence secondaryLabel; public CharSequence contentDescription; - public CharSequence stateDescription; public CharSequence dualLabelContentDescription; public boolean disabledByPolicy; public boolean dualTarget = false; @@ -152,7 +151,6 @@ public interface QSTile { || !Objects.equals(other.label, label) || !Objects.equals(other.secondaryLabel, secondaryLabel) || !Objects.equals(other.contentDescription, contentDescription) - || !Objects.equals(other.stateDescription, stateDescription) || !Objects.equals(other.dualLabelContentDescription, dualLabelContentDescription) || !Objects.equals(other.expandedAccessibilityClassName, @@ -170,7 +168,6 @@ public interface QSTile { other.label = label; other.secondaryLabel = secondaryLabel; other.contentDescription = contentDescription; - other.stateDescription = stateDescription; other.dualLabelContentDescription = dualLabelContentDescription; other.expandedAccessibilityClassName = expandedAccessibilityClassName; other.disabledByPolicy = disabledByPolicy; @@ -198,7 +195,6 @@ public interface QSTile { sb.append(",label=").append(label); sb.append(",secondaryLabel=").append(secondaryLabel); sb.append(",contentDescription=").append(contentDescription); - sb.append(",stateDescription=").append(stateDescription); sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription); sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName); sb.append(",disabledByPolicy=").append(disabledByPolicy); diff --git a/packages/SystemUI/res/layout/home_controls.xml b/packages/SystemUI/res/layout/home_controls.xml deleted file mode 100644 index 69a0e872dc8c..000000000000 --- a/packages/SystemUI/res/layout/home_controls.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/home_controls_layout" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="@integer/notification_panel_layout_gravity" - android:visibility="gone" - android:padding="8dp" - android:layout_margin="5dp" - android:background="?android:attr/colorBackgroundFloating"> -</FrameLayout> diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index 76c1045ef1dd..4fae3c500a45 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -42,32 +42,6 @@ android:visibility="gone" /> - <LinearLayout - android:id="@+id/divider_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal" - android:background="@color/transparent" > - - <android.widget.Space - android:layout_height="match_parent" - android:layout_width="0dp" - android:layout_weight="@integer/qqs_split_fraction" /> - - <com.android.systemui.DarkReceiverImpl - android:id="@+id/divider" - android:layout_height="match_parent" - android:layout_width="1dp" - android:layout_marginTop="4dp" - android:layout_marginBottom="4dp" /> - - <android.widget.Space - android:layout_height="match_parent" - android:layout_width="0dp" - android:layout_weight="@integer/qs_split_fraction" /> - - </LinearLayout> - <LinearLayout android:id="@+id/status_bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 479f255b7e44..115b4a86b86d 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -55,9 +55,6 @@ android:clipChildren="false" systemui:viewType="com.android.systemui.plugins.qs.QS" /> - <!-- Temporary area to test out home controls --> - <include layout="@layout/home_controls" /> - <com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout android:id="@+id/notification_stack_scroller" android:layout_marginTop="@dimen/notification_panel_margin_top" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 8d935ecc691d..1f13f8dc02fe 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2549,7 +2549,4 @@ <!-- Quick Controls strings [CHAR LIMIT=30] --> <string name="quick_controls_title">Quick Controls</string> - - <!-- The tile in quick settings is unavailable. [CHAR LIMIT=32] --> - <string name="tile_unavailable">Unvailable</string> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java deleted file mode 100644 index 78b1b26140d5..000000000000 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.systemui.shared.recents.model; - -import static android.content.pm.PackageManager.MATCH_ANY_USER; - -import android.app.ActivityManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.UserHandle; -import android.util.IconDrawableFactory; -import android.util.Log; -import android.util.LruCache; - -import com.android.systemui.shared.system.PackageManagerWrapper; - -public abstract class IconLoader { - - private static final String TAG = "IconLoader"; - - protected final Context mContext; - protected final TaskKeyLruCache<Drawable> mIconCache; - protected final LruCache<ComponentName, ActivityInfo> mActivityInfoCache; - - public IconLoader(Context context, TaskKeyLruCache<Drawable> iconCache, LruCache<ComponentName, - ActivityInfo> activityInfoCache) { - mContext = context; - mIconCache = iconCache; - mActivityInfoCache = activityInfoCache; - } - - /** - * Returns the activity info for the given task key, retrieving one from the system if the - * task key is expired. - * - * TODO: Move this to an ActivityInfoCache class - */ - public ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) { - ComponentName cn = taskKey.getComponent(); - ActivityInfo activityInfo = mActivityInfoCache.get(cn); - if (activityInfo == null) { - activityInfo = PackageManagerWrapper.getInstance().getActivityInfo(cn, taskKey.userId); - if (cn == null || activityInfo == null) { - Log.e(TAG, "Unexpected null component name or activity info: " + cn + ", " + - activityInfo); - return null; - } - mActivityInfoCache.put(cn, activityInfo); - } - return activityInfo; - } - - public Drawable getIcon(Task t) { - Drawable cachedIcon = mIconCache.get(t.key); - if (cachedIcon == null) { - cachedIcon = createNewIconForTask(t.key, t.taskDescription, true /* returnDefault */); - mIconCache.put(t.key, cachedIcon); - } - return cachedIcon; - } - - /** - * Returns the cached task icon if the task key is not expired, updating the cache if it is. - */ - public Drawable getAndInvalidateIfModified(Task.TaskKey taskKey, - ActivityManager.TaskDescription td, boolean loadIfNotCached) { - // Return the cached activity icon if it exists - Drawable icon = mIconCache.getAndInvalidateIfModified(taskKey); - if (icon != null) { - return icon; - } - - if (loadIfNotCached) { - icon = createNewIconForTask(taskKey, td, false /* returnDefault */); - if (icon != null) { - mIconCache.put(taskKey, icon); - return icon; - } - } - - // We couldn't load any icon - return null; - } - - private Drawable createNewIconForTask(Task.TaskKey taskKey, - ActivityManager.TaskDescription desc, boolean returnDefault) { - int userId = taskKey.userId; - Bitmap tdIcon = desc.getInMemoryIcon(); - if (tdIcon != null) { - return createDrawableFromBitmap(tdIcon, userId, desc); - } - if (desc.getIconResource() != 0) { - try { - PackageManager pm = mContext.getPackageManager(); - ApplicationInfo appInfo = pm.getApplicationInfo(taskKey.getPackageName(), - MATCH_ANY_USER); - Resources res = pm.getResourcesForApplication(appInfo); - return createBadgedDrawable(res.getDrawable(desc.getIconResource(), null), userId, - desc); - } catch (Resources.NotFoundException|PackageManager.NameNotFoundException e) { - Log.e(TAG, "Could not find icon drawable from resource", e); - } - } - - tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon( - desc.getIconFilename(), userId); - if (tdIcon != null) { - return createDrawableFromBitmap(tdIcon, userId, desc); - } - - // Load the icon from the activity info and cache it - ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey); - if (activityInfo != null) { - Drawable icon = getBadgedActivityIcon(activityInfo, userId, desc); - if (icon != null) { - return icon; - } - } - - // At this point, even if we can't load the icon, we will set the default icon. - return returnDefault ? getDefaultIcon(userId) : null; - } - - public abstract Drawable getDefaultIcon(int userId); - - protected Drawable createDrawableFromBitmap(Bitmap icon, int userId, - ActivityManager.TaskDescription desc) { - return createBadgedDrawable( - new BitmapDrawable(mContext.getResources(), icon), userId, desc); - } - - protected abstract Drawable createBadgedDrawable(Drawable icon, int userId, - ActivityManager.TaskDescription desc); - - /** - * @return the activity icon for the ActivityInfo for a user, badging if necessary. - */ - protected abstract Drawable getBadgedActivityIcon(ActivityInfo info, int userId, - ActivityManager.TaskDescription desc); - - public static class DefaultIconLoader extends IconLoader { - - private final BitmapDrawable mDefaultIcon; - private final IconDrawableFactory mDrawableFactory; - - public DefaultIconLoader(Context context, TaskKeyLruCache<Drawable> iconCache, - LruCache<ComponentName, ActivityInfo> activityInfoCache) { - super(context, iconCache, activityInfoCache); - - // Create the default assets - Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); - icon.eraseColor(0); - mDefaultIcon = new BitmapDrawable(context.getResources(), icon); - mDrawableFactory = IconDrawableFactory.newInstance(context); - } - - @Override - public Drawable getDefaultIcon(int userId) { - return mDefaultIcon; - } - - @Override - protected Drawable createBadgedDrawable(Drawable icon, int userId, - ActivityManager.TaskDescription desc) { - if (userId != UserHandle.myUserId()) { - icon = mContext.getPackageManager().getUserBadgedIcon(icon, new UserHandle(userId)); - } - return icon; - } - - @Override - protected Drawable getBadgedActivityIcon(ActivityInfo info, int userId, - ActivityManager.TaskDescription desc) { - return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId); - } - } -} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java deleted file mode 100644 index 8a244bf81c7c..000000000000 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.shared.recents.model; - -import android.util.Log; -import android.util.SparseArray; - -import com.android.systemui.shared.recents.model.Task.TaskKey; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * Base class for both strong and LRU task key cache. - */ -public abstract class TaskKeyCache<V> { - - protected static final String TAG = "TaskKeyCache"; - - protected final SparseArray<TaskKey> mKeys = new SparseArray<>(); - - /** - * Gets a specific entry in the cache with the specified key, regardless of whether the cached - * value is valid or not. - */ - public final synchronized V get(TaskKey key) { - return getCacheEntry(key.id); - } - - /** - * Returns the value only if the key is valid (has not been updated since the last time it was - * in the cache) - */ - public final synchronized V getAndInvalidateIfModified(TaskKey key) { - TaskKey lastKey = mKeys.get(key.id); - if (lastKey != null) { - if ((lastKey.windowingMode != key.windowingMode) || - (lastKey.lastActiveTime != key.lastActiveTime)) { - // The task has updated (been made active since the last time it was put into the - // LRU cache) or the stack id for the task has changed, invalidate that cache item - remove(key); - return null; - } - } - // Either the task does not exist in the cache, or the last active time is the same as - // the key specified, so return what is in the cache - return getCacheEntry(key.id); - } - - /** Puts an entry in the cache for a specific key. */ - public final synchronized void put(TaskKey key, V value) { - if (key == null || value == null) { - Log.e(TAG, "Unexpected null key or value: " + key + ", " + value); - return; - } - mKeys.put(key.id, key); - putCacheEntry(key.id, value); - } - - - /** Removes a cache entry for a specific key. */ - public final synchronized void remove(TaskKey key) { - // Remove the key after the cache value because we need it to make the callback - removeCacheEntry(key.id); - mKeys.remove(key.id); - } - - /** @return {@link Collection} of {@link TaskKey} */ - public Collection<TaskKey> getValues() { - Collection<TaskKey> result = new ArrayList<>(mKeys.size()); - for (int i = 0; i < mKeys.size(); i++) { - result.add(mKeys.valueAt(i)); - } - return result; - } - - /** Removes all the entries in the cache. */ - public final synchronized void evictAll() { - evictAllCache(); - mKeys.clear(); - } - - protected abstract V getCacheEntry(int id); - protected abstract void putCacheEntry(int id, V value); - protected abstract void removeCacheEntry(int id); - protected abstract void evictAllCache(); -} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyLruCache.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyLruCache.java deleted file mode 100644 index bc57b08236cf..000000000000 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyLruCache.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.shared.recents.model; - -import android.util.LruCache; - -import com.android.systemui.shared.recents.model.Task.TaskKey; - -import java.io.PrintWriter; - -/** - * A mapping of {@link TaskKey} to value, with additional LRU functionality where the least - * recently referenced key/values will be evicted as more values than the given cache size are - * inserted. - * - * In addition, this also allows the caller to invalidate cached values for keys that have since - * changed. - */ -public class TaskKeyLruCache<V> extends TaskKeyCache<V> { - - public interface EvictionCallback { - void onEntryEvicted(TaskKey key); - } - - private final LruCache<Integer, V> mCache; - private final EvictionCallback mEvictionCallback; - - public TaskKeyLruCache(int cacheSize) { - this(cacheSize, null); - } - - public TaskKeyLruCache(int cacheSize, EvictionCallback evictionCallback) { - mEvictionCallback = evictionCallback; - mCache = new LruCache<Integer, V>(cacheSize) { - - @Override - protected void entryRemoved(boolean evicted, Integer taskId, V oldV, V newV) { - if (mEvictionCallback != null && evicted) { - mEvictionCallback.onEntryEvicted(mKeys.get(taskId)); - } - - // Only remove from mKeys on cache remove, not a cache update. - if (newV == null) { - mKeys.remove(taskId); - } - } - }; - } - - /** Trims the cache to a specific size */ - public final void trimToSize(int cacheSize) { - mCache.trimToSize(cacheSize); - } - - public void dump(String prefix, PrintWriter writer) { - String innerPrefix = prefix + " "; - - writer.print(prefix); writer.print(TAG); - writer.print(" numEntries="); writer.print(mKeys.size()); - writer.println(); - int keyCount = mKeys.size(); - for (int i = 0; i < keyCount; i++) { - writer.print(innerPrefix); writer.println(mKeys.get(mKeys.keyAt(i))); - } - } - - @Override - protected V getCacheEntry(int id) { - return mCache.get(id); - } - - @Override - protected void putCacheEntry(int id, V value) { - mCache.put(id, value); - } - - @Override - protected void removeCacheEntry(int id) { - mCache.remove(id); - } - - @Override - protected void evictAllCache() { - mCache.evictAll(); - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java index ed1cd8191092..d5a08dda9853 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java @@ -409,15 +409,6 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback { mAudioManager.dispatchMediaKeyEvent(keyEvent); } - @Override - public void dispatchSystemUiVisibilityChanged(int visibility) { - super.dispatchSystemUiVisibilityChanged(visibility); - - if (!(mContext instanceof Activity)) { - setSystemUiVisibility(STATUS_BAR_DISABLE_BACK); - } - } - /** * In general, we enable unlocking the insecure keyguard with the menu key. However, there are * some cases where we wish to disable it, notably when the menu button placement or technology diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index ae787260adca..29c67ae1b4a6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -15,7 +15,12 @@ */ package com.android.keyguard; +import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; +import static android.view.ViewRootImpl.sNewInsetsMode; +import static android.view.WindowInsets.Type.ime; +import static android.view.WindowInsets.Type.systemBars; import static com.android.systemui.DejankUtils.whitelistIpcs; +import static java.lang.Integer.max; import android.app.Activity; import android.app.AlertDialog; @@ -38,6 +43,7 @@ import android.view.SurfaceControl; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; +import android.view.WindowInsets; import android.view.WindowManager; import android.widget.FrameLayout; @@ -339,13 +345,22 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe } @Override - protected boolean fitSystemWindows(Rect insets) { + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + // Consume bottom insets because we're setting the padding locally (for IME and navbar.) - setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), insets.bottom); - insets.bottom = 0; - return false; + int inset; + if (sNewInsetsMode == NEW_INSETS_MODE_FULL) { + int bottomInset = insets.getInsetsIgnoringVisibility(systemBars()).bottom; + int imeInset = insets.getInsets(ime()).bottom; + inset = max(bottomInset, imeInset); + } else { + inset = insets.getSystemWindowInsetBottom(); + } + setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), inset); + return insets.inset(0, 0, 0, inset); } + private void showDialog(String title, String message) { if (mAlertDialog != null) { mAlertDialog.dismiss(); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 58a6c17e8239..4e2f7d4ee862 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -371,7 +371,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab checkIsHandlerThread(); if (DEBUG_SIM_STATES) { Log.v(TAG, "onSubscriptionInfoChanged()"); - List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(false); + List<SubscriptionInfo> sil = mSubscriptionManager + .getActiveAndHiddenSubscriptionInfoList(); if (sil != null) { for (SubscriptionInfo subInfo : sil) { Log.v(TAG, "SubInfo:" + subInfo); @@ -425,10 +426,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) { List<SubscriptionInfo> sil = mSubscriptionInfo; if (sil == null || forceReload) { - sil = mSubscriptionManager.getActiveSubscriptionInfoList(false); + sil = mSubscriptionManager.getActiveAndHiddenSubscriptionInfoList(); } if (sil == null) { - // getActiveSubscriptionInfoList was null callers expect an empty list. + // getActiveAndHiddenSubscriptionInfoList was null callers expect an empty list. mSubscriptionInfo = new ArrayList<SubscriptionInfo>(); } else { mSubscriptionInfo = sil; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java index c243309d960a..581cf7a2fbef 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java @@ -86,6 +86,8 @@ public class WindowMagnificationController implements View.OnClickListener, private SurfaceView mMirrorSurfaceView; private View mControlsView; private View mOverlayView; + // The boundary of magnification frame. + private final Rect mMagnificationFrameBoundary = new Rect(); private MoveMirrorRunnable mMoveMirrorRunnable = new MoveMirrorRunnable(); @@ -93,7 +95,7 @@ public class WindowMagnificationController implements View.OnClickListener, mContext = context; mHandler = handler; Display display = mContext.getDisplay(); - display.getSize(mDisplaySize); + display.getRealSize(mDisplaySize); mDisplayId = mContext.getDisplayId(); mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); @@ -114,6 +116,7 @@ public class WindowMagnificationController implements View.OnClickListener, return; } setInitialStartBounds(); + setMagnificationFrameBoundary(); createOverlayWindow(); } @@ -330,7 +333,7 @@ public class WindowMagnificationController implements View.OnClickListener, @Override public void onClick(View v) { setMoveOffset(v, mMoveFrameAmountShort); - moveMirrorFromControls(); + moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y); } @Override @@ -370,10 +373,8 @@ public class WindowMagnificationController implements View.OnClickListener, case MotionEvent.ACTION_MOVE: int xDiff = (int) (event.getRawX() - mLastDrag.x); int yDiff = (int) (event.getRawY() - mLastDrag.y); - mMagnificationFrame.offset(xDiff, yDiff); + moveMirrorWindow(xDiff, yDiff); mLastDrag.set(event.getRawX(), event.getRawY()); - modifyWindowMagnification(mTransaction); - mTransaction.apply(); return true; } return false; @@ -393,11 +394,11 @@ public class WindowMagnificationController implements View.OnClickListener, } } - private void moveMirrorFromControls() { - mMagnificationFrame.offset(mMoveWindowOffset.x, mMoveWindowOffset.y); - - modifyWindowMagnification(mTransaction); - mTransaction.apply(); + private void moveMirrorWindow(int xOffset, int yOffset) { + if (updateMagnificationFramePosition(xOffset, yOffset)) { + modifyWindowMagnification(mTransaction); + mTransaction.apply(); + } } /** @@ -414,6 +415,52 @@ public class WindowMagnificationController implements View.OnClickListener, return new Rect(left, top, right, bottom); } + private void setMagnificationFrameBoundary() { + // Calculates width and height for magnification frame could exceed out the screen. + // TODO : re-calculating again when scale is changed. + // The half width of magnification frame. + final int halfWidth = mMagnificationFrame.width() / 2; + // The half height of magnification frame. + final int halfHeight = mMagnificationFrame.height() / 2; + // The scaled half width of magnified region. + final int scaledWidth = (int) (halfWidth / mScale); + // The scaled half height of magnified region. + final int scaledHeight = (int) (halfHeight / mScale); + final int exceededWidth = halfWidth - scaledWidth; + final int exceededHeight = halfHeight - scaledHeight; + + mMagnificationFrameBoundary.set(-exceededWidth, -exceededHeight, + mDisplaySize.x + exceededWidth, mDisplaySize.y + exceededHeight); + } + + /** + * Calculates and sets the real position of magnification frame based on the magnified region + * should be limited by the region of the display. + */ + private boolean updateMagnificationFramePosition(int xOffset, int yOffset) { + mTmpRect.set(mMagnificationFrame); + mTmpRect.offset(xOffset, yOffset); + + if (mTmpRect.left < mMagnificationFrameBoundary.left) { + mTmpRect.offsetTo(mMagnificationFrameBoundary.left, mTmpRect.top); + } else if (mTmpRect.right > mMagnificationFrameBoundary.right) { + final int leftOffset = mMagnificationFrameBoundary.right - mMagnificationFrame.width(); + mTmpRect.offsetTo(leftOffset, mTmpRect.top); + } + + if (mTmpRect.top < mMagnificationFrameBoundary.top) { + mTmpRect.offsetTo(mTmpRect.left, mMagnificationFrameBoundary.top); + } else if (mTmpRect.bottom > mMagnificationFrameBoundary.bottom) { + final int topOffset = mMagnificationFrameBoundary.bottom - mMagnificationFrame.height(); + mTmpRect.offsetTo(mTmpRect.left, topOffset); + } + + if (!mTmpRect.equals(mMagnificationFrame)) { + mMagnificationFrame.set(mTmpRect); + return true; + } + return false; + } @Override public void surfaceCreated(SurfaceHolder holder) { createMirror(); @@ -431,7 +478,7 @@ public class WindowMagnificationController implements View.OnClickListener, @Override public void run() { if (mIsPressedDown) { - moveMirrorFromControls(); + moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y); mHandler.postDelayed(mMoveMirrorRunnable, 100); } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java b/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java deleted file mode 100644 index d2fe39424875..000000000000 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeEvent.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.doze; - -import android.annotation.IntDef; - -import com.android.systemui.log.RichEvent; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * An event related to dozing. {@link DozeLog} stores and prints these events for debugging - * and triaging purposes. - */ -public class DozeEvent extends RichEvent { - /** - * Initializes a doze event - */ - public DozeEvent init(@EventType int type, String reason) { - super.init(DEBUG, type, reason); - return this; - } - - /** - * Event labels for each doze event - * Index corresponds to the integer associated with each {@link EventType} - */ - @Override - public String[] getEventLabels() { - final String[] events = new String[]{ - "PickupWakeup", - "PulseStart", - "PulseFinish", - "NotificationPulse", - "Dozing", - "Fling", - "EmergencyCall", - "KeyguardBouncerChanged", - "ScreenOn", - "ScreenOff", - "MissedTick", - "TimeTickScheduled", - "KeyguardVisibilityChanged", - "DozeStateChanged", - "WakeDisplay", - "ProximityResult", - "PulseDropped", - "PulseDisabledByProx", - "SensorTriggered" - }; - - if (events.length != TOTAL_EVENT_TYPES) { - throw new IllegalStateException("DozeEvent events.length should match TOTAL_EVENT_TYPES" - + " events.length=" + events.length - + " TOTAL_EVENT_LENGTH=" + TOTAL_EVENT_TYPES); - } - return events; - } - - /** - * Converts the reason (integer) to a user-readable string - */ - public static String reasonToString(@Reason int pulseReason) { - switch (pulseReason) { - case PULSE_REASON_INTENT: return "intent"; - case PULSE_REASON_NOTIFICATION: return "notification"; - case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion"; - case REASON_SENSOR_PICKUP: return "pickup"; - case REASON_SENSOR_DOUBLE_TAP: return "doubletap"; - case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress"; - case PULSE_REASON_DOCKING: return "docking"; - case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen"; - case REASON_SENSOR_WAKE_UP: return "wakeup"; - case REASON_SENSOR_TAP: return "tap"; - default: throw new IllegalArgumentException("invalid reason: " + pulseReason); - } - } - - @IntDef({PICKUP_WAKEUP, PULSE_START, PULSE_FINISH, NOTIFICATION_PULSE, DOZING, FLING, - EMERGENCY_CALL, KEYGUARD_BOUNCER_CHANGED, SCREEN_ON, SCREEN_OFF, MISSED_TICK, - TIME_TICK_SCHEDULED, KEYGUARD_VISIBILITY_CHANGE, DOZE_STATE_CHANGED, WAKE_DISPLAY, - PROXIMITY_RESULT, PULSE_DROPPED, PULSE_DISABLED_BY_PROX, SENSOR_TRIGGERED}) - /** - * Types of DozeEvents - */ - @Retention(RetentionPolicy.SOURCE) - public @interface EventType {} - public static final int PICKUP_WAKEUP = 0; - public static final int PULSE_START = 1; - public static final int PULSE_FINISH = 2; - public static final int NOTIFICATION_PULSE = 3; - public static final int DOZING = 4; - public static final int FLING = 5; - public static final int EMERGENCY_CALL = 6; - public static final int KEYGUARD_BOUNCER_CHANGED = 7; - public static final int SCREEN_ON = 8; - public static final int SCREEN_OFF = 9; - public static final int MISSED_TICK = 10; - public static final int TIME_TICK_SCHEDULED = 11; - public static final int KEYGUARD_VISIBILITY_CHANGE = 12; - public static final int DOZE_STATE_CHANGED = 13; - public static final int WAKE_DISPLAY = 14; - public static final int PROXIMITY_RESULT = 15; - public static final int PULSE_DROPPED = 16; - public static final int PULSE_DISABLED_BY_PROX = 17; - public static final int SENSOR_TRIGGERED = 18; - public static final int TOTAL_EVENT_TYPES = 19; - - public static final int TOTAL_REASONS = 10; - @IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION, - PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP, - PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP, - PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP}) - @Retention(RetentionPolicy.SOURCE) - public @interface Reason {} - public static final int PULSE_REASON_NONE = -1; - public static final int PULSE_REASON_INTENT = 0; - public static final int PULSE_REASON_NOTIFICATION = 1; - public static final int PULSE_REASON_SENSOR_SIGMOTION = 2; - public static final int REASON_SENSOR_PICKUP = 3; - public static final int REASON_SENSOR_DOUBLE_TAP = 4; - public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5; - public static final int PULSE_REASON_DOCKING = 6; - public static final int REASON_SENSOR_WAKE_UP = 7; - public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8; - public static final int REASON_SENSOR_TAP = 9; -} diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java index fe504216b166..8afdf1aeb023 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java @@ -16,15 +16,20 @@ package com.android.systemui.doze; +import android.annotation.IntDef; import android.util.TimeUtils; +import androidx.annotation.NonNull; + import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.DumpController; -import com.android.systemui.log.SysuiLog; +import com.android.systemui.Dumpable; +import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.Date; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import javax.inject.Inject; import javax.inject.Singleton; @@ -32,13 +37,11 @@ import javax.inject.Singleton; /** * Logs doze events for debugging and triaging purposes. Logs are dumped in bugreports or on demand: * adb shell dumpsys activity service com.android.systemui/.SystemUIService \ - * dependency DumpController DozeLog + * dependency DumpController DozeLog,DozeStats */ @Singleton -public class DozeLog extends SysuiLog<DozeEvent> { - private static final String TAG = "DozeLog"; - - private DozeEvent mRecycledEvent; +public class DozeLog implements Dumpable { + private final DozeLogger mLogger; private boolean mPulsing; private long mSince; @@ -51,8 +54,11 @@ public class DozeLog extends SysuiLog<DozeEvent> { private SummaryStats[][] mProxStats; // [reason][near/far] @Inject - public DozeLog(KeyguardUpdateMonitor keyguardUpdateMonitor, DumpController dumpController) { - super(dumpController, TAG, MAX_DOZE_DEBUG_LOGS, MAX_DOZE_LOGS); + public DozeLog( + KeyguardUpdateMonitor keyguardUpdateMonitor, + DumpController dumpController, + DozeLogger logger) { + mLogger = logger; mSince = System.currentTimeMillis(); mPickupPulseNearVibrationStats = new SummaryStats(); mPickupPulseNotNearVibrationStats = new SummaryStats(); @@ -60,8 +66,8 @@ public class DozeLog extends SysuiLog<DozeEvent> { mScreenOnPulsingStats = new SummaryStats(); mScreenOnNotPulsingStats = new SummaryStats(); mEmergencyCallStats = new SummaryStats(); - mProxStats = new SummaryStats[DozeEvent.TOTAL_REASONS][2]; - for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) { + mProxStats = new SummaryStats[TOTAL_REASONS][2]; + for (int i = 0; i < TOTAL_REASONS; i++) { mProxStats[i][0] = new SummaryStats(); mProxStats[i][1] = new SummaryStats(); } @@ -69,42 +75,42 @@ public class DozeLog extends SysuiLog<DozeEvent> { if (keyguardUpdateMonitor != null) { keyguardUpdateMonitor.registerCallback(mKeyguardCallback); } + + dumpController.registerDumpable("DumpStats", this); } /** * Appends pickup wakeup event to the logs */ public void tracePickupWakeUp(boolean withinVibrationThreshold) { - log(DozeEvent.PICKUP_WAKEUP, "withinVibrationThreshold=" + withinVibrationThreshold); - if (mEnabled) { - (withinVibrationThreshold ? mPickupPulseNearVibrationStats - : mPickupPulseNotNearVibrationStats).append(); - } + mLogger.logPickupWakeup(withinVibrationThreshold); + (withinVibrationThreshold ? mPickupPulseNearVibrationStats + : mPickupPulseNotNearVibrationStats).append(); } /** * Appends pulse started event to the logs. * @param reason why the pulse started */ - public void tracePulseStart(@DozeEvent.Reason int reason) { - log(DozeEvent.PULSE_START, DozeEvent.reasonToString(reason)); - if (mEnabled) mPulsing = true; + public void tracePulseStart(@Reason int reason) { + mLogger.logPulseStart(reason); + mPulsing = true; } /** * Appends pulse finished event to the logs */ public void tracePulseFinish() { - log(DozeEvent.PULSE_FINISH); - if (mEnabled) mPulsing = false; + mLogger.logPulseFinish(); + mPulsing = false; } /** * Appends pulse event to the logs */ public void traceNotificationPulse() { - log(DozeEvent.NOTIFICATION_PULSE); - if (mEnabled) mNotificationPulseStats.append(); + mLogger.logNotificationPulse(); + mNotificationPulseStats.append(); } /** @@ -112,8 +118,8 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param dozing true if dozing, else false */ public void traceDozing(boolean dozing) { - log(DozeEvent.DOZING, "dozing=" + dozing); - if (mEnabled) mPulsing = false; + mLogger.logDozing(dozing); + mPulsing = false; } /** @@ -121,18 +127,15 @@ public class DozeLog extends SysuiLog<DozeEvent> { */ public void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded, boolean screenOnFromTouch) { - log(DozeEvent.FLING, "expand=" + expand - + " aboveThreshold=" + aboveThreshold - + " thresholdNeeded=" + thresholdNeeded - + " screenOnFromTouch=" + screenOnFromTouch); + mLogger.logFling(expand, aboveThreshold, thresholdNeeded, screenOnFromTouch); } /** * Appends emergency call event to the logs */ public void traceEmergencyCall() { - log(DozeEvent.EMERGENCY_CALL); - if (mEnabled) mEmergencyCallStats.append(); + mLogger.logEmergencyCall(); + mEmergencyCallStats.append(); } /** @@ -140,18 +143,16 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param showing true if the keyguard bouncer is showing, else false */ public void traceKeyguardBouncerChanged(boolean showing) { - log(DozeEvent.KEYGUARD_BOUNCER_CHANGED, "showing=" + showing); + mLogger.logKeyguardBouncerChanged(showing); } /** * Appends screen-on event to the logs */ public void traceScreenOn() { - log(DozeEvent.SCREEN_ON, "pulsing=" + mPulsing); - if (mEnabled) { - (mPulsing ? mScreenOnPulsingStats : mScreenOnNotPulsingStats).append(); - mPulsing = false; - } + mLogger.logScreenOn(mPulsing); + (mPulsing ? mScreenOnPulsingStats : mScreenOnNotPulsingStats).append(); + mPulsing = false; } /** @@ -159,7 +160,7 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param why reason the screen is off */ public void traceScreenOff(int why) { - log(DozeEvent.SCREEN_OFF, "why=" + why); + mLogger.logScreenOff(why); } /** @@ -167,7 +168,7 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param delay of the missed tick */ public void traceMissedTick(String delay) { - log(DozeEvent.MISSED_TICK, "delay=" + delay); + mLogger.logMissedTick(delay); } /** @@ -176,9 +177,7 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param triggerAt time tick trigger at */ public void traceTimeTickScheduled(long when, long triggerAt) { - log(DozeEvent.TIME_TICK_SCHEDULED, - "scheduledAt=" + DATE_FORMAT.format(new Date(when)) - + " triggerAt=" + DATE_FORMAT.format(new Date(triggerAt))); + mLogger.logTimeTickScheduled(when, triggerAt); } /** @@ -186,8 +185,8 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param showing whether the keyguard is now showing */ public void traceKeyguard(boolean showing) { - log(DozeEvent.KEYGUARD_VISIBILITY_CHANGE, "showing=" + showing); - if (mEnabled && !showing) mPulsing = false; + mLogger.logKeyguardVisibilityChange(showing); + if (!showing) mPulsing = false; } /** @@ -195,7 +194,7 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param state new DozeMachine state */ public void traceState(DozeMachine.State state) { - log(DozeEvent.DOZE_STATE_CHANGED, state.name()); + mLogger.logDozeStateChanged(state); } /** @@ -203,31 +202,22 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param wake if we're waking up or sleeping. */ public void traceWakeDisplay(boolean wake) { - log(DozeEvent.WAKE_DISPLAY, "wake=" + wake); + mLogger.logWakeDisplay(wake); } /** * Appends proximity result event to the logs * @param near true if near, else false - * @param millis * @param reason why proximity result was triggered */ - public void traceProximityResult(boolean near, long millis, @DozeEvent.Reason int reason) { - log(DozeEvent.PROXIMITY_RESULT, - " reason=" + DozeEvent.reasonToString(reason) - + " near=" + near - + " millis=" + millis); - if (mEnabled) mProxStats[reason][near ? 0 : 1].append(); + public void traceProximityResult(boolean near, long millis, @Reason int reason) { + mLogger.logProximityResult(near, millis, reason); + mProxStats[reason][near ? 0 : 1].append(); } - /** - * Prints doze log timeline and consolidated stats - * @param pw - */ - public void dump(PrintWriter pw) { + @Override + public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { synchronized (DozeLog.class) { - super.dump(null, pw, null); // prints timeline - pw.print(" Doze summary stats (for "); TimeUtils.formatDuration(System.currentTimeMillis() - mSince, pw); pw.println("):"); @@ -237,32 +227,19 @@ public class DozeLog extends SysuiLog<DozeEvent> { mScreenOnPulsingStats.dump(pw, "Screen on (pulsing)"); mScreenOnNotPulsingStats.dump(pw, "Screen on (not pulsing)"); mEmergencyCallStats.dump(pw, "Emergency call"); - for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) { - final String reason = DozeEvent.reasonToString(i); + for (int i = 0; i < TOTAL_REASONS; i++) { + final String reason = reasonToString(i); mProxStats[i][0].dump(pw, "Proximity near (" + reason + ")"); mProxStats[i][1].dump(pw, "Proximity far (" + reason + ")"); } } } - private void log(@DozeEvent.EventType int eventType) { - log(eventType, ""); - } - - private void log(@DozeEvent.EventType int eventType, String msg) { - if (mRecycledEvent != null) { - mRecycledEvent = log(mRecycledEvent.init(eventType, msg)); - } else { - mRecycledEvent = log(new DozeEvent().init(eventType, msg)); - } - } - /** * Appends pulse dropped event to logs */ public void tracePulseDropped(boolean pulsePending, DozeMachine.State state, boolean blocked) { - log(DozeEvent.PULSE_DROPPED, "pulsePending=" + pulsePending + " state=" - + state.name() + " blocked=" + blocked); + mLogger.logPulseDropped(pulsePending, state, blocked); } /** @@ -270,7 +247,7 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param reason why the pulse was dropped */ public void tracePulseDropped(String reason) { - log(DozeEvent.PULSE_DROPPED, "why=" + reason); + mLogger.logPulseDropped(reason); } /** @@ -278,15 +255,15 @@ public class DozeLog extends SysuiLog<DozeEvent> { * @param disabled */ public void tracePulseTouchDisabledByProx(boolean disabled) { - log(DozeEvent.PULSE_DISABLED_BY_PROX, "disabled=" + disabled); + mLogger.logPulseTouchDisabledByProx(disabled); } /** * Appends sensor triggered event to logs * @param reason why the sensor was triggered */ - public void traceSensor(@DozeEvent.Reason int reason) { - log(DozeEvent.SENSOR_TRIGGERED, "type=" + DozeEvent.reasonToString(reason)); + public void traceSensor(@Reason int reason) { + mLogger.logSensorTriggered(reason); } private class SummaryStats { @@ -339,6 +316,42 @@ public class DozeLog extends SysuiLog<DozeEvent> { } }; - private static final int MAX_DOZE_DEBUG_LOGS = 400; - private static final int MAX_DOZE_LOGS = 50; + /** + * Converts the reason (integer) to a user-readable string + */ + public static String reasonToString(@Reason int pulseReason) { + switch (pulseReason) { + case PULSE_REASON_INTENT: return "intent"; + case PULSE_REASON_NOTIFICATION: return "notification"; + case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion"; + case REASON_SENSOR_PICKUP: return "pickup"; + case REASON_SENSOR_DOUBLE_TAP: return "doubletap"; + case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress"; + case PULSE_REASON_DOCKING: return "docking"; + case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen"; + case REASON_SENSOR_WAKE_UP: return "wakeup"; + case REASON_SENSOR_TAP: return "tap"; + default: throw new IllegalArgumentException("invalid reason: " + pulseReason); + } + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION, + PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP, + PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP, + PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP}) + public @interface Reason {} + public static final int PULSE_REASON_NONE = -1; + public static final int PULSE_REASON_INTENT = 0; + public static final int PULSE_REASON_NOTIFICATION = 1; + public static final int PULSE_REASON_SENSOR_SIGMOTION = 2; + public static final int REASON_SENSOR_PICKUP = 3; + public static final int REASON_SENSOR_DOUBLE_TAP = 4; + public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5; + public static final int PULSE_REASON_DOCKING = 6; + public static final int REASON_SENSOR_WAKE_UP = 7; + public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8; + public static final int REASON_SENSOR_TAP = 9; + + public static final int TOTAL_REASONS = 10; } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt new file mode 100644 index 000000000000..42decd592071 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.doze + +import com.android.systemui.doze.DozeLog.Reason +import com.android.systemui.doze.DozeLog.reasonToString +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.LogLevel.DEBUG +import com.android.systemui.log.LogLevel.ERROR +import com.android.systemui.log.LogLevel.INFO +import com.android.systemui.log.dagger.DozeLog +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale +import javax.inject.Inject + +/** Interface for logging messages to the [DozeLog]. */ +class DozeLogger @Inject constructor( + @DozeLog private val buffer: LogBuffer +) { + fun logPickupWakeup(isWithinVibrationThreshold: Boolean) { + buffer.log(TAG, DEBUG, { + bool1 = isWithinVibrationThreshold + }, { + "PickupWakeup withinVibrationThreshold=$bool1" + }) + } + + fun logPulseStart(@Reason reason: Int) { + buffer.log(TAG, INFO, { + int1 = reason + }, { + "Pulse start, reason=${reasonToString(int1)}" + }) + } + + fun logPulseFinish() { + buffer.log(TAG, INFO, {}, { "Pulse finish" }) + } + + fun logNotificationPulse() { + buffer.log(TAG, INFO, {}, { "Notification pulse" }) + } + + fun logDozing(isDozing: Boolean) { + buffer.log(TAG, INFO, { + bool1 = isDozing + }, { + "Dozing=$bool1" + }) + } + + fun logFling( + expand: Boolean, + aboveThreshold: Boolean, + thresholdNeeded: Boolean, + screenOnFromTouch: Boolean + ) { + buffer.log(TAG, DEBUG, { + bool1 = expand + bool2 = aboveThreshold + bool3 = thresholdNeeded + bool4 = screenOnFromTouch + }, { + "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " + + "screenOnFromTouch=$bool4" + }) + } + + fun logEmergencyCall() { + buffer.log(TAG, INFO, {}, { "Emergency call" }) + } + + fun logKeyguardBouncerChanged(isShowing: Boolean) { + buffer.log(TAG, INFO, { + bool1 = isShowing + }, { + "Keyguard bouncer changed, showing=$bool1" + }) + } + + fun logScreenOn(isPulsing: Boolean) { + buffer.log(TAG, INFO, { + bool1 = isPulsing + }, { + "Screen on, pulsing=$bool1" + }) + } + + fun logScreenOff(why: Int) { + buffer.log(TAG, INFO, { + int1 = why + }, { + "Screen off, why=$int1" + }) + } + + fun logMissedTick(delay: String) { + buffer.log(TAG, ERROR, { + str1 = delay + }, { + "Missed AOD time tick by $str1" + }) + } + + fun logTimeTickScheduled(whenAt: Long, triggerAt: Long) { + buffer.log(TAG, DEBUG, { + long1 = whenAt + long2 = triggerAt + }, { + "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " + + "triggerAt=${DATE_FORMAT.format(Date(long2))}" + }) + } + + fun logKeyguardVisibilityChange(isShowing: Boolean) { + buffer.log(TAG, INFO, { + bool1 = isShowing + }, { + "Keyguard visibility change, isShowing=$bool1" + }) + } + + fun logDozeStateChanged(state: DozeMachine.State) { + buffer.log(TAG, INFO, { + str1 = state.name + }, { + "Doze state changed to $str1" + }) + } + + fun logWakeDisplay(isAwake: Boolean) { + buffer.log(TAG, DEBUG, { + bool1 = isAwake + }, { + "Display wakefulness changed, isAwake=$bool1" + }) + } + + fun logProximityResult(isNear: Boolean, millis: Long, @Reason reason: Int) { + buffer.log(TAG, DEBUG, { + bool1 = isNear + long1 = millis + int1 = reason + }, { + "Proximity result reason=${reasonToString(int1)} near=$bool1 millis=$long1" + }) + } + + fun logPulseDropped(pulsePending: Boolean, state: DozeMachine.State, blocked: Boolean) { + buffer.log(TAG, INFO, { + bool1 = pulsePending + str1 = state.name + bool2 = blocked + }, { + "Pulse dropped, pulsePending=$bool1 state=$str1 blocked=$bool2" + }) + } + + fun logPulseDropped(reason: String) { + buffer.log(TAG, INFO, { + str1 = reason + }, { + "Pulse dropped, why=$str1" + }) + } + + fun logPulseTouchDisabledByProx(disabled: Boolean) { + buffer.log(TAG, DEBUG, { + bool1 = disabled + }, { + "Pulse touch modified by prox, disabled=$bool1" + }) + } + + fun logSensorTriggered(@Reason reason: Int) { + buffer.log(TAG, DEBUG, { + int1 = reason + }, { + "Sensor triggered, type=${reasonToString(int1)}" + }) + } +} + +private const val TAG = "DozeLog" + +val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.S", Locale.US) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index 40603ab24c1e..03c25eee4f6f 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -169,7 +169,7 @@ public class DozeMachine { @MainThread public void requestState(State requestedState) { Preconditions.checkArgument(requestedState != State.DOZE_REQUEST_PULSE); - requestState(requestedState, DozeEvent.PULSE_REASON_NONE); + requestState(requestedState, DozeLog.PULSE_REASON_NONE); } @MainThread @@ -271,7 +271,7 @@ public class DozeMachine { if (newState == State.DOZE_REQUEST_PULSE) { mPulseReason = pulseReason; } else if (oldState == State.DOZE_PULSE_DONE) { - mPulseReason = DozeEvent.PULSE_REASON_NONE; + mPulseReason = DozeLog.PULSE_REASON_NONE; } } @@ -368,7 +368,7 @@ public class DozeMachine { nextState = State.DOZE; } - transitionTo(nextState, DozeEvent.PULSE_REASON_NONE); + transitionTo(nextState, DozeLog.PULSE_REASON_NONE); break; default: break; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index d008e665d171..44e5d3de5ca7 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -97,14 +97,14 @@ public class DozeSensors { mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION), null /* setting */, dozeParameters.getPulseOnSigMotion(), - DozeEvent.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */, + DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */, false /* touchscreen */, dozeLog), mPickupSensor = new TriggerSensor( mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE), Settings.Secure.DOZE_PICK_UP_GESTURE, true /* settingDef */, config.dozePickupSensorAvailable(), - DozeEvent.REASON_SENSOR_PICKUP, false /* touchCoords */, + DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */, false /* touchscreen */, false /* ignoresSetting */, dozeLog), @@ -112,7 +112,7 @@ public class DozeSensors { findSensorWithType(config.doubleTapSensorType()), Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, true /* configured */, - DozeEvent.REASON_SENSOR_DOUBLE_TAP, + DozeLog.REASON_SENSOR_DOUBLE_TAP, dozeParameters.doubleTapReportsTouchCoordinates(), true /* touchscreen */, dozeLog), @@ -120,7 +120,7 @@ public class DozeSensors { findSensorWithType(config.tapSensorType()), Settings.Secure.DOZE_TAP_SCREEN_GESTURE, true /* configured */, - DozeEvent.REASON_SENSOR_TAP, + DozeLog.REASON_SENSOR_TAP, false /* reports touch coordinates */, true /* touchscreen */, dozeLog), @@ -129,7 +129,7 @@ public class DozeSensors { Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, false /* settingDef */, true /* configured */, - DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS, + DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, true /* reports touch coordinates */, true /* touchscreen */, dozeLog), @@ -137,7 +137,7 @@ public class DozeSensors { new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY), Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE, mConfig.wakeScreenGestureAvailable() && alwaysOn, - DozeEvent.REASON_SENSOR_WAKE_UP, + DozeLog.REASON_SENSOR_WAKE_UP, false /* reports touch coordinates */, false /* touchscreen */, dozeLog), @@ -145,7 +145,7 @@ public class DozeSensors { new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN), Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, mConfig.wakeScreenGestureAvailable(), - DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, + DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, false /* reports touch coordinates */, false /* touchscreen */, mConfig.getWakeLockScreenDebounce(), @@ -525,7 +525,7 @@ public class DozeSensors { /** * Called when a sensor requests a pulse - * @param pulseReason Requesting sensor, e.g. {@link DozeEvent#REASON_SENSOR_PICKUP} + * @param pulseReason Requesting sensor, e.g. {@link DozeLog#REASON_SENSOR_PICKUP} * @param screenX the location on the screen where the sensor fired or -1 * if the sensor doesn't support reporting screen locations. * @param screenY the location on the screen where the sensor fired or -1 diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 722dc038f853..b9c056df89a1 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -127,7 +127,7 @@ public class DozeTriggers implements DozeMachine.Part { mDozeLog.tracePulseDropped("pulseOnNotificationsDisabled"); return; } - requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */, + requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */, onPulseSuppressedListener); mDozeLog.traceNotificationPulse(); } @@ -163,12 +163,12 @@ public class DozeTriggers implements DozeMachine.Part { @VisibleForTesting void onSensor(int pulseReason, float screenX, float screenY, float[] rawValues) { - boolean isDoubleTap = pulseReason == DozeEvent.REASON_SENSOR_DOUBLE_TAP; - boolean isTap = pulseReason == DozeEvent.REASON_SENSOR_TAP; - boolean isPickup = pulseReason == DozeEvent.REASON_SENSOR_PICKUP; - boolean isLongPress = pulseReason == DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS; - boolean isWakeDisplay = pulseReason == DozeEvent.REASON_SENSOR_WAKE_UP; - boolean isWakeLockScreen = pulseReason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN; + boolean isDoubleTap = pulseReason == DozeLog.REASON_SENSOR_DOUBLE_TAP; + boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP; + boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP; + boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS; + boolean isWakeDisplay = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP; + boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN; boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0; if (isWakeDisplay) { @@ -281,9 +281,9 @@ public class DozeTriggers implements DozeMachine.Part { // Logs AOD open due to sensor wake up. mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING) .setType(MetricsEvent.TYPE_OPEN) - .setSubtype(DozeEvent.REASON_SENSOR_WAKE_UP)); + .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP)); } - }, true /* alreadyPerformedProxCheck */, DozeEvent.REASON_SENSOR_WAKE_UP); + }, true /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP); } else { boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); @@ -292,7 +292,7 @@ public class DozeTriggers implements DozeMachine.Part { // Logs AOD close due to sensor wake up. mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING) .setType(MetricsEvent.TYPE_CLOSE) - .setSubtype(DozeEvent.REASON_SENSOR_WAKE_UP)); + .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP)); } } } @@ -361,7 +361,7 @@ public class DozeTriggers implements DozeMachine.Part { // When already pulsing we're allowed to show the wallpaper directly without // requesting a new pulse. if (mMachine.getState() == DozeMachine.State.DOZE_PULSING - && reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { + && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT); return; } @@ -426,7 +426,7 @@ public class DozeTriggers implements DozeMachine.Part { public void onReceive(Context context, Intent intent) { if (PULSE_ACTION.equals(intent.getAction())) { if (DozeMachine.DEBUG) Log.d(TAG, "Received pulse intent"); - requestPulse(DozeEvent.PULSE_REASON_INTENT, false, /* performedProxCheck */ + requestPulse(DozeLog.PULSE_REASON_INTENT, false, /* performedProxCheck */ null /* onPulseSupressedListener */); } if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) { diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index a6aa90916c25..1c056215f1cb 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -100,7 +100,7 @@ public class DozeUi implements DozeMachine.Part { public void onPulseStarted() { try { mMachine.requestState( - reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN + reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN ? DozeMachine.State.DOZE_PULSING_BRIGHT : DozeMachine.State.DOZE_PULSING); } catch (IllegalStateException e) { diff --git a/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt b/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt index d971ac58fb0b..2a0a2aa6fb38 100644 --- a/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt +++ b/packages/SystemUI/src/com/android/systemui/log/LogMessage.kt @@ -43,5 +43,10 @@ interface LogMessage { var int1: Int var int2: Int var long1: Long + var long2: Long var double1: Double + var bool1: Boolean + var bool2: Boolean + var bool3: Boolean + var bool4: Boolean } diff --git a/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt b/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt index 32334bc382e1..d33ac4b4a80b 100644 --- a/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt @@ -30,7 +30,12 @@ data class LogMessageImpl( override var int1: Int, override var int2: Int, override var long1: Long, - override var double1: Double + override var long2: Long, + override var double1: Double, + override var bool1: Boolean, + override var bool2: Boolean, + override var bool3: Boolean, + override var bool4: Boolean ) : LogMessage { fun reset( @@ -49,7 +54,12 @@ data class LogMessageImpl( int1 = 0 int2 = 0 long1 = 0 + long2 = 0 double1 = 0.0 + bool1 = false + bool2 = false + bool3 = false + bool4 = false } companion object Factory { @@ -65,7 +75,12 @@ data class LogMessageImpl( 0, 0, 0, - 0.0) + 0, + 0.0, + false, + false, + false, + false) } } } diff --git a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java index 4e15668f6a34..9ee3e6765e4a 100644 --- a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java +++ b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java @@ -48,7 +48,7 @@ import java.util.Locale; */ public class SysuiLog<E extends Event> implements Dumpable { public static final SimpleDateFormat DATE_FORMAT = - new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US); + new SimpleDateFormat("MM-dd HH:mm:ss.S", Locale.US); protected final Object mDataLock = new Object(); private final String mId; diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index b1990beb9f57..e119beff3c6f 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -42,7 +42,7 @@ public class LogModule { @Singleton @DozeLog public static LogBuffer provideDozeLogBuffer( - LogcatEchoTrackerDebug bufferFilter, + LogcatEchoTracker bufferFilter, DumpController dumpController) { LogBuffer buffer = new LogBuffer("DozeLog", 100, 10, bufferFilter); buffer.attach(dumpController); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 35b8312ba25c..0fd74547334b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -31,7 +31,6 @@ import android.metrics.LogMaker; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.service.quicksettings.Tile; import android.util.AttributeSet; @@ -62,7 +61,6 @@ import com.android.systemui.qs.external.CustomTile; import com.android.systemui.settings.BrightnessController; import com.android.systemui.settings.ToggleSliderView; import com.android.systemui.shared.plugins.PluginManager; -import com.android.systemui.statusbar.phone.NPVPluginManager; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener; import com.android.systemui.tuner.TunerService; @@ -120,7 +118,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne private FrameLayout mPluginFrame; private final PluginManager mPluginManager; - private NPVPluginManager mNPVPluginManager; private final LocalMediaManager.DeviceCallback mDeviceCallback = new LocalMediaManager.DeviceCallback() { @@ -201,14 +198,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne findViewById(R.id.brightness_slider), broadcastDispatcher); mDumpController = dumpController; mPluginManager = pluginManager; - if (mPluginManager != null && Settings.System.getInt( - mContext.getContentResolver(), "npv_plugin_flag", 0) == 2) { - mPluginFrame = (FrameLayout) LayoutInflater.from(mContext).inflate( - R.layout.status_bar_expanded_plugin_frame, this, false); - addView(mPluginFrame); - mNPVPluginManager = new NPVPluginManager(mPluginFrame, mPluginManager); - } - } /** @@ -556,7 +545,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne if (mListening) { refreshAllTiles(); } - if (mNPVPluginManager != null) mNPVPluginManager.setListening(listening); } public void setListening(boolean listening, boolean expanded) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java index 557c64b7dfb9..411980b399bd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -191,7 +191,6 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener mTile.setLabel(tile.getLabel()); mTile.setSubtitle(tile.getSubtitle()); mTile.setContentDescription(tile.getContentDescription()); - mTile.setStateDescription(tile.getStateDescription()); mTile.setState(tile.getState()); } @@ -346,12 +345,6 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener state.contentDescription = state.label; } - if (mTile.getStateDescription() != null) { - state.stateDescription = mTile.getStateDescription(); - } else { - state.stateDescription = null; - } - if (state instanceof BooleanState) { state.expandedAccessibilityClassName = Switch.class.getName(); ((BooleanState) state).value = (state.state == Tile.STATE_ACTIVE); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java index 2b53727f237e..554672d88052 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java @@ -16,7 +16,6 @@ package com.android.systemui.qs.tileimpl; import android.content.Context; import android.os.Build; -import android.provider.Settings; import android.util.Log; import android.view.ContextThemeWrapper; @@ -33,7 +32,6 @@ import com.android.systemui.qs.tiles.BluetoothTile; import com.android.systemui.qs.tiles.CastTile; import com.android.systemui.qs.tiles.CellularTile; import com.android.systemui.qs.tiles.ColorInversionTile; -import com.android.systemui.qs.tiles.ControlsTile; import com.android.systemui.qs.tiles.DataSaverTile; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.FlashlightTile; @@ -60,7 +58,6 @@ public class QSFactoryImpl implements QSFactory { private final Provider<WifiTile> mWifiTileProvider; private final Provider<BluetoothTile> mBluetoothTileProvider; - private final Provider<ControlsTile> mControlsTileProvider; private final Provider<CellularTile> mCellularTileProvider; private final Provider<DndTile> mDndTileProvider; private final Provider<ColorInversionTile> mColorInversionTileProvider; @@ -85,7 +82,6 @@ public class QSFactoryImpl implements QSFactory { @Inject public QSFactoryImpl(Provider<WifiTile> wifiTileProvider, Provider<BluetoothTile> bluetoothTileProvider, - Provider<ControlsTile> controlsTileProvider, Provider<CellularTile> cellularTileProvider, Provider<DndTile> dndTileProvider, Provider<ColorInversionTile> colorInversionTileProvider, @@ -106,7 +102,6 @@ public class QSFactoryImpl implements QSFactory { Provider<ScreenRecordTile> screenRecordTileProvider) { mWifiTileProvider = wifiTileProvider; mBluetoothTileProvider = bluetoothTileProvider; - mControlsTileProvider = controlsTileProvider; mCellularTileProvider = cellularTileProvider; mDndTileProvider = dndTileProvider; mColorInversionTileProvider = colorInversionTileProvider; @@ -146,11 +141,6 @@ public class QSFactoryImpl implements QSFactory { return mWifiTileProvider.get(); case "bt": return mBluetoothTileProvider.get(); - case "controls": - if (Settings.System.getInt(mHost.getContext().getContentResolver(), - "npv_plugin_flag", 0) == 3) { - return mControlsTileProvider.get(); - } else return null; case "cell": return mCellularTileProvider.get(); case "dnd": diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java index fda9e5b1f1ef..8b7f280608a5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java @@ -65,6 +65,7 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView { private String mAccessibilityClass; private boolean mTileState; private boolean mCollapsedView; + private boolean mClicked; private boolean mShowRippleEffect = true; private final ImageView mBg; @@ -233,35 +234,13 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView { setLongClickable(state.handlesLongClick); mIcon.setIcon(state, allowAnimations); setContentDescription(state.contentDescription); - final StringBuilder stateDescription = new StringBuilder(); - switch (state.state) { - case Tile.STATE_UNAVAILABLE: - stateDescription.append(mContext.getString(R.string.tile_unavailable)); - break; - case Tile.STATE_INACTIVE: - if (state instanceof QSTile.BooleanState) { - stateDescription.append(mContext.getString(R.string.switch_bar_off)); - } - break; - case Tile.STATE_ACTIVE: - if (state instanceof QSTile.BooleanState) { - stateDescription.append(mContext.getString(R.string.switch_bar_on)); - } - break; - default: - break; - } - if (!TextUtils.isEmpty(state.stateDescription)) { - stateDescription.append(", "); - stateDescription.append(state.stateDescription); - } - setStateDescription(stateDescription.toString()); mAccessibilityClass = state.state == Tile.STATE_UNAVAILABLE ? null : state.expandedAccessibilityClassName; if (state instanceof QSTile.BooleanState) { boolean newState = ((BooleanState) state).value; if (mTileState != newState) { + mClicked = false; mTileState = newState; } } @@ -318,10 +297,23 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView { } @Override + public boolean performClick() { + mClicked = true; + return super.performClick(); + } + + @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); if (!TextUtils.isEmpty(mAccessibilityClass)) { event.setClassName(mAccessibilityClass); + if (Switch.class.getName().equals(mAccessibilityClass)) { + boolean b = mClicked ? !mTileState : mTileState; + String label = getResources() + .getString(b ? R.string.switch_bar_on : R.string.switch_bar_off); + event.setContentDescription(label); + event.setChecked(b); + } } } @@ -333,6 +325,11 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView { if (!TextUtils.isEmpty(mAccessibilityClass)) { info.setClassName(mAccessibilityClass); if (Switch.class.getName().equals(mAccessibilityClass)) { + boolean b = mClicked ? !mTileState : mTileState; + String label = getResources() + .getString(b ? R.string.switch_bar_on : R.string.switch_bar_off); + info.setText(label); + info.setChecked(b); info.setCheckable(true); if (isLongClickable()) { info.addAction( diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 361b6c1b1260..9282a2e3b312 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -134,27 +134,25 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { state.label = mContext.getString(R.string.quick_settings_bluetooth_label); state.secondaryLabel = TextUtils.emptyIfNull( getSecondaryLabel(enabled, connecting, connected, state.isTransient)); - state.contentDescription = state.label; - state.stateDescription = ""; if (enabled) { if (connected) { state.icon = new BluetoothConnectedTileIcon(); if (!TextUtils.isEmpty(mController.getConnectedDeviceName())) { state.label = mController.getConnectedDeviceName(); } - state.stateDescription = + state.contentDescription = mContext.getString(R.string.accessibility_bluetooth_name, state.label) + ", " + state.secondaryLabel; } else if (state.isTransient) { state.icon = ResourceIcon.get( com.android.internal.R.drawable.ic_bluetooth_transient_animation); - state.stateDescription = state.secondaryLabel; + state.contentDescription = state.secondaryLabel; } else { state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth); state.contentDescription = mContext.getString( - R.string.accessibility_quick_settings_bluetooth); - state.stateDescription = mContext.getString(R.string.accessibility_not_connected); + R.string.accessibility_quick_settings_bluetooth) + "," + + mContext.getString(R.string.accessibility_not_connected); } state.state = Tile.STATE_ACTIVE; } else { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 58de0575fa75..32b051e35604 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -183,7 +183,6 @@ public class CastTile extends QSTileImpl<BooleanState> { protected void handleUpdateState(BooleanState state, Object arg) { state.label = mContext.getString(R.string.quick_settings_cast_title); state.contentDescription = state.label; - state.stateDescription = ""; state.value = false; final List<CastDevice> devices = mController.getCastDevices(); boolean connecting = false; @@ -193,9 +192,8 @@ public class CastTile extends QSTileImpl<BooleanState> { if (device.state == CastDevice.STATE_CONNECTED) { state.value = true; state.secondaryLabel = getDeviceName(device); - state.stateDescription = state.stateDescription + "," - + mContext.getString( - R.string.accessibility_cast_name, state.label); + state.contentDescription = state.contentDescription + "," + + mContext.getString(R.string.accessibility_cast_name, state.label); connecting = false; break; } else if (device.state == CastDevice.STATE_CONNECTING) { @@ -219,8 +217,9 @@ public class CastTile extends QSTileImpl<BooleanState> { state.state = Tile.STATE_UNAVAILABLE; String noWifi = mContext.getString(R.string.quick_settings_cast_no_wifi); state.secondaryLabel = noWifi; + state.contentDescription = state.contentDescription + ", " + mContext.getString( + R.string.accessibility_quick_settings_not_available, noWifi); } - state.stateDescription = state.stateDescription + ", " + state.secondaryLabel; mDetailAdapter.updateItems(devices); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index d5f86c951407..22470c7f5af5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -194,13 +194,17 @@ public class CellularTile extends QSTileImpl<SignalState> { state.secondaryLabel = r.getString(R.string.cell_data_off); } - state.contentDescription = state.label; + + // TODO(b/77881974): Instead of switching out the description via a string check for + // we need to have two strings provided by the MobileIconGroup. + final CharSequence contentDescriptionSuffix; if (state.state == Tile.STATE_INACTIVE) { - // This information is appended later by converting the Tile.STATE_INACTIVE state. - state.stateDescription = ""; + contentDescriptionSuffix = r.getString(R.string.cell_data_off_content_description); } else { - state.stateDescription = state.secondaryLabel; + contentDescriptionSuffix = state.secondaryLabel; } + + state.contentDescription = state.label + ", " + contentDescriptionSuffix; } private CharSequence appendMobileDataType(CharSequence current, CharSequence dataType) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java deleted file mode 100644 index 39ae66e7607a..000000000000 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ControlsTile.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.qs.tiles; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; - -import com.android.systemui.R; -import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.plugins.NPVPlugin; -import com.android.systemui.plugins.PluginListener; -import com.android.systemui.plugins.qs.DetailAdapter; -import com.android.systemui.plugins.qs.QSTile.BooleanState; -import com.android.systemui.qs.QSHost; -import com.android.systemui.qs.tileimpl.QSTileImpl; -import com.android.systemui.shared.plugins.PluginManager; - -import javax.inject.Inject; - - -/** - * Temporary control test for prototyping - */ -public class ControlsTile extends QSTileImpl<BooleanState> { - private ControlsDetailAdapter mDetailAdapter; - private final ActivityStarter mActivityStarter; - private PluginManager mPluginManager; - private NPVPlugin mPlugin; - private Intent mHomeAppIntent; - - @Inject - public ControlsTile(QSHost host, - ActivityStarter activityStarter, - PluginManager pluginManager) { - super(host); - mActivityStarter = activityStarter; - mPluginManager = pluginManager; - mDetailAdapter = (ControlsDetailAdapter) createDetailAdapter(); - - mHomeAppIntent = new Intent(Intent.ACTION_VIEW); - mHomeAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mHomeAppIntent.setComponent(new ComponentName("com.google.android.apps.chromecast.app", - "com.google.android.apps.chromecast.app.DiscoveryActivity")); - } - - @Override - public DetailAdapter getDetailAdapter() { - return mDetailAdapter; - } - - @Override - public BooleanState newTileState() { - return new BooleanState(); - } - - @Override - public void handleSetListening(boolean listening) { - - } - - @Override - public void setDetailListening(boolean listening) { - if (mPlugin == null) return; - - mPlugin.setListening(listening); - } - - @Override - protected void handleClick() { - showDetail(true); - } - - @Override - public Intent getLongClickIntent() { - return mHomeAppIntent; - } - - @Override - protected void handleSecondaryClick() { - showDetail(true); - } - - @Override - public CharSequence getTileLabel() { - return "Controls"; - } - - @Override - protected void handleUpdateState(BooleanState state, Object arg) { - state.icon = ResourceIcon.get(R.drawable.ic_lightbulb_outline_gm2_24px); - state.label = "Controls"; - } - - @Override - public boolean supportsDetailView() { - return getDetailAdapter() != null && mQSSettingsPanelOption == QSSettingsPanel.OPEN_CLICK; - } - - @Override - public int getMetricsCategory() { - return -1; - } - - @Override - protected String composeChangeAnnouncement() { - if (mState.value) { - return "On"; - } else { - return "Off"; - } - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - protected DetailAdapter createDetailAdapter() { - mDetailAdapter = new ControlsDetailAdapter(); - return mDetailAdapter; - } - - private class ControlsDetailAdapter implements DetailAdapter { - private View mDetailView; - protected FrameLayout mHomeControlsLayout; - - public CharSequence getTitle() { - return "Controls"; - } - - public Boolean getToggleState() { - return null; - } - - public boolean getToggleEnabled() { - return false; - } - - public View createDetailView(Context context, View convertView, final ViewGroup parent) { - if (convertView != null) return convertView; - - mHomeControlsLayout = (FrameLayout) LayoutInflater.from(context).inflate( - R.layout.home_controls, parent, false); - mHomeControlsLayout.setVisibility(View.VISIBLE); - parent.addView(mHomeControlsLayout); - - mPluginManager.addPluginListener( - new PluginListener<NPVPlugin>() { - @Override - public void onPluginConnected(NPVPlugin plugin, - Context pluginContext) { - mPlugin = plugin; - mPlugin.attachToRoot(mHomeControlsLayout); - mPlugin.setListening(true); - } - - @Override - public void onPluginDisconnected(NPVPlugin plugin) { - mPlugin.setListening(false); - mHomeControlsLayout.removeAllViews(); - - } - }, NPVPlugin.class, false); - return mHomeControlsLayout; - } - - public Intent getSettingsIntent() { - return mHomeAppIntent; - } - - public void setToggleState(boolean state) { - - } - - public int getMetricsCategory() { - return -1; - } - - public boolean hasHeader() { - return false; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 9215da4cda9a..52d1a5b3b991 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -240,8 +240,6 @@ public class DndTile extends QSTileImpl<BooleanState> { zen != Global.ZEN_MODE_OFF, mController.getConfig(), false)); state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_dnd); checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME); - // Keeping the secondaryLabel in contentDescription instead of stateDescription is easier - // to understand. switch (zen) { case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: state.contentDescription = diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 792c36477962..dafdd89ee62c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -102,13 +102,14 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements } state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label); state.secondaryLabel = ""; - state.stateDescription = ""; if (!mFlashlightController.isAvailable()) { state.icon = mIcon; state.slash.isSlashed = true; state.secondaryLabel = mContext.getString( R.string.quick_settings_flashlight_camera_in_use); - state.stateDescription = state.secondaryLabel; + state.contentDescription = mContext.getString( + R.string.accessibility_quick_settings_flashlight_unavailable) + + ", " + state.secondaryLabel; state.state = Tile.STATE_UNAVAILABLE; return; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index fd6b936d71c0..001e09406e3a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -147,7 +147,6 @@ public class HotspotTile extends QSTileImpl<BooleanState> { state.secondaryLabel = getSecondaryLabel( isTileActive, isTransient, isDataSaverEnabled, numConnectedDevices); - state.stateDescription = state.secondaryLabel; } @Nullable diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index e617867eb10e..fbdca3ba1c7b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -105,8 +105,15 @@ public class LocationTile extends QSTileImpl<BooleanState> { } state.icon = mIcon; state.slash.isSlashed = !state.value; - state.label = mContext.getString(R.string.quick_settings_location_label); - state.contentDescription = state.label; + if (locationEnabled) { + state.label = mContext.getString(R.string.quick_settings_location_label); + state.contentDescription = mContext.getString( + R.string.accessibility_quick_settings_location_on); + } else { + state.label = mContext.getString(R.string.quick_settings_location_label); + state.contentDescription = mContext.getString( + R.string.accessibility_quick_settings_location_off); + } state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; state.expandedAccessibilityClassName = Switch.class.getName(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 6e8dcf36bacc..b7ce101cacab 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -195,7 +195,6 @@ public class WifiTile extends QSTileImpl<SignalState> { state.activityIn = cb.enabled && cb.activityIn; state.activityOut = cb.enabled && cb.activityOut; final StringBuffer minimalContentDescription = new StringBuffer(); - final StringBuffer minimalStateDescription = new StringBuffer(); final Resources r = mContext.getResources(); if (isTransient) { state.icon = ResourceIcon.get( @@ -220,14 +219,13 @@ public class WifiTile extends QSTileImpl<SignalState> { mContext.getString(R.string.quick_settings_wifi_label)).append(","); if (state.value) { if (wifiConnected) { - minimalStateDescription.append(cb.wifiSignalContentDescription); + minimalContentDescription.append(cb.wifiSignalContentDescription).append(","); minimalContentDescription.append(removeDoubleQuotes(cb.ssid)); if (!TextUtils.isEmpty(state.secondaryLabel)) { minimalContentDescription.append(",").append(state.secondaryLabel); } } } - state.stateDescription = minimalStateDescription.toString(); state.contentDescription = minimalContentDescription.toString(); state.dualLabelContentDescription = r.getString( R.string.accessibility_quick_settings_open_settings, getTileLabel()); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java index e54ee51fb9d4..7853dc388bcb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -103,11 +103,14 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements state.icon = mIcon; if (state.value) { state.slash.isSlashed = false; + state.contentDescription = mContext.getString( + R.string.accessibility_quick_settings_work_mode_on); } else { state.slash.isSlashed = true; + state.contentDescription = mContext.getString( + R.string.accessibility_quick_settings_work_mode_off); } state.label = mContext.getString(R.string.quick_settings_work_mode_label); - state.contentDescription = state.label; state.expandedAccessibilityClassName = Switch.class.getName(); state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java index afaa593b3bb9..e7d6eba1dcb3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java @@ -22,7 +22,6 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; -import com.android.systemui.doze.DozeEvent; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -53,7 +52,7 @@ public class DozeScrimController implements StateListener { public void onDisplayBlanked() { if (DEBUG) { Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason=" - + DozeEvent.reasonToString(mPulseReason)); + + DozeLog.reasonToString(mPulseReason)); } if (!mDozing) { return; @@ -74,8 +73,8 @@ public class DozeScrimController implements StateListener { // Notifications should time out on their own. Pulses due to notifications should // instead be managed externally based off the notification's lifetime. // Dock also controls the time out by self. - if (mPulseReason != DozeEvent.PULSE_REASON_NOTIFICATION - && mPulseReason != DozeEvent.PULSE_REASON_DOCKING) { + if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION + && mPulseReason != DozeLog.PULSE_REASON_DOCKING) { mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration()); mHandler.postDelayed(mPulseOutExtended, mDozeParameters.getPulseVisibleDurationExtended()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index 04efc2d7558d..56e5cb08f6d1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -31,7 +31,6 @@ import android.view.View; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.assist.AssistManager; -import com.android.systemui.doze.DozeEvent; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.doze.DozeReceiver; @@ -221,18 +220,18 @@ public final class DozeServiceHost implements DozeHost { @Override public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) { - if (reason == DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS) { + if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) { mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:LONG_PRESS"); mAssistManagerLazy.get().startAssist(new Bundle()); return; } - if (reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { + if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { mScrimController.setWakeLockScreenSensorActive(true); } - boolean passiveAuthInterrupt = reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN + boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN && mWakeLockScreenPerformsAuth; // Set the state to pulsing, so ScrimController will know what to do once we ask it to // execute the transition. The pulse callback will then be invoked when the scrims @@ -332,7 +331,7 @@ public final class DozeServiceHost implements DozeHost { @Override public void extendPulse(int reason) { - if (reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { + if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { mScrimController.setWakeLockScreenSensorActive(true); } if (mDozeScrimController.isPulsing() && mHeadsUpManagerPhone.hasNotifications()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt deleted file mode 100644 index 53601babfd56..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVPluginManager.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.phone - -import android.content.Context -import android.view.View -import android.view.ViewGroup.MarginLayoutParams -import android.widget.FrameLayout -import com.android.systemui.plugins.NPVPlugin -import com.android.systemui.plugins.PluginListener -import com.android.systemui.qs.TouchAnimator -import com.android.systemui.shared.plugins.PluginManager - -/** - * Manages the NPVPlugin view and state - * - * Abstracts NPVPlugin from NPV and helps animate on expansion and respond to changes in Config. - */ -class NPVPluginManager( - var parent: FrameLayout, - val pluginManager: PluginManager -) : PluginListener<NPVPlugin> { - - private var plugin: NPVPlugin? = null - private var animator = createAnimator() - private var yOffset = 0f - - private fun createAnimator() = TouchAnimator.Builder() - .addFloat(parent, "alpha", 1f, 0f) - .addFloat(parent, "scaleY", 1f, 0f) - .build() - - init { - pluginManager.addPluginListener(NPVPlugin.ACTION, this, NPVPlugin::class.java, false) - parent.pivotY = 0f - } - - override fun onPluginConnected(plugin: NPVPlugin, pluginContext: Context) { - parent.removeAllViews() - plugin.attachToRoot(parent) - this.plugin = plugin - parent.visibility = View.VISIBLE - } - - fun changeVisibility(visibility: Int) { - parent.visibility = if (plugin != null) visibility else View.GONE - } - - fun destroy() { - plugin?.onDestroy() - pluginManager.removePluginListener(this) - } - - override fun onPluginDisconnected(plugin: NPVPlugin) { - if (this.plugin == plugin) { - this.plugin = null - parent.removeAllViews() - parent.visibility = View.GONE - } - } - - fun setListening(listening: Boolean) { - plugin?.setListening(listening) - } - - fun setExpansion(expansion: Float, headerTranslation: Float, heightDiff: Float) { - parent.setTranslationY(expansion * heightDiff + headerTranslation + yOffset) - if (!expansion.isNaN()) animator.setPosition(expansion) - } - - fun replaceFrameLayout(newParent: FrameLayout) { - newParent.visibility = parent.visibility - parent.removeAllViews() - plugin?.attachToRoot(newParent) - parent = newParent - animator = createAnimator() - } - - fun getHeight() = - if (plugin != null) { - parent.height + (parent.getLayoutParams() as MarginLayoutParams).topMargin - } else 0 - - fun setYOffset(y: Float) { - yOffset = y - parent.setTranslationY(yOffset) - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 6112ae88f634..d2186f959aba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -25,10 +25,8 @@ import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.Fragment; import android.app.StatusBarManager; -import android.content.Context; import android.content.pm.ResolveInfo; import android.content.res.Configuration; -import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; @@ -40,8 +38,6 @@ import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; import android.os.PowerManager; import android.os.SystemClock; -import android.provider.DeviceConfig; -import android.provider.Settings; import android.util.Log; import android.util.MathUtils; import android.view.LayoutInflater; @@ -57,7 +53,6 @@ import android.widget.FrameLayout; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; @@ -73,13 +68,10 @@ import com.android.systemui.doze.DozeLog; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.plugins.HomeControlsPlugin; -import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.qs.QSFragment; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.GestureRecorder; @@ -113,7 +105,6 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.InjectionInflationController; -import com.android.systemui.util.Utils; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -173,8 +164,6 @@ public class NotificationPanelViewController extends PanelViewController { private final ConfigurationController mConfigurationController; private final FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder; - private double mQqsSplitFraction; - // Cap and total height of Roboto font. Needs to be adjusted when font for the big clock is // changed. private static final int CAP_HEIGHT = 1456; @@ -258,7 +247,6 @@ public class NotificationPanelViewController extends PanelViewController { private View mQsNavbarScrim; private NotificationsQuickSettingsContainer mNotificationContainerParent; private NotificationStackScrollLayout mNotificationStackScroller; - private FrameLayout mHomeControlsLayout; private boolean mAnimateNextPositionUpdate; private int mTrackingPointer; @@ -446,9 +434,6 @@ public class NotificationPanelViewController extends PanelViewController { */ private boolean mDelayShowingKeyguardStatusBar; - private PluginManager mPluginManager; - private FrameLayout mPluginFrame; - private NPVPluginManager mNPVPluginManager; private int mOldLayoutDirection; @Inject @@ -457,7 +442,7 @@ public class NotificationPanelViewController extends PanelViewController { NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler, DynamicPrivacyController dynamicPrivacyController, KeyguardBypassController bypassController, FalsingManager falsingManager, - PluginManager pluginManager, ShadeController shadeController, + ShadeController shadeController, NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationEntryManager notificationEntryManager, KeyguardStateController keyguardStateController, @@ -523,7 +508,6 @@ public class NotificationPanelViewController extends PanelViewController { }); mBottomAreaShadeAlphaAnimator.setDuration(160); mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT); - mPluginManager = pluginManager; mShadeController = shadeController; mLockscreenUserManager = notificationLockscreenUserManager; mEntryManager = notificationEntryManager; @@ -553,7 +537,6 @@ public class NotificationPanelViewController extends PanelViewController { mBigClockContainer = mView.findViewById(R.id.big_clock_container); keyguardClockSwitch.setBigClockContainer(mBigClockContainer); - mHomeControlsLayout = mView.findViewById(R.id.home_controls_layout); mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent); mNotificationStackScroller = mView.findViewById(R.id.notification_stack_scroller); mNotificationStackScroller.setOnHeightChangedListener(mOnHeightChangedListener); @@ -563,12 +546,6 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardBottomArea = mView.findViewById(R.id.keyguard_bottom_area); mQsNavbarScrim = mView.findViewById(R.id.qs_navbar_scrim); mLastOrientation = mResources.getConfiguration().orientation; - mPluginFrame = mView.findViewById(R.id.plugin_frame); - if (Settings.System.getInt(mView.getContext().getContentResolver(), "npv_plugin_flag", 0) - == 1) { - mNPVPluginManager = new NPVPluginManager(mPluginFrame, mPluginManager); - } - initBottomArea(); @@ -592,19 +569,6 @@ public class NotificationPanelViewController extends PanelViewController { } }); - mPluginManager.addPluginListener(new PluginListener<HomeControlsPlugin>() { - - @Override - public void onPluginConnected(HomeControlsPlugin plugin, Context pluginContext) { - plugin.sendParentGroup(mHomeControlsLayout); - } - - @Override - public void onPluginDisconnected(HomeControlsPlugin plugin) { - - } - }, HomeControlsPlugin.class, false); - mView.setRtlChangeListener(layoutDirection -> { if (layoutDirection != mOldLayoutDirection) { mAffordanceHelper.onRtlPropertiesChanged(); @@ -637,9 +601,6 @@ public class NotificationPanelViewController extends PanelViewController { com.android.internal.R.dimen.status_bar_height); mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize( R.dimen.heads_up_status_bar_padding); - mQqsSplitFraction = ((float) mResources.getInteger(R.integer.qqs_split_fraction)) / ( - mResources.getInteger(R.integer.qqs_split_fraction) + mResources.getInteger( - R.integer.qs_split_fraction)); } /** @@ -679,18 +640,6 @@ public class NotificationPanelViewController extends PanelViewController { lp.gravity = panelGravity; mNotificationStackScroller.setLayoutParams(lp); } - int sideMargin = mResources.getDimensionPixelOffset(R.dimen.notification_side_paddings); - int topMargin = sideMargin; - lp = (FrameLayout.LayoutParams) mPluginFrame.getLayoutParams(); - if (lp.width != qsWidth || lp.gravity != panelGravity || lp.leftMargin != sideMargin - || lp.rightMargin != sideMargin || lp.topMargin != topMargin) { - lp.width = qsWidth; - lp.gravity = panelGravity; - lp.leftMargin = sideMargin; - lp.rightMargin = sideMargin; - lp.topMargin = topMargin; - mPluginFrame.setLayoutParams(lp); - } } private void reInflateViews() { @@ -732,41 +681,6 @@ public class NotificationPanelViewController extends PanelViewController { if (mOnReinflationListener != null) { mOnReinflationListener.run(); } - reinflatePluginContainer(); - } - - private void reinflatePluginContainer() { - int index = mView.indexOfChild(mPluginFrame); - mView.removeView(mPluginFrame); - mPluginFrame = (FrameLayout) mInjectionInflationController.injectable( - LayoutInflater.from(mView.getContext())).inflate( - R.layout.status_bar_expanded_plugin_frame, mView, false); - mView.addView(mPluginFrame, index); - - Resources res = mView.getResources(); - int qsWidth = res.getDimensionPixelSize(R.dimen.qs_panel_width); - int panelGravity = mView.getResources().getInteger( - R.integer.notification_panel_layout_gravity); - FrameLayout.LayoutParams lp; - int sideMargin = res.getDimensionPixelOffset(R.dimen.notification_side_paddings); - int topMargin = res.getDimensionPixelOffset( - com.android.internal.R.dimen.quick_qs_total_height); - if (Utils.useQsMediaPlayer(mView.getContext())) { - topMargin = res.getDimensionPixelOffset( - com.android.internal.R.dimen.quick_qs_total_height_with_media); - } - lp = (FrameLayout.LayoutParams) mPluginFrame.getLayoutParams(); - if (lp.width != qsWidth || lp.gravity != panelGravity || lp.leftMargin != sideMargin - || lp.rightMargin != sideMargin || lp.topMargin != topMargin) { - lp.width = qsWidth; - lp.gravity = panelGravity; - lp.leftMargin = sideMargin; - lp.rightMargin = sideMargin; - lp.topMargin = topMargin; - mPluginFrame.setLayoutParams(lp); - } - - if (mNPVPluginManager != null) mNPVPluginManager.replaceFrameLayout(mPluginFrame); } private void initBottomArea() { @@ -1266,17 +1180,6 @@ public class NotificationPanelViewController extends PanelViewController { // earlier so the state is already up to date when dragging down. setListening(true); } - if (isQsSplitEnabled() && !mKeyguardShowing) { - if (mQsExpandImmediate) { - mNotificationStackScroller.setVisibility(View.GONE); - mQsFrame.setVisibility(View.VISIBLE); - mHomeControlsLayout.setVisibility(View.VISIBLE); - } else { - mNotificationStackScroller.setVisibility(View.VISIBLE); - mQsFrame.setVisibility(View.GONE); - mHomeControlsLayout.setVisibility(View.GONE); - } - } return false; } @@ -1286,17 +1189,6 @@ public class NotificationPanelViewController extends PanelViewController { || y <= mQs.getView().getY() + mQs.getView().getHeight()); } - private boolean isOnQsEndArea(float x) { - if (!isQsSplitEnabled()) return false; - if (mView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) { - return x >= mQsFrame.getX() + mQqsSplitFraction * mQsFrame.getWidth() - && x <= mQsFrame.getX() + mQsFrame.getWidth(); - } else { - return x >= mQsFrame.getX() - && x <= mQsFrame.getX() + (1 - mQqsSplitFraction) * mQsFrame.getWidth(); - } - } - private boolean isOpenQsEvent(MotionEvent event) { final int pointerCount = event.getPointerCount(); final int action = event.getActionMasked(); @@ -1317,9 +1209,7 @@ public class NotificationPanelViewController extends PanelViewController { MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed( MotionEvent.BUTTON_TERTIARY)); - final boolean onHeaderRight = isOnQsEndArea(event.getX()); - - return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag || onHeaderRight; + return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag; } private void handleQsDown(MotionEvent event) { @@ -1659,10 +1549,7 @@ public class NotificationPanelViewController extends PanelViewController { mBarState != StatusBarState.KEYGUARD && (!mQsExpanded || mQsExpansionFromOverscroll)); updateEmptyShadeView(); - if (mNPVPluginManager != null) { - mNPVPluginManager.changeVisibility( - (mBarState != StatusBarState.KEYGUARD) ? View.VISIBLE : View.INVISIBLE); - } + mQsNavbarScrim.setVisibility( mBarState == StatusBarState.SHADE && mQsExpanded && !mStackScrollerOverscrolling && mQsScrimEnabled ? View.VISIBLE : View.INVISIBLE); @@ -1718,9 +1605,6 @@ public class NotificationPanelViewController extends PanelViewController { float qsExpansionFraction = getQsExpansionFraction(); mQs.setQsExpansion(qsExpansionFraction, getHeaderTranslation()); int heightDiff = mQs.getDesiredHeight() - mQs.getQsMinExpansionHeight(); - if (mNPVPluginManager != null) { - mNPVPluginManager.setExpansion(qsExpansionFraction, getHeaderTranslation(), heightDiff); - } mNotificationStackScroller.setQsExpansionFraction(qsExpansionFraction); } @@ -2015,7 +1899,6 @@ public class NotificationPanelViewController extends PanelViewController { targetHeight = mQsMinExpansionHeight + t * (mQsMaxExpansionHeight - mQsMinExpansionHeight); setQsExpansion(targetHeight); - mHomeControlsLayout.setTranslationY(targetHeight); } updateExpandedHeight(expandedHeight); updateHeader(); @@ -2150,7 +2033,6 @@ public class NotificationPanelViewController extends PanelViewController { appearAmount = mNotificationStackScroller.calculateAppearFractionBypass(); } startHeight = -mQs.getQsMinExpansionHeight(); - if (mNPVPluginManager != null) startHeight -= mNPVPluginManager.getHeight(); } float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount)) + mExpandOffset; @@ -2294,7 +2176,6 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBar.setListening(listening); if (mQs == null) return; mQs.setListening(listening); - if (mNPVPluginManager != null) mNPVPluginManager.setListening(listening); } @Override @@ -3029,11 +2910,6 @@ public class NotificationPanelViewController extends PanelViewController { mOnReinflationListener = onReinflationListener; } - public static boolean isQsSplitEnabled() { - return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.QS_SPLIT_ENABLED, false); - } - public void setAlpha(float alpha) { mView.setAlpha(alpha); } @@ -3500,9 +3376,7 @@ public class NotificationPanelViewController extends PanelViewController { } @Override - public void onUiModeChanged() { - reinflatePluginContainer(); - } + public void onUiModeChanged() {} } private class StatusBarStateListener implements StateListener { @@ -3517,11 +3391,6 @@ public class NotificationPanelViewController extends PanelViewController { mBarState = statusBarState; mKeyguardShowing = keyguardShowing; - if (mKeyguardShowing && isQsSplitEnabled()) { - mNotificationStackScroller.setVisibility(View.VISIBLE); - mQsFrame.setVisibility(View.VISIBLE); - mHomeControlsLayout.setVisibility(View.GONE); - } if (oldState == StatusBarState.KEYGUARD && (goingToFullShade || statusBarState == StatusBarState.SHADE_LOCKED)) { @@ -3544,7 +3413,6 @@ public class NotificationPanelViewController extends PanelViewController { } else { mKeyguardStatusBar.setAlpha(1f); mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE); - ((PhoneStatusBarView) mBar).maybeShowDivider(keyguardShowing); if (keyguardShowing && oldState != mBarState) { if (mQs != null) { mQs.hideImmediately(); @@ -3622,10 +3490,6 @@ public class NotificationPanelViewController extends PanelViewController { int oldMaxHeight = mQsMaxExpansionHeight; if (mQs != null) { mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQs.getQsMinExpansionHeight(); - if (mNPVPluginManager != null) { - mNPVPluginManager.setYOffset(mQsMinExpansionHeight); - mQsMinExpansionHeight += mNPVPluginManager.getHeight(); - } mQsMaxExpansionHeight = mQs.getDesiredHeight(); mNotificationStackScroller.setMaxTopPadding( mQsMaxExpansionHeight + mQsNotificationTopPadding); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java index 3af80387778b..10b68b9a518d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java @@ -16,8 +16,10 @@ package com.android.systemui.statusbar.phone; +import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED; import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT; @@ -180,6 +182,13 @@ public class NotificationShadeWindowController implements Callback, Dumpable, mLp.setTitle("NotificationShade"); mLp.packageName = mContext.getPackageName(); mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + + // We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in + // window manager which disables the transient show behavior. + // TODO: Clean this up once that behavior moves into the Shell. + mLp.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED; + mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; + mWindowManager.addView(mNotificationShadeView, mLp); mLpChanged.copyFrom(mLp); onThemeChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java index 96b4b22d0580..e8bc2f58adb4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java @@ -32,7 +32,7 @@ public final class PhoneStatusBarTransitions extends BarTransitions { private final PhoneStatusBarView mView; private final float mIconAlphaWhenOpaque; - private View mLeftSide, mStatusIcons, mBattery, mClock, mDivider; + private View mLeftSide, mStatusIcons, mBattery, mClock; private Animator mCurrentAnimation; public PhoneStatusBarTransitions(PhoneStatusBarView view) { @@ -46,7 +46,6 @@ public final class PhoneStatusBarTransitions extends BarTransitions { mLeftSide = mView.findViewById(R.id.status_bar_left_side); mStatusIcons = mView.findViewById(R.id.statusIcons); mBattery = mView.findViewById(R.id.battery); - mDivider = mView.findViewById(R.id.divider); applyModeBackground(-1, getMode(), false /*animate*/); applyMode(getMode(), false /*animate*/); } @@ -89,7 +88,6 @@ public final class PhoneStatusBarTransitions extends BarTransitions { anims.playTogether( animateTransitionTo(mLeftSide, newAlpha), animateTransitionTo(mStatusIcons, newAlpha), - animateTransitionTo(mDivider, newAlpha), animateTransitionTo(mBattery, newAlphaBC) ); if (isLightsOut(mode)) { @@ -100,8 +98,7 @@ public final class PhoneStatusBarTransitions extends BarTransitions { } else { mLeftSide.setAlpha(newAlpha); mStatusIcons.setAlpha(newAlpha); - mDivider.setAlpha(newAlpha); mBattery.setAlpha(newAlphaBC); } } -}
\ No newline at end of file +} 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 ffbbffc0d8d9..f3b0a79f9518 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -25,7 +25,6 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.Rect; -import android.provider.DeviceConfig; import android.util.AttributeSet; import android.util.EventLog; import android.util.Pair; @@ -40,8 +39,6 @@ import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; import android.widget.LinearLayout; -import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.systemui.DarkReceiverImpl; import com.android.systemui.Dependency; import com.android.systemui.EventLogTags; import com.android.systemui.R; @@ -81,9 +78,6 @@ public class PhoneStatusBarView extends PanelBar { @Nullable private DisplayCutout mDisplayCutout; - private DarkReceiverImpl mSplitDivider; - private View mDividerContainer; - private QsSplitPropertyListener mPropertyListener; /** * Draw this many pixels into the left/right side of the cutout to optimally use the space */ @@ -115,10 +109,6 @@ public class PhoneStatusBarView extends PanelBar { mBattery = findViewById(R.id.battery); mCutoutSpace = findViewById(R.id.cutout_space_view); mCenterIconSpace = findViewById(R.id.centered_icon_area); - mSplitDivider = findViewById(R.id.divider); - mDividerContainer = findViewById(R.id.divider_container); - maybeShowDivider(true); - mPropertyListener = new QsSplitPropertyListener(mDividerContainer); updateResources(); } @@ -128,26 +118,16 @@ public class PhoneStatusBarView extends PanelBar { super.onAttachedToWindow(); // Always have Battery meters in the status bar observe the dark/light modes. Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery); - Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSplitDivider); - maybeShowDivider(true); if (updateOrientationAndCutout(getResources().getConfiguration().orientation)) { updateLayoutForCutout(); } - if (mPropertyListener != null) { - DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, - mContext.getMainExecutor(), mPropertyListener); - } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mBattery); - Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mSplitDivider); mDisplayCutout = null; - if (mPropertyListener != null) { - DeviceConfig.removeOnPropertiesChangedListener(mPropertyListener); - } } @Override @@ -216,7 +196,6 @@ public class PhoneStatusBarView extends PanelBar { public void onPanelPeeked() { super.onPanelPeeked(); mBar.makeExpandedVisible(false); - maybeShowDivider(!mBar.mPanelExpanded); } @Override @@ -225,7 +204,6 @@ public class PhoneStatusBarView extends PanelBar { // Close the status bar in the next frame so we can show the end of the animation. post(mHideExpandedRunnable); mIsFullyOpenedPanel = false; - maybeShowDivider(!mBar.mPanelExpanded); } public void removePendingHideExpandedRunnables() { @@ -239,7 +217,6 @@ public class PhoneStatusBarView extends PanelBar { mPanel.getView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } mIsFullyOpenedPanel = true; - maybeShowDivider(!mBar.mPanelExpanded); } @Override @@ -263,28 +240,24 @@ public class PhoneStatusBarView extends PanelBar { mBar.onTrackingStarted(); mScrimController.onTrackingStarted(); removePendingHideExpandedRunnables(); - maybeShowDivider(!mBar.mPanelExpanded); } @Override public void onClosingFinished() { super.onClosingFinished(); mBar.onClosingFinished(); - maybeShowDivider(!mBar.mPanelExpanded); } @Override public void onTrackingStopped(boolean expand) { super.onTrackingStopped(expand); mBar.onTrackingStopped(expand); - maybeShowDivider(!mBar.mPanelExpanded); } @Override public void onExpandingFinished() { super.onExpandingFinished(); mScrimController.onExpandingFinished(); - maybeShowDivider(!mBar.mPanelExpanded); } @Override @@ -416,31 +389,4 @@ public class PhoneStatusBarView extends PanelBar { protected boolean shouldPanelBeVisible() { return mHeadsUpVisible || super.shouldPanelBeVisible(); } - - void maybeShowDivider(boolean showDivider) { - int state = - showDivider && NotificationPanelViewController.isQsSplitEnabled() - ? View.VISIBLE : View.GONE; - mDividerContainer.setVisibility(state); - } - - private static class QsSplitPropertyListener implements - DeviceConfig.OnPropertiesChangedListener { - private final View mDivider; - - QsSplitPropertyListener(View divider) { - mDivider = divider; - } - - @Override - public void onPropertiesChanged(DeviceConfig.Properties properties) { - if (properties.getNamespace().equals(DeviceConfig.NAMESPACE_SYSTEMUI) - && properties.getKeyset().contains( - SystemUiDeviceConfigFlags.QS_SPLIT_ENABLED)) { - boolean splitEnabled = properties.getBoolean( - SystemUiDeviceConfigFlags.QS_SPLIT_ENABLED, false); - mDivider.setVisibility(splitEnabled ? VISIBLE : GONE); - } - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 86a81ce3d1f1..6a046884e835 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.phone; +import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; +import static android.view.ViewRootImpl.sNewInsetsMode; +import static android.view.WindowInsets.Type.navigationBars; import static com.android.systemui.plugins.ActivityStarter.OnDismissAction; import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING; import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK; @@ -789,7 +792,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() { @Override public void run() { - mStatusBar.getNavigationBarView().getRootView().setVisibility(View.VISIBLE); + if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) { + mStatusBar.getNotificationShadeWindowView().getWindowInsetsController() + .show(navigationBars()); + } else { + mStatusBar.getNavigationBarView().getRootView().setVisibility(View.VISIBLE); + } } }; @@ -856,7 +864,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } } else { mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable); - mStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE); + if (sNewInsetsMode == NEW_INSETS_MODE_FULL) { + mStatusBar.getNotificationShadeWindowView().getWindowInsetsController() + .hide(navigationBars()); + } else { + mStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE); + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 3a1feaa2de14..28ba1257524d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -26,10 +26,12 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Settings.Global; +import android.telephony.AccessNetworkConstants; import android.telephony.Annotation; import android.telephony.CdmaEriInformation; import android.telephony.CellSignalStrength; import android.telephony.CellSignalStrengthCdma; +import android.telephony.DataSpecificRegistrationInfo; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; @@ -321,9 +323,9 @@ public class MobileSignalController extends SignalController< private int getNumLevels() { if (mInflateSignalStrengths) { - return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1; + return CellSignalStrength.getNumSignalStrengthLevels() + 1; } - return SignalStrength.NUM_SIGNAL_STRENGTH_BINS; + return CellSignalStrength.getNumSignalStrengthLevels(); } @Override @@ -616,10 +618,19 @@ public class MobileSignalController extends SignalController< notifyListenersIfNecessary(); } + private int getNrState(ServiceState serviceState) { + NetworkRegistrationInfo nri = serviceState.getNetworkRegistrationInfo( + NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + if (nri != null) { + return nri.getNrState(); + } + return NetworkRegistrationInfo.NR_STATE_NONE; + } + private MobileIconGroup getNr5GIconGroup() { if (mServiceState == null) return null; - int nrState = mServiceState.getNrState(); + int nrState = getNrState(mServiceState); if (nrState == NetworkRegistrationInfo.NR_STATE_CONNECTED) { // Check if the NR 5G is using millimeter wave and the icon is config. if (mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE) { @@ -772,12 +783,24 @@ public class MobileSignalController extends SignalController< if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE) { if (isCarrierSpecificDataIcon()) { mCAPlus = true; - } else if (mServiceState != null && mServiceState.isUsingCarrierAggregation()) { + } else if (mServiceState != null && isUsingCarrierAggregation(mServiceState)) { mCA = true; } } } + private boolean isUsingCarrierAggregation(ServiceState serviceState) { + NetworkRegistrationInfo nri = serviceState.getNetworkRegistrationInfo( + NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + if (nri != null) { + DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo(); + if (dsri != null) { + return dsri.isUsingCarrierAggregation(); + } + } + return false; + } + @Override public void onDataActivity(int direction) { if (DEBUG) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 6dd113377ce7..46143ca0dd24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -41,9 +41,9 @@ import android.os.Looper; import android.os.PersistableBundle; import android.provider.Settings; import android.telephony.CarrierConfigManager; +import android.telephony.CellSignalStrength; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; -import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; @@ -56,7 +56,6 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.telephony.TelephonyIntents; import com.android.settingslib.net.DataUsageController; import com.android.systemui.DemoMode; import com.android.systemui.Dumpable; @@ -605,7 +604,7 @@ public class NetworkControllerImpl extends BroadcastReceiver @VisibleForTesting void doUpdateMobileControllers() { List<SubscriptionInfo> subscriptions = mSubscriptionManager - .getActiveSubscriptionInfoList(false); + .getActiveAndHiddenSubscriptionInfoList(); if (subscriptions == null) { subscriptions = Collections.emptyList(); } @@ -1035,7 +1034,7 @@ public class NetworkControllerImpl extends BroadcastReceiver if (level != null) { controller.getState().level = level.equals("null") ? -1 : Math.min(Integer.parseInt(level), - SignalStrength.NUM_SIGNAL_STRENGTH_BINS); + CellSignalStrength.getNumSignalStrengthLevels()); controller.getState().connected = controller.getState().level >= 0; } if (args.containsKey("inflate")) { diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java index 47454cb5aca1..cfa2947eb862 100644 --- a/packages/SystemUI/src/com/android/systemui/util/Utils.java +++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java @@ -129,8 +129,6 @@ public class Utils { */ public static boolean useQsMediaPlayer(Context context) { int flag = Settings.System.getInt(context.getContentResolver(), "qs_media_player", 0); - flag |= Settings.System.getInt(context.getContentResolver(), "npv_plugin_flag", 0); - return flag > 0; } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java index eccf09633f16..ea6cf3329772 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java @@ -249,7 +249,7 @@ public class CarrierTextControllerTest extends SysuiTestCase { // STOPSHIP(b/130246708) This line makes sure that SubscriptionManager provides the // same answer as KeyguardUpdateMonitor. Remove when this is addressed - when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn( + when(mSubscriptionManager.getActiveAndHiddenSubscriptionInfoList()).thenReturn( new ArrayList<>()); when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn( diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 59eb6c59a2cd..795cbb92fefe 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -22,7 +22,6 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_DEFAULT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -483,7 +482,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { List<SubscriptionInfo> list = new ArrayList<>(); list.add(TEST_SUBSCRIPTION); list.add(TEST_SUBSCRIPTION_2); - when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(list); + when(mSubscriptionManager.getActiveAndHiddenSubscriptionInfoList()).thenReturn(list); mKeyguardUpdateMonitor.mPhoneStateListener.onActiveDataSubscriptionIdChanged( TEST_SUBSCRIPTION_2.getSubscriptionId()); mTestableLooper.processAllMessages(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java index 0723a4ce74a4..f4cf314aa8fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java @@ -142,7 +142,7 @@ public class DozeMachineTest extends SysuiTestCase { public void testPulseDone_goesToDoze() { when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false); mMachine.requestState(INITIALIZED); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSING); mMachine.requestState(DOZE_PULSE_DONE); @@ -155,7 +155,7 @@ public class DozeMachineTest extends SysuiTestCase { public void testPulseDone_goesToAoD() { when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true); mMachine.requestState(INITIALIZED); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSING); mMachine.requestState(DOZE_PULSE_DONE); @@ -168,7 +168,7 @@ public class DozeMachineTest extends SysuiTestCase { public void testPulseDone_afterDocked_goesToDockedAoD() { when(mDockManager.isDocked()).thenReturn(true); mMachine.requestState(INITIALIZED); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSING); mMachine.requestState(DOZE_PULSE_DONE); @@ -183,7 +183,7 @@ public class DozeMachineTest extends SysuiTestCase { when(mDockManager.isDocked()).thenReturn(true); when(mDockManager.isHidden()).thenReturn(true); mMachine.requestState(INITIALIZED); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSING); mMachine.requestState(DOZE_PULSE_DONE); @@ -227,7 +227,7 @@ public class DozeMachineTest extends SysuiTestCase { public void testWakeLock_heldInPulseStates() { mMachine.requestState(INITIALIZED); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); assertTrue(mWakeLockFake.isHeld()); mMachine.requestState(DOZE_PULSING); @@ -250,7 +250,7 @@ public class DozeMachineTest extends SysuiTestCase { mMachine.requestState(INITIALIZED); mMachine.requestState(DOZE); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSING); mMachine.requestState(DOZE_PULSE_DONE); @@ -262,9 +262,9 @@ public class DozeMachineTest extends SysuiTestCase { mMachine.requestState(INITIALIZED); mMachine.requestState(DOZE); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSING); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSE_DONE); } @@ -273,7 +273,7 @@ public class DozeMachineTest extends SysuiTestCase { mMachine.requestState(INITIALIZED); mMachine.requestState(DOZE); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSE_DONE); } @@ -286,7 +286,7 @@ public class DozeMachineTest extends SysuiTestCase { return null; }).when(mPartMock).transitionTo(any(), eq(DOZE_REQUEST_PULSE)); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); assertEquals(DOZE_PULSING, mMachine.getState()); } @@ -295,9 +295,9 @@ public class DozeMachineTest extends SysuiTestCase { public void testPulseReason_getMatchesRequest() { mMachine.requestState(INITIALIZED); mMachine.requestState(DOZE); - mMachine.requestPulse(DozeEvent.REASON_SENSOR_DOUBLE_TAP); + mMachine.requestPulse(DozeLog.REASON_SENSOR_DOUBLE_TAP); - assertEquals(DozeEvent.REASON_SENSOR_DOUBLE_TAP, mMachine.getPulseReason()); + assertEquals(DozeLog.REASON_SENSOR_DOUBLE_TAP, mMachine.getPulseReason()); } @Test @@ -309,7 +309,7 @@ public class DozeMachineTest extends SysuiTestCase { if (newState == DOZE_REQUEST_PULSE || newState == DOZE_PULSING || newState == DOZE_PULSE_DONE) { - assertEquals(DozeEvent.PULSE_REASON_NOTIFICATION, mMachine.getPulseReason()); + assertEquals(DozeLog.PULSE_REASON_NOTIFICATION, mMachine.getPulseReason()); } else { assertTrue("unexpected state " + newState, newState == DOZE || newState == DOZE_AOD); @@ -317,7 +317,7 @@ public class DozeMachineTest extends SysuiTestCase { return null; }).when(mPartMock).transitionTo(any(), any()); - mMachine.requestPulse(DozeEvent.PULSE_REASON_NOTIFICATION); + mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION); mMachine.requestState(DOZE_PULSING); mMachine.requestState(DOZE_PULSE_DONE); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java index 775acdf58c64..ff03fbae3f3a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java @@ -115,14 +115,14 @@ public class DozeSensorsTest extends SysuiTestCase { mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mTestableLooper.processAllMessages(); - verify(mCallback).onSensorPulse(eq(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), + verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), anyFloat(), anyFloat(), eq(null)); mDozeSensors.requestTemporaryDisable(); reset(mCallback); mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mTestableLooper.processAllMessages(); - verify(mCallback, never()).onSensorPulse(eq(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), + verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), anyFloat(), anyFloat(), eq(null)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java index bf1060905f10..debc9d6430e0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java @@ -165,10 +165,10 @@ public class DozeTriggersTest extends SysuiTestCase { @Test public void testProximitySensorNotAvailablel() { mProximitySensor.setSensorAvailable(false); - mTriggers.onSensor(DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null); - mTriggers.onSensor(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, 100, 100, + mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null); + mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, 100, 100, new float[]{1}); - mTriggers.onSensor(DozeEvent.REASON_SENSOR_TAP, 100, 100, null); + mTriggers.onSensor(DozeLog.REASON_SENSOR_TAP, 100, 100, null); } private void waitForSensorManager() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/recents/model/TaskKeyLruCacheTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/recents/model/TaskKeyLruCacheTest.java deleted file mode 100644 index de6c87c7ff01..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/shared/recents/model/TaskKeyLruCacheTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.shared.recents.model; - - -import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertNull; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.systemui.SysuiTestCase; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -@SmallTest -@RunWith(MockitoJUnitRunner.class) -public class TaskKeyLruCacheTest extends SysuiTestCase { - private static int sCacheSize = 3; - private static int sIdTask1 = 1; - private static int sIdTask2 = 2; - private static int sIdTask3 = 3; - private static int sIdUser1 = 1; - - TaskKeyLruCache.EvictionCallback mEvictionCallback; - - TaskKeyLruCache<Integer> mCache; - private Task.TaskKey mKey1; - private Task.TaskKey mKey2; - private Task.TaskKey mKey3; - - @Before - public void setup() { - mEvictionCallback = mock(TaskKeyLruCache.EvictionCallback.class); - mCache = new TaskKeyLruCache<>(sCacheSize, mEvictionCallback); - - mKey1 = new Task.TaskKey(sIdTask1, 0, null, null, sIdUser1, System.currentTimeMillis()); - mKey2 = new Task.TaskKey(sIdTask2, 0, null, null, sIdUser1, System.currentTimeMillis()); - mKey3 = new Task.TaskKey(sIdTask3, 0, null, null, sIdUser1, System.currentTimeMillis()); - } - - @Test - public void addSingleItem_get_success() { - mCache.put(mKey1, 1); - - assertEquals(1, (int) mCache.get(mKey1)); - } - - @Test - public void addSingleItem_getUninsertedItem_returnsNull() { - mCache.put(mKey1, 1); - - assertNull(mCache.get(mKey2)); - } - - @Test - public void emptyCache_get_returnsNull() { - assertNull(mCache.get(mKey1)); - } - - @Test - public void updateItem_get_returnsSecond() { - mCache.put(mKey1, 1); - mCache.put(mKey1, 2); - - assertEquals(2, (int) mCache.get(mKey1)); - assertEquals(1, mCache.mKeys.size()); - } - - @Test - public void fillCache_put_evictsOldest() { - mCache.put(mKey1, 1); - mCache.put(mKey2, 2); - mCache.put(mKey3, 3); - Task.TaskKey key4 = new Task.TaskKey(sIdTask3 + 1, 0, - null, null, sIdUser1, System.currentTimeMillis()); - mCache.put(key4, 4); - - assertNull(mCache.get(mKey1)); - assertEquals(3, mCache.mKeys.size()); - assertEquals(mKey2, mCache.mKeys.valueAt(0)); - verify(mEvictionCallback, times(1)).onEntryEvicted(mKey1); - } - - @Test - public void fillCache_remove_success() { - mCache.put(mKey1, 1); - mCache.put(mKey2, 2); - mCache.put(mKey3, 3); - - mCache.remove(mKey2); - - assertNull(mCache.get(mKey2)); - assertEquals(2, mCache.mKeys.size()); - verify(mEvictionCallback, times(0)).onEntryEvicted(mKey2); - } - - @Test - public void put_evictionCallback_notCalled() { - mCache.put(mKey1, 1); - verify(mEvictionCallback, times(0)).onEntryEvicted(mKey1); - } - - @Test - public void evictAll_evictionCallback_called() { - mCache.put(mKey1, 1); - mCache.evictAllCache(); - verify(mEvictionCallback, times(1)).onEntryEvicted(mKey1); - } - - @Test - public void trimAll_evictionCallback_called() { - mCache.put(mKey1, 1); - mCache.put(mKey2, 2); - mCache.trimToSize(-1); - verify(mEvictionCallback, times(1)).onEntryEvicted(mKey1); - verify(mEvictionCallback, times(1)).onEntryEvicted(mKey2); - - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java index 3c6a69882d44..a6e29181e435 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java @@ -36,7 +36,6 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; -import com.android.systemui.doze.DozeEvent; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; @@ -144,13 +143,13 @@ public class DozeServiceHostTest extends SysuiTestCase { @Override public void onPulseFinished() { } - }, DozeEvent.PULSE_REASON_NOTIFICATION); + }, DozeLog.PULSE_REASON_NOTIFICATION); ArgumentCaptor<DozeHost.PulseCallback> pulseCallbackArgumentCaptor = ArgumentCaptor.forClass(DozeHost.PulseCallback.class); verify(mDozeScrimController).pulse( - pulseCallbackArgumentCaptor.capture(), eq(DozeEvent.PULSE_REASON_NOTIFICATION)); + pulseCallbackArgumentCaptor.capture(), eq(DozeLog.PULSE_REASON_NOTIFICATION)); verify(mStatusBar).updateScrimController(); reset(mStatusBar); @@ -162,21 +161,21 @@ public class DozeServiceHostTest extends SysuiTestCase { @Test public void testPulseWhileDozing_notifyAuthInterrupt() { HashSet<Integer> reasonsWantingAuth = new HashSet<>( - Collections.singletonList(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN)); + Collections.singletonList(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN)); HashSet<Integer> reasonsSkippingAuth = new HashSet<>( - Arrays.asList(DozeEvent.PULSE_REASON_INTENT, - DozeEvent.PULSE_REASON_NOTIFICATION, - DozeEvent.PULSE_REASON_SENSOR_SIGMOTION, - DozeEvent.REASON_SENSOR_PICKUP, - DozeEvent.REASON_SENSOR_DOUBLE_TAP, - DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS, - DozeEvent.PULSE_REASON_DOCKING, - DozeEvent.REASON_SENSOR_WAKE_UP, - DozeEvent.REASON_SENSOR_TAP)); + Arrays.asList(DozeLog.PULSE_REASON_INTENT, + DozeLog.PULSE_REASON_NOTIFICATION, + DozeLog.PULSE_REASON_SENSOR_SIGMOTION, + DozeLog.REASON_SENSOR_PICKUP, + DozeLog.REASON_SENSOR_DOUBLE_TAP, + DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, + DozeLog.PULSE_REASON_DOCKING, + DozeLog.REASON_SENSOR_WAKE_UP, + DozeLog.REASON_SENSOR_TAP)); HashSet<Integer> reasonsThatDontPulse = new HashSet<>( - Arrays.asList(DozeEvent.REASON_SENSOR_PICKUP, - DozeEvent.REASON_SENSOR_DOUBLE_TAP, - DozeEvent.REASON_SENSOR_TAP)); + Arrays.asList(DozeLog.REASON_SENSOR_PICKUP, + DozeLog.REASON_SENSOR_DOUBLE_TAP, + DozeLog.REASON_SENSOR_TAP)); doAnswer(invocation -> { DozeHost.PulseCallback callback = invocation.getArgument(0); @@ -185,7 +184,7 @@ public class DozeServiceHostTest extends SysuiTestCase { }).when(mDozeScrimController).pulse(any(), anyInt()); mDozeServiceHost.mWakeLockScreenPerformsAuth = true; - for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) { + for (int i = 0; i < DozeLog.TOTAL_REASONS; i++) { reset(mKeyguardUpdateMonitor); mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class), i); if (reasonsWantingAuth.contains(i)) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 1f37ad8b2b1c..5fb71599e2a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -55,7 +55,6 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.doze.DozeLog; import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.KeyguardAffordanceView; @@ -133,8 +132,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private DynamicPrivacyController mDynamicPrivacyController; @Mock - private PluginManager mPluginManager; - @Mock private ShadeController mShadeController; @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager; @@ -218,7 +215,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mNotificationPanelViewController = new NotificationPanelViewController(mView, mInjectionInflationController, coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController, - mFalsingManager, mPluginManager, mShadeController, + mFalsingManager, mShadeController, mNotificationLockscreenUserManager, mNotificationEntryManager, mKeyguardStateController, mStatusBarStateController, mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index cc3c3ccdc316..294d546e087b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -30,6 +30,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -43,6 +44,7 @@ import android.os.Handler; import android.provider.Settings; import android.provider.Settings.Global; import android.telephony.CdmaEriInformation; +import android.telephony.CellSignalStrength; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; @@ -56,7 +58,6 @@ import android.util.Log; import androidx.test.InstrumentationRegistry; -import com.android.internal.telephony.cdma.EriInfo; import com.android.settingslib.graph.SignalDrawable; import com.android.settingslib.net.DataUsageController; import com.android.systemui.R; @@ -95,6 +96,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected PhoneStateListener mPhoneStateListener; protected SignalStrength mSignalStrength; protected ServiceState mServiceState; + protected NetworkRegistrationInfo mFakeRegInfo; protected ConnectivityManager mMockCm; protected WifiManager mMockWm; protected SubscriptionManager mMockSm; @@ -158,6 +160,14 @@ public class NetworkControllerBaseTest extends SysuiTestCase { mSignalStrength = mock(SignalStrength.class); mServiceState = mock(ServiceState.class); + mFakeRegInfo = new NetworkRegistrationInfo.Builder() + .setTransportType(TRANSPORT_TYPE_WWAN) + .setDomain(DOMAIN_PS) + .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) + .build(); + doReturn(mFakeRegInfo).when(mServiceState) + .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN); + mEriInformation = new CdmaEriInformation(CdmaEriInformation.ERI_OFF, CdmaEriInformation.ERI_ICON_MODE_NORMAL); when(mMockTm.getCdmaEriInformation()).thenReturn(mEriInformation); @@ -219,7 +229,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { subs.add(subscription); } when(mMockSm.getActiveSubscriptionInfoList()).thenReturn(subs); - when(mMockSm.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subs); + when(mMockSm.getActiveAndHiddenSubscriptionInfoList()).thenReturn(subs); mNetworkController.doUpdateMobileControllers(); } @@ -405,7 +415,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(), anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean()); IconState iconState = iconArg.getValue(); - int state = SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, + int state = SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(), false); assertEquals("Visibility in, quick settings", visible, iconState.visible); assertEquals("Signal icon in, quick settings", state, iconState.icon); @@ -440,7 +450,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase { IconState iconState = iconArg.getValue(); int state = icon == -1 ? 0 - : SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS, !inet); + : SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(), + !inet); assertEquals("Signal icon in status bar", state, iconState.icon); assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue()); assertEquals("Visibility in status bar", visible, iconState.visible); @@ -483,7 +494,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { IconState iconState = iconArg.getValue(); - int numSignalStrengthBins = SignalStrength.NUM_SIGNAL_STRENGTH_BINS; + int numSignalStrengthBins = CellSignalStrength.getNumSignalStrengthLevels(); if (mMobileSignalController.mInflateSignalStrengths) { numSignalStrengthBins++; icon++; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index f6c750db56b7..1eb59396e525 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -187,7 +187,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_LTE); updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT); ServiceState ss = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED); mPhoneStateListener.onServiceStateChanged(ss); verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, TelephonyIcons.ICON_5G, @@ -202,7 +202,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { TelephonyManager.NETWORK_TYPE_LTE); updateDataActivity(TelephonyManager.DATA_ACTIVITY_DORMANT); ServiceState ss = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED); mPhoneStateListener.onServiceStateChanged(ss); verifyDataIndicators(TelephonyIcons.ICON_5G); @@ -215,7 +215,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { updateDataConnectionState(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); ServiceState ss = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange(); mPhoneStateListener.onServiceStateChanged(ss); @@ -229,7 +229,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { updateDataConnectionState(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); ServiceState ss = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss).getNrFrequencyRange(); mPhoneStateListener.onServiceStateChanged(ss); @@ -243,7 +243,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { updateDataConnectionState(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); ServiceState ss = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(ss).getNrState(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_RESTRICTED); mPhoneStateListener.onServiceStateChanged(mServiceState); verifyDataIndicators(TelephonyIcons.ICON_LTE); @@ -259,7 +259,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { ServiceState ss = Mockito.mock(ServiceState.class); // While nrIconDisplayGracePeriodMs > 0 & is Nr5G, mIsShowingIconGracefully should be true - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -278,7 +278,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0); // While nrIconDisplayGracePeriodMs <= 0, mIsShowingIconGracefully should be false - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); + setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -295,7 +295,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { mPhoneStateListener.onServiceStateChanged(mServiceState); ServiceState ss = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -305,7 +305,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { // Enabled timer Nr5G switch to None Nr5G, showing 5G icon gracefully ServiceState ssLte = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState(); + setNrState(ssLte, NetworkRegistrationInfo.NR_STATE_NONE); doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -321,14 +321,14 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { setupDefaultSignal(); mNetworkController.handleConfigurationChanged(); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); + setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); verifyDataIndicators(TelephonyIcons.ICON_5G); - doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); + setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_NONE); doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -342,7 +342,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds(); setupDefaultSignal(); mNetworkController.handleConfigurationChanged(); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); + setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -352,7 +352,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { // Disabled timer, when out of service, reset timer to display latest state updateDataConnectionState(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); - doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); + setNrState(mServiceState, NetworkRegistrationInfo.NR_STATE_NONE); doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_DISCONNECTED, TelephonyManager.NETWORK_TYPE_UMTS); @@ -369,7 +369,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { mPhoneStateListener.onServiceStateChanged(mServiceState); ServiceState ss5G = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState(); + setNrState(ss5G, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -379,7 +379,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { // When timeout enabled, 5G/5G+ switching should be updated immediately ServiceState ss5GPlus = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5GPlus).getNrState(); + setNrState(ss5GPlus, NetworkRegistrationInfo.NR_STATE_CONNECTED); doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss5GPlus).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -396,22 +396,21 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { mNetworkController.handleConfigurationChanged(); mPhoneStateListener.onServiceStateChanged(mServiceState); - ServiceState ss5G = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState(); - doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange(); + ServiceState ss = Mockito.mock(ServiceState.class); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_CONNECTED); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); - mPhoneStateListener.onServiceStateChanged(ss5G); + mPhoneStateListener.onServiceStateChanged(ss); verifyDataIndicators(TelephonyIcons.ICON_5G); // State from NR_5G to NONE NR_5G with timeout, should show previous 5G icon - ServiceState ssLte = Mockito.mock(ServiceState.class); - doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState(); - doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange(); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_NONE); + doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ss).getNrFrequencyRange(); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); - mPhoneStateListener.onServiceStateChanged(ssLte); + mPhoneStateListener.onServiceStateChanged(ss); verifyDataIndicators(TelephonyIcons.ICON_5G); @@ -420,14 +419,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { mNetworkController.handleConfigurationChanged(); // State from NR_5G to NONE NR_STATE_RESTRICTED, showing corresponding icon - doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState(); - NetworkRegistrationInfo fakeRegInfo = new NetworkRegistrationInfo.Builder() - .setTransportType(TRANSPORT_TYPE_WWAN) - .setDomain(DOMAIN_PS) - .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) - .build(); - doReturn(fakeRegInfo).when(mServiceState) - .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN); + setNrState(ss, NetworkRegistrationInfo.NR_STATE_RESTRICTED); mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_LTE); @@ -531,4 +523,10 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { true, DEFAULT_QS_SIGNAL_STRENGTH, dataIcon, false, false); } + + private void setNrState(ServiceState ss, int nrState) { + mFakeRegInfo.setNrState(nrState); + doReturn(mFakeRegInfo).when(ss) + .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java index 4406248ec9ea..f52c8c17bfa5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java @@ -136,7 +136,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { @Test public void testSignalStrength() { for (int testStrength = 0; - testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) { + testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) { setupDefaultSignal(); setLevel(testStrength); @@ -153,7 +153,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { @Test public void testCdmaSignalStrength() { for (int testStrength = 0; - testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) { + testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) { setupDefaultSignal(); setCdma(); setLevel(testStrength); @@ -167,7 +167,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { @Test public void testSignalRoaming() { for (int testStrength = 0; - testStrength < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; testStrength++) { + testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) { setupDefaultSignal(); setGsmRoaming(true); setLevel(testStrength); @@ -494,7 +494,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { // Carrier network change is true, show special indicator verifyLastMobileDataIndicators(true /* visible */, - SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS), + SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()), 0 /* typeIcon */); // Revert back @@ -525,7 +525,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { // Carrier network change is true, show special indicator, no roaming. verifyLastMobileDataIndicators(true /* visible */, - SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS), + SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()), 0 /* typeIcon */, false /* roaming */); @@ -557,7 +557,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { // Carrier network change is true, show special indicator, no roaming. verifyLastMobileDataIndicators(true /* visible */, - SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS), + SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()), 0 /* typeIcon */, false /* roaming */); @@ -565,7 +565,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { // Roaming should not show. verifyLastMobileDataIndicators(true /* visible */, - SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS), + SignalDrawable.getCarrierChangeState(CellSignalStrength.getNumSignalStrengthLevels()), 0 /* typeIcon */, false /* roaming */); diff --git a/packages/WAPPushManager/Android.bp b/packages/WAPPushManager/Android.bp index 083dac944936..cd804b2c8514 100644 --- a/packages/WAPPushManager/Android.bp +++ b/packages/WAPPushManager/Android.bp @@ -4,7 +4,6 @@ android_app { name: "WAPPushManager", srcs: ["src/**/*.java"], platform_apis: true, - libs: ["telephony-common"], static_libs: ["android-common"], optimize: { proguard_flags_files: ["proguard.flags"], diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index e28ef0f920e9..4f18f3547449 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -216,7 +216,7 @@ final class AutofillManagerServiceImpl updateRemoteAugmentedAutofillService(); final ComponentName componentName = RemoteInlineSuggestionRenderService - .getServiceComponentName(getContext()); + .getServiceComponentName(getContext(), mUserId); if (componentName != null) { mRemoteInlineSuggestionRenderService = new RemoteInlineSuggestionRenderService( getContext(), componentName, InlineSuggestionRenderService.SERVICE_INTERFACE, diff --git a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java index f9e08e683b6c..31dc23f0118d 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java @@ -20,6 +20,7 @@ import static com.android.server.autofill.Helper.sVerbose; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -86,7 +87,7 @@ final class RemoteInlineSuggestionRenderService extends } @Nullable - private static ServiceInfo getServiceInfo(Context context) { + private static ServiceInfo getServiceInfo(Context context, int userId) { final String packageName = context.getPackageManager().getServicesSystemSharedLibraryPackageName(); if (packageName == null) { @@ -96,8 +97,8 @@ final class RemoteInlineSuggestionRenderService extends final Intent intent = new Intent(InlineSuggestionRenderService.SERVICE_INTERFACE); intent.setPackage(packageName); - final ResolveInfo resolveInfo = context.getPackageManager().resolveService(intent, - PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); + final ResolveInfo resolveInfo = context.getPackageManager().resolveServiceAsUser(intent, + PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, userId); final ServiceInfo serviceInfo = resolveInfo == null ? null : resolveInfo.serviceInfo; if (resolveInfo == null || serviceInfo == null) { Slog.w(TAG, "No valid components found."); @@ -115,8 +116,8 @@ final class RemoteInlineSuggestionRenderService extends } @Nullable - public static ComponentName getServiceComponentName(Context context) { - final ServiceInfo serviceInfo = getServiceInfo(context); + public static ComponentName getServiceComponentName(Context context, @UserIdInt int userId) { + final ServiceInfo serviceInfo = getServiceInfo(context, userId); if (serviceInfo == null) return null; final ComponentName componentName = new ComponentName(serviceInfo.packageName, diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java index 6a1de6378a5e..205b7dda267e 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java @@ -16,7 +16,6 @@ package com.android.server.backup; -import static com.android.server.backup.BackupManagerService.DEBUG; import static com.android.server.backup.BackupManagerService.TAG; import android.util.Slog; @@ -33,10 +32,13 @@ final class UserBackupManagerFilePersistedSettings { private static final String BACKUP_ENABLE_FILE = "backup_enabled"; static boolean readBackupEnableState(int userId) { - return readBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId)); + boolean enabled = readBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId)); + Slog.d(TAG, "user:" + userId + " readBackupEnableState enabled:" + enabled); + return enabled; } static void writeBackupEnableState(int userId, boolean enable) { + Slog.d(TAG, "user:" + userId + " writeBackupEnableState enable:" + enable); writeBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId), enable); } @@ -45,15 +47,17 @@ final class UserBackupManagerFilePersistedSettings { if (enableFile.exists()) { try (FileInputStream fin = new FileInputStream(enableFile)) { int state = fin.read(); + if (state != 0 && state != 1) { + // TODO (b/148587496) handle instead of only logging + Slog.e(TAG, "Unexpected enabled state:" + state); + } return state != 0; } catch (IOException e) { // can't read the file; fall through to assume disabled Slog.e(TAG, "Cannot read enable state; assuming disabled"); } } else { - if (DEBUG) { - Slog.i(TAG, "isBackupEnabled() => false due to absent settings file"); - } + Slog.i(TAG, "isBackupEnabled() => false due to absent settings file"); } return false; } @@ -64,7 +68,11 @@ final class UserBackupManagerFilePersistedSettings { try (FileOutputStream fout = new FileOutputStream(stage)) { fout.write(enable ? 1 : 0); fout.close(); - stage.renameTo(enableFile); + boolean renamed = stage.renameTo(enableFile); + if (!renamed) { + // TODO (b/148587496) handle instead of only logging + Slog.e(TAG, "Write enable failed as could not rename staging file to actual"); + } // will be synced immediately by the try-with-resources call to close() } catch (IOException | RuntimeException e) { Slog.e( diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java index 9b1326bc88d7..043f657b7f2c 100644 --- a/services/core/java/com/android/server/MmsServiceBroker.java +++ b/services/core/java/com/android/server/MmsServiceBroker.java @@ -128,13 +128,15 @@ public class MmsServiceBroker extends SystemService { @Override public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl, - Bundle configOverrides, PendingIntent sentIntent) throws RemoteException { + Bundle configOverrides, PendingIntent sentIntent, long messageId) + throws RemoteException { returnPendingIntentWithError(sentIntent); } @Override public void downloadMessage(int subId, String callingPkg, String locationUrl, - Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent) + Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent, + long messageId) throws RemoteException { returnPendingIntentWithError(downloadedIntent); } @@ -329,7 +331,8 @@ public class MmsServiceBroker extends SystemService { @Override public void sendMessage(int subId, String callingPkg, Uri contentUri, - String locationUrl, Bundle configOverrides, PendingIntent sentIntent) + String locationUrl, Bundle configOverrides, PendingIntent sentIntent, + long messageId) throws RemoteException { Slog.d(TAG, "sendMessage() by " + callingPkg); mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message"); @@ -343,13 +346,13 @@ public class MmsServiceBroker extends SystemService { Intent.FLAG_GRANT_READ_URI_PERMISSION, subId); getServiceGuarded().sendMessage(subId, callingPkg, contentUri, locationUrl, - configOverrides, sentIntent); + configOverrides, sentIntent, messageId); } @Override public void downloadMessage(int subId, String callingPkg, String locationUrl, Uri contentUri, Bundle configOverrides, - PendingIntent downloadedIntent) throws RemoteException { + PendingIntent downloadedIntent, long messageId) throws RemoteException { Slog.d(TAG, "downloadMessage() by " + callingPkg); mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS, "Download MMS message"); @@ -364,7 +367,7 @@ public class MmsServiceBroker extends SystemService { subId); getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, contentUri, - configOverrides, downloadedIntent); + configOverrides, downloadedIntent, messageId); } @Override diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index d7201054dea6..4a65a96e57a1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -438,14 +438,15 @@ final class ActivityManagerConstants extends ContentObserver { DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, ActivityThread.currentApplication().getMainExecutor(), mOnDeviceConfigChangedListener); - updateMaxCachedProcesses(); + loadDeviceConfigConstants(); + // The following read from Settings. updateActivityStartsLoggingEnabled(); - updateBackgroundActivityStarts(); - updateForceRestrictedBackgroundCheck(); updateForegroundServiceStartsLoggingEnabled(); - updateBackgroundFgsStartsRestriction(); - updateOomAdjUpdatePolicy(); - updateImperceptibleKillExemptions(); + } + + private void loadDeviceConfigConstants() { + mOnDeviceConfigChangedListener.onPropertiesChanged( + DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER)); } public void setOverrideMaxCachedProcesses(int value) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2b160dddedbb..a2209e848ccd 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9763,15 +9763,21 @@ public class ActivityManagerService extends IActivityManager.Stub * @param crashInfo describing the context of the error * @return true if the process should exit immediately (WTF is fatal) */ + @Override public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, - final ApplicationErrorReport.ParcelableCrashInfo crashInfo) { + final ApplicationErrorReport.ParcelableCrashInfo crashInfo, int immediateCallerPid) { final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); - if (system) { - // If this is coming from the system, we could very well have low-level - // system locks held, so we want to do this all asynchronously. And we - // never want this to become fatal, so there is that too. + // If this is coming from the system, we could very well have low-level + // system locks held, so we want to do this all asynchronously. And we + // never want this to become fatal, so there is that too. + // + // Note: "callingPid == Process.myPid())" wouldn't be reliable because even if the caller + // is within the system server, if it calls Log.wtf() without clearning the calling + // identity, callingPid would still be of a remote caller. So we explicltly pass the + // process PID from the caller. + if (system || (immediateCallerPid == Process.myPid())) { mHandler.post(new Runnable() { @Override public void run() { handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 4d5af9ac5d5c..47bb5f397aaa 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -30,7 +30,6 @@ import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; -import android.util.StatsLog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.compat.AndroidBuildClassifier; @@ -40,6 +39,7 @@ import com.android.internal.compat.CompatibilityChangeInfo; import com.android.internal.compat.IOverrideValidator; import com.android.internal.compat.IPlatformCompat; import com.android.internal.util.DumpUtils; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.LocalServices; import java.io.FileDescriptor; @@ -59,7 +59,7 @@ public class PlatformCompat extends IPlatformCompat.Stub { public PlatformCompat(Context context) { mContext = context; mChangeReporter = new ChangeReporter( - StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); + FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); mCompatConfig = CompatConfig.create(new AndroidBuildClassifier(), mContext); } @@ -67,7 +67,7 @@ public class PlatformCompat extends IPlatformCompat.Stub { PlatformCompat(Context context, CompatConfig compatConfig) { mContext = context; mChangeReporter = new ChangeReporter( - StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); + FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER); mCompatConfig = compatConfig; } @@ -75,7 +75,7 @@ public class PlatformCompat extends IPlatformCompat.Stub { public void reportChange(long changeId, ApplicationInfo appInfo) { checkCompatChangeLogPermission(); reportChange(changeId, appInfo.uid, - StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); + FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); } @Override @@ -91,7 +91,8 @@ public class PlatformCompat extends IPlatformCompat.Stub { @Override public void reportChangeByUid(long changeId, int uid) { checkCompatChangeLogPermission(); - reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); + reportChange(changeId, uid, + FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); } @Override @@ -99,11 +100,11 @@ public class PlatformCompat extends IPlatformCompat.Stub { checkCompatChangeReadPermission(); if (mCompatConfig.isChangeEnabled(changeId, appInfo)) { reportChange(changeId, appInfo.uid, - StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); + FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED); return true; } reportChange(changeId, appInfo.uid, - StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); + FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED); return false; } diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java index 2c415570d5fa..25c761ab80ec 100644 --- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java +++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java @@ -188,14 +188,14 @@ public class NetworkNotificationManager { int icon = getIcon(transportType, notifyType); if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) { title = r.getString(R.string.wifi_no_internet, - WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID())); + WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID())); details = r.getString(R.string.wifi_no_internet_detailed); } else if (notifyType == NotificationType.PRIVATE_DNS_BROKEN) { if (transportType == TRANSPORT_CELLULAR) { title = r.getString(R.string.mobile_no_internet); } else if (transportType == TRANSPORT_WIFI) { title = r.getString(R.string.wifi_no_internet, - WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID())); + WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID())); } else { title = r.getString(R.string.other_networks_no_internet); } @@ -203,19 +203,19 @@ public class NetworkNotificationManager { } else if (notifyType == NotificationType.PARTIAL_CONNECTIVITY && transportType == TRANSPORT_WIFI) { title = r.getString(R.string.network_partial_connectivity, - WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID())); + WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID())); details = r.getString(R.string.network_partial_connectivity_detailed); } else if (notifyType == NotificationType.LOST_INTERNET && transportType == TRANSPORT_WIFI) { title = r.getString(R.string.wifi_no_internet, - WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID())); + WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID())); details = r.getString(R.string.wifi_no_internet_detailed); } else if (notifyType == NotificationType.SIGN_IN) { switch (transportType) { case TRANSPORT_WIFI: title = r.getString(R.string.wifi_available_sign_in, 0); details = r.getString(R.string.network_available_sign_in_detailed, - WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID())); + WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID())); break; case TRANSPORT_CELLULAR: title = r.getString(R.string.network_available_sign_in, 0); @@ -236,7 +236,7 @@ public class NetworkNotificationManager { break; } } else if (notifyType == NotificationType.LOGGED_IN) { - title = WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()); + title = WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()); details = r.getString(R.string.captive_portal_logged_in_detailed); } else if (notifyType == NotificationType.NETWORK_SWITCH) { String fromTransport = getTransportName(transportType); diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java index 86a84e312899..b3546dc79572 100644 --- a/services/core/java/com/android/server/location/GnssConfiguration.java +++ b/services/core/java/com/android/server/location/GnssConfiguration.java @@ -23,7 +23,8 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.text.TextUtils; import android.util.Log; -import android.util.StatsLog; + +import com.android.internal.util.FrameworkStatsLog; import libcore.io.IoUtils; @@ -283,7 +284,7 @@ class GnssConfiguration { } private void logConfigurations() { - StatsLog.write(StatsLog.GNSS_CONFIGURATION_REPORTED, + FrameworkStatsLog.write(FrameworkStatsLog.GNSS_CONFIGURATION_REPORTED, getSuplHost(), getSuplPort(0), getC2KHost(), diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 62fa5ec82aea..a7fd57afc86b 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -63,7 +63,6 @@ import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.util.Log; -import android.util.StatsLog; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; @@ -74,6 +73,7 @@ import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.location.gnssmetrics.GnssMetrics; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.DeviceIdleInternal; import com.android.server.FgThread; import com.android.server.LocalServices; @@ -1825,8 +1825,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } native_send_ni_response(notificationId, userResponse); - StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED, - StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE, + FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED, + FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE, notificationId, /* niType= */ 0, /* needNotify= */ false, @@ -1891,8 +1891,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements notification.textEncoding = textEncoding; mNIHandler.handleNiNotification(notification); - StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED, - StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST, + FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED, + FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST, notification.notificationId, notification.niType, notification.needNotify, diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java index dd522b95a938..2b5fc7989d8b 100644 --- a/services/core/java/com/android/server/location/GnssVisibilityControl.java +++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java @@ -36,11 +36,11 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; -import android.util.StatsLog; import com.android.internal.R; import com.android.internal.location.GpsNetInitiatedHandler; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.util.FrameworkStatsLog; import java.util.Arrays; import java.util.List; @@ -650,7 +650,7 @@ class GnssVisibilityControl { } private void logEvent(NfwNotification notification, boolean isPermissionMismatched) { - StatsLog.write(StatsLog.GNSS_NFW_NOTIFICATION_REPORTED, + FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NFW_NOTIFICATION_REPORTED, notification.mProxyAppPackageName, notification.mProtocolStack, notification.mOtherProtocolStackName, diff --git a/services/core/java/com/android/server/location/LocationUsageLogger.java b/services/core/java/com/android/server/location/LocationUsageLogger.java index 755438b1a413..93e19df01cf3 100644 --- a/services/core/java/com/android/server/location/LocationUsageLogger.java +++ b/services/core/java/com/android/server/location/LocationUsageLogger.java @@ -24,9 +24,9 @@ import android.location.LocationManager; import android.location.LocationRequest; import android.stats.location.LocationStatsEnums; import android.util.Log; -import android.util.StatsLog; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.FrameworkStatsLog; import java.time.Instant; @@ -61,8 +61,8 @@ public class LocationUsageLogger { boolean isLocationRequestNull = locationRequest == null; boolean isGeofenceNull = geofence == null; - StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType, - apiInUse, packageName, + FrameworkStatsLog.write(FrameworkStatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, + usageType, apiInUse, packageName, isLocationRequestNull ? LocationStatsEnums.PROVIDER_UNKNOWN : bucketizeProvider(locationRequest.getProvider()), @@ -101,7 +101,8 @@ public class LocationUsageLogger { return; } - StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType, apiInUse, + FrameworkStatsLog.write(FrameworkStatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, + usageType, apiInUse, /* package_name= */ null, bucketizeProvider(providerName), LocationStatsEnums.QUALITY_UNKNOWN, diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 80f6a941bfa0..7104790d0a7c 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -90,10 +90,10 @@ import static android.service.notification.NotificationListenerService.REASON_UN import static android.service.notification.NotificationListenerService.REASON_USER_STOPPED; import static android.service.notification.NotificationListenerService.TRIM_FULL; import static android.service.notification.NotificationListenerService.TRIM_LIGHT; -import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING; -import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; +import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING; +import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE; import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER; import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER; import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER; @@ -219,7 +219,6 @@ import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; -import android.util.StatsLog; import android.util.Xml; import android.util.proto.ProtoOutputStream; import android.view.accessibility.AccessibilityEvent; @@ -232,6 +231,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.compat.IPlatformCompat; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; +import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -243,6 +243,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.internal.util.function.TriPredicate; @@ -380,6 +381,8 @@ public class NotificationManagerService extends SystemService { private static final String SCHEME_TIMEOUT = "timeout"; private static final String EXTRA_KEY = "key"; + private static final int NOTIFICATION_INSTANCE_ID_MAX = (1 << 13); + /** * Apps that post custom toasts in the background will have those blocked. Apps can * still post toasts created with @@ -519,6 +522,7 @@ public class NotificationManagerService extends SystemService { private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable(); private NotificationRecordLogger mNotificationRecordLogger; + private InstanceIdSequence mNotificationInstanceIdSequence; private static class Archive { final int mBufferSize; @@ -1718,18 +1722,22 @@ public class NotificationManagerService extends SystemService { } public NotificationManagerService(Context context) { - this(context, new NotificationRecordLoggerImpl()); + this(context, + new NotificationRecordLoggerImpl(), + new InstanceIdSequence(NOTIFICATION_INSTANCE_ID_MAX)); } @VisibleForTesting public NotificationManagerService(Context context, - NotificationRecordLogger notificationRecordLogger) { + NotificationRecordLogger notificationRecordLogger, + InstanceIdSequence notificationInstanceIdSequence) { super(context); mNotificationRecordLogger = notificationRecordLogger; + mNotificationInstanceIdSequence = notificationInstanceIdSequence; Notification.processWhitelistToken = WHITELIST_TOKEN; } - // TODO - replace these methods with a single VisibleForTesting constructor + // TODO - replace these methods with new fields in the VisibleForTesting constructor @VisibleForTesting void setAudioManager(AudioManager audioMananger) { mAudioManager = audioMananger; @@ -5780,14 +5788,14 @@ public class NotificationManagerService extends SystemService { ? intent.resolveActivityInfo(context.getPackageManager(), 0) : null; if (info == null) { - StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName, + FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName, BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING); Log.w(TAG, "Unable to send as bubble -- couldn't find activity info for intent: " + intent); return false; } if (!ActivityInfo.isResizeableMode(info.resizeMode)) { - StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName, + FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName, BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE); Log.w(TAG, "Unable to send as bubble -- activity is not resizable for intent: " + intent); @@ -6291,6 +6299,14 @@ public class NotificationManagerService extends SystemService { NotificationRecord old = mNotificationsByKey.get(key); final StatusBarNotification n = r.sbn; final Notification notification = n.getNotification(); + + // Make sure the SBN has an instance ID for statsd logging. + if (old == null || old.sbn.getInstanceId() == null) { + n.setInstanceId(mNotificationInstanceIdSequence.newInstanceId()); + } else { + n.setInstanceId(old.sbn.getInstanceId()); + } + int index = indexOfNotificationLocked(n.getKey()); if (index < 0) { mNotificationList.add(r); diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java index 03929e883852..9bbc39249e2e 100644 --- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java +++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java @@ -138,5 +138,9 @@ public interface NotificationRecordLogger { String assistant = r.getAdjustmentIssuer(); return (assistant == null) ? 0 : assistant.hashCode(); } + + int getInstanceId() { + return (r.sbn.getInstanceId() == null ? 0 : r.sbn.getInstanceId().getId()); + } } } diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java index d637ad5e368b..00b4c2b060ac 100644 --- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java +++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java @@ -35,7 +35,7 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger { /* int32 event_id = 1 */ p.getUiEvent().getId(), /* int32 uid = 2 */ r.getUid(), /* string package_name = 3 */ r.sbn.getPackageName(), - /* int32 instance_id = 4 */ 0, // TODO generate and fill instance ids + /* int32 instance_id = 4 */ p.getInstanceId(), /* int32 notification_id = 5 */ r.sbn.getId(), /* string notification_tag = 6 */ r.sbn.getTag(), /* string channel_id = 7 */ r.sbn.getChannelIdLogTag(), diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 431b4dc280f1..38da8ab26962 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -147,7 +147,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final String TAG = "PackageInstallerSession"; @@ -736,22 +735,33 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } return result; } - return mFiles.stream().map(fileInfo -> fileInfo.name).toArray(String[]::new); + + String[] result = new String[mFiles.size()]; + for (int i = 0, size = mFiles.size(); i < size; ++i) { + result[i] = mFiles.get(i).name; + } + return result; } - private static File[] filterFiles(File parent, String[] names, FileFilter filter) { - return Arrays.stream(names).map(name -> new File(parent, name)).filter( - file -> filter.accept(file)).toArray(File[]::new); + private static ArrayList<File> filterFiles(File parent, String[] names, FileFilter filter) { + ArrayList<File> result = new ArrayList<>(names.length); + for (String name : names) { + File file = new File(parent, name); + if (filter.accept(file)) { + result.add(file); + } + } + return result; } @GuardedBy("mLock") - private File[] getAddedApksLocked() { + private List<File> getAddedApksLocked() { String[] names = getNamesLocked(); return filterFiles(stageDir, names, sAddedApkFilter); } @GuardedBy("mLock") - private File[] getRemovedFilesLocked() { + private List<File> getRemovedFilesLocked() { String[] names = getNamesLocked(); return filterFiles(stageDir, names, sRemovedFilter); } @@ -1070,11 +1080,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private final class FileSystemConnector extends IPackageInstallerSessionFileSystemConnector.Stub { - final Set<String> mAddedFiles; + final Set<String> mAddedFiles = new ArraySet<>(); FileSystemConnector(List<InstallationFile> addedFiles) { - mAddedFiles = addedFiles.stream().map(file -> file.getName()).collect( - Collectors.toSet()); + for (InstallationFile file : addedFiles) { + mAddedFiles.add(file.getName()); + } } @Override @@ -1741,8 +1752,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @GuardedBy("mLock") private void validateApexInstallLocked() throws PackageManagerException { - final File[] addedFiles = getAddedApksLocked(); - if (ArrayUtils.isEmpty(addedFiles)) { + final List<File> addedFiles = getAddedApksLocked(); + if (addedFiles.isEmpty()) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); } @@ -1751,7 +1762,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Too many files for apex install"); } - File addedFile = addedFiles[0]; // there is only one file + File addedFile = addedFiles.get(0); // there is only one file // Ensure file name has proper suffix final String sourceName = addedFile.getName(); @@ -1818,9 +1829,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { && params.mode == SessionParams.MODE_INHERIT_EXISTING && VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath()); - final File[] removedFiles = getRemovedFilesLocked(); + final List<File> removedFiles = getRemovedFilesLocked(); final List<String> removeSplitList = new ArrayList<>(); - if (!ArrayUtils.isEmpty(removedFiles)) { + if (!removedFiles.isEmpty()) { for (File removedFile : removedFiles) { final String fileName = removedFile.getName(); final String splitName = fileName.substring( @@ -1829,8 +1840,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } - final File[] addedFiles = getAddedApksLocked(); - if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) { + final List<File> addedFiles = getAddedApksLocked(); + if (addedFiles.isEmpty() && removeSplitList.size() == 0) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); } @@ -2449,16 +2460,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return true; } - final List<InstallationFile> addedFiles = mFiles.stream().filter( - file -> sAddedFilter.accept(new File(file.name))).map( - file -> new InstallationFile( - file.name, file.lengthBytes, file.metadata)).collect( - Collectors.toList()); - final List<String> removedFiles = mFiles.stream().filter( - file -> sRemovedFilter.accept(new File(file.name))).map( - file -> file.name.substring( - 0, file.name.length() - REMOVE_MARKER_EXTENSION.length())).collect( - Collectors.toList()); + final List<InstallationFile> addedFiles = new ArrayList<>(mFiles.size()); + for (FileInfo file : mFiles) { + if (sAddedFilter.accept(new File(this.stageDir, file.name))) { + addedFiles.add(new InstallationFile( + file.name, file.lengthBytes, file.metadata)); + } + } + final List<String> removedFiles = new ArrayList<>(mFiles.size()); + for (FileInfo file : mFiles) { + if (sRemovedFilter.accept(new File(this.stageDir, file.name))) { + String name = file.name.substring( + 0, file.name.length() - REMOVE_MARKER_EXTENSION.length()); + removedFiles.add(name); + } + } if (mIncrementalFileStorages != null) { for (InstallationFile file : addedFiles) { @@ -3101,8 +3117,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } if (grantedRuntimePermissions.size() > 0) { - params.grantedRuntimePermissions = grantedRuntimePermissions - .stream().toArray(String[]::new); + params.grantedRuntimePermissions = (String[]) grantedRuntimePermissions.toArray(); } if (whitelistedRestrictedPermissions.size() > 0) { @@ -3111,14 +3126,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { int[] childSessionIdsArray; if (childSessionIds.size() > 0) { - childSessionIdsArray = childSessionIds.stream().mapToInt(i -> i).toArray(); + childSessionIdsArray = new int[childSessionIds.size()]; + for (int i = 0, size = childSessionIds.size(); i < size; ++i) { + childSessionIdsArray[i] = childSessionIds.get(i); + } } else { childSessionIdsArray = EMPTY_CHILD_SESSION_ARRAY; } FileInfo[] fileInfosArray = null; if (!files.isEmpty()) { - fileInfosArray = files.stream().toArray(FileInfo[]::new); + fileInfosArray = (FileInfo[]) files.toArray(); } InstallSource installSource = InstallSource.create(installInitiatingPackageName, diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c50048eeab64..857467208b6e 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1244,6 +1244,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return mDisplayRotation; } + void setInsetProvider(@InternalInsetsType int type, WindowState win, + @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider){ + setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */); + } + /** * Marks a window as providing insets for the rest of the windows in the system. * @@ -1251,10 +1256,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * @param win The window. * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of * the window should be taken. + * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or + * {@code null} if the normal frame should be taken. */ void setInsetProvider(@InternalInsetsType int type, WindowState win, - @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) { - mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider); + @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider, + @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) { + mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider, + imeFrameProvider); } InsetsStateController getInsetsStateController() { @@ -3283,7 +3292,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } computeImeTarget(true /* updateImeTarget */); mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win, - null /* frameProvider */); + null /* frameProvider */, null /* imeFrameProvider */); } /** diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index c6ccd4af06c5..4baf913c2a37 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1026,7 +1026,12 @@ public class DisplayPolicy { - getNavigationBarHeight(displayFrames.mRotation, mDisplayContent.getConfiguration().uiMode); } - }); + }, + + // For IME we use regular frame. + (displayFrames, windowState, inOutFrame) -> + inOutFrame.set(windowState.getFrameLw())); + mDisplayContent.setInsetProvider(ITYPE_BOTTOM_GESTURES, win, (displayFrames, windowState, inOutFrame) -> { inOutFrame.top -= mBottomGestureAdditionalInset; @@ -3068,7 +3073,9 @@ public class DisplayPolicy { } final InsetsControlTarget controlTarget = swipeTarget.getControllableInsetProvider().getControlTarget(); - if (controlTarget == null) { + + // No transient mode on lockscreen (in notification shade window). + if (controlTarget == null || controlTarget == getNotificationShade()) { return; } if (controlTarget.canShowTransient()) { diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index fa764e3dfc18..2d4211aa16d8 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -187,6 +187,10 @@ class InsetsPolicy { if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) { return mTransientControlTarget; } + if (focusedWin == mPolicy.getNotificationShade()) { + // Notification shade has control anyways, no reason to force anything. + return focusedWin; + } if (areSystemBarsForciblyVisible() || isKeyguardOrStatusBarForciblyVisible()) { return null; } @@ -197,6 +201,10 @@ class InsetsPolicy { if (mShowingTransientTypes.indexOf(ITYPE_NAVIGATION_BAR) != -1) { return mTransientControlTarget; } + if (focusedWin == mPolicy.getNotificationShade()) { + // Notification shade has control anyways, no reason to force anything. + return focusedWin; + } if (areSystemBarsForciblyVisible() || isNavBarForciblyVisible()) { return null; } @@ -204,9 +212,6 @@ class InsetsPolicy { } private boolean isKeyguardOrStatusBarForciblyVisible() { - if (mPolicy.isKeyguardShowing()) { - return true; - } final WindowState statusBar = mPolicy.getStatusBar(); if (statusBar != null) { // TODO(b/118118435): Pretend to the app that it's still able to control it? diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 2bb58ddc5b38..d540179a9491 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -34,6 +34,7 @@ import android.util.proto.ProtoOutputStream; import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; +import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; @@ -61,6 +62,8 @@ class InsetsSourceProvider { private @Nullable ControlAdapter mAdapter; private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider; + private TriConsumer<DisplayFrames, WindowState, Rect> mImeFrameProvider; + private final Rect mImeOverrideFrame = new Rect(); /** The visibility override from the current controlling window. */ private boolean mClientVisible; @@ -111,9 +114,12 @@ class InsetsSourceProvider { * @param win The window that links to this source. * @param frameProvider Based on display frame state and the window, calculates the resulting * frame that should be reported to clients. + * @param imeFrameProvider Based on display frame state and the window, calculates the resulting + * frame that should be reported to IME. */ void setWindow(@Nullable WindowState win, - @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) { + @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider, + @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) { if (mWin != null) { if (mControllable) { mWin.setControllableInsetProvider(null); @@ -126,6 +132,7 @@ class InsetsSourceProvider { } mWin = win; mFrameProvider = frameProvider; + mImeFrameProvider = imeFrameProvider; if (win == null) { setServerVisible(false); mSource.setFrame(new Rect()); @@ -162,6 +169,12 @@ class InsetsSourceProvider { } mSource.setFrame(mTmpRect); + if (mImeFrameProvider != null) { + mImeOverrideFrame.set(mWin.getFrameLw()); + mImeFrameProvider.accept(mWin.getDisplayContent().mDisplayFrames, mWin, + mImeOverrideFrame); + } + if (mWin.mGivenVisibleInsets.left != 0 || mWin.mGivenVisibleInsets.top != 0 || mWin.mGivenVisibleInsets.right != 0 || mWin.mGivenVisibleInsets.bottom != 0) { mTmpRect.set(mWin.getFrameLw()); @@ -303,6 +316,21 @@ class InsetsSourceProvider { return sNewInsetsMode == NEW_INSETS_MODE_NONE || mClientVisible; } + /** + * @return Whether this provider uses a different frame to dispatch to the IME. + */ + boolean overridesImeFrame() { + return mImeFrameProvider != null; + } + + /** + * @return Rect to dispatch to the IME as frame. Only valid if {@link #overridesImeFrame()} + * returns {@code true}. + */ + Rect getImeOverrideFrame() { + return mImeOverrideFrame; + } + private class ControlAdapter implements AnimationAdapter { private SurfaceControl mCapturedLeash; diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index b2234d17984e..3e698da13097 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -88,6 +88,20 @@ class InsetsStateController { state.removeSource(ITYPE_IME); state.removeSource(ITYPE_STATUS_BAR); } + + // IME needs different frames for certain cases (e.g. navigation bar in gesture nav). + if (type == ITYPE_IME) { + for (int i = mProviders.size() - 1; i >= 0; i--) { + InsetsSourceProvider otherProvider = mProviders.valueAt(i); + if (otherProvider.overridesImeFrame()) { + InsetsSource override = + new InsetsSource(state.getSource(otherProvider.getSource().getType())); + override.setFrame(otherProvider.getImeOverrideFrame()); + state.addSource(override); + } + } + } + return state; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index d7ea2f53c286..ec3ef7807c3a 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -9553,9 +9553,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override - public void setDefaultSmsApplication(ComponentName admin, String packageName) { + public void setDefaultSmsApplication(ComponentName admin, String packageName, boolean parent) { Objects.requireNonNull(admin, "ComponentName is null"); - enforceDeviceOwner(admin); + + if (parent) { + ActiveAdmin ap = getActiveAdminForCallerLocked(admin, + DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent); + enforceProfileOwnerOfOrganizationOwnedDevice(ap); + mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage( + packageName, getProfileParentId(mInjector.userHandleGetCallingUserId()))); + } else { + enforceDeviceOwner(admin); + } + mInjector.binderWithCleanCallingIdentity(() -> SmsApplication.setDefaultApplication(packageName, mContext)); } @@ -10778,7 +10788,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // API cannot be used to leak if certain non-system package exists in the person // profile. mInjector.binderWithCleanCallingIdentity(() -> - enforcePackageIsSystemPackage(packageName, hidden, userId)); + enforcePackageIsSystemPackage(packageName, userId)); } result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager @@ -10811,7 +10821,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent); // Ensure the package provided is a system package. mInjector.binderWithCleanCallingIdentity(() -> - enforcePackageIsSystemPackage(packageName, false, userId)); + enforcePackageIsSystemPackage(packageName, userId)); } return mInjector.binderWithCleanCallingIdentity( @@ -10819,16 +10829,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void enforcePackageIsSystemPackage(String packageName, boolean hidden, int userId) + private void enforcePackageIsSystemPackage(String packageName, int userId) throws RemoteException { - int flags = PackageManager.MATCH_SYSTEM_ONLY; - // If the package is currently hidden then it is considered uninstalled and - // the MATCH_UNINSTALLED_PACKAGES flag has to be added. - if (!hidden) { - flags |= PackageManager.MATCH_UNINSTALLED_PACKAGES; - } - PackageInfo packageInfo = mIPackageManager.getPackageInfo(packageName, flags, userId); - if (packageInfo == null || !packageInfo.applicationInfo.isSystemApp()) { + if (!isSystemApp(mIPackageManager, packageName, userId)) { throw new IllegalArgumentException( "The provided package is not a system package"); } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 422c278a3af7..f7a9e5456156 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -2223,17 +2223,13 @@ public class DevicePolicyManagerTest extends DpmTestBase { String packageName = "com.google.android.test"; - PackageInfo packageInfo = new PackageInfo(); - packageInfo.applicationInfo = new ApplicationInfo(); - packageInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; when(getServices().userManager.getProfileParent(MANAGED_PROFILE_USER_ID)) .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); - when(getServices().ipackageManager.getPackageInfo(packageName, - PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM)).thenReturn( - packageInfo); - when(getServices().ipackageManager.getPackageInfo(packageName, - PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_SYSTEM_ONLY, - UserHandle.USER_SYSTEM)).thenReturn(packageInfo); + when(getServices().ipackageManager.getApplicationInfo(packageName, + PackageManager.MATCH_UNINSTALLED_PACKAGES, UserHandle.USER_SYSTEM)).thenReturn( + applicationInfo); parentDpm.setApplicationHidden(admin1, packageName, true); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, diff --git a/core/java/com/android/internal/logging/testing/InstanceIdSequenceFake.java b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java index 0fd40b9ceb06..1629ef00b65a 100644 --- a/core/java/com/android/internal/logging/testing/InstanceIdSequenceFake.java +++ b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java @@ -14,12 +14,7 @@ * limitations under the License. */ -package com.android.internal.logging.testing; - -import android.annotation.SuppressLint; - -import com.android.internal.logging.InstanceId; -import com.android.internal.logging.InstanceIdSequence; +package com.android.internal.logging; /** * A fake implementation of InstanceIdSequence that returns 0, 1, 2, ... @@ -30,27 +25,15 @@ public class InstanceIdSequenceFake extends InstanceIdSequence { super(instanceIdMax); } - /** - * Extend InstanceId to add a constructor we can call, strictly for testing purposes. - * Public so that tests can check whether the InstanceIds they see are fake. - */ - public static class InstanceIdFake extends InstanceId { - @SuppressLint("VisibleForTests") // This is test infrastructure, which ought to count - InstanceIdFake(int id) { - super(id); - } - } - private int mNextId = 0; @Override public InstanceId newInstanceId() { synchronized (this) { - ++mNextId; if (mNextId >= mInstanceIdMax) { mNextId = 0; } - return new InstanceIdFake(mNextId); + return newInstanceIdInternal(mNextId++); } } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index 651ad40a4781..f029bc80480a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -72,6 +72,8 @@ import android.view.accessibility.IAccessibilityManagerClient; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.InstanceIdSequenceFake; import com.android.internal.util.IntPair; import com.android.server.UiServiceTestCase; import com.android.server.lights.LogicalLight; @@ -99,6 +101,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { @Mock IAccessibilityManager mAccessibilityService; NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); + private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( + 1 << 30); private NotificationManagerService mService; private String mPkg = "com.android.server.notification"; @@ -149,7 +153,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt()); assertTrue(accessibilityManager.isEnabled()); - mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger)); + mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger, + mNotificationInstanceIdSequence)); mService.setAudioManager(mAudioManager); mService.setVibrator(mVibrator); mService.setSystemReady(true); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 768b4721a1ee..2cf5eaefcc58 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -148,6 +148,8 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.R; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; +import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.InstanceIdSequenceFake; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.util.FastXmlSerializer; import com.android.server.LocalServices; @@ -257,7 +259,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock NotificationHistoryManager mHistoryManager; NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); - + private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( + 1 << 30); // Use a Testable subclass so we can simulate calls from the system without failing. private static class TestableNotificationManagerService extends NotificationManagerService { @@ -267,8 +270,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Nullable NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; - TestableNotificationManagerService(Context context, NotificationRecordLogger logger) { - super(context, logger); + TestableNotificationManagerService(Context context, NotificationRecordLogger logger, + InstanceIdSequence notificationInstanceIdSequence) { + super(context, logger, notificationInstanceIdSequence); } @Override @@ -355,7 +359,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger); + mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, + mNotificationInstanceIdSequence); // Use this testable looper. mTestableLooper = TestableLooper.get(this); @@ -1135,6 +1140,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(PKG, call.r.sbn.getPackageName()); assertEquals(0, call.r.sbn.getId()); assertEquals(tag, call.r.sbn.getTag()); + assertNotNull(call.r.sbn.getInstanceId()); + assertEquals(0, call.r.sbn.getInstanceId().getId()); } @Test @@ -1151,14 +1158,19 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, update, 0); waitForIdle(); assertEquals(2, mNotificationRecordLogger.getCalls().size()); + assertTrue(mNotificationRecordLogger.get(0).shouldLog()); assertEquals( NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, mNotificationRecordLogger.get(0).getUiEvent()); + assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId()); + + assertTrue(mNotificationRecordLogger.get(1).shouldLog()); assertEquals( NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_UPDATED, mNotificationRecordLogger.get(1).getUiEvent()); - assertTrue(mNotificationRecordLogger.get(1).shouldLog()); + // Instance ID doesn't change on update of an active notification + assertEquals(0, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId()); } @Test @@ -1175,6 +1187,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testEnqueueNotificationWithTag_LogsAgainAfterCancel() throws Exception { + final String tag = "testEnqueueNotificationWithTag_LogsAgainAfterCancel"; + Notification notification = new Notification.Builder(mContext, + mTestNotificationChannel.getId()) + .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); + mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, 0); + waitForIdle(); + mBinderService.cancelNotificationWithTag(PKG, PKG, tag, 0, 0); + waitForIdle(); + mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, 0); + waitForIdle(); + assertEquals(2, mNotificationRecordLogger.getCalls().size()); + + assertTrue(mNotificationRecordLogger.get(0).shouldLog()); + assertEquals( + NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, + mNotificationRecordLogger.get(0).getUiEvent()); + assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId()); + + assertTrue(mNotificationRecordLogger.get(1).shouldLog()); + assertEquals( + NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, + mNotificationRecordLogger.get(1).getUiEvent()); + // New instance ID because notification was canceled before re-post + assertEquals(1, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId()); + } + + @Test public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception { mBinderService.enqueueNotificationWithTag(PKG, PKG, "testCancelNotificationImmediatelyAfterEnqueue", 0, @@ -2309,7 +2349,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testHasCompanionDevice_noService() { - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger); + mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, + mNotificationInstanceIdSequence); assertFalse(mService.hasCompanionDevice(mListener)); } @@ -4679,8 +4720,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.canNotifyAsPackage("src", "target", mContext.getUserId() + 1); } @@ -4698,8 +4738,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.getNotificationChannels("src", "target", mContext.getUserId() + 1); } @@ -5317,8 +5356,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid + UserHandle.PER_USER_RANGE); } @@ -5334,12 +5372,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.areBubblesAllowedForPackage(mContext.getPackageName(), mUid + UserHandle.PER_USER_RANGE); } + private void enableInteractAcrossUsers() { + TestablePermissions perms = mContext.getTestablePermissions(); + perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + } + @Test public void testNotificationBubbleChanged_false() throws Exception { // Bubbles are allowed! diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java index 11972fd6a8dc..5c1487f0fdf6 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java @@ -23,7 +23,7 @@ import java.util.List; * Fake implementation of NotificationRecordLogger, for testing. */ class NotificationRecordLoggerFake implements NotificationRecordLogger { - class CallRecord extends NotificationRecordPair { + static class CallRecord extends NotificationRecordPair { public int position, buzzBeepBlink; CallRecord(NotificationRecord r, NotificationRecord old, int position, int buzzBeepBlink) { @@ -35,7 +35,7 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger { return shouldLog(buzzBeepBlink); } } - List<CallRecord> mCalls = new ArrayList<CallRecord>(); + private List<CallRecord> mCalls = new ArrayList<CallRecord>(); List<CallRecord> getCalls() { return mCalls; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java index e18c8919b645..64a980484539 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -54,6 +54,8 @@ import android.util.ArraySet; import android.util.AtomicFile; import android.util.Pair; +import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.InstanceIdSequenceFake; import com.android.server.LocalServices; import com.android.server.UiServiceTestCase; import com.android.server.lights.LightsManager; @@ -92,12 +94,15 @@ public class RoleObserverTest extends UiServiceTestCase { @Mock private RoleManager mRoleManager; NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); - + private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( + 1 << 30); private List<UserInfo> mUsers; private static class TestableNotificationManagerService extends NotificationManagerService { - TestableNotificationManagerService(Context context, NotificationRecordLogger logger) { - super(context, logger); + TestableNotificationManagerService(Context context, + NotificationRecordLogger logger, + InstanceIdSequence notificationInstanceIdSequence) { + super(context, logger, notificationInstanceIdSequence); } @Override @@ -120,7 +125,8 @@ public class RoleObserverTest extends UiServiceTestCase { mUsers.add(new UserInfo(10, "second", 0)); when(mUm.getUsers()).thenReturn(mUsers); - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger); + mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, + mNotificationInstanceIdSequence); mRoleObserver = mService.new RoleObserver(mRoleManager, mPm, mExecutor); try { diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index c3bead7162e6..e71225579989 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -119,18 +119,6 @@ public class InsetsPolicyTest extends WindowTestsBase { assertNull(controls); } - @Test - public void testControlsForDispatch_keyguard() { - addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade"); - addWindow(TYPE_NAVIGATION_BAR, "navBar"); - mockKeyguardShowing(); - - final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); - // The app must not control the top bar. - assertNotNull(controls); - assertEquals(1, controls.length); - } - // TODO: adjust this test if we pretend to the app that it's still able to control it. @Test public void testControlsForDispatch_forceStatusBarVisible() { @@ -159,6 +147,21 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test + public void testControlsForDispatch_statusBarForceShowNavigation_butFocusedAnyways() { + WindowState notifShade = addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade"); + notifShade.mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; + addWindow(TYPE_NAVIGATION_BAR, "navBar"); + + mDisplayContent.getInsetsPolicy().updateBarControlTarget(notifShade); + InsetsSourceControl[] controls + = mDisplayContent.getInsetsStateController().getControlsForDispatch(notifShade); + + // The app controls the navigation bar. + assertNotNull(controls); + assertEquals(1, controls.length); + } + + @Test public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() { addWindow(TYPE_STATUS_BAR, "statusBar") .getControllableInsetProvider().getSource().setVisible(false); @@ -260,10 +263,4 @@ public class InsetsPolicyTest extends WindowTestsBase { mDisplayContent.getInsetsPolicy().updateBarControlTarget(win); return mDisplayContent.getInsetsStateController().getControlsForDispatch(win); } - - private void mockKeyguardShowing() { - final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy(); - spyOn(displayPolicy); - doReturn(true).when(displayPolicy).isKeyguardShowing(); - } } diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java index d819b1ada659..7ffdd7cdceb6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java @@ -57,7 +57,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); statusBar.getFrameLw().set(0, 0, 500, 100); statusBar.mHasSurface = true; - mProvider.setWindow(statusBar, null); + mProvider.setWindow(statusBar, null, null); mProvider.onPostLayout(); assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame()); assertEquals(Insets.of(0, 100, 0, 0), @@ -74,7 +74,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { ime.getGivenContentInsetsLw().set(0, 0, 0, 60); ime.getGivenVisibleInsetsLw().set(0, 0, 0, 75); ime.mHasSurface = true; - mProvider.setWindow(ime, null); + mProvider.setWindow(ime, null, null); mProvider.onPostLayout(); assertEquals(new Rect(0, 0, 500, 40), mProvider.getSource().getFrame()); assertEquals(new Rect(0, 0, 500, 25), mProvider.getSource().getVisibleFrame()); @@ -89,7 +89,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { public void testPostLayout_invisible() { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); statusBar.getFrameLw().set(0, 0, 500, 100); - mProvider.setWindow(statusBar, null); + mProvider.setWindow(statusBar, null, null); mProvider.onPostLayout(); assertEquals(Insets.NONE, mProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500), false /* ignoreVisibility */)); @@ -102,7 +102,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { mProvider.setWindow(statusBar, (displayFrames, windowState, rect) -> { rect.set(10, 10, 20, 20); - }); + }, null); mProvider.onPostLayout(); assertEquals(new Rect(10, 10, 20, 20), mProvider.getSource().getFrame()); } @@ -112,7 +112,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); statusBar.getFrameLw().set(0, 0, 500, 100); - mProvider.setWindow(statusBar, null); + mProvider.setWindow(statusBar, null, null); mProvider.updateControlForTarget(target, false /* force */); assertNotNull(mProvider.getControl(target)); mProvider.updateControlForTarget(null, false /* force */); @@ -124,7 +124,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); statusBar.getFrameLw().set(0, 0, 500, 100); - mProvider.setWindow(statusBar, null); + mProvider.setWindow(statusBar, null, null); mProvider.updateControlForFakeTarget(target); assertNotNull(mProvider.getControl(target)); assertNull(mProvider.getControl(target).getLeash()); @@ -137,7 +137,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); statusBar.getFrameLw().set(0, 0, 500, 100); - mProvider.setWindow(statusBar, null); + mProvider.setWindow(statusBar, null, null); mProvider.updateControlForTarget(target, false /* force */); InsetsState state = new InsetsState(); state.getSource(ITYPE_STATUS_BAR).setVisible(false); @@ -150,7 +150,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); statusBar.getFrameLw().set(0, 0, 500, 100); - mProvider.setWindow(statusBar, null); + mProvider.setWindow(statusBar, null, null); InsetsState state = new InsetsState(); state.getSource(ITYPE_STATUS_BAR).setVisible(false); mProvider.onInsetsModified(target, state.getSource(ITYPE_STATUS_BAR)); diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java index d13baeccb68a..39cdd2cb907e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java @@ -21,26 +21,26 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.test.InsetsModeSession; -import androidx.test.filters.FlakyTest; -import androidx.test.filters.SmallTest; - import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import androidx.test.filters.FlakyTest; +import androidx.test.filters.SmallTest; + @SmallTest @FlakyTest(detail = "Promote to pre-submit once confirmed stable.") @Presubmit @@ -65,7 +65,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { public void testStripForDispatch_notOwn() { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); - getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null); + getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null); statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR)); assertNotNull(getController().getInsetsForDispatch(app).getSource(ITYPE_STATUS_BAR)); } @@ -74,7 +74,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { public void testStripForDispatch_own() { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR) - .setWindow(statusBar, null); + .setWindow(statusBar, null, null); statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR)); final InsetsState state = getController().getInsetsForDispatch(statusBar); for (int i = state.getSourcesCount() - 1; i >= 0; i--) { @@ -88,19 +88,36 @@ public class InsetsStateControllerTest extends WindowTestsBase { final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar"); final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); - getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null); - getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null); - getController().getSourceProvider(ITYPE_IME).setWindow(ime, null); + getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null); + getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null); + getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); assertEquals(0, getController().getInsetsForDispatch(navBar).getSourcesCount()); } @Test + public void testImeForDispatch() { + final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); + final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); + InsetsSourceProvider statusBarProvider = + getController().getSourceProvider(ITYPE_STATUS_BAR); + statusBarProvider.setWindow(statusBar, null, ((displayFrames, windowState, rect) -> + rect.set(0, 1, 2, 3))); + getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + statusBar.setControllableInsetProvider(statusBarProvider); + + statusBarProvider.onPostLayout(); + + final InsetsState state = getController().getInsetsForDispatch(ime); + assertEquals(new Rect(0, 1, 2, 3), state.getSource(ITYPE_STATUS_BAR).getFrame()); + } + + @Test public void testBarControllingWinChanged() { final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar"); final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); - getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null); - getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null); + getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null); + getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null); getController().onBarControlTargetChanged(app, null, app, null); InsetsSourceControl[] controls = getController().getControlsForDispatch(app); assertEquals(2, controls.length); @@ -110,7 +127,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { public void testControlRevoked() { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); - getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null); + getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null); getController().onBarControlTargetChanged(app, null, null, null); assertNotNull(getController().getControlsForDispatch(app)); getController().onBarControlTargetChanged(null, null, null, null); @@ -122,7 +139,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { public void testControlRevoked_animation() { final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar"); final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); - getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null); + getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null); getController().onBarControlTargetChanged(app, null, null, null); assertNotNull(getController().getControlsForDispatch(app)); statusBar.cancelAnimation(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 186ff6b1515b..2c68cc7a19bf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -425,7 +425,7 @@ public class WindowStateTests extends WindowTestsBase { statusBar.mHasSurface = true; assertTrue(statusBar.isVisible()); mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR) - .setWindow(statusBar, null /* frameProvider */); + .setWindow(statusBar, null /* frameProvider */, null /* imeFrameProvider */); mDisplayContent.getInsetsStateController().onBarControlTargetChanged( app, null /* fakeTopControlling */, app, null /* fakeNavControlling */); final InsetsSource source = new InsetsSource(ITYPE_STATUS_BAR); diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index 9967bebf20b8..140a95d61100 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -34,9 +34,9 @@ import android.service.usb.UsbIsHeadsetProto; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Slog; -import android.util.StatsLog; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.usb.descriptors.UsbDescriptor; @@ -418,10 +418,11 @@ public class UsbHostManager { parser.getRawDescriptors()); // Stats collection - StatsLog.write(StatsLog.USB_DEVICE_ATTACHED, newDevice.getVendorId(), - newDevice.getProductId(), parser.hasAudioInterface(), - parser.hasHIDInterface(), parser.hasStorageInterface(), - StatsLog.USB_DEVICE_ATTACHED__STATE__STATE_CONNECTED, 0); + FrameworkStatsLog.write(FrameworkStatsLog.USB_DEVICE_ATTACHED, + newDevice.getVendorId(), newDevice.getProductId(), + parser.hasAudioInterface(), parser.hasHIDInterface(), + parser.hasStorageInterface(), + FrameworkStatsLog.USB_DEVICE_ATTACHED__STATE__STATE_CONNECTED, 0); } } @@ -454,10 +455,10 @@ public class UsbHostManager { UsbDescriptorParser parser = new UsbDescriptorParser(deviceAddress, current.mDescriptors); // Stats collection - StatsLog.write(StatsLog.USB_DEVICE_ATTACHED, device.getVendorId(), - device.getProductId(), parser.hasAudioInterface(), + FrameworkStatsLog.write(FrameworkStatsLog.USB_DEVICE_ATTACHED, + device.getVendorId(), device.getProductId(), parser.hasAudioInterface(), parser.hasHIDInterface(), parser.hasStorageInterface(), - StatsLog.USB_DEVICE_ATTACHED__STATE__STATE_DISCONNECTED, + FrameworkStatsLog.USB_DEVICE_ATTACHED__STATE__STATE_DISCONNECTED, System.currentTimeMillis() - current.mTimestamp); } } else { diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index c3e2013eff10..1025bf5d67b0 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -66,11 +66,11 @@ import android.service.usb.UsbServiceProto; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; -import android.util.StatsLog; import com.android.internal.annotations.GuardedBy; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.server.FgThread; @@ -1040,8 +1040,9 @@ public class UsbPortManager { if (mConnected.containsKey(portInfo.mUsbPort.getId())) { //Previous logged a connected. Set it to disconnected. if (mConnected.get(portInfo.mUsbPort.getId())) { - StatsLog.write(StatsLog.USB_CONNECTOR_STATE_CHANGED, - StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED, + FrameworkStatsLog.write(FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED, + FrameworkStatsLog + .USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED, portInfo.mUsbPort.getId(), portInfo.mLastConnectDurationMillis); } mConnected.remove(portInfo.mUsbPort.getId()); @@ -1051,7 +1052,7 @@ public class UsbPortManager { //Previous logged a contaminant detected. Set it to not detected. if ((mContaminantStatus.get(portInfo.mUsbPort.getId()) == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED)) { - StatsLog.write(StatsLog.USB_CONTAMINANT_REPORTED, + FrameworkStatsLog.write(FrameworkStatsLog.USB_CONTAMINANT_REPORTED, portInfo.mUsbPort.getId(), convertContaminantDetectionStatusToProto( UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED)); @@ -1065,10 +1066,10 @@ public class UsbPortManager { || (mConnected.get(portInfo.mUsbPort.getId()) != portInfo.mUsbPortStatus.isConnected())) { mConnected.put(portInfo.mUsbPort.getId(), portInfo.mUsbPortStatus.isConnected()); - StatsLog.write(StatsLog.USB_CONNECTOR_STATE_CHANGED, + FrameworkStatsLog.write(FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED, portInfo.mUsbPortStatus.isConnected() - ? StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_CONNECTED : - StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED, + ? FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_CONNECTED : + FrameworkStatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED, portInfo.mUsbPort.getId(), portInfo.mLastConnectDurationMillis); } @@ -1077,7 +1078,7 @@ public class UsbPortManager { != portInfo.mUsbPortStatus.getContaminantDetectionStatus())) { mContaminantStatus.put(portInfo.mUsbPort.getId(), portInfo.mUsbPortStatus.getContaminantDetectionStatus()); - StatsLog.write(StatsLog.USB_CONTAMINANT_REPORTED, + FrameworkStatsLog.write(FrameworkStatsLog.USB_CONTAMINANT_REPORTED, portInfo.mUsbPort.getId(), convertContaminantDetectionStatusToProto( portInfo.mUsbPortStatus.getContaminantDetectionStatus())); diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java index b230e4bbf8a2..43d5bf323abb 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java @@ -292,9 +292,27 @@ public final class UsbDescriptorParser { // Clean up descriptor.postParse(stream); } catch (Exception ex) { - Log.e(TAG, "Exception parsing USB descriptors.", ex); + // Clean up, compute error status + descriptor.postParse(stream); - // Clean up + // Report + Log.w(TAG, "Exception parsing USB descriptors. type:0x" + descriptor.getType() + + " status:" + descriptor.getStatus()); + if (DEBUG) { + // Show full stack trace if debugging + Log.e(TAG, "Exception parsing USB descriptors.", ex); + } + StackTraceElement[] stackElems = ex.getStackTrace(); + if (stackElems.length > 0) { + Log.i(TAG, " class:" + stackElems[0].getClassName() + + " @ " + stackElems[0].getLineNumber()); + } + if (stackElems.length > 1) { + Log.i(TAG, " class:" + stackElems[1].getClassName() + + " @ " + stackElems[1].getLineNumber()); + } + + // Finish up descriptor.setStatus(UsbDescriptor.STATUS_PARSE_EXCEPTION); } finally { mDescriptors.add(descriptor); diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index 3f0aeb54f132..0c2f1f325793 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -69,8 +69,8 @@ public abstract class CellIdentity implements Parcelable { protected String mAlphaShort; /** @hide */ - protected CellIdentity(String tag, int type, String mcc, String mnc, String alphal, - String alphas) { + protected CellIdentity(@Nullable String tag, int type, @Nullable String mcc, + @Nullable String mnc, @Nullable String alphal, @Nullable String alphas) { mTag = tag; mType = type; diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java index 1a6bf33cec71..e220b07d703a 100644 --- a/telephony/java/android/telephony/CellIdentityCdma.java +++ b/telephony/java/android/telephony/CellIdentityCdma.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.Parcel; import android.telephony.cdma.CdmaCellLocation; @@ -90,8 +91,8 @@ public final class CellIdentityCdma extends CellIdentity { * * @hide */ - public CellIdentityCdma( - int nid, int sid, int bid, int lon, int lat, String alphal, String alphas) { + public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat, + @Nullable String alphal, @Nullable String alphas) { super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas); mNetworkId = inRangeOrUnavailable(nid, 0, NETWORK_ID_MAX); mSystemId = inRangeOrUnavailable(sid, 0, SYSTEM_ID_MAX); @@ -108,22 +109,22 @@ public final class CellIdentityCdma extends CellIdentity { } /** @hide */ - public CellIdentityCdma(android.hardware.radio.V1_0.CellIdentityCdma cid) { + public CellIdentityCdma(@NonNull android.hardware.radio.V1_0.CellIdentityCdma cid) { this(cid.networkId, cid.systemId, cid.baseStationId, cid.longitude, cid.latitude, "", ""); } /** @hide */ - public CellIdentityCdma(android.hardware.radio.V1_2.CellIdentityCdma cid) { + public CellIdentityCdma(@NonNull android.hardware.radio.V1_2.CellIdentityCdma cid) { this(cid.base.networkId, cid.base.systemId, cid.base.baseStationId, cid.base.longitude, cid.base.latitude, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort); } - private CellIdentityCdma(CellIdentityCdma cid) { + private CellIdentityCdma(@NonNull CellIdentityCdma cid) { this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude, cid.mAlphaLong, cid.mAlphaShort); } - CellIdentityCdma copy() { + @NonNull CellIdentityCdma copy() { return new CellIdentityCdma(this); } diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index dc73cbf735b0..9f2537c7ed10 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -23,6 +23,7 @@ import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -78,26 +79,31 @@ public final class CellIdentityGsm extends CellIdentity { * * @hide */ - public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, String mccStr, - String mncStr, String alphal, String alphas, - List<String> additionalPlmns) { + public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, @Nullable String mccStr, + @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas, + @NonNull List<String> additionalPlmns) { super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas); mLac = inRangeOrUnavailable(lac, 0, MAX_LAC); mCid = inRangeOrUnavailable(cid, 0, MAX_CID); mArfcn = inRangeOrUnavailable(arfcn, 0, MAX_ARFCN); mBsic = inRangeOrUnavailable(bsic, 0, MAX_BSIC); - mAdditionalPlmns = additionalPlmns; + mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + for (String plmn : additionalPlmns) { + if (isValidPlmn(plmn)) { + mAdditionalPlmns.add(plmn); + } + } } /** @hide */ - public CellIdentityGsm(android.hardware.radio.V1_0.CellIdentityGsm cid) { + public CellIdentityGsm(@NonNull android.hardware.radio.V1_0.CellIdentityGsm cid) { this(cid.lac, cid.cid, cid.arfcn, cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic, cid.mcc, cid.mnc, "", "", Collections.emptyList()); } /** @hide */ - public CellIdentityGsm(android.hardware.radio.V1_2.CellIdentityGsm cid) { + public CellIdentityGsm(@NonNull android.hardware.radio.V1_2.CellIdentityGsm cid) { this(cid.base.lac, cid.base.cid, cid.base.arfcn, cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort, @@ -105,7 +111,7 @@ public final class CellIdentityGsm extends CellIdentity { } /** @hide */ - public CellIdentityGsm(android.hardware.radio.V1_5.CellIdentityGsm cid) { + public CellIdentityGsm(@NonNull android.hardware.radio.V1_5.CellIdentityGsm cid) { this(cid.base.base.lac, cid.base.base.cid, cid.base.base.arfcn, cid.base.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.base.bsic, cid.base.base.mcc, @@ -113,12 +119,12 @@ public final class CellIdentityGsm extends CellIdentity { cid.base.operatorNames.alphaShort, cid.additionalPlmns); } - private CellIdentityGsm(CellIdentityGsm cid) { + private CellIdentityGsm(@NonNull CellIdentityGsm cid) { this(cid.mLac, cid.mCid, cid.mArfcn, cid.mBsic, cid.mMccStr, cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns); } - CellIdentityGsm copy() { + @NonNull CellIdentityGsm copy() { return new CellIdentityGsm(this); } diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index cf8fe6a3c345..a194ae35216c 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -24,6 +24,7 @@ import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -104,34 +105,40 @@ public final class CellIdentityLte extends CellIdentity { * * @hide */ - public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth, String mccStr, - String mncStr, String alphal, String alphas, List<String> additionalPlmns, - ClosedSubscriberGroupInfo csgInfo) { + public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth, + @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal, + @Nullable String alphas, @NonNull List<String> additionalPlmns, + @Nullable ClosedSubscriberGroupInfo csgInfo) { super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas); mCi = inRangeOrUnavailable(ci, 0, MAX_CI); mPci = inRangeOrUnavailable(pci, 0, MAX_PCI); mTac = inRangeOrUnavailable(tac, 0, MAX_TAC); mEarfcn = inRangeOrUnavailable(earfcn, 0, MAX_EARFCN); mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH); - mAdditionalPlmns = additionalPlmns; + mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + for (String plmn : additionalPlmns) { + if (isValidPlmn(plmn)) { + mAdditionalPlmns.add(plmn); + } + } mCsgInfo = csgInfo; } /** @hide */ - public CellIdentityLte(android.hardware.radio.V1_0.CellIdentityLte cid) { + public CellIdentityLte(@NonNull android.hardware.radio.V1_0.CellIdentityLte cid) { this(cid.ci, cid.pci, cid.tac, cid.earfcn, CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null); } /** @hide */ - public CellIdentityLte(android.hardware.radio.V1_2.CellIdentityLte cid) { + public CellIdentityLte(@NonNull android.hardware.radio.V1_2.CellIdentityLte cid) { this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth, cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort, Collections.emptyList(), null); } /** @hide */ - public CellIdentityLte(android.hardware.radio.V1_5.CellIdentityLte cid) { + public CellIdentityLte(@NonNull android.hardware.radio.V1_5.CellIdentityLte cid) { this(cid.base.base.ci, cid.base.base.pci, cid.base.base.tac, cid.base.base.earfcn, cid.base.bandwidth, cid.base.base.mcc, cid.base.base.mnc, cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort, @@ -139,7 +146,7 @@ public final class CellIdentityLte extends CellIdentity { ? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null); } - private CellIdentityLte(CellIdentityLte cid) { + private CellIdentityLte(@NonNull CellIdentityLte cid) { this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr, cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo); } @@ -152,7 +159,7 @@ public final class CellIdentityLte extends CellIdentity { mMccStr, mMncStr, mAlphaLong, mAlphaShort, mAdditionalPlmns, null); } - CellIdentityLte copy() { + @NonNull CellIdentityLte copy() { return new CellIdentityLte(this); } diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index d4f181fc735a..a0ef5aa2feae 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -64,26 +64,32 @@ public final class CellIdentityNr extends CellIdentity { * @hide */ public CellIdentityNr(int pci, int tac, int nrArfcn, @NgranBand List<Integer> bands, - String mccStr, String mncStr, long nci, String alphal, String alphas, - List<String> additionalPlmns) { + @Nullable String mccStr, @Nullable String mncStr, long nci, + @Nullable String alphal, @Nullable String alphas, + @NonNull List<String> additionalPlmns) { super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas); mPci = inRangeOrUnavailable(pci, 0, MAX_PCI); mTac = inRangeOrUnavailable(tac, 0, MAX_TAC); mNrArfcn = inRangeOrUnavailable(nrArfcn, 0, MAX_NRARFCN); mBands = new ArrayList<>(bands); mNci = inRangeOrUnavailable(nci, 0, MAX_NCI); - mAdditionalPlmns = new ArrayList<>(additionalPlmns); + mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + for (String plmn : additionalPlmns) { + if (isValidPlmn(plmn)) { + mAdditionalPlmns.add(plmn); + } + } } /** @hide */ - public CellIdentityNr(android.hardware.radio.V1_4.CellIdentityNr cid) { + public CellIdentityNr(@NonNull android.hardware.radio.V1_4.CellIdentityNr cid) { this(cid.pci, cid.tac, cid.nrarfcn, Collections.emptyList(), cid.mcc, cid.mnc, cid.nci, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort, Collections.emptyList()); } /** @hide */ - public CellIdentityNr(android.hardware.radio.V1_5.CellIdentityNr cid) { + public CellIdentityNr(@NonNull android.hardware.radio.V1_5.CellIdentityNr cid) { this(cid.base.pci, cid.base.tac, cid.base.nrarfcn, cid.bands, cid.base.mcc, cid.base.mnc, cid.base.nci, cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort, cid.additionalPlmns); diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 2ff351c17e9a..531487a313d9 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -82,39 +83,44 @@ public final class CellIdentityTdscdma extends CellIdentity { * * @hide */ - public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid, int uarfcn, - String alphal, String alphas, @NonNull List<String> additionalPlmns, - ClosedSubscriberGroupInfo csgInfo) { + public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid, + int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas, + @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) { super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas); mLac = inRangeOrUnavailable(lac, 0, MAX_LAC); mCid = inRangeOrUnavailable(cid, 0, MAX_CID); mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID); mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN); - mAdditionalPlmns = additionalPlmns; + mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + for (String plmn : additionalPlmns) { + if (isValidPlmn(plmn)) { + mAdditionalPlmns.add(plmn); + } + } mCsgInfo = csgInfo; } - private CellIdentityTdscdma(CellIdentityTdscdma cid) { + private CellIdentityTdscdma(@NonNull CellIdentityTdscdma cid) { this(cid.mMccStr, cid.mMncStr, cid.mLac, cid.mCid, cid.mCpid, cid.mUarfcn, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo); } /** @hide */ - public CellIdentityTdscdma(android.hardware.radio.V1_0.CellIdentityTdscdma cid) { + public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_0.CellIdentityTdscdma cid) { this(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, CellInfo.UNAVAILABLE, "", "", Collections.emptyList(), null); } /** @hide */ - public CellIdentityTdscdma(android.hardware.radio.V1_2.CellIdentityTdscdma cid) { + public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_2.CellIdentityTdscdma cid) { this(cid.base.mcc, cid.base.mnc, cid.base.lac, cid.base.cid, cid.base.cpid, cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort, Collections.emptyList(), null); } /** @hide */ - public CellIdentityTdscdma(android.hardware.radio.V1_5.CellIdentityTdscdma cid) { + public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_5.CellIdentityTdscdma cid) { this(cid.base.base.mcc, cid.base.base.mnc, cid.base.base.lac, cid.base.base.cid, cid.base.base.cpid, cid.base.uarfcn, cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort, @@ -130,7 +136,7 @@ public final class CellIdentityTdscdma extends CellIdentity { mAdditionalPlmns, null); } - CellIdentityTdscdma copy() { + @NonNull CellIdentityTdscdma copy() { return new CellIdentityTdscdma(this); } diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index 9be42a17677b..15e491b66575 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -23,6 +23,7 @@ import android.os.Parcel; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -83,34 +84,38 @@ public final class CellIdentityWcdma extends CellIdentity { * * @hide */ - public CellIdentityWcdma (int lac, int cid, int psc, int uarfcn, - String mccStr, String mncStr, String alphal, String alphas, - @NonNull List<String> additionalPlmns, - @Nullable ClosedSubscriberGroupInfo csgInfo) { + public CellIdentityWcdma(int lac, int cid, int psc, int uarfcn, @Nullable String mccStr, + @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas, + @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) { super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas); mLac = inRangeOrUnavailable(lac, 0, MAX_LAC); mCid = inRangeOrUnavailable(cid, 0, MAX_CID); mPsc = inRangeOrUnavailable(psc, 0, MAX_PSC); mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN); - mAdditionalPlmns = additionalPlmns; + mAdditionalPlmns = new ArrayList<>(additionalPlmns.size()); + for (String plmn : additionalPlmns) { + if (isValidPlmn(plmn)) { + mAdditionalPlmns.add(plmn); + } + } mCsgInfo = csgInfo; } /** @hide */ - public CellIdentityWcdma(android.hardware.radio.V1_0.CellIdentityWcdma cid) { + public CellIdentityWcdma(@NonNull android.hardware.radio.V1_0.CellIdentityWcdma cid) { this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null); } /** @hide */ - public CellIdentityWcdma(android.hardware.radio.V1_2.CellIdentityWcdma cid) { + public CellIdentityWcdma(@NonNull android.hardware.radio.V1_2.CellIdentityWcdma cid) { this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn, cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort, Collections.emptyList(), null); } /** @hide */ - public CellIdentityWcdma(android.hardware.radio.V1_5.CellIdentityWcdma cid) { + public CellIdentityWcdma(@NonNull android.hardware.radio.V1_5.CellIdentityWcdma cid) { this(cid.base.base.lac, cid.base.base.cid, cid.base.base.psc, cid.base.base.uarfcn, cid.base.base.mcc, cid.base.base.mnc, cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort, cid.additionalPlmns, @@ -118,7 +123,7 @@ public final class CellIdentityWcdma extends CellIdentity { ? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null); } - private CellIdentityWcdma(CellIdentityWcdma cid) { + private CellIdentityWcdma(@NonNull CellIdentityWcdma cid) { this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr, cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo); } @@ -131,7 +136,7 @@ public final class CellIdentityWcdma extends CellIdentity { mAlphaLong, mAlphaShort, mAdditionalPlmns, null); } - CellIdentityWcdma copy() { + @NonNull CellIdentityWcdma copy() { return new CellIdentityWcdma(this); } diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 5cd7cf8fae8a..8e83c4c11992 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -2543,7 +2543,7 @@ public final class SmsManager { MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE); if (m != null) { m.sendMultimediaMessage(getSubscriptionId(), contentUri, locationUrl, configOverrides, - sentIntent); + sentIntent, 0L /* messageId */); } } @@ -2581,7 +2581,7 @@ public final class SmsManager { MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE); if (m != null) { m.downloadMultimediaMessage(getSubscriptionId(), locationUrl, contentUri, - configOverrides, downloadedIntent); + configOverrides, downloadedIntent, 0L /* messageId */); } } diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 31b3a5064932..1f1c0c12cf21 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -123,8 +123,6 @@ interface IWifiManager boolean isWifiStandardSupported(int standard); - boolean needs5GHzToAnyApBandConversion(); - DhcpInfo getDhcpInfo(); boolean isScanAlwaysAvailable(); diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index f8d48c5403f7..7c031eaaeaf4 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -889,6 +889,13 @@ public class WifiInfo implements Parcelable { */ @Nullable @SystemApi + public static String sanitizeSsid(@Nullable String string) { + return removeDoubleQuotes(string); + } + + /** @hide */ + @UnsupportedAppUsage + @Nullable public static String removeDoubleQuotes(@Nullable String string) { if (string == null) return null; final int length = string.length(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 9a251062cd9e..76f97164032c 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2802,29 +2802,6 @@ public class WifiManager { } /** - * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP. - * - * If the device is dual mode capable, it may require conversion of the user's Soft AP band - * selection {@link SoftApConfiguration#mBand} from {@link SoftApConfiguration#BAND_5GHZ} to - * include also {@link SoftApConfiguration#BAND_2GHZ}, since if the device is connected to a - * 5GHz DFS channel as a STA, it may be unable to honor a request to start Soft AP on the same - * DFS channel. - * - * @return {@code true} if dual mode STA + AP is supported by this device, {@code false} - * otherwise. - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public boolean isDualModeSupported() { - try { - return mService.needs5GHzToAnyApBandConversion(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * Return the DHCP-assigned addresses from the last successful DHCP request, * if any. * @return the DHCP information diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index b46755349ad7..060c85cac209 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -38,6 +38,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkSuggestion; import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; @@ -268,7 +269,8 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated use {@link WifiManager#isStaApConcurrencySupported()} */ + @Deprecated public boolean needs5GHzToAnyApBandConversion() { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 0c2876e340c1..a189d507a32a 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1928,16 +1928,6 @@ public class WifiManagerTest { } /** - * Test behavior of {@link WifiManager#isDualModeSupported()} ()} - */ - @Test - public void testIsDualModeSupported() throws Exception { - when(mWifiService.needs5GHzToAnyApBandConversion()).thenReturn(true); - assertTrue(mWifiManager.isDualModeSupported()); - verify(mWifiService).needs5GHzToAnyApBandConversion(); - } - - /** * Test behavior of {@link WifiManager#is5GHzBandSupported()} */ @Test |