Merge changes from topic "dynamic_power_saver"
* changes:
Create APIs to interact with DynamicPowerSaver
Create new battery saver mode
diff --git a/api/current.txt b/api/current.txt
index f736f12..28863b8 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -740,6 +740,7 @@
field public static final int immersive = 16843456; // 0x10102c0
field public static final int importantForAccessibility = 16843690; // 0x10103aa
field public static final int importantForAutofill = 16844120; // 0x1010558
+ field public static final int importantForContentCapture = 16844182; // 0x1010596
field public static final int inAnimation = 16843127; // 0x1010177
field public static final int includeFontPadding = 16843103; // 0x101015f
field public static final int includeInGlobalSearch = 16843374; // 0x101026e
@@ -7580,6 +7581,8 @@
method public java.lang.String getShortcutId();
method public long getTimeStamp();
field public static final int CONFIGURATION_CHANGE = 5; // 0x5
+ field public static final int FOREGROUND_SERVICE_START = 19; // 0x13
+ field public static final int FOREGROUND_SERVICE_STOP = 20; // 0x14
field public static final int KEYGUARD_HIDDEN = 18; // 0x12
field public static final int KEYGUARD_SHOWN = 17; // 0x11
field public static final int MOVE_TO_BACKGROUND = 2; // 0x2
@@ -7597,9 +7600,11 @@
method public void add(android.app.usage.UsageStats);
method public int describeContents();
method public long getFirstTimeStamp();
+ method public long getLastTimeForegroundServiceUsed();
method public long getLastTimeStamp();
method public long getLastTimeUsed();
method public java.lang.String getPackageName();
+ method public long getTotalTimeForegroundServiceUsed();
method public long getTotalTimeInForeground();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.usage.UsageStats> CREATOR;
@@ -42136,7 +42141,7 @@
field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
- field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
+ field public static final deprecated int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
field public static final int CAPABILITY_HOLD = 1; // 0x1
field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
@@ -42556,6 +42561,7 @@
method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
method public java.util.List<android.telecom.PhoneAccountHandle> getSelfManagedPhoneAccounts();
method public android.telecom.PhoneAccountHandle getSimCallManager();
+ method public java.lang.String getSystemDialerPackage();
method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
method public boolean handleMmi(java.lang.String);
method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
@@ -48838,6 +48844,7 @@
method public int getId();
method public int getImportantForAccessibility();
method public int getImportantForAutofill();
+ method public int getImportantForContentCapture();
method public boolean getKeepScreenOn();
method public android.view.KeyEvent.DispatcherState getKeyDispatcherState();
method public int getLabelFor();
@@ -48971,6 +48978,7 @@
method public boolean isHovered();
method public boolean isImportantForAccessibility();
method public final boolean isImportantForAutofill();
+ method public final boolean isImportantForContentCapture();
method public boolean isInEditMode();
method public boolean isInLayout();
method public boolean isInTouchMode();
@@ -49045,6 +49053,7 @@
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
method public void onProvideAutofillStructure(android.view.ViewStructure, int);
method public void onProvideAutofillVirtualStructure(android.view.ViewStructure, int);
+ method public boolean onProvideContentCaptureStructure(android.view.ViewStructure, int);
method public void onProvideStructure(android.view.ViewStructure);
method public void onProvideVirtualStructure(android.view.ViewStructure);
method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int);
@@ -49163,6 +49172,7 @@
method public void setId(int);
method public void setImportantForAccessibility(int);
method public void setImportantForAutofill(int);
+ method public void setImportantForContentCapture(int);
method public void setKeepScreenOn(boolean);
method public void setKeyboardNavigationCluster(boolean);
method public void setLabelFor(int);
@@ -49333,6 +49343,11 @@
field public static final int IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS = 8; // 0x8
field public static final int IMPORTANT_FOR_AUTOFILL_YES = 1; // 0x1
field public static final int IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS = 4; // 0x4
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0; // 0x0
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 2; // 0x2
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 8; // 0x8
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 1; // 0x1
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 4; // 0x4
field public static final int INVISIBLE = 4; // 0x4
field public static final int KEEP_SCREEN_ON = 67108864; // 0x4000000
field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
@@ -51787,6 +51802,10 @@
method public void disableContentCapture();
method public android.content.ComponentName getIntelligenceServiceComponentName();
method public boolean isContentCaptureEnabled();
+ method public android.view.ViewStructure newVirtualViewStructure(android.view.autofill.AutofillId, int);
+ method public void notifyViewAppeared(android.view.ViewStructure);
+ method public void notifyViewDisappeared(android.view.autofill.AutofillId);
+ method public void notifyViewTextChanged(android.view.autofill.AutofillId, java.lang.CharSequence, int);
field public static final int FLAG_USER_INPUT = 1; // 0x1
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 93a9f52..5c4efcd 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5431,15 +5431,21 @@
method public int getAllPhoneAccountsCount();
method public int getCallState();
method public android.telecom.PhoneAccountHandle getConnectionManager();
+ method public int getCurrentTtyMode();
method public deprecated android.content.ComponentName getDefaultPhoneApp();
method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage();
method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
method public boolean isInEmergencyCall();
method public boolean isRinging();
method public boolean isTtySupported();
+ method public boolean setDefaultDialer(java.lang.String);
field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
field public static final java.lang.String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT";
field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE";
+ field public static final int TTY_MODE_FULL = 1; // 0x1
+ field public static final int TTY_MODE_HCO = 2; // 0x2
+ field public static final int TTY_MODE_OFF = 0; // 0x0
+ field public static final int TTY_MODE_VCO = 3; // 0x3
}
}
@@ -7003,8 +7009,8 @@
field public static final int TYPE_ACTIVITY_RESUMED = 2; // 0x2
field public static final int TYPE_ACTIVITY_STARTED = 1; // 0x1
field public static final int TYPE_ACTIVITY_STOPPED = 4; // 0x4
- field public static final int TYPE_VIEW_ADDED = 5; // 0x5
- field public static final int TYPE_VIEW_REMOVED = 6; // 0x6
+ field public static final int TYPE_VIEW_APPEARED = 5; // 0x5
+ field public static final int TYPE_VIEW_DISAPPEARED = 6; // 0x6
field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7
}
diff --git a/api/test-current.txt b/api/test-current.txt
index a66c209..5531014 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1650,9 +1650,9 @@
}
public abstract interface WindowManager implements android.view.ViewManager {
- method public abstract void setShouldShowIme(int, boolean);
- method public abstract void setShouldShowWithInsecureKeyguard(int, boolean);
- method public abstract void setShouldShowSystemDecors(int, boolean);
+ method public default void setShouldShowIme(int, boolean);
+ method public default void setShouldShowSystemDecors(int, boolean);
+ method public default void setShouldShowWithInsecureKeyguard(int, boolean);
}
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index c6d717a..783c8c4 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -127,6 +127,8 @@
filterType = VolumeInfo.TYPE_PRIVATE;
} else if ("emulated".equals(filter)) {
filterType = VolumeInfo.TYPE_EMULATED;
+ } else if ("stub".equals(filter)) {
+ filterType = VolumeInfo.TYPE_STUB;
} else {
filterType = -1;
}
@@ -314,7 +316,7 @@
private static int showUsage() {
System.err.println("usage: sm list-disks [adoptable]");
- System.err.println(" sm list-volumes [public|private|emulated|all]");
+ System.err.println(" sm list-volumes [public|private|emulated|stub|all]");
System.err.println(" sm has-adoptable");
System.err.println(" sm get-primary-storage-uuid");
System.err.println(" sm set-force-adoptable [on|off|default]");
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 5c46a29..aa789c7 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -274,6 +274,7 @@
optional bool use_diff = 12;
enum ValueDirection {
+ UNKNOWN = 0;
INCREASING = 1;
DECREASING = 2;
ANY = 3;
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 308b39e..3a5975a 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -50,12 +50,20 @@
public static final int NONE = 0;
/**
- * An event type denoting that a component moved to the foreground.
+ * An event type denoting that an {@link android.app.Activity} moved to the foreground.
+ * This event has a package name and class name associated with it and can be retrieved
+ * using {@link #getPackageName()} and {@link #getClassName()}.
+ * If a package has multiple activities, this event is reported for each activity that moves
+ * to foreground.
*/
public static final int MOVE_TO_FOREGROUND = 1;
/**
- * An event type denoting that a component moved to the background.
+ * An event type denoting that an {@link android.app.Activity} moved to the background.
+ * This event has a package name and class name associated with it and can be retrieved
+ * using {@link #getPackageName()} and {@link #getClassName()}.
+ * If a package has multiple activities, this event is reported for each activity that moves
+ * to background.
*/
public static final int MOVE_TO_BACKGROUND = 2;
@@ -166,10 +174,43 @@
public static final int KEYGUARD_HIDDEN = 18;
/**
+ * An event type denoting start of a foreground service.
+ * This event has a package name and class name associated with it and can be retrieved
+ * using {@link #getPackageName()} and {@link #getClassName()}.
+ * If a package has multiple foreground services, this event is reported for each service
+ * that is started.
+ */
+ public static final int FOREGROUND_SERVICE_START = 19;
+
+ /**
+ * An event type denoting stop of a foreground service.
+ * This event has a package name and class name associated with it and can be retrieved
+ * using {@link #getPackageName()} and {@link #getClassName()}.
+ * If a package has multiple foreground services, this event is reported for each service
+ * that is stopped.
+ */
+ public static final int FOREGROUND_SERVICE_STOP = 20;
+
+ /**
+ * An event type denoting that a foreground service is at started state at beginning of a
+ * time interval.
+ * This is effectively treated as a {@link #FOREGROUND_SERVICE_START}.
+ * {@hide}
+ */
+ public static final int CONTINUING_FOREGROUND_SERVICE = 21;
+
+ /**
+ * An event type denoting that a foreground service is at started state when the stats
+ * rolled-over at the end of a time interval.
+ * {@hide}
+ */
+ public static final int ROLLOVER_FOREGROUND_SERVICE = 22;
+
+ /**
* Keep in sync with the greatest event type value.
* @hide
*/
- public static final int MAX_EVENT_TYPE = 18;
+ public static final int MAX_EVENT_TYPE = 22;
/** @hide */
public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index 0659a23..73426e4 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -16,6 +16,15 @@
package android.app.usage;
+import static android.app.usage.UsageEvents.Event.CONTINUE_PREVIOUS_DAY;
+import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE;
+import static android.app.usage.UsageEvents.Event.END_OF_DAY;
+import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START;
+import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP;
+import static android.app.usage.UsageEvents.Event.MOVE_TO_BACKGROUND;
+import static android.app.usage.UsageEvents.Event.MOVE_TO_FOREGROUND;
+import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE;
+
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
@@ -48,19 +57,32 @@
public long mEndTimeStamp;
/**
- * Last time used by the user with an explicit action (notification, activity launch).
+ * Last time used by the user with an explicit action (notification, activity launch)
* {@hide}
*/
@UnsupportedAppUsage
public long mLastTimeUsed;
/**
+ * Total time this package's activity is in foreground.
* {@hide}
*/
@UnsupportedAppUsage
public long mTotalTimeInForeground;
/**
+ * Last time foreground service is started.
+ * {@hide}
+ */
+ public long mLastTimeForegroundServiceUsed;
+
+ /**
+ * Total time this package's foreground service is started.
+ * {@hide}
+ */
+ public long mTotalTimeForegroundServiceUsed;
+
+ /**
* {@hide}
*/
@UnsupportedAppUsage
@@ -71,16 +93,36 @@
*/
public int mAppLaunchCount;
- /**
+ /** Last activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event.
* {@hide}
+ * @deprecated use {@link #mLastForegroundActivityEventMap} instead.
*/
@UnsupportedAppUsage
+ @Deprecated
public int mLastEvent;
/**
+ * If an activity is in foreground, it has one entry in this map.
+ * When activity moves to background, it is removed from this map.
+ * Key is activity class name.
+ * Value is last time this activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event.
+ * {@hide}
+ */
+ public ArrayMap<String, Integer> mLastForegroundActivityEventMap = new ArrayMap<>();
+
+ /**
+ * If a foreground service is started, it has one entry in this map.
+ * When a foreground service is stopped, it is removed from this map.
+ * Key is foreground service class name.
+ * Value is last foreground service FOREGROUND_SERVICE_START ot FOREGROUND_SERVICE_STOP event.
+ * {@hide}
+ */
+ public ArrayMap<String, Integer> mLastForegroundServiceEventMap = new ArrayMap<>();
+
+ /**
* {@hide}
*/
- public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts;
+ public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts = new ArrayMap<>();
/**
* {@hide}
@@ -93,10 +135,14 @@
mBeginTimeStamp = stats.mBeginTimeStamp;
mEndTimeStamp = stats.mEndTimeStamp;
mLastTimeUsed = stats.mLastTimeUsed;
+ mLastTimeForegroundServiceUsed = stats.mLastTimeForegroundServiceUsed;
mTotalTimeInForeground = stats.mTotalTimeInForeground;
+ mTotalTimeForegroundServiceUsed = stats.mTotalTimeForegroundServiceUsed;
mLaunchCount = stats.mLaunchCount;
mAppLaunchCount = stats.mAppLaunchCount;
mLastEvent = stats.mLastEvent;
+ mLastForegroundActivityEventMap = stats.mLastForegroundActivityEventMap;
+ mLastForegroundServiceEventMap = stats.mLastForegroundServiceEventMap;
mChooserCounts = stats.mChooserCounts;
}
@@ -136,7 +182,7 @@
}
/**
- * Get the last time this package was used, measured in milliseconds since the epoch.
+ * Get the last time this package's activity was used, measured in milliseconds since the epoch.
* <p/>
* See {@link System#currentTimeMillis()}.
*/
@@ -152,6 +198,23 @@
}
/**
+ * Get the last time this package's foreground service was used, measured in milliseconds since
+ * the epoch.
+ * <p/>
+ * See {@link System#currentTimeMillis()}.
+ */
+ public long getLastTimeForegroundServiceUsed() {
+ return mLastTimeForegroundServiceUsed;
+ }
+
+ /**
+ * Get the total time this package's foreground services are started, measured in milliseconds.
+ */
+ public long getTotalTimeForegroundServiceUsed() {
+ return mTotalTimeForegroundServiceUsed;
+ }
+
+ /**
* Returns the number of times the app was launched as an activity from outside of the app.
* Excludes intra-app activity transitions.
* @hide
@@ -161,6 +224,19 @@
return mAppLaunchCount;
}
+ private void mergeEventMap(ArrayMap<String, Integer> left, ArrayMap<String, Integer> right) {
+ final int size = right.size();
+ for (int i = 0; i < size; i++) {
+ final String className = right.keyAt(i);
+ final Integer event = right.valueAt(i);
+ if (left.containsKey(className)) {
+ left.put(className, Math.max(left.get(className), event));
+ } else {
+ left.put(className, event);
+ }
+ }
+ }
+
/**
* Add the statistics from the right {@link UsageStats} to the left. The package name for
* both {@link UsageStats} objects must be the same.
@@ -179,12 +255,16 @@
if (right.mBeginTimeStamp > mBeginTimeStamp) {
// Even though incoming UsageStat begins after this one, its last time used fields
// may somehow be empty or chronologically preceding the older UsageStat.
- mLastEvent = Math.max(mLastEvent, right.mLastEvent);
+ mergeEventMap(mLastForegroundActivityEventMap, right.mLastForegroundActivityEventMap);
+ mergeEventMap(mLastForegroundServiceEventMap, right.mLastForegroundServiceEventMap);
mLastTimeUsed = Math.max(mLastTimeUsed, right.mLastTimeUsed);
+ mLastTimeForegroundServiceUsed = Math.max(mLastTimeForegroundServiceUsed,
+ right.mLastTimeForegroundServiceUsed);
}
mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp);
mTotalTimeInForeground += right.mTotalTimeInForeground;
+ mTotalTimeForegroundServiceUsed += right.mTotalTimeForegroundServiceUsed;
mLaunchCount += right.mLaunchCount;
mAppLaunchCount += right.mAppLaunchCount;
if (mChooserCounts == null) {
@@ -209,6 +289,161 @@
}
}
+ /**
+ * Tell if an event indicate activity is in foreground or not.
+ * @param event the activity event.
+ * @return true if activity is in foreground, false otherwise.
+ * @hide
+ */
+ private boolean isActivityInForeground(int event) {
+ return event == MOVE_TO_FOREGROUND
+ || event == CONTINUE_PREVIOUS_DAY;
+ }
+
+ /**
+ * Tell if an event indicate foreground sevice is started or not.
+ * @param event the foreground service event.
+ * @return true if foreground service is started, false if stopped.
+ * @hide
+ */
+ private boolean isForegroundServiceStarted(int event) {
+ return event == FOREGROUND_SERVICE_START
+ || event == CONTINUING_FOREGROUND_SERVICE;
+ }
+
+ /**
+ * If any activity in foreground or any foreground service is started, the app is considered in
+ * use.
+ * @return true if in use, false otherwise.
+ * @hide
+ */
+ private boolean isAppInUse() {
+ return !mLastForegroundActivityEventMap.isEmpty()
+ || !mLastForegroundServiceEventMap.isEmpty();
+ }
+
+ /**
+ * Update by an event of an activity.
+ * @param className className of the activity.
+ * @param timeStamp timeStamp of the event.
+ * @param eventType type of the event.
+ * @hide
+ */
+ private void updateForegroundActivity(String className, long timeStamp, int eventType) {
+ if (eventType != MOVE_TO_BACKGROUND
+ && eventType != MOVE_TO_FOREGROUND
+ && eventType != END_OF_DAY) {
+ return;
+ }
+
+ final Integer lastEvent = mLastForegroundActivityEventMap.get(className);
+ if (lastEvent != null) {
+ if (isActivityInForeground(lastEvent)) {
+ if (timeStamp > mLastTimeUsed) {
+ mTotalTimeInForeground += timeStamp - mLastTimeUsed;
+ mLastTimeUsed = timeStamp;
+ }
+ }
+ if (eventType == MOVE_TO_BACKGROUND) {
+ mLastForegroundActivityEventMap.remove(className);
+ } else {
+ mLastForegroundActivityEventMap.put(className, eventType);
+ }
+ } else if (eventType == MOVE_TO_FOREGROUND) {
+ if (!isAppInUse()) {
+ mLastTimeUsed = timeStamp;
+ }
+ mLastForegroundActivityEventMap.put(className, eventType);
+ }
+ }
+
+ /**
+ * Update by an event of an foreground service.
+ * @param className className of the foreground service.
+ * @param timeStamp timeStamp of the event.
+ * @param eventType type of the event.
+ * @hide
+ */
+ private void updateForegroundService(String className, long timeStamp, int eventType) {
+ if (eventType != FOREGROUND_SERVICE_STOP
+ && eventType != FOREGROUND_SERVICE_START
+ && eventType != ROLLOVER_FOREGROUND_SERVICE) {
+ return;
+ }
+ final Integer lastEvent = mLastForegroundServiceEventMap.get(className);
+ if (lastEvent != null) {
+ if (isForegroundServiceStarted(lastEvent)) {
+ if (timeStamp > mLastTimeForegroundServiceUsed) {
+ mTotalTimeForegroundServiceUsed +=
+ timeStamp - mLastTimeForegroundServiceUsed;
+ mLastTimeForegroundServiceUsed = timeStamp;
+ }
+ }
+ if (eventType == FOREGROUND_SERVICE_STOP) {
+ mLastForegroundServiceEventMap.remove(className);
+ } else {
+ mLastForegroundServiceEventMap.put(className, eventType);
+ }
+ } else if (eventType == FOREGROUND_SERVICE_START) {
+ if (!isAppInUse()) {
+ mLastTimeForegroundServiceUsed = timeStamp;
+ }
+ mLastForegroundServiceEventMap.put(className, eventType);
+ }
+ }
+
+ /**
+ * Update the UsageStats by a activity or foreground service event.
+ * @param className class name of a activity or foreground service, could be null to mark
+ * END_OF_DAY or rollover.
+ * @param timeStamp Epoch timestamp in milliseconds.
+ * @param eventType event type as in {@link UsageEvents.Event}
+ * @hide
+ */
+ public void update(String className, long timeStamp, int eventType) {
+ switch(eventType) {
+ case MOVE_TO_BACKGROUND:
+ case MOVE_TO_FOREGROUND:
+ updateForegroundActivity(className, timeStamp, eventType);
+ break;
+ case END_OF_DAY:
+ // END_OF_DAY means updating all activities.
+ final int size = mLastForegroundActivityEventMap.size();
+ for (int i = 0; i < size; i++) {
+ final String name = mLastForegroundActivityEventMap.keyAt(i);
+ updateForegroundActivity(name, timeStamp, eventType);
+ }
+ break;
+ case CONTINUE_PREVIOUS_DAY:
+ mLastTimeUsed = timeStamp;
+ mLastForegroundActivityEventMap.put(className, eventType);
+ break;
+ case FOREGROUND_SERVICE_STOP:
+ case FOREGROUND_SERVICE_START:
+ updateForegroundService(className, timeStamp, eventType);
+ break;
+ case ROLLOVER_FOREGROUND_SERVICE:
+ // ROLLOVER_FOREGROUND_SERVICE means updating all foreground services.
+ final int size2 = mLastForegroundServiceEventMap.size();
+ for (int i = 0; i < size2; i++) {
+ final String name = mLastForegroundServiceEventMap.keyAt(i);
+ updateForegroundService(name, timeStamp, eventType);
+ }
+ break;
+ case CONTINUING_FOREGROUND_SERVICE:
+ mLastTimeForegroundServiceUsed = timeStamp;
+ mLastForegroundServiceEventMap.put(className, eventType);
+ break;
+ default:
+ break;
+ }
+ mEndTimeStamp = timeStamp;
+
+ if (eventType == MOVE_TO_FOREGROUND) {
+ mLaunchCount += 1;
+ }
+ }
+
@Override
public int describeContents() {
return 0;
@@ -220,7 +455,9 @@
dest.writeLong(mBeginTimeStamp);
dest.writeLong(mEndTimeStamp);
dest.writeLong(mLastTimeUsed);
+ dest.writeLong(mLastTimeForegroundServiceUsed);
dest.writeLong(mTotalTimeInForeground);
+ dest.writeLong(mTotalTimeForegroundServiceUsed);
dest.writeInt(mLaunchCount);
dest.writeInt(mAppLaunchCount);
dest.writeInt(mLastEvent);
@@ -239,6 +476,22 @@
}
}
dest.writeBundle(allCounts);
+
+ final Bundle foregroundActivityEventBundle = new Bundle();
+ final int foregroundEventSize = mLastForegroundActivityEventMap.size();
+ for (int i = 0; i < foregroundEventSize; i++) {
+ foregroundActivityEventBundle.putInt(mLastForegroundActivityEventMap.keyAt(i),
+ mLastForegroundActivityEventMap.valueAt(i));
+ }
+ dest.writeBundle(foregroundActivityEventBundle);
+
+ final Bundle foregroundServiceEventBundle = new Bundle();
+ final int foregroundServiceEventSize = mLastForegroundServiceEventMap.size();
+ for (int i = 0; i < foregroundServiceEventSize; i++) {
+ foregroundServiceEventBundle.putInt(mLastForegroundServiceEventMap.keyAt(i),
+ mLastForegroundServiceEventMap.valueAt(i));
+ }
+ dest.writeBundle(foregroundServiceEventBundle);
}
public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() {
@@ -249,7 +502,9 @@
stats.mBeginTimeStamp = in.readLong();
stats.mEndTimeStamp = in.readLong();
stats.mLastTimeUsed = in.readLong();
+ stats.mLastTimeForegroundServiceUsed = in.readLong();
stats.mTotalTimeInForeground = in.readLong();
+ stats.mTotalTimeForegroundServiceUsed = in.readLong();
stats.mLaunchCount = in.readInt();
stats.mAppLaunchCount = in.readInt();
stats.mLastEvent = in.readInt();
@@ -272,9 +527,20 @@
}
}
}
+ readBundleToEventMap(stats.mLastForegroundActivityEventMap, in.readBundle());
+ readBundleToEventMap(stats.mLastForegroundServiceEventMap, in.readBundle());
return stats;
}
+ private void readBundleToEventMap(ArrayMap<String, Integer> eventMap, Bundle bundle) {
+ if (bundle != null) {
+ for (String className : bundle.keySet()) {
+ final int event = bundle.getInt(className);
+ eventMap.put(className, event);
+ }
+ }
+ }
+
@Override
public UsageStats[] newArray(int size) {
return new UsageStats[size];
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 6d7400e..5514851 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -192,7 +192,10 @@
public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C;
/** @hide */
public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D;
-
+ /** @hide */
+ public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_START = 0x000E;
+ /** @hide */
+ public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP = 0x000F;
/** @hide */
public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001;
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 8a36a78..d679fc7 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -801,7 +801,7 @@
try {
for (VolumeInfo vol : mStorageManager.getVolumes(0)) {
if (vol.path != null && FileUtils.contains(vol.path, pathString)
- && vol.type != VolumeInfo.TYPE_PUBLIC) {
+ && vol.type != VolumeInfo.TYPE_PUBLIC && vol.type != VolumeInfo.TYPE_STUB) {
// TODO: verify that emulated adopted devices have UUID of
// underlying volume
try {
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index e55afb6..8c3aa17 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -84,6 +84,7 @@
public static final int TYPE_EMULATED = IVold.VOLUME_TYPE_EMULATED;
public static final int TYPE_ASEC = IVold.VOLUME_TYPE_ASEC;
public static final int TYPE_OBB = IVold.VOLUME_TYPE_OBB;
+ public static final int TYPE_STUB = IVold.VOLUME_TYPE_STUB;
public static final int STATE_UNMOUNTED = IVold.VOLUME_STATE_UNMOUNTED;
public static final int STATE_CHECKING = IVold.VOLUME_STATE_CHECKING;
@@ -295,7 +296,7 @@
}
public boolean isVisibleForUser(int userId) {
- if (type == TYPE_PUBLIC && mountUserId == userId) {
+ if ((type == TYPE_PUBLIC || type == TYPE_STUB) && mountUserId == userId) {
return isVisible();
} else if (type == TYPE_EMULATED) {
return isVisible();
@@ -327,7 +328,7 @@
public File getPathForUser(int userId) {
if (path == null) {
return null;
- } else if (type == TYPE_PUBLIC) {
+ } else if (type == TYPE_PUBLIC || type == TYPE_STUB) {
return new File(path);
} else if (type == TYPE_EMULATED) {
return new File(path, Integer.toString(userId));
@@ -344,7 +345,7 @@
public File getInternalPathForUser(int userId) {
if (path == null) {
return null;
- } else if (type == TYPE_PUBLIC) {
+ } else if (type == TYPE_PUBLIC || type == TYPE_STUB) {
// TODO: plumb through cleaner path from vold
return new File(path.replace("/storage/", "/mnt/media_rw/"));
} else {
@@ -390,7 +391,7 @@
removable = true;
}
- } else if (type == TYPE_PUBLIC) {
+ } else if (type == TYPE_PUBLIC || type == TYPE_STUB) {
emulated = false;
removable = true;
@@ -447,7 +448,8 @@
public @Nullable Intent buildBrowseIntentForUser(int userId) {
final Uri uri;
- if (type == VolumeInfo.TYPE_PUBLIC && mountUserId == userId) {
+ if ((type == VolumeInfo.TYPE_PUBLIC || type == VolumeInfo.TYPE_STUB)
+ && mountUserId == userId) {
uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, fsUuid);
} else if (type == VolumeInfo.TYPE_EMULATED && isPrimary()) {
uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7ba027f..ec16828 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -112,6 +112,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.view.intelligence.IntelligenceManager;
import android.widget.Checkable;
import android.widget.FrameLayout;
import android.widget.ScrollBarDrawable;
@@ -799,6 +800,11 @@
private static final String AUTOFILL_LOG_TAG = "View.Autofill";
/**
+ * The logging tag used by this class when logging content capture-related messages.
+ */
+ private static final String CONTENT_CAPTURE_LOG_TAG = "View.ContentCapture";
+
+ /**
* When set to true, apps will draw debugging information about their layouts.
*
* @hide
@@ -1337,6 +1343,59 @@
*/
public static final int AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x1;
+ /** @hide */
+ @IntDef(prefix = { "IMPORTANT_FOR_CONTENT_CAPTURE_" }, value = {
+ IMPORTANT_FOR_CONTENT_CAPTURE_AUTO,
+ IMPORTANT_FOR_CONTENT_CAPTURE_YES,
+ IMPORTANT_FOR_CONTENT_CAPTURE_NO,
+ IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS,
+ IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ContentCaptureImportance {}
+
+ /**
+ * Automatically determine whether a view is important for content capture.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ */
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0x0;
+
+ /**
+ * The view is important for content capture, and its children (if any) will be traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ */
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 0x1;
+
+ /**
+ * The view is not important for content capture, but its children (if any) will be traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ */
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 0x2;
+
+ /**
+ * The view is important for content capture, but its children (if any) will not be traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ */
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 0x4;
+
+ /**
+ * The view is not important for content capture, and its children (if any) will not be
+ * traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ */
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 0x8;
+
+
/**
* This view is enabled. Interpretation varies by subclass.
* Use with ENABLED_MASK when calling setFlags.
@@ -2243,7 +2302,44 @@
@UnsupportedAppUsage
protected Object mTag = null;
- // for mPrivateFlags:
+ /*
+ * Masks for mPrivateFlags, as generated by dumpFlags():
+ *
+ * |-------|-------|-------|-------|
+ * 1 PFLAG_WANTS_FOCUS
+ * 1 PFLAG_FOCUSED
+ * 1 PFLAG_SELECTED
+ * 1 PFLAG_IS_ROOT_NAMESPACE
+ * 1 PFLAG_HAS_BOUNDS
+ * 1 PFLAG_DRAWN
+ * 1 PFLAG_DRAW_ANIMATION
+ * 1 PFLAG_SKIP_DRAW
+ * 1 PFLAG_REQUEST_TRANSPARENT_REGIONS
+ * 1 PFLAG_DRAWABLE_STATE_DIRTY
+ * 1 PFLAG_MEASURED_DIMENSION_SET
+ * 1 PFLAG_FORCE_LAYOUT
+ * 1 PFLAG_LAYOUT_REQUIRED
+ * 1 PFLAG_PRESSED
+ * 1 PFLAG_DRAWING_CACHE_VALID
+ * 1 PFLAG_ANIMATION_STARTED
+ * 1 PFLAG_SAVE_STATE_CALLED
+ * 1 PFLAG_ALPHA_SET
+ * 1 PFLAG_SCROLL_CONTAINER
+ * 1 PFLAG_SCROLL_CONTAINER_ADDED
+ * 1 PFLAG_DIRTY
+ * 1 PFLAG_DIRTY_MASK
+ * 1 PFLAG_OPAQUE_BACKGROUND
+ * 1 PFLAG_OPAQUE_SCROLLBARS
+ * 11 PFLAG_OPAQUE_MASK
+ * 1 PFLAG_PREPRESSED
+ * 1 PFLAG_CANCEL_NEXT_UP_EVENT
+ * 1 PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH
+ * 1 PFLAG_HOVERED
+ * 1 PFLAG_NOTIFY_AUTOFILL_MANAGER_ON_CLICK
+ * 1 PFLAG_ACTIVATED
+ * 1 PFLAG_INVALIDATED
+ * |-------|-------|-------|-------|
+ */
/** {@hide} */
static final int PFLAG_WANTS_FOCUS = 0x00000001;
/** {@hide} */
@@ -2393,7 +2489,9 @@
*/
static final int PFLAG_INVALIDATED = 0x80000000;
- /**
+ /* End of masks for mPrivateFlags */
+
+ /*
* Masks for mPrivateFlags2, as generated by dumpFlags():
*
* |-------|-------|-------|-------|
@@ -2934,7 +3032,7 @@
/* End of masks for mPrivateFlags2 */
- /**
+ /*
* Masks for mPrivateFlags3, as generated by dumpFlags():
*
* |-------|-------|-------|-------|
@@ -3270,6 +3368,57 @@
/* End of masks for mPrivateFlags3 */
+ /*
+ * Masks for mPrivateFlags4, as generated by dumpFlags():
+ *
+ * |-------|-------|-------|-------|
+ * 1111 PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK
+ * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT
+ * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED
+ * 1 PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE
+ * |-------|-------|-------|-------|
+ */
+
+ /**
+ * Mask for obtaining the bits which specify how to determine
+ * whether a view is important for autofill.
+ *
+ * <p>NOTE: the important for content capture values were the first flags added and are set in
+ * the rightmost position, so we don't need to shift them
+ */
+ private static final int PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK =
+ IMPORTANT_FOR_CONTENT_CAPTURE_AUTO | IMPORTANT_FOR_CONTENT_CAPTURE_YES
+ | IMPORTANT_FOR_CONTENT_CAPTURE_NO
+ | IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS
+ | IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS;
+
+ /*
+ * Variables used to control when the IntelligenceManager.notifyNodeAdded()/removed() methods
+ * should be called.
+ *
+ * The idea is to call notifyNodeAdded() after the view is layout and visible, then call
+ * notifyNodeRemoved() when it's gone (without known when it was removed from the parent).
+ *
+ * TODO(b/111276913): the current algortighm could probably be optimized and some of them
+ * removed
+ */
+ private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT = 0x10;
+ private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED = 0x20;
+ private static final int PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE = 0x40;
+
+ private static final int CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED = 1;
+ private static final int CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED = 0;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = { "CONTENT_CAPTURE_NOTIFICATION_TYPE_" }, value = {
+ CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED,
+ CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ContentCaptureNotificationType {}
+
+ /* End of masks for mPrivateFlags4 */
+
/**
* Always allow a user to over-scroll this view, provided it is a
* view that can scroll.
@@ -3861,6 +4010,8 @@
@UnsupportedAppUsage
int mPrivateFlags3;
+ private int mPrivateFlags4;
+
/**
* This view's request for the visibility of the status bar.
* @hide
@@ -5803,6 +5954,7 @@
mAttributes = trimmed;
}
+ @Override
public String toString() {
StringBuilder out = new StringBuilder(128);
out.append(getClass().getName());
@@ -5875,6 +6027,9 @@
}
}
}
+ if (mAutofillId != null) {
+ out.append(" aid="); out.append(mAutofillId);
+ }
out.append("}");
return out.toString();
}
@@ -7888,7 +8043,8 @@
* fills in all data that can be inferred from the view itself.
*/
public void onProvideStructure(ViewStructure structure) {
- onProvideStructureForAssistOrAutofill(structure, false, 0);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false,
+ /* forViewCapture= */ false, /* flags= */ 0);
}
/**
@@ -7961,11 +8117,46 @@
* @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
*/
public void onProvideAutofillStructure(ViewStructure structure, @AutofillFlags int flags) {
- onProvideStructureForAssistOrAutofill(structure, true, flags);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ true,
+ /* forViewCapture= */ false, flags);
}
- private void onProvideStructureForAssistOrAutofill(ViewStructure structure,
- boolean forAutofill, @AutofillFlags int flags) {
+ /**
+ * Populates a {@link ViewStructure} for Content Capture.
+ *
+ * <p>This method is called after a view is that is eligible for Content Capture
+ * (for example, if it {@link #isImportantForAutofill()}, an intelligence service is enabled for
+ * the user, and the activity rendering the view is enabled for Content Capture) is laid out and
+ * is visible.
+ *
+ * <p><b>Note: </b>the following methods of the {@code structure} will be ignored:
+ * <ul>
+ * <li>{@link ViewStructure#setChildCount(int)}
+ * <li>{@link ViewStructure#addChildCount(int)}
+ * <li>{@link ViewStructure#getChildCount()}
+ * <li>{@link ViewStructure#newChild(int)}
+ * <li>{@link ViewStructure#asyncNewChild(int)}
+ * <li>{@link ViewStructure#asyncCommit()}
+ * <li>{@link ViewStructure#setWebDomain(String)}
+ * <li>{@link ViewStructure#newHtmlInfoBuilder(String)}
+ * <li>{@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)}
+ * <li>{@link ViewStructure#setDataIsSensitive(boolean)}
+ * </ul>
+ *
+ * @return whether the IntelligenceService should be notified that the view was added (through
+ * the {@link IntelligenceManager#notifyViewAppeared(ViewStructure)} method) to the view
+ * hierarchy. Most views should return {@code true} here, but views that contains virtual
+ * hierarchy might opt to return {@code false} and notify the manager independently, as the
+ * virtual views are rendered.
+ */
+ public boolean onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) {
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false,
+ /* forViewCapture= */ true, flags);
+ return true;
+ }
+
+ private void onProvideStructureForAssistOrAutofillOrViewCapture(ViewStructure structure,
+ boolean forAutofill, boolean forViewCapture, @AutofillFlags int flags) {
final int id = mID;
if (id != NO_ID && !isViewIdGenerated(id)) {
String pkg, type, entry;
@@ -7981,8 +8172,11 @@
} else {
structure.setId(id, null, null, null);
}
+ if (forViewCapture) {
+ structure.setDataIsSensitive(false);
+ }
- if (forAutofill) {
+ if (forAutofill || forViewCapture) {
final @AutofillType int autofillType = getAutofillType();
// Don't need to fill autofill info if view does not support it.
// For example, only TextViews that are editable support autofill
@@ -8530,9 +8724,8 @@
if (parentImportance == IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
|| parentImportance == IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS) {
if (Log.isLoggable(AUTOFILL_LOG_TAG, Log.VERBOSE)) {
- Log.v(AUTOFILL_LOG_TAG, "View (autofillId=" + getAutofillViewId() + ", "
- + getClass() + ") is not important for autofill because parent "
- + parent + "'s importance is " + parentImportance);
+ Log.v(AUTOFILL_LOG_TAG, "View (" + this + ") is not important for autofill "
+ + "because parent " + parent + "'s importance is " + parentImportance);
}
return false;
}
@@ -8549,14 +8742,18 @@
if (importance == IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
|| importance == IMPORTANT_FOR_AUTOFILL_NO) {
if (Log.isLoggable(AUTOFILL_LOG_TAG, Log.VERBOSE)) {
- Log.v(AUTOFILL_LOG_TAG, "View (autofillId=" + getAutofillViewId() + ", "
- + getClass() + ") is not important for autofill because its "
- + "importance is " + importance);
+ Log.v(AUTOFILL_LOG_TAG, "View (" + this + ") is not important for autofill "
+ + "because its importance is " + importance);
}
return false;
}
// Then use some heuristics to handle AUTO.
+ if (importance != IMPORTANT_FOR_AUTOFILL_AUTO) {
+ Log.w(AUTOFILL_LOG_TAG, "invalid autofill importance (" + importance + " on view "
+ + this);
+ return false;
+ }
// Always include views that have an explicit resource id.
final int id = mID;
@@ -8584,6 +8781,198 @@
return false;
}
+ /**
+ * Gets the mode for determining whether this view is important for content capture.
+ *
+ * <p>See {@link #setImportantForContentCapture(int)} and
+ * {@link #isImportantForContentCapture()} for more info about this mode.
+ *
+ * @return {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO} by default, or value passed to
+ * {@link #setImportantForContentCapture(int)}.
+ *
+ * @attr ref android.R.styleable#View_importantForContentCapture
+ */
+ @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to = "auto"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES, to = "yes"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO, to = "no"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS,
+ to = "yesExcludeDescendants"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS,
+ to = "noExcludeDescendants")})
+ public @ContentCaptureImportance int getImportantForContentCapture() {
+ // NOTE: the important for content capture values were the first flags added and are set in
+ // the rightmost position, so we don't need to shift them
+ return mPrivateFlags4 & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK;
+ }
+
+ /**
+ * Sets the mode for determining whether this view is considered important for content capture.
+ *
+ * <p>The platform determines the importance for autofill automatically but you
+ * can use this method to customize the behavior. Typically, a view that provides text should
+ * be marked as {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}.
+ *
+ * @param mode {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO},
+ * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}, {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO},
+ * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS},
+ * or {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS}.
+ *
+ * @attr ref android.R.styleable#View_importantForContentCapture
+ */
+ public void setImportantForContentCapture(@ContentCaptureImportance int mode) {
+ // Reset first
+ mPrivateFlags4 &= ~PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK;
+ // Then set again
+ // NOTE: the important for content capture values were the first flags added and are set in
+ // the rightmost position, so we don't need to shift them
+ mPrivateFlags4 |= (mode & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK);
+ }
+
+ /**
+ * Hints the Android System whether this view is considered important for Content Capture, based
+ * on the value explicitly set by {@link #setImportantForContentCapture(int)} and heuristics
+ * when it's {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}.
+ *
+ * @return whether the view is considered important for autofill.
+ *
+ * @see #setImportantForContentCapture(int)
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ */
+ public final boolean isImportantForContentCapture() {
+ // Check parent mode to ensure we're important
+ ViewParent parent = mParent;
+ while (parent instanceof View) {
+ final int parentImportance = ((View) parent).getImportantForContentCapture();
+ if (parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ || parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for "
+ + "content capture because parent " + parent + "'s importance is "
+ + parentImportance);
+ }
+ return false;
+ }
+ parent = parent.getParent();
+ }
+
+ final int importance = getImportantForContentCapture();
+
+ // First, check the explicit states.
+ if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS
+ || importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES) {
+ return true;
+ }
+ if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ || importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for content "
+ + "capture because its importance is " + importance);
+ }
+ return false;
+ }
+
+ // Then use some heuristics to handle AUTO.
+ if (importance != IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) {
+ Log.w(CONTENT_CAPTURE_LOG_TAG, "invalid content capture importance (" + importance
+ + " on view " + this);
+ return false;
+ }
+
+ // View group is important if at least one children also is
+ //TODO(b/111276913): decide if we really need to send the relevant parents or just the
+ // leaves (with absolute coordinates). If it's the latter, then we need to update this
+ // javadoc and ViewGroup's implementation.
+ if (this instanceof ViewGroup) {
+ final ViewGroup group = (ViewGroup) this;
+ for (int i = 0; i < group.getChildCount(); i++) {
+ final View child = group.getChildAt(i);
+ if (child.isImportantForContentCapture()) {
+ return true;
+ }
+ }
+ }
+
+ // If the app developer explicitly set hints or autofill hintsfor it, it's important.
+ if (getAutofillHints() != null) {
+ return true;
+ }
+
+ // Otherwise, assume it's not important...
+ return false;
+ }
+
+ /**
+ * Helper used to notify the {@link IntelligenceManager}anager when the view is removed or
+ * added, based on whether it's laid out and visible, and without knowing if the parent removed
+ * it from the view
+ * hierarchy.
+ */
+ // TODO(b/111276913): make sure the current algorithm covers all cases. For example, it should
+ // probably be called every time notifyEnterOrExitForAutoFillIfNeeded() is called as well.
+ private void notifyNodeAddedOrRemovedForContentCaptureIfNeeded(
+ @ContentCaptureNotificationType int type) {
+ if (type != CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED
+ && type != CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED) {
+ // Sanity check so it does not screw up the flags
+ Log.wtf(CONTENT_CAPTURE_LOG_TAG, "notifyNodeAddedOrRemovedForContentCaptureIfNeeded(): "
+ + "invalid type " + type + " for " + this);
+ return;
+ }
+
+ if (!isImportantForContentCapture()) return;
+
+ final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class);
+ if (im == null || !im.isContentCaptureEnabled()) return;
+
+ // Make sure event is notified just once, and reset the
+ // PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE flag
+ boolean ignoreNotification = false;
+ if (type == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) {
+ if ((mPrivateFlags4 & PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE)
+ == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) {
+ ignoreNotification = true;
+ } else {
+ mPrivateFlags4 |= PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE;
+ }
+ } else {
+ if ((mPrivateFlags4 & PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE)
+ == CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED) {
+ ignoreNotification = true;
+ } else {
+ mPrivateFlags4 &= ~PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE;
+ }
+ }
+ if (ignoreNotification) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ // TODO(b/111276913): remove this log statement if the algorithm is not improved
+ // (right now it's called too many times when the activity is stopped and/or views
+ // disappear
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "notifyNodeAddedOrRemovedForContentCaptureIfNeeded("
+ + type + "): ignoring repeated notification on " + this);
+ }
+ return;
+ }
+
+ if (type == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) {
+ final ViewStructure structure = im.newViewStructure(this);
+ boolean notifyMgr = onProvideContentCaptureStructure(structure, /* flags= */ 0);
+ if (notifyMgr) {
+ im.notifyViewAppeared(structure);
+ }
+ mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED;
+ } else {
+ if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED) == 0) {
+ return; // skip initial notification
+ }
+ im.notifyViewDisappeared(getAutofillId());
+ }
+ }
+
@Nullable
private AutofillManager getAutofillManager() {
return mContext.getSystemService(AutofillManager.class);
@@ -13094,6 +13483,9 @@
: AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED);
}
}
+ notifyNodeAddedOrRemovedForContentCaptureIfNeeded(isVisible
+ ? CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED
+ : CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED);
}
/**
@@ -18630,6 +19022,8 @@
}
notifyEnterOrExitForAutoFillIfNeeded(false);
+ notifyNodeAddedOrRemovedForContentCaptureIfNeeded(
+ CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED);
}
/**
@@ -20934,6 +21328,13 @@
mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT;
notifyEnterOrExitForAutoFillIfNeeded(true);
}
+
+ if ((mViewFlags & VISIBILITY_MASK) == VISIBLE
+ && (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT) == 0) {
+ notifyNodeAddedOrRemovedForContentCaptureIfNeeded(
+ CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED);
+ mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT;
+ }
}
private boolean hasParentWantsFocus() {
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 38dcdd3..6efb6f3 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -24,7 +24,6 @@
import android.os.LocaleList;
import android.util.Pair;
import android.view.View.AutofillImportance;
-import android.view.ViewStructure.HtmlInfo;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java
index 2530ae3..befcb55 100644
--- a/core/java/android/view/intelligence/ContentCaptureEvent.java
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.java
@@ -16,12 +16,17 @@
package android.view.intelligence;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.view.autofill.AutofillId;
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -60,14 +65,14 @@
*
* <p>The metadata of the node is available through {@link #getViewNode()}.
*/
- public static final int TYPE_VIEW_ADDED = 5;
+ public static final int TYPE_VIEW_APPEARED = 5;
/**
* Called when a node has been removed from the screen and is not visible to the user anymore.
*
* <p>The id of the node is available through {@link #getId()}.
*/
- public static final int TYPE_VIEW_REMOVED = 6;
+ public static final int TYPE_VIEW_DISAPPEARED = 6;
/**
* Called when the text of a node has been changed.
@@ -85,8 +90,8 @@
TYPE_ACTIVITY_PAUSED,
TYPE_ACTIVITY_RESUMED,
TYPE_ACTIVITY_STOPPED,
- TYPE_VIEW_ADDED,
- TYPE_VIEW_REMOVED,
+ TYPE_VIEW_APPEARED,
+ TYPE_VIEW_DISAPPEARED,
TYPE_VIEW_TEXT_CHANGED
})
@Retention(RetentionPolicy.SOURCE)
@@ -95,7 +100,9 @@
private final int mType;
private final long mEventTime;
private final int mFlags;
-
+ private @Nullable AutofillId mId;
+ private @Nullable ViewNode mNode;
+ private @Nullable CharSequence mText;
/** @hide */
public ContentCaptureEvent(int type, long eventTime, int flags) {
@@ -104,12 +111,42 @@
mFlags = flags;
}
+
+ /** @hide */
+ public ContentCaptureEvent(int type, int flags) {
+ this(type, SystemClock.uptimeMillis(), flags);
+ }
+
+ /** @hide */
+ public ContentCaptureEvent(int type) {
+ this(type, /* flags= */ 0);
+ }
+
+ /** @hide */
+ public ContentCaptureEvent setAutofillId(@NonNull AutofillId id) {
+ mId = Preconditions.checkNotNull(id);
+ return this;
+ }
+
+ /** @hide */
+ public ContentCaptureEvent setViewNode(@NonNull ViewNode node) {
+ mNode = Preconditions.checkNotNull(node);
+ return this;
+ }
+
+ /** @hide */
+ public ContentCaptureEvent setText(@Nullable CharSequence text) {
+ mText = text;
+ return this;
+ }
+
/**
* Gets the type of the event.
*
* @return one of {@link #TYPE_ACTIVITY_STARTED}, {@link #TYPE_ACTIVITY_RESUMED},
* {@link #TYPE_ACTIVITY_PAUSED}, {@link #TYPE_ACTIVITY_STOPPED},
- * {@link #TYPE_VIEW_ADDED}, {@link #TYPE_VIEW_REMOVED}, or {@link #TYPE_VIEW_TEXT_CHANGED}.
+ * {@link #TYPE_VIEW_APPEARED}, {@link #TYPE_VIEW_DISAPPEARED},
+ * or {@link #TYPE_VIEW_TEXT_CHANGED}.
*/
public @EventType int getType() {
return mType;
@@ -135,21 +172,21 @@
/**
* Gets the whole metadata of the node associated with the event.
*
- * <p>Only set on {@link #TYPE_VIEW_ADDED} events.
+ * <p>Only set on {@link #TYPE_VIEW_APPEARED} events.
*/
@Nullable
public ViewNode getViewNode() {
- return null;
+ return mNode;
}
/**
* Gets the {@link AutofillId} of the node associated with the event.
*
- * <p>Only set on {@link #TYPE_VIEW_REMOVED} and {@link #TYPE_VIEW_TEXT_CHANGED} events.
+ * <p>Only set on {@link #TYPE_VIEW_DISAPPEARED} and {@link #TYPE_VIEW_TEXT_CHANGED} events.
*/
@Nullable
public AutofillId getId() {
- return null;
+ return mId;
}
/**
@@ -159,16 +196,41 @@
*/
@Nullable
public CharSequence getText() {
- return null;
+ return mText;
+ }
+
+ /** @hide */
+ public void dump(@NonNull PrintWriter pw) {
+ pw.print("type="); pw.print(getTypeAsString(mType));
+ pw.print(", time="); pw.print(mEventTime);
+ if (mFlags > 0) {
+ pw.print(", flags="); pw.print(mFlags);
+ }
+ if (mId != null) {
+ pw.print(", id="); pw.print(mId);
+ }
+ if (mNode != null) {
+ pw.print(", id="); pw.print(mNode.getAutofillId());
+ }
}
@Override
public String toString() {
final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
- .append(getTypeAsString(mType)).append(", time=").append(mEventTime);
+ .append(getTypeAsString(mType));
if (mFlags > 0) {
string.append(", flags=").append(mFlags);
}
+ if (mId != null) {
+ string.append(", id=").append(mId);
+ }
+ if (mNode != null) {
+ final String className = mNode.getClassName();
+ if (mNode != null) {
+ string.append(", class=").append(className);
+ }
+ string.append(", id=").append(mNode.getAutofillId());
+ }
return string.append(']').toString();
}
@@ -182,6 +244,9 @@
parcel.writeInt(mType);
parcel.writeLong(mEventTime);
parcel.writeInt(mFlags);
+ parcel.writeParcelable(mId, flags);
+ ViewNode.writeToParcel(parcel, mNode, flags);
+ parcel.writeCharSequence(mText);
}
public static final Parcelable.Creator<ContentCaptureEvent> CREATOR =
@@ -192,7 +257,17 @@
final int type = parcel.readInt();
final long eventTime = parcel.readLong();
final int flags = parcel.readInt();
- return new ContentCaptureEvent(type, eventTime, flags);
+ final ContentCaptureEvent event = new ContentCaptureEvent(type, eventTime, flags);
+ final AutofillId id = parcel.readParcelable(null);
+ if (id != null) {
+ event.setAutofillId(id);
+ }
+ final ViewNode node = ViewNode.readFromParcel(parcel);
+ if (node != null) {
+ event.setViewNode(node);
+ }
+ event.setText(parcel.readCharSequence());
+ return event;
}
@Override
@@ -201,7 +276,6 @@
}
};
-
/** @hide */
public static String getTypeAsString(@EventType int type) {
switch (type) {
@@ -213,10 +287,10 @@
return "ACTIVITY_PAUSED";
case TYPE_ACTIVITY_STOPPED:
return "ACTIVITY_STOPPED";
- case TYPE_VIEW_ADDED:
- return "VIEW_ADDED";
- case TYPE_VIEW_REMOVED:
- return "VIEW_REMOVED";
+ case TYPE_VIEW_APPEARED:
+ return "VIEW_APPEARED";
+ case TYPE_VIEW_DISAPPEARED:
+ return "VIEW_DISAPPEARED";
case TYPE_VIEW_TEXT_CHANGED:
return "VIEW_TEXT_CHANGED";
default:
diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/IntelligenceManager.java
index 9bf6c2c..c02fb32 100644
--- a/core/java/android/view/intelligence/IntelligenceManager.java
+++ b/core/java/android/view/intelligence/IntelligenceManager.java
@@ -15,6 +15,12 @@
*/
package android.view.intelligence;
+import static android.view.intelligence.ContentCaptureEvent.TYPE_VIEW_APPEARED;
+import static android.view.intelligence.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
+import static android.view.intelligence.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -22,11 +28,15 @@
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.service.intelligence.InteractionSessionId;
import android.util.Log;
+import android.view.View;
+import android.view.ViewStructure;
+import android.view.autofill.AutofillId;
import android.view.intelligence.ContentCaptureEvent.EventType;
import com.android.internal.annotations.GuardedBy;
@@ -34,8 +44,7 @@
import com.android.internal.util.Preconditions;
import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.List;
+import java.util.ArrayList;
import java.util.Set;
/**
@@ -46,8 +55,9 @@
private static final String TAG = "IntelligenceManager";
- // TODO(b/111276913): define a way to dynamically set it (for example, using settings?)
+ // TODO(b/111276913): define a way to dynamically set them(for example, using settings?)
private static final boolean VERBOSE = false;
+ private static final boolean DEBUG = true; // STOPSHIP if not set to false
/**
* Used to indicate that a text change was caused by user input (for example, through IME).
@@ -55,7 +65,6 @@
//TODO(b/111276913): link to notifyTextChanged() method once available
public static final int FLAG_USER_INPUT = 0x1;
-
/**
* Initial state, when there is no session.
*
@@ -77,6 +86,15 @@
*/
public static final int STATE_ACTIVE = 2;
+ private static final String BG_THREAD_NAME = "intel_svc_streamer_thread";
+
+ /**
+ * Maximum number of events that are delayed for an app.
+ *
+ * <p>If the session is not started after the limit is reached, it's discarded.
+ */
+ private static final int MAX_DELAYED_SIZE = 20;
+
private final Context mContext;
@Nullable
@@ -99,10 +117,24 @@
@GuardedBy("mLock")
private ComponentName mComponentName;
+ // TODO(b/111276913): create using maximum batch size as capacity
+ /**
+ * List of events held to be sent as a batch.
+ */
+ @GuardedBy("mLock")
+ private final ArrayList<ContentCaptureEvent> mEvents = new ArrayList<>();
+
+ private final Handler mHandler;
+
/** @hide */
public IntelligenceManager(@NonNull Context context, @Nullable IIntelligenceManager service) {
mContext = Preconditions.checkNotNull(context, "context cannot be null");
mService = service;
+
+ // TODO(b/111276913): use an existing bg thread instead...
+ final HandlerThread bgThread = new HandlerThread(BG_THREAD_NAME);
+ bgThread.start();
+ mHandler = Handler.createAsync(bgThread.getLooper());
}
/** @hide */
@@ -111,8 +143,9 @@
synchronized (mLock) {
if (mState != STATE_UNKNOWN) {
+ // TODO(b/111276913): revisit this scenario
Log.w(TAG, "ignoring onActivityStarted(" + token + ") while on state "
- + getStateAsStringLocked());
+ + getStateAsString(mState));
return;
}
mState = STATE_WAITING_FOR_SERVER;
@@ -121,8 +154,8 @@
mComponentName = componentName;
if (VERBOSE) {
- Log.v(TAG, "onActivityStarted(): token=" + token + ", act=" + componentName
- + ", id=" + mId);
+ Log.v(TAG, "onActivityCreated(): token=" + token + ", act="
+ + getActivityDebugNameLocked() + ", id=" + mId);
}
final int flags = 0; // TODO(b/111276913): get proper flags
@@ -138,12 +171,12 @@
} else {
// TODO(b/111276913): handle other cases like disabled by
// service
- mState = STATE_UNKNOWN;
+ resetStateLocked();
}
if (VERBOSE) {
Log.v(TAG, "onActivityStarted() result: code=" + resultCode
+ ", id=" + mId
- + ", state=" + getStateAsStringLocked());
+ + ", state=" + getStateAsString(mState));
}
}
}
@@ -154,6 +187,60 @@
}
}
+ //TODO(b/111276913): should buffer event (and call service on handler thread), instead of
+ // calling right away
+ private void sendEvent(@NonNull ContentCaptureEvent event) {
+ mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, event));
+ }
+
+ private void handleSendEvent(@NonNull ContentCaptureEvent event) {
+
+ synchronized (mLock) {
+ mEvents.add(event);
+ final int numberEvents = mEvents.size();
+ if (mState != STATE_ACTIVE) {
+ if (numberEvents >= MAX_DELAYED_SIZE) {
+ // Typically happens on system apps that are started before the system service
+ // is ready (like com.android.settings/.FallbackHome)
+ //TODO(b/111276913): try to ignore session while system is not ready / boot
+ // not complete instead.
+ Log.w(TAG, "Closing session for " + getActivityDebugNameLocked()
+ + " after " + numberEvents + " delayed events");
+ // TODO(b/111276913): blacklist activity / use special flag to indicate that
+ // when it's launched again
+ resetStateLocked();
+ return;
+ }
+
+ if (VERBOSE) {
+ Log.v(TAG, "Delaying " + numberEvents + " events for "
+ + getActivityDebugNameLocked() + " while on state "
+ + getStateAsString(mState));
+ }
+ return;
+ }
+
+ if (mId == null) {
+ // Sanity check - should not happen
+ Log.wtf(TAG, "null session id for " + mComponentName);
+ return;
+ }
+
+ //TODO(b/111276913): right now we're sending sending right away (unless not ready), but
+ // we should hold the events and flush later.
+ try {
+ if (DEBUG) {
+ Log.d(TAG, "Sending " + numberEvents + " event(s) for "
+ + getActivityDebugNameLocked());
+ }
+ mService.sendEvents(mContext.getUserId(), mId, mEvents);
+ mEvents.clear();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
/**
* Used for intermediate events (i.e, other than created and destroyed).
*
@@ -161,28 +248,11 @@
*/
public void onActivityLifecycleEvent(@EventType int type) {
if (!isContentCaptureEnabled()) return;
-
- //TODO(b/111276913): should buffer event (and call service on handler thread), instead of
- // calling right away
- final ContentCaptureEvent event = new ContentCaptureEvent(type, SystemClock.uptimeMillis(),
- 0);
- final List<ContentCaptureEvent> events = Arrays.asList(event);
-
- synchronized (mLock) {
- //TODO(b/111276913): check session state; for example, how to handle if it's waiting for
- // remote id
-
- if (VERBOSE) {
- Log.v(TAG, "onActivityLifecycleEvent() for " + mComponentName.flattenToShortString()
- + ": " + ContentCaptureEvent.getTypeAsString(type));
- }
-
- try {
- mService.sendEvents(mContext.getUserId(), mId, events);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ if (VERBOSE) {
+ Log.v(TAG, "onActivityLifecycleEvent() for " + getActivityDebugNameLocked()
+ + ": " + ContentCaptureEvent.getTypeAsString(type));
}
+ sendEvent(new ContentCaptureEvent(type));
}
/** @hide */
@@ -194,22 +264,105 @@
// id) and send it to the cache of batched commands
if (VERBOSE) {
- Log.v(TAG, "onActivityDestroyed(): state=" + getStateAsStringLocked()
+ Log.v(TAG, "onActivityDestroyed(): state=" + getStateAsString(mState)
+ ", mId=" + mId);
}
try {
mService.finishSession(mContext.getUserId(), mId);
- mState = STATE_UNKNOWN;
- mId = null;
- mApplicationToken = null;
- mComponentName = null;
+ resetStateLocked();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
+ @GuardedBy("mLock")
+ private void resetStateLocked() {
+ mState = STATE_UNKNOWN;
+ mId = null;
+ mApplicationToken = null;
+ mComponentName = null;
+ mEvents.clear();
+ }
+
+ /**
+ * Notifies the Intelligence Service that a node has been added to the view structure.
+ *
+ * <p>Typically called "manually" by views that handle their own virtual view hierarchy, or
+ * automatically by the Android System for views that return {@code true} on
+ * {@link View#onProvideContentCaptureStructure(ViewStructure, int)}.
+ *
+ * @param node node that has been added.
+ */
+ public void notifyViewAppeared(@NonNull ViewStructure node) {
+ Preconditions.checkNotNull(node);
+ if (!isContentCaptureEnabled()) return;
+
+ if (!(node instanceof ViewNode.ViewStructureImpl)) {
+ throw new IllegalArgumentException("Invalid node class: " + node.getClass());
+ }
+ sendEvent(new ContentCaptureEvent(TYPE_VIEW_APPEARED)
+ .setViewNode(((ViewNode.ViewStructureImpl) node).mNode));
+ }
+
+ /**
+ * Notifies the Intelligence Service that a node has been removed from the view structure.
+ *
+ * <p>Typically called "manually" by views that handle their own virtual view hierarchy, or
+ * automatically by the Android System for standard views.
+ *
+ * @param id id of the node that has been removed.
+ */
+ public void notifyViewDisappeared(@NonNull AutofillId id) {
+ Preconditions.checkNotNull(id);
+ if (!isContentCaptureEnabled()) return;
+
+ sendEvent(new ContentCaptureEvent(TYPE_VIEW_DISAPPEARED).setAutofillId(id));
+ }
+
+ /**
+ * Notifies the Intelligence Service that the value of a text node has been changed.
+ *
+ * @param id of the node.
+ * @param text new text.
+ * @param flags either {@code 0} or {@link #FLAG_USER_INPUT} when the value was explicitly
+ * changed by the user (for example, through the keyboard).
+ */
+ public void notifyViewTextChanged(@NonNull AutofillId id, @Nullable CharSequence text,
+ int flags) {
+ Preconditions.checkNotNull(id);
+ if (!isContentCaptureEnabled()) return;
+
+ sendEvent(new ContentCaptureEvent(TYPE_VIEW_TEXT_CHANGED, flags).setAutofillId(id)
+ .setText(text));
+ }
+
+ /**
+ * Creates a {@link ViewStructure} for a "standard" view.
+ *
+ * @hide
+ */
+ @NonNull
+ public ViewStructure newViewStructure(@NonNull View view) {
+ return new ViewNode.ViewStructureImpl(view);
+ }
+
+ /**
+ * Creates a {@link ViewStructure} for a "virtual" view, so it can be passed to
+ * {@link #notifyViewAppeared(ViewStructure)} by the view managing the virtual view hierarchy.
+ *
+ * @param parentId id of the virtual view parent (it can be obtained by calling
+ * {@link ViewStructure#getAutofillId()} on the parent).
+ * @param virtualId id of the virtual child, relative to the parent.
+ *
+ * @return a new {@link ViewStructure} that can be used for Content Capture purposes.
+ */
+ @NonNull
+ public ViewStructure newVirtualViewStructure(@NonNull AutofillId parentId, int virtualId) {
+ return new ViewNode.ViewStructureImpl(parentId, virtualId);
+ }
+
/**
* Returns the component name of the {@code android.service.intelligence.IntelligenceService}
* that is enabled for the current user.
@@ -322,15 +475,29 @@
pw.print(prefix2); pw.print("enabled: "); pw.println(isContentCaptureEnabled());
pw.print(prefix2); pw.print("id: "); pw.println(mId);
pw.print(prefix2); pw.print("state: "); pw.print(mState); pw.print(" (");
- pw.print(getStateAsStringLocked()); pw.println(")");
- pw.print(prefix2); pw.print("appToken: "); pw.println(mApplicationToken);
- pw.print(prefix2); pw.print("componentName: "); pw.println(mComponentName);
+ pw.print(getStateAsString(mState)); pw.println(")");
+ pw.print(prefix2); pw.print("app token: "); pw.println(mApplicationToken);
+ pw.print(prefix2); pw.print("component name: ");
+ pw.println(mComponentName == null ? "null" : mComponentName.flattenToShortString());
+ final int numberEvents = mEvents.size();
+ pw.print(prefix2); pw.print("batched events: "); pw.println(numberEvents);
+ if (numberEvents > 0) {
+ for (int i = 0; i < numberEvents; i++) {
+ final ContentCaptureEvent event = mEvents.get(i);
+ pw.println(i); pw.print(": "); event.dump(pw); pw.println();
+ }
+
+ }
}
}
+ /**
+ * Gets a string that can be used to identify the activity on logging statements.
+ */
@GuardedBy("mLock")
- private String getStateAsStringLocked() {
- return getStateAsString(mState);
+ private String getActivityDebugNameLocked() {
+ return mComponentName == null ? mContext.getPackageName()
+ : mComponentName.flattenToShortString();
}
@NonNull
diff --git a/core/java/android/view/intelligence/ViewNode.java b/core/java/android/view/intelligence/ViewNode.java
index 357ecf5..cc78e6b 100644
--- a/core/java/android/view/intelligence/ViewNode.java
+++ b/core/java/android/view/intelligence/ViewNode.java
@@ -15,10 +15,24 @@
*/
package android.view.intelligence;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.assist.AssistStructure;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.LocaleList;
+import android.os.Parcel;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewParent;
+import android.view.ViewStructure;
+import android.view.ViewStructure.HtmlInfo.Builder;
import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+
+import com.android.internal.util.Preconditions;
//TODO(b/111276913): add javadocs / implement Parcelable / implement
//TODO(b/111276913): for now it's extending ViewNode directly as it needs most of its properties,
@@ -28,6 +42,16 @@
@SystemApi
public final class ViewNode extends AssistStructure.ViewNode {
+ private static final String TAG = "ViewNode";
+
+ private AutofillId mParentAutofillId;
+
+ // TODO(b/111276913): temporarily setting some fields here while they're not accessible from the
+ // superclass
+ private AutofillId mAutofillId;
+ private CharSequence mText;
+ private String mClassName;
+
/** @hide */
public ViewNode() {
}
@@ -38,7 +62,343 @@
*/
@Nullable
public AutofillId getParentAutofillId() {
- //TODO(b/111276913): implement
- return null;
+ return mParentAutofillId;
+ }
+
+ // TODO(b/111276913): temporarily overwriting some methods
+ @Override
+ public AutofillId getAutofillId() {
+ return mAutofillId;
+ }
+ @Override
+ public CharSequence getText() {
+ return mText;
+ }
+ @Override
+ public String getClassName() {
+ return mClassName;
+ }
+
+ /** @hide */
+ public static void writeToParcel(@NonNull Parcel parcel, @Nullable ViewNode node, int flags) {
+ if (node == null) {
+ parcel.writeParcelable(null, flags);
+ return;
+ }
+ parcel.writeParcelable(node.mAutofillId, flags);
+ parcel.writeParcelable(node.mParentAutofillId, flags);
+ parcel.writeCharSequence(node.mText);
+ parcel.writeString(node.mClassName);
+ }
+
+ /** @hide */
+ public static @Nullable ViewNode readFromParcel(@NonNull Parcel parcel) {
+ final AutofillId id = parcel.readParcelable(null);
+ if (id == null) return null;
+
+ final ViewNode node = new ViewNode();
+
+ node.mAutofillId = id;
+ node.mParentAutofillId = parcel.readParcelable(null);
+ node.mText = parcel.readCharSequence();
+ node.mClassName = parcel.readString();
+
+ return node;
+ }
+
+ /** @hide */
+ static final class ViewStructureImpl extends ViewStructure {
+
+ final ViewNode mNode = new ViewNode();
+
+ ViewStructureImpl(@NonNull View view) {
+ mNode.mAutofillId = Preconditions.checkNotNull(view).getAutofillId();
+ final ViewParent parent = view.getParent();
+ if (parent instanceof View) {
+ mNode.mParentAutofillId = ((View) parent).getAutofillId();
+ }
+ }
+
+ ViewStructureImpl(@NonNull AutofillId parentId, int virtualId) {
+ mNode.mParentAutofillId = Preconditions.checkNotNull(parentId);
+ mNode.mAutofillId = new AutofillId(parentId, virtualId);
+ }
+
+ @Override
+ public void setId(int id, String packageName, String typeName, String entryName) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setTransformation(Matrix matrix) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setElevation(float elevation) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setAssistBlocked(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setEnabled(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setClickable(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setLongClickable(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setContextClickable(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setFocusable(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setFocused(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setAccessibilityFocused(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setCheckable(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setChecked(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setSelected(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setActivated(boolean state) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setOpaque(boolean opaque) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setClassName(String className) {
+ // TODO(b/111276913): temporarily setting directly; should be done on superclass instead
+ mNode.mClassName = className;
+ }
+
+ @Override
+ public void setContentDescription(CharSequence contentDescription) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setText(CharSequence text) {
+ // TODO(b/111276913): temporarily setting directly; should be done on superclass instead
+ mNode.mText = text;
+ }
+
+ @Override
+ public void setText(CharSequence text, int selectionStart, int selectionEnd) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setTextStyle(float size, int fgColor, int bgColor, int style) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setTextLines(int[] charOffsets, int[] baselines) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setHint(CharSequence hint) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public CharSequence getText() {
+ // TODO(b/111276913): temporarily getting directly; should be done on superclass instead
+ return mNode.mText;
+ }
+
+ @Override
+ public int getTextSelectionStart() {
+ // TODO(b/111276913): implement or move to superclass
+ return 0;
+ }
+
+ @Override
+ public int getTextSelectionEnd() {
+ // TODO(b/111276913): implement or move to superclass
+ return 0;
+ }
+
+ @Override
+ public CharSequence getHint() {
+ // TODO(b/111276913): implement or move to superclass
+ return null;
+ }
+
+ @Override
+ public Bundle getExtras() {
+ // TODO(b/111276913): implement or move to superclass
+ return null;
+ }
+
+ @Override
+ public boolean hasExtras() {
+ // TODO(b/111276913): implement or move to superclass
+ return false;
+ }
+
+ @Override
+ public void setChildCount(int num) {
+ Log.w(TAG, "setChildCount() is not supported");
+ }
+
+ @Override
+ public int addChildCount(int num) {
+ Log.w(TAG, "addChildCount() is not supported");
+ return 0;
+ }
+
+ @Override
+ public int getChildCount() {
+ Log.w(TAG, "getChildCount() is not supported");
+ return 0;
+ }
+
+ @Override
+ public ViewStructure newChild(int index) {
+ Log.w(TAG, "newChild() is not supported");
+ return null;
+ }
+
+ @Override
+ public ViewStructure asyncNewChild(int index) {
+ Log.w(TAG, "asyncNewChild() is not supported");
+ return null;
+ }
+
+ @Override
+ public AutofillId getAutofillId() {
+ // TODO(b/111276913): temporarily getting directly; should be done on superclass instead
+ return mNode.mAutofillId;
+ }
+
+ @Override
+ public void setAutofillId(AutofillId id) {
+ // TODO(b/111276913): temporarily setting directly; should be done on superclass instead
+ mNode.mAutofillId = id;
+ }
+
+ @Override
+ public void setAutofillId(AutofillId parentId, int virtualId) {
+ // TODO(b/111276913): temporarily setting directly; should be done on superclass instead
+ mNode.mAutofillId = new AutofillId(parentId, virtualId);
+ }
+
+ @Override
+ public void setAutofillType(int type) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setAutofillHints(String[] hint) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setAutofillValue(AutofillValue value) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setAutofillOptions(CharSequence[] options) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setInputType(int inputType) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void setDataIsSensitive(boolean sensitive) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public void asyncCommit() {
+ Log.w(TAG, "asyncCommit() is not supported");
+ }
+
+ @Override
+ public Rect getTempRect() {
+ // TODO(b/111276913): implement or move to superclass
+ return null;
+ }
+
+ @Override
+ public void setWebDomain(String domain) {
+ Log.w(TAG, "setWebDomain() is not supported");
+ }
+
+ @Override
+ public void setLocaleList(LocaleList localeList) {
+ // TODO(b/111276913): implement or move to superclass
+ }
+
+ @Override
+ public Builder newHtmlInfoBuilder(String tagName) {
+ Log.w(TAG, "newHtmlInfoBuilder() is not supported");
+ return null;
+ }
+
+ @Override
+ public void setHtmlInfo(HtmlInfo htmlInfo) {
+ Log.w(TAG, "setHtmlInfo() is not supported");
+ }
}
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index a93604f..c0979fe 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -196,12 +196,6 @@
private boolean mIsRoot = true;
/**
- * Optional theme resource id applied in inflateView(). When 0, Theme.DeviceDefault will be
- * used.
- */
- private int mApplyThemeResId;
-
- /**
* Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify
* the layout in a way that isn't recoverable, since views are being removed.
*/
@@ -3262,14 +3256,6 @@
}
/**
- * Set the theme used in apply() and applyASync().
- * @hide
- */
- public void setApplyTheme(@StyleRes int themeResId) {
- mApplyThemeResId = themeResId;
- }
-
- /**
* Inflates the view hierarchy represented by this object and applies
* all of the actions.
*
@@ -3290,11 +3276,25 @@
View result = inflateView(context, rvToApply, parent);
rvToApply.performApply(result, parent, handler);
+ return result;
+ }
+ /** @hide */
+ public View applyWithTheme(Context context, ViewGroup parent, OnClickHandler handler,
+ @StyleRes int applyThemeResId) {
+ RemoteViews rvToApply = getRemoteViewsToApply(context);
+
+ View result = inflateView(context, rvToApply, parent, applyThemeResId);
+ rvToApply.performApply(result, parent, handler);
return result;
}
private View inflateView(Context context, RemoteViews rv, ViewGroup parent) {
+ return inflateView(context, rv, parent, 0);
+ }
+
+ private View inflateView(Context context, RemoteViews rv, ViewGroup parent,
+ @StyleRes int applyThemeResId) {
// RemoteViews may be built by an application installed in another
// user. So build a context that loads resources from that user but
// still returns the current users userId so settings like data / time formats
@@ -3303,8 +3303,8 @@
Context inflationContext = new RemoteViewsContextWrapper(context, contextForResources);
// If mApplyThemeResId is not given, Theme.DeviceDefault will be used.
- if (mApplyThemeResId != 0) {
- inflationContext = new ContextThemeWrapper(inflationContext, mApplyThemeResId);
+ if (applyThemeResId != 0) {
+ inflationContext = new ContextThemeWrapper(inflationContext, applyThemeResId);
}
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 8bfc151..d55c09f 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -1422,17 +1422,24 @@
@Override
public void onProvideStructure(ViewStructure structure) {
super.onProvideStructure(structure);
- onProvideAutoFillStructureForAssistOrAutofill(structure);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure);
}
@Override
public void onProvideAutofillStructure(ViewStructure structure, int flags) {
super.onProvideAutofillStructure(structure, flags);
- onProvideAutoFillStructureForAssistOrAutofill(structure);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure);
}
- // NOTE: currently there is no difference for Assist or AutoFill, so it doesn't take flags
- private void onProvideAutoFillStructureForAssistOrAutofill(ViewStructure structure) {
+ @Override
+ public boolean onProvideContentCaptureStructure(ViewStructure structure, int flags) {
+ final boolean notifyManager = super.onProvideContentCaptureStructure(structure, flags);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure);
+ return notifyManager;
+ }
+
+ // NOTE: currently there is no difference for any type, so it doesn't take flags
+ private void onProvideStructureForAssistOrAutofillOrViewCapture(ViewStructure structure) {
CharSequence switchText = isChecked() ? mTextOn : mTextOff;
if (!TextUtils.isEmpty(switchText)) {
CharSequence oldText = structure.getText();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 572670f..3bdd7b8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -166,6 +166,7 @@
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.view.intelligence.IntelligenceManager;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationContext;
import android.view.textclassifier.TextClassificationManager;
@@ -948,6 +949,9 @@
if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) {
setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES);
}
+ if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) {
+ setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES);
+ }
setTextInternal("");
@@ -6072,7 +6076,7 @@
if (needEditableForNotification) {
sendAfterTextChanged((Editable) text);
} else {
- notifyAutoFillManagerAfterTextChanged();
+ notifyManagersAfterTextChanged();
}
// SelectionModifierCursorController depends on textCanBeSelected, which depends on text
@@ -10121,23 +10125,33 @@
}
// Always notify AutoFillManager - it will return right away if autofill is disabled.
- notifyAutoFillManagerAfterTextChanged();
+ notifyManagersAfterTextChanged();
hideErrorIfUnchanged();
}
- private void notifyAutoFillManagerAfterTextChanged() {
- // It is important to not check whether the view is important for autofill
- // since the user can trigger autofill manually on not important views.
- if (!isAutofillable()) {
- return;
- }
- final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
- if (afm != null) {
- if (android.view.autofill.Helper.sVerbose) {
- Log.v(LOG_TAG, "notifyAutoFillManagerAfterTextChanged");
+ private void notifyManagersAfterTextChanged() {
+
+ // Autofill
+ if (isAutofillable()) {
+ // It is important to not check whether the view is important for autofill
+ // since the user can trigger autofill manually on not important views.
+ final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
+ if (afm != null) {
+ if (android.view.autofill.Helper.sVerbose) {
+ Log.v(LOG_TAG, "notifyAutoFillManagerAfterTextChanged");
+ }
+ afm.notifyValueChanged(TextView.this);
}
- afm.notifyValueChanged(TextView.this);
+ }
+
+ // ContentCapture
+ if (isImportantForContentCapture() && isTextEditable()) {
+ final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class);
+ if (im != null && im.isContentCaptureEnabled()) {
+ // TODO(b/111276913): pass flags when edited by user / add CTS test
+ im.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0);
+ }
}
}
@@ -10900,21 +10914,33 @@
@Override
public void onProvideStructure(ViewStructure structure) {
super.onProvideStructure(structure);
- onProvideAutoStructureForAssistOrAutofill(structure, false);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false,
+ /* forViewCapture= */ false);
}
@Override
public void onProvideAutofillStructure(ViewStructure structure, int flags) {
super.onProvideAutofillStructure(structure, flags);
- onProvideAutoStructureForAssistOrAutofill(structure, true);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ true,
+ /* forViewCapture= */ false);
}
- private void onProvideAutoStructureForAssistOrAutofill(ViewStructure structure,
- boolean forAutofill) {
+ @Override
+ public boolean onProvideContentCaptureStructure(ViewStructure structure, int flags) {
+ final boolean notifyManager = super.onProvideContentCaptureStructure(structure, flags);
+ onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false,
+ /* forViewCapture= */ true);
+ return notifyManager;
+ }
+
+ private void onProvideStructureForAssistOrAutofillOrViewCapture(ViewStructure structure,
+ boolean forAutofill, boolean forViewCapture) {
final boolean isPassword = hasPasswordTransformationMethod()
|| isPasswordInputType(getInputType());
- if (forAutofill) {
- structure.setDataIsSensitive(!mTextSetFromXmlOrResourceId);
+ if (forAutofill || forViewCapture) {
+ if (forAutofill) {
+ structure.setDataIsSensitive(!mTextSetFromXmlOrResourceId);
+ }
if (mTextId != ResourceId.ID_NULL) {
try {
structure.setTextIdEntry(getResources().getResourceEntryName(mTextId));
@@ -10927,7 +10953,7 @@
}
}
- if (!isPassword || forAutofill) {
+ if (!isPassword || forAutofill || forViewCapture) {
if (mLayout == null) {
assumeLayout();
}
@@ -11043,7 +11069,8 @@
// of the View (and can be any drawable) or a BackgroundColorSpan inside the text.
structure.setTextStyle(getTextSize(), getCurrentTextColor(),
AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
- } else {
+ }
+ if (forAutofill || forViewCapture) {
structure.setMinTextEms(getMinEms());
structure.setMaxTextEms(getMaxEms());
int maxLength = -1;
diff --git a/core/proto/android/server/usagestatsservice.proto b/core/proto/android/server/usagestatsservice.proto
index 941c81f..3d60a86 100644
--- a/core/proto/android/server/usagestatsservice.proto
+++ b/core/proto/android/server/usagestatsservice.proto
@@ -45,11 +45,15 @@
optional string package = 1;
// package_index contains the index + 1 of the package name in the string pool
optional int32 package_index = 2;
+ // Time attributes stored as an offset of the IntervalStats's beginTime.
optional int64 last_time_active_ms = 3;
optional int64 total_time_active_ms = 4;
optional int32 last_event = 5;
optional int32 app_launch_count = 6;
repeated ChooserAction chooser_actions = 7;
+ // Time attributes stored as an offset of the IntervalStats's beginTime.
+ optional int64 last_time_service_used_ms = 8;
+ optional int64 total_time_service_used_ms = 9;
}
// Stores the relevant information an IntervalStats will have about a Configuration
@@ -86,6 +90,8 @@
// stringpool contains all the package and class names used by UsageStats and Event
// They will hold a number that is equal to the index + 1 of their string in the pool
optional StringPool stringpool = 2;
+ optional int32 major_version = 3;
+ optional int32 minor_version = 4;
// The following fields contain aggregated usage stats data
optional CountAndTime interactive = 10;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 68ec342..a99b942 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2448,6 +2448,25 @@
<flag name="noExcludeDescendants" value="0x8" />
</attr>
+ <!-- Hints the Android System whether the view node associated with this View should be
+ use for content capture purposes. -->
+ <attr name="importantForContentCapture">
+ <!-- Let the Android System use its heuristics to determine if the view is important for content capture. -->
+ <flag name="auto" value="0" />
+ <!-- Hint the Android System that this view is important for content capture,
+ and its children (if any) will be traversed.. -->
+ <flag name="yes" value="0x1" />
+ <!-- Hint the Android System that this view is *not* important for content capture,
+ but its children (if any) will be traversed.. -->
+ <flag name="no" value="0x2" />
+ <!-- Hint the Android System that this view is important for content capture,
+ but its children (if any) will not be traversed. -->
+ <flag name="yesExcludeDescendants" value="0x4" />
+ <!-- Hint the Android System that this view is *not* important for content capture,
+ and its children (if any) will not be traversed. -->
+ <flag name="noExcludeDescendants" value="0x8" />
+ </attr>
+
<!-- Boolean that controls whether a view can take focus while in touch mode.
If this is true for a view, that view can gain focus when clicked on, and can keep
focus if another view is clicked on that doesn't have this attribute set to true. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 86879c3..73dae08 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2919,6 +2919,7 @@
<public name="settingsSliceUri" />
<public name="shell" />
<public name="interactiveUiTimeout" />
+ <public name="importantForContentCapture" />
</public-group>
<public-group type="drawable" first-id="0x010800b4">
diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
index c6d077d..1f047f9e 100644
--- a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
+++ b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
@@ -16,8 +16,19 @@
package android.app.usage;
-import static com.google.common.truth.Truth.assertThat;
+import static android.app.usage.UsageEvents.Event.CONTINUE_PREVIOUS_DAY;
+import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE;
+import static android.app.usage.UsageEvents.Event.END_OF_DAY;
+import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START;
+import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP;
+import static android.app.usage.UsageEvents.Event.MOVE_TO_BACKGROUND;
+import static android.app.usage.UsageEvents.Event.MOVE_TO_FOREGROUND;
+import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.os.Parcel;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -46,7 +57,7 @@
left.add(right);
- assertThat(left.getFirstTimeStamp()).isEqualTo(99999);
+ assertEquals(left.getFirstTimeStamp(), 99999);
}
@Test
@@ -58,7 +69,7 @@
left.add(right);
- assertThat(left.getLastTimeStamp()).isEqualTo(100001);
+ assertEquals(left.getLastTimeStamp(), 100001);
}
@Test
@@ -72,7 +83,7 @@
left.add(right);
- assertThat(left.getLastTimeUsed()).isEqualTo(200001);
+ assertEquals(left.getLastTimeUsed(), 200001);
}
@Test
@@ -86,7 +97,7 @@
left.add(right);
- assertThat(left.getLastTimeUsed()).isEqualTo(200000);
+ assertEquals(left.getLastTimeUsed(), 200000);
}
@Test
@@ -100,6 +111,373 @@
left.add(right);
- assertThat(left.getTotalTimeInForeground()).isEqualTo(11);
+ assertEquals(left.getTotalTimeInForeground(), 11);
+ }
+
+ @Test
+ public void testParcelable() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+ left.mTotalTimeInForeground = 10;
+
+ left.mLastForegroundActivityEventMap.put("com.test.activity1", MOVE_TO_FOREGROUND);
+ left.mLastForegroundActivityEventMap.put("com.test.activity2", MOVE_TO_FOREGROUND);
+ left.mLastForegroundServiceEventMap.put("com.test.service1", FOREGROUND_SERVICE_START);
+ left.mLastForegroundServiceEventMap.put("com.test.service2", FOREGROUND_SERVICE_START);
+
+ Parcel p = Parcel.obtain();
+ left.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ right = UsageStats.CREATOR.createFromParcel(p);
+ compareUsageStats(left, right);
+ }
+
+ @Test
+ public void testForegroundActivity() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.activity1", 200000, MOVE_TO_FOREGROUND);
+ assertEquals(left.mLastTimeUsed, 200000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(MOVE_TO_FOREGROUND));
+ assertEquals(left.mLaunchCount, 1);
+
+ left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 350000);
+ assertFalse(left.mLastForegroundActivityEventMap.containsKey("com.test.activity1"));
+ assertEquals(left.mTotalTimeInForeground, 350000 - 200000);
+ }
+
+ @Test
+ public void testEvent_CONTINUE_PREVIOUS_DAY() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY);
+ assertEquals(left.mLastTimeUsed, 100000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 350000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null);
+ assertEquals(left.mTotalTimeInForeground, 350000 - 100000);
+ }
+
+ @Test
+ public void testEvent_END_OF_DAY() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY);
+ assertEquals(left.mLastTimeUsed, 100000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update(null, 350000, END_OF_DAY);
+ assertEquals(left.mLastTimeUsed, 350000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(END_OF_DAY));
+ assertEquals(left.mTotalTimeInForeground, 350000 - 100000);
+ }
+
+ @Test
+ public void testForegroundActivityEventSequence() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY);
+ assertEquals(left.mLastTimeUsed, 100000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 350000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null);
+ assertEquals(left.mTotalTimeInForeground, 250000 /*350000 - 100000*/);
+
+ left.update("com.test.activity1", 450000, MOVE_TO_FOREGROUND);
+ assertEquals(left.mLastTimeUsed, 450000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(MOVE_TO_FOREGROUND));
+ assertEquals(left.mTotalTimeInForeground, 250000);
+
+ left.update("com.test.activity1", 500000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 500000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null);
+ assertEquals(left.mTotalTimeInForeground, 250000 + 50000 /*500000 - 450000*/);
+ }
+
+ @Test
+ public void testForegroundActivityEventOutOfSequence() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY);
+ assertEquals(left.mLastTimeUsed, 100000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.activity1", 150000, MOVE_TO_FOREGROUND);
+ assertEquals(left.mLastTimeUsed, 150000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(MOVE_TO_FOREGROUND));
+ assertEquals(left.mLaunchCount, 1);
+ assertEquals(left.mTotalTimeInForeground, 50000 /*150000 - 100000*/);
+
+ left.update("com.test.activity1", 200000, MOVE_TO_FOREGROUND);
+ assertEquals(left.mLastTimeUsed, 200000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(MOVE_TO_FOREGROUND));
+ assertEquals(left.mLaunchCount, 2);
+ assertEquals(left.mTotalTimeInForeground, 100000);
+
+ left.update("com.test.activity1", 250000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 250000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null);
+ assertEquals(left.mTotalTimeInForeground, 150000);
+
+ left.update("com.test.activity1", 300000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 250000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null);
+ assertEquals(left.mTotalTimeInForeground, 150000);
+
+ left.update("com.test.activity1", 350000, MOVE_TO_FOREGROUND);
+ assertEquals(left.mLastTimeUsed, 350000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(MOVE_TO_FOREGROUND));
+ assertEquals(left.mTotalTimeInForeground, 150000);
+
+ left.update("com.test.activity1", 400000, END_OF_DAY);
+ assertEquals(left.mLastTimeUsed, 400000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(END_OF_DAY));
+ assertEquals(left.mTotalTimeInForeground, 200000);
+ }
+
+ @Test
+ public void testTwoActivityEventSequence() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY);
+ left.update("com.test.activity2", 100000, CONTINUE_PREVIOUS_DAY);
+ assertEquals(left.mLastTimeUsed, 100000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 350000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null);
+ assertEquals(left.mTotalTimeInForeground, 250000 /*350000 - 100000*/);
+
+ left.update("com.test.activity2", 450000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 450000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"), null);
+ assertEquals(left.mTotalTimeInForeground, 250000 + 100000 /*450000 - 350000*/);
+
+ left.update(null, 500000, END_OF_DAY);
+ assertEquals(left.mLastTimeUsed, 450000);
+ assertEquals(left.mTotalTimeInForeground, 350000);
+ }
+
+ @Test
+ public void testForegroundService() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.service1", 200000, FOREGROUND_SERVICE_START);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 200000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(FOREGROUND_SERVICE_START));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 350000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 350000 - 200000);
+ }
+
+ @Test
+ public void testEvent_CONTINUING_FOREGROUND_SERVICE() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.service1", 100000, CONTINUING_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 100000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(CONTINUING_FOREGROUND_SERVICE));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 350000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 350000 - 100000);
+ }
+
+ @Test
+ public void testEvent_ROLLOVER_FOREGROUND_SERVICE() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.service1", 100000,
+ CONTINUING_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 100000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(CONTINUING_FOREGROUND_SERVICE));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update(null, 350000, ROLLOVER_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 350000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(ROLLOVER_FOREGROUND_SERVICE));
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 350000 - 100000);
+ }
+
+ @Test
+ public void testForegroundServiceEventSequence() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.service1", 100000,
+ CONTINUING_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 100000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(CONTINUING_FOREGROUND_SERVICE));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 350000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 /*350000 - 100000*/);
+
+ left.update("com.test.service1", 450000, FOREGROUND_SERVICE_START);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 450000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(FOREGROUND_SERVICE_START));
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 250000);
+
+ left.update("com.test.service1", 500000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 500000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 + 50000 /*500000 - 450000*/);
+ }
+
+ @Test
+ public void testTwoServiceEventSequence() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.service1", 100000,
+ CONTINUING_FOREGROUND_SERVICE);
+ left.update("com.test.service2", 100000,
+ CONTINUING_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 100000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(CONTINUING_FOREGROUND_SERVICE));
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"),
+ new Integer(CONTINUING_FOREGROUND_SERVICE));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 350000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 /*350000 - 100000*/);
+
+ left.update("com.test.service2", 450000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 450000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 + 100000 /*450000 - 350000*/);
+
+ left.update(null, 500000, ROLLOVER_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 450000);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 350000);
+ }
+
+ @Test
+ public void testTwoActivityAndTwoServiceEventSequence() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+
+ left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY);
+ left.update("com.test.activity2", 100000, CONTINUE_PREVIOUS_DAY);
+ left.update("com.test.service1", 100000,
+ CONTINUING_FOREGROUND_SERVICE);
+ left.update("com.test.service2", 100000,
+ CONTINUING_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeUsed, 100000);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 100000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"),
+ new Integer(CONTINUE_PREVIOUS_DAY));
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"),
+ new Integer(CONTINUING_FOREGROUND_SERVICE));
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"),
+ new Integer(CONTINUING_FOREGROUND_SERVICE));
+ assertEquals(left.mLaunchCount, 0);
+
+ left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 350000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null);
+ assertEquals(left.mTotalTimeInForeground, 250000 /*350000 - 100000*/);
+
+ left.update("com.test.service1", 400000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 400000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 300000 /*400000 - 100000*/);
+
+ left.update("com.test.activity2", 450000, MOVE_TO_BACKGROUND);
+ assertEquals(left.mLastTimeUsed, 450000);
+ assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"), null);
+ assertEquals(left.mTotalTimeInForeground, 250000 + 100000 /*450000 - 350000*/);
+
+ left.update("com.test.service2", 500000, FOREGROUND_SERVICE_STOP);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 500000);
+ assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"), null);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 300000 + 100000 /*500000 - 400000*/);
+
+
+ left.update(null, 550000, END_OF_DAY);
+ assertEquals(left.mLastTimeUsed, 450000);
+ assertEquals(left.mTotalTimeInForeground, 350000);
+ left.update(null, 550000, ROLLOVER_FOREGROUND_SERVICE);
+ assertEquals(left.mLastTimeForegroundServiceUsed, 500000);
+ assertEquals(left.mTotalTimeForegroundServiceUsed, 400000);
+ }
+
+ void compareUsageStats(UsageStats us1, UsageStats us2) {
+ assertEquals(us1.mPackageName, us2.mPackageName);
+ assertEquals(us1.mBeginTimeStamp, us2.mBeginTimeStamp);
+ assertEquals(us1.mLastTimeUsed, us2.mLastTimeUsed);
+ assertEquals(us1.mLastTimeForegroundServiceUsed, us2.mLastTimeForegroundServiceUsed);
+ assertEquals(us1.mTotalTimeInForeground, us2.mTotalTimeInForeground);
+ assertEquals(us1.mTotalTimeForegroundServiceUsed, us2.mTotalTimeForegroundServiceUsed);
+ assertEquals(us1.mAppLaunchCount, us2.mAppLaunchCount);
+ assertEquals(us1.mLastForegroundActivityEventMap.size(),
+ us2.mLastForegroundActivityEventMap.size());
+ for (int i = 0; i < us1.mLastForegroundActivityEventMap.size(); i++) {
+ assertEquals(us1.mLastForegroundActivityEventMap.keyAt(i),
+ us2.mLastForegroundActivityEventMap.keyAt(i));
+ assertEquals(us1.mLastForegroundActivityEventMap.valueAt(i),
+ us2.mLastForegroundActivityEventMap.valueAt(i));
+ }
+ assertEquals(us1.mLastForegroundServiceEventMap.size(),
+ us2.mLastForegroundServiceEventMap.size());
+ for (int i = 0; i < us1.mLastForegroundServiceEventMap.size(); i++) {
+ assertEquals(us1.mLastForegroundServiceEventMap.keyAt(i),
+ us2.mLastForegroundServiceEventMap.keyAt(i));
+ assertEquals(us1.mLastForegroundServiceEventMap.valueAt(i),
+ us2.mLastForegroundServiceEventMap.valueAt(i));
+ }
+ assertEquals(us1.mChooserCounts, us2.mChooserCounts);
}
}
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 4e52ff6d..4abcf73 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -186,7 +186,8 @@
title = mStorageManager.getBestVolumeDescription(privateVol);
storageUuid = StorageManager.convert(privateVol.fsUuid);
}
- } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC
+ } else if ((volume.getType() == VolumeInfo.TYPE_PUBLIC
+ || volume.getType() == VolumeInfo.TYPE_STUB)
&& volume.getMountUserId() == userId) {
rootId = volume.getFsUuid();
title = mStorageManager.getBestVolumeDescription(volume);
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index b77d4e5..d34820c 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Kan nie skandeer vir netwerke nie"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Geen"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Gestoor"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Gedeaktiveer"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-opstelling het misluk"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 836ec80..b595e2b 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ለአውታረመረቦች መቃኘት አይቻልም"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"የለም"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"ተቀምጧል"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"ተሰናክሏል"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"የአይ.ፒ. ውቅረት መሰናከል"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 83c4b8e..f8c2ba2 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"لا يمكن فحص الشبكات"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"بدون"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"تم الحفظ"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"غير مفعّلة"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"تعذّرت تهيئة عنوان IP"</string>
@@ -227,11 +226,11 @@
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"اختيار برنامج ترميز LDAC\nلصوت مشغّل البلوتوث: جودة التشغيل"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"البث: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="3700456559305263922">"نظام أسماء النطاقات الخاص"</string>
- <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"اختر وضع نظام أسماء النطاقات الخاص"</string>
+ <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"تحديد وضع \"نظام أسماء النطاقات الخاص\""</string>
<string name="private_dns_mode_off" msgid="8236575187318721684">"غير مفعّل"</string>
<string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"تلقائي"</string>
- <string name="private_dns_mode_provider" msgid="8354935160639360804">"اسم مضيف مزوّد نظام أسماء النطاقات الخاص"</string>
- <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"أدخل اسم مضيف مزوّد نظام أسماء النطاقات"</string>
+ <string name="private_dns_mode_provider" msgid="8354935160639360804">"اسم مضيف مزوّد \"نظام أسماء النطاقات الخاص\""</string>
+ <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"يُرجى إدخال اسم مضيف \"مزوّد نظام أسماء النطاقات\""</string>
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"تعذّر الاتصال"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string>
@@ -371,10 +370,10 @@
<string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك"</string>
<string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_short" msgid="3463575350656389957">"الوقت المتبقي: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
- <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك."</string>
- <string name="power_discharge_by" msgid="6453537733650125582">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string>
+ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
+ <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك."</string>
+ <string name="power_discharge_by" msgid="6453537733650125582">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string>
<string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string>
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"يتبقى أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index ddd17daf..72122c2 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"নেটৱৰ্ক বিচাৰি স্কেন কৰিব পৰা নাই"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"নাই"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"ছেভ কৰি থোৱা নেটৱৰ্কসমূহ"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"নিষ্ক্ৰিয় হৈ আছে"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP কনফিগাৰেশ্বন বিফল হৈছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index a6e484f..23008e2 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Şəbəkə axtarmaq olmur"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Heç biri"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Yadda saxlanılan"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Deaktiv"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Konfiqurasiya Uğursuzluğu"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index a446845..3ee8589 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -21,13 +21,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nije moguće skenirati mreže"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nema"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Sačuvano"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogućeno"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP konfiguracija je otkazala"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nije povezano zbog lošeg kvaliteta mreže"</string>
<string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi veza je otkazala"</string>
- <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem sa potvrdom autentičnosti"</string>
+ <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem sa potvrdom identiteta"</string>
<string name="wifi_cant_connect" msgid="5410016875644565884">"Povezivanje nije uspelo"</string>
<string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Povezivanje sa „<xliff:g id="AP_NAME">%1$s</xliff:g>“ nije uspelo"</string>
<string name="wifi_check_password_try_again" msgid="516958988102584767">"Proverite lozinku i probajte ponovo"</string>
@@ -448,5 +447,5 @@
<string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Trajanje"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Uvek pitaj"</string>
<string name="zen_mode_forever" msgid="2704305038191592967">"Dok ne isključite"</string>
- <string name="time_unit_just_now" msgid="6363336622778342422">"Upravo sada"</string>
+ <string name="time_unit_just_now" msgid="6363336622778342422">"Upravo"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index d56db13..64253bf 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не атрымлiваецца выканаць сканаванне для сетак"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Няма"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Захавана"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Адключана"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Збой канфігурацыі IP"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index c1bc31c..668aa2d 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не може да се сканира за мрежи"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Няма"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Запазено"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Деактивирани"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Неуспешно конфигуриране на IP адреса"</string>
@@ -374,7 +373,7 @@
<string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g> въз основа на използването (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g> въз основа на използването"</string>
<string name="power_discharge_by" msgid="6453537733650125582">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"Следва да издържи до около <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Остава/т повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 1550c00..c6eed2c 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"নেটওয়ার্কগুলির জন্য স্ক্যান করা যাবে না"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"কোনো কিছুই নয়"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"সংরক্ষিত"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"অক্ষম হয়েছে"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP কনফিগারেশনের ব্যর্থতা"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 460e7cf..16179fb 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ne može skenirati mreže"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nema"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Sačuvano"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogućeno"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Greška u konfiguraciji IP-a"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 5638947..f906ea4 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"No es poden cercar xarxes"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Cap"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Desat"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Desactivat"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuració d\'IP"</string>
@@ -70,7 +69,7 @@
<string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actiu"</string>
<string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Àudio multimèdia"</string>
<string name="bluetooth_profile_headset" msgid="7815495680863246034">"Trucades telefòniques"</string>
- <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència del fitxer"</string>
+ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència de fitxers"</string>
<string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositiu d\'entrada"</string>
<string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accés a Internet"</string>
<string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactes"</string>
@@ -393,7 +392,7 @@
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"s\'està carregant"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"No s\'està carregant"</string>
<string name="battery_info_status_not_charging" msgid="8523453668342598579">"El dispositiu està endollat però en aquests moments no es pot carregar"</string>
- <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string>
+ <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlat per l\'administrador"</string>
<string name="disabled" msgid="9206776641295849915">"Desactivat"</string>
<string name="external_source_trusted" msgid="2707996266575928037">"Amb permís"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index de02245..f9c8669 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nelze hledat sítě"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Žádné"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Uloženo"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Vypnuto"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Selhání konfigurace protokolu IP"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 34608d3..6b2bd98 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Der kan ikke søges efter netværk"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ingen"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Gemt"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Deaktiveret"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurationsfejl"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 79965d2..ad6f5f2 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Netzwerkscan nicht möglich"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Keine"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Gespeichert"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Deaktiviert"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-Konfigurationsfehler"</string>
@@ -231,7 +230,7 @@
<string name="private_dns_mode_off" msgid="8236575187318721684">"Aus"</string>
<string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatisch"</string>
<string name="private_dns_mode_provider" msgid="8354935160639360804">"Hostname des privaten DNS-Anbieters"</string>
- <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Hostnamen des DNS-Anbieters eingeben"</string>
+ <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Hostname des DNS-Anbieters eingeben"</string>
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Verbindung nicht möglich"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Level für WLAN-Protokollierung erhöhen, in WiFi Picker pro SSID-RSSI anzeigen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index b9ea843..5bfbf2c 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Δεν είναι δυνατή η σάρωση για δίκτυα"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Καμία"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Αποθηκευμένο"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Απενεργοποιημένο"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Αποτυχία διαμόρφωσης διεύθυνσης IP"</string>
@@ -231,7 +230,7 @@
<string name="private_dns_mode_off" msgid="8236575187318721684">"Ανενεργή"</string>
<string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Αυτόματα"</string>
<string name="private_dns_mode_provider" msgid="8354935160639360804">"Όνομα κεντρικού υπολογιστή παρόχου DNS"</string>
- <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Εισαγάγετε το όνομα κεντρικού υπολογιστή του παρόχου DNS"</string>
+ <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Όνομα κεντρικού υπολογιστή του παρόχου DNS"</string>
<string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Δεν ήταν δυνατή η σύνδεση"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string>
<string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 1a7d7c5..f0eaeed 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 1a7d7c5..f0eaeed 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 1a7d7c5..f0eaeed 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 1a7d7c5..f0eaeed 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 2bfd5b1..6927fda 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"None"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 790c0d3..675084f 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"No se pueden buscar las redes."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ninguna"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Guardada"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Inhabilitada"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuración IP"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1dec85d..b51b847 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"No se puede buscar redes."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ninguna"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Guardado"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Inhabilitado"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuración de IP"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 406e15d..fb077be 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Võrke ei saa kontrollida"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Puudub"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Salvestatud"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Keelatud"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP seadistamise ebaõnnestumine"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index bd4724e..3d3b8c3 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ezin dira sareak bilatu"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Bat ere ez"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Gordeta"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Desgaituta"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Ezin izan da konfiguratu IP helbidea"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 45b8ac7..0af118e 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"اسکن شبکهها امکانپذیر نیست"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"هیچکدام"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"ذخیرهشده"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"غیرفعال شد"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"پیکربندی IP انجام نشد"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 23c63b1..dde10d0d 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Verkkoja ei voi etsiä."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ei mitään"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Tallennettu"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Pois käytöstä"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-kokoonpanovirhe"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index ad99000..1257ea5 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Impossible de rechercher des réseaux."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Aucune"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Enregistré"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Désactivés"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Échec de configuration de l\'adresse IP"</string>
@@ -227,7 +226,7 @@
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Déclencher le codec audio Bluetooth LDAC\nSélection : qualité de lecture"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="3700456559305263922">"DNS privé"</string>
- <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Sélectionnez le mode DNS privé"</string>
+ <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Sélectionner le mode DNS privé"</string>
<string name="private_dns_mode_off" msgid="8236575187318721684">"Désactivé"</string>
<string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatique"</string>
<string name="private_dns_mode_provider" msgid="8354935160639360804">"Nom d\'hôte du fournisseur DNS privé"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index c23db25..444a52e 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Impossible de rechercher des réseaux."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Aucune"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Enregistré"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Désactivé"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Échec de configuration de l\'adresse IP"</string>
@@ -70,7 +69,7 @@
<string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actif"</string>
<string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multimédia"</string>
<string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string>
- <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string>
+ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichiers"</string>
<string name="bluetooth_profile_hid" msgid="3680729023366986480">"Périphérique d\'entrée"</string>
<string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accès Internet"</string>
<string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partage de contacts"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 46532e9..8df2697 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Non se poden explorar redes"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ningunha"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Gardada"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Desactivadas"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Erro na configuración de IP"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 6a74490..4a92f2a 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"નેટવર્ક્સ માટે સ્કૅન કરી શકતા નથી"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"કોઈ નહીં"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"સાચવેલા"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"અક્ષમ કર્યો"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP કન્ફિગરેશન નિષ્ફળ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index bd9a6ec..6d88c35 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"नेटवर्क के लिए स्कैन नहीं कर सकता"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"कोई नहीं"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"सेव किया गया"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"अक्षम"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP कॉन्फ़िगरेशन की विफलता"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 5270531..32c9a62 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Skeniranje mreža nije moguće"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nema"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Spremljeno"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogućeno"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Konfiguracija IP-a nije uspjela"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index ad897f8..ed19267 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nem lehet beolvasni a hálózatokat"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nincs"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Mentve"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Letiltva"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurációs hiba"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 82755f9..6d516ea 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Հնարավոր չէ սկանավորել ցանցերը"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ոչ մեկը"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Պահված է"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Անջատված"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP կարգավորման ձախողում"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 961f892..a5f2317 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Tidak dapat memindai jaringan"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Tidak ada"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Disimpan"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Nonaktif"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Kegagalan Konfigurasi IP"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 759b7ba..6cf09a6 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ekki er hægt að leita að netum"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ekkert"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Vistað"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Óvirkt"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-stillingarvilla"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index bd41e28..a1b9b82 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Impossibile cercare reti"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nessuna"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Salvata"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Disattivata"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Errore configurazione IP"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 5da253c..1a50622 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"לא ניתן לסרוק לאיתור רשתות"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ללא"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"נשמר"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"מושבת"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"כשל בתצורת IP"</string>
@@ -316,7 +315,7 @@
<string name="app_process_limit_title" msgid="4280600650253107163">"מגבלה של תהליכים ברקע"</string>
<string name="show_all_anrs" msgid="4924885492787069007">"הצגת מקרי ANR ברקע"</string>
<string name="show_all_anrs_summary" msgid="6636514318275139826">"הצגת תיבת דו-שיח של \'אפליקציה לא מגיבה\' עבור אפליקציות שפועלות ברקע"</string>
- <string name="show_notification_channel_warnings" msgid="1399948193466922683">"אזהרות לגבי ערוץ הודעות"</string>
+ <string name="show_notification_channel_warnings" msgid="1399948193466922683">"אזהרות לגבי ערוץ התראות"</string>
<string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"הצגת אזהרה כשאפליקציה שולחת התראה ללא ערוץ חוקי"</string>
<string name="force_allow_on_external" msgid="3215759785081916381">"אילוץ הרשאת אפליקציות באחסון חיצוני"</string>
<string name="force_allow_on_external_summary" msgid="3640752408258034689">"מאפשר כתיבה של כל אפליקציה באחסון חיצוני, ללא התחשבות בערכי המניפסט"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index f6b81ed..4c544af 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ネットワークをスキャンできません"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"なし"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"保存済み"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"無効"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP設定エラー"</string>
@@ -436,7 +435,7 @@
<string name="cancel" msgid="6859253417269739139">"キャンセル"</string>
<string name="okay" msgid="1997666393121016642">"OK"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"ON にする"</string>
- <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"マナーモードを ON にする"</string>
+ <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"サイレント モードを ON にする"</string>
<string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"なし"</string>
<string name="zen_interruption_level_priority" msgid="2078370238113347720">"優先的な通知のみ"</string>
<string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index d5f5408..92f3049 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ქსელების სკანირება არა არის შესაძლებელი"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"არცერთი"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"დამახსოვრებულია"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"გამორთულია"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP კონფიგურაციის შეფერხება"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index c3fbfcd..b56c6fd 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Желілерді шолу мүмкін емес"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ешқандай"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Сақталды"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Өшірілген"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP конфигурациясының қатесі"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 8e73f81..5860473 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"មិនអាចវិភាគរកបណ្ដាញ"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"គ្មាន"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"បានរក្សាទុក"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"បានបិទ"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"ការកំណត់រចនាសម្ព័ន្ធ IP បរាជ័យ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index ce225ea..87e18e6 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ನೆಟ್ವರ್ಕ್ಗಳಿಗಾಗಿ ಸ್ಕ್ಯಾನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ಯಾವುದೂ ಇಲ್ಲ"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"ಉಳಿಸಲಾಗಿದೆ"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP ಕಾನ್ಫಿಗರೇಶನ್ ವಿಫಲತೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index b47471b..3333c0d 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"네트워크를 검색할 수 없습니다."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"없음"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"저장됨"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"사용 중지됨"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 설정 실패"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 9853dac4..cbbc47c 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Түйүндөрдү издөө мүмкүн эмес"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Жок"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Сакталды"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Өчүрүлгөн"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP конфигурациясы бузулду"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 1816515..21e4679 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ບໍ່ສາມາດກວດຫາເຄືອຂ່າຍໄດ້"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ບໍ່ໃຊ້"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"ບັນທຶກແລ້ວ"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"ປິດການນຳໃຊ້"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"ການຕັ້ງຄ່າ IP ລົ້ມເຫຼວ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index e6a8e1c..cbff9e7 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nepavyksta nuskaityti tinklų"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nėra"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Išsaugotas"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Neleidžiama"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP konfigūracijos triktis"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index b55afc0..d200828 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nevar skenēt tīklus"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nav"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saglabāts"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Atspējots"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP konfigurācijas kļūme"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index e28c8ee..db16847 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не може да скенира за мрежи"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ниедна"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Зачувано"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Оневозможено"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Конфигурирањето ИП не успеа"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 6860398..c3af968 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"നെറ്റ്വർക്കുകൾക്കായി സ്കാൻ ചെയ്യാനായില്ല"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ഒന്നുമില്ല"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"സംരക്ഷിച്ചു"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP കോൺഫിഗറേഷൻ പരാജയം"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index ba6d601..8627e1b 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Сүлжээнүүдийг скан хийх боломжгүй"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Байхгүй"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Хадгалагдсан"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Идэвхгүйжүүлсэн"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP тохируулга амжилтгүй"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a5d230a..cd7f175 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"नेटवर्कसाठी स्कॅन करू शकत नाही"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"काहीही नाही"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"सेव्ह केले"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"अक्षम"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP कॉन्फिगरेशन अयशस्वी"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index a7ac3ef..d0b2e12 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Tidak boleh mengimbas untuk rangkaian"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Tiada"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Disimpan"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Dinyahdayakan"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Kegagalan Konfigurasi IP"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 6cdab67..5f5957c 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ကွန်ယက်များကို စကင်မလုပ်နိုင်ပါ"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"တစ်ခုမျှ မဟုတ်ပါ"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"သိမ်းဆည်းပြီး"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"ပိတ်ထားသည်"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP ပြုပြင်ခြင်း မအောင်မြင်ပါ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index cf18477..3c240f8 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Kan ikke søke etter nettverk"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ingen"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Lagret"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Slått av"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurasjonsfeil"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 8aba0f8..1699870 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"सञ्जालका लागि स्क्यान गर्न सक्दैन"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"कुनै पनि होइन"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"सुरक्षित गरियो"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"असक्षम पारियो"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP विन्यास असफल"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index e3f1aea..738df94 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Kan niet zoeken naar netwerken"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Geen"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Opgeslagen"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Uitgeschakeld"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-configuratie mislukt"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 8ecac4d..2d39cc6 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ନେଟ୍ୱର୍କଗୁଡ଼ିକୁ ଖୋଜିପାରୁନାହିଁ"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"କିଛି ନାହିଁ"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"ସେଭ୍ ହୋଇଗଲା"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"ଅକ୍ଷମ ହୋଇଛି"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP କନଫିଗରେଶନ ବିଫଳ ହୋଇଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 6f17e13..61f0447 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ਨੈਟਵਰਕਾਂ ਲਈ ਸਕੈਨ ਨਹੀਂ ਕਰ ਸਕਦਾ"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ਕੋਈ ਨਹੀਂ"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"ਰੱਖਿਅਤ ਕੀਤਾ"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"ਅਯੋਗ ਬਣਾਇਆ"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP ਕੌਂਫਿਗਰੇਸ਼ਨ ਅਸਫਲਤਾ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 3c208e3..519f82c 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nie można wyszukać sieci."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Brak"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Zapisana"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Wyłączona"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Błąd konfiguracji IP"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 5c363a4..16844a2 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Não é possível verificar a existência de redes"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nenhuma"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Salva"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Desativado"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Falha de configuração de IP"</string>
@@ -227,7 +226,7 @@
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Acionar seleção de codec de áudio\nBluetooth LDAC: qualidade de reprodução"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="3700456559305263922">"DNS particular"</string>
- <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo DNS particular"</string>
+ <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo de DNS particular"</string>
<string name="private_dns_mode_off" msgid="8236575187318721684">"Desativado"</string>
<string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automático"</string>
<string name="private_dns_mode_provider" msgid="8354935160639360804">"Nome do host do provedor de DNS particular"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 66c59ac..f01ddfa 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Não é possível verificar redes"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nenhuma"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Guardada"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Desativado"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Falha de configuração de IP"</string>
@@ -278,7 +277,7 @@
<string name="media_category" msgid="4388305075496848353">"Multimédia"</string>
<string name="debug_monitoring_category" msgid="7640508148375798343">"Monitorização"</string>
<string name="strict_mode" msgid="1938795874357830695">"Modo rigoroso ativado"</string>
- <string name="strict_mode_summary" msgid="142834318897332338">"Piscar ecrã se aplic. fazem oper. prolong. no tópico princ."</string>
+ <string name="strict_mode_summary" msgid="142834318897332338">"Piscar ecrã se app fazem oper. prolong. no tópico princ."</string>
<string name="pointer_location" msgid="6084434787496938001">"Localização do ponteiro"</string>
<string name="pointer_location_summary" msgid="840819275172753713">"Apresentar dados atuais de toque"</string>
<string name="show_touches" msgid="2642976305235070316">"Mostrar toques"</string>
@@ -305,7 +304,7 @@
<string name="show_non_rect_clip" msgid="505954950474595172">"Depurar operações de clipe não retangulares"</string>
<string name="track_frame_time" msgid="6094365083096851167">"Renderiz. HWUI do perfil"</string>
<string name="enable_gpu_debug_layers" msgid="3848838293793255097">"Ativar cam. depuração GPU"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"Permitir carreg. cam. depuração GPU p/ dep. aplic."</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"Permitir carreg. cam. depuração GPU p/ dep. app"</string>
<string name="window_animation_scale_title" msgid="6162587588166114700">"Escala de anim. da janela"</string>
<string name="transition_animation_scale_title" msgid="387527540523595875">"Escala de anim. de trans."</string>
<string name="animator_duration_scale_title" msgid="3406722410819934083">"Esc. de duração do anim."</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 5c363a4..16844a2 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Não é possível verificar a existência de redes"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Nenhuma"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Salva"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Desativado"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Falha de configuração de IP"</string>
@@ -227,7 +226,7 @@
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Acionar seleção de codec de áudio\nBluetooth LDAC: qualidade de reprodução"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="3700456559305263922">"DNS particular"</string>
- <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo DNS particular"</string>
+ <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo de DNS particular"</string>
<string name="private_dns_mode_off" msgid="8236575187318721684">"Desativado"</string>
<string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automático"</string>
<string name="private_dns_mode_provider" msgid="8354935160639360804">"Nome do host do provedor de DNS particular"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 703add6..8a7b440 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nu se poate scana pentru rețele"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Niciuna"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Salvată"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Dezactivată"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Eroare de configurație IP"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 4eb3ca4..31274d1 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не удалось начать поиск сетей."</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Нет"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Сохранено"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Отключено"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Ошибка IP-конфигурации"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 1ab5b79..b22e068 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ජාල සඳහා පරිලෝකනය කළ නොහැක"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"කිසිවක් නැත"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"සුරකින ලදි"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"අබලයි"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP වින්යාස කිරීම අසාර්ථකයි"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 5c3920f..43923b8 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Siete sa nedajú vyhľadávať"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Žiadne"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Uložené"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Vypnuté"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Zlyhanie konfigurácie adresy IP"</string>
@@ -438,7 +437,7 @@
<string name="cancel" msgid="6859253417269739139">"Zrušiť"</string>
<string name="okay" msgid="1997666393121016642">"OK"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"Zapnúť"</string>
- <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"Zapnite režim Nerušiť"</string>
+ <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"Zapnite režim bez vyrušení"</string>
<string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"Nikdy"</string>
<string name="zen_interruption_level_priority" msgid="2078370238113347720">"Iba prioritné"</string>
<string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index f479405..6d392fe 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ni mogoče iskati omrežij"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Brez"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Shranjeno"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogočeno"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Konfiguracija IP-ja ni uspela"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 2741985..e05a019 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nuk mund të skanojë për rrjete"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Asnjë"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"U ruajt"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Të çaktivizuara"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Dështim në konfigurimin e IP-së"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 241d9cb..371b909 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -21,13 +21,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Није могуће скенирати мреже"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Нема"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Сачувано"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Онемогућено"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP конфигурација је отказала"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Није повезано због лошег квалитета мреже"</string>
<string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi веза је отказала"</string>
- <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблем са потврдом аутентичности"</string>
+ <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблем са потврдом идентитета"</string>
<string name="wifi_cant_connect" msgid="5410016875644565884">"Повезивање није успело"</string>
<string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Повезивање са „<xliff:g id="AP_NAME">%1$s</xliff:g>“ није успело"</string>
<string name="wifi_check_password_try_again" msgid="516958988102584767">"Проверите лозинку и пробајте поново"</string>
@@ -448,5 +447,5 @@
<string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Трајање"</string>
<string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Увек питај"</string>
<string name="zen_mode_forever" msgid="2704305038191592967">"Док не искључите"</string>
- <string name="time_unit_just_now" msgid="6363336622778342422">"Управо сада"</string>
+ <string name="time_unit_just_now" msgid="6363336622778342422">"Управо"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index d338e96..e6872bb 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Det går inte att söka efter nätverk"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Ingen"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Sparat"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Inaktiverad"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurationsfel"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index d693077..23efb91 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Haiwezi kutambaza mitandao"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Hamna"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Imehifadhiwa"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Imezimwa"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Haikuweza Kusanidi IP"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 8f5c7d8..53ba738 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"நெட்வொர்க்குகளுக்கு ஸ்கேன் செய்யப்படவில்லை"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ஏதுமில்லை"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"சேமிக்கப்பட்டது"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"முடக்கப்பட்டது"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP உள்ளமைவில் தோல்வி"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 5f7ab996..c8c6b4c 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"నెట్వర్క్ల కోసం స్కాన్ చేయడం సాధ్యపడదు"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ఏదీ లేదు"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"సేవ్ చేయబడింది"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"నిలిపివేయబడింది"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP కాన్ఫిగరేషన్ వైఫల్యం"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 020baf0..d293d59 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"ไม่สามารถสแกนหาเครือข่าย"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"ไม่มี"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"บันทึกแล้ว"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"ปิดอยู่"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"การกำหนดค่า IP ล้มเหลว"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 2164ade..9da4561 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Hindi makapag-scan ng mga network"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Wala"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Na-save"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Naka-disable"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Pagkabigo ng Configuration ng IP"</string>
@@ -374,7 +373,7 @@
<string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> batay sa iyong paggamit (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> batay sa iyong paggamit"</string>
<string name="power_discharge_by" msgid="6453537733650125582">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string>
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 532927c..2d5cd7f 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ağlar taranamıyor"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Yok"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Kaydedildi"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Devre dışı"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Yapılandırması Hatası"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index cf26d20..512ea86 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Неможливо здійснити сканування мереж"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Немає"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Збережено"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Вимкнено"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Помилка конфігурації IP-адреси"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index c158179..84ad3ed 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"نیٹ ورکس کیلئے اسکین نہيں کر سکتے ہیں"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"کوئی نہیں"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"محفوظ کردیا گیا"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"غیر فعال"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP کنفیگریشن کی ناکامی"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index ac8bffe..af2ada5 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Tarmoqlarni tekshirib chiqishni iloji bo‘lmadi"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Hech qanday"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Saqlandi"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"O‘chiq"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP manzilini sozlab bo‘lmadi"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 78306da..f454127 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Không thể dò tìm mạng"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Không"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Đã lưu"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Đã tắt"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Lỗi cấu hình IP"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 4fb26100..10a20be 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"无法扫描网络"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"无"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"已保存"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"已停用"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 配置失败"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index c5a8f920..1510545 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"無法掃瞄網絡"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"無"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"已儲存"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"已停用"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 設定失敗"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 0947ccec..90c0d80 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"無法掃描網路"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"無"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"已儲存"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"已停用"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 設定失敗"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index cd90d74..e4f9f4d7 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ayikwazi ukuhlola amanethiwekhi"</string>
- <string name="wifi_security_none" msgid="7985461072596594400">"Lutho"</string>
<string name="wifi_remembered" msgid="4955746899347821096">"Kulondoloziwe"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"Akusebenzi"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Ukwehluleka kokulungiswa kwe-IP"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index c9bcd65..70f9bb6 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -930,6 +930,8 @@
<string name="power_discharge_by">Should last until about <xliff:g id="time">%1$s</xliff:g> (<xliff:g id="level">%2$s</xliff:g>)</string>
<!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
<string name="power_discharge_by_only">Should last until about <xliff:g id="time">%1$s</xliff:g></string>
+ <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
+ <string name="power_discharge_by_only_short">Until <xliff:g id="time" example="12 PM">%1$s</xliff:g></string>
<!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount -->
<string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index 5a57e69..8f9394f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -152,7 +152,8 @@
final MeasurementDetails details = new MeasurementDetails();
if (mVolume == null) return details;
- if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC) {
+ if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC
+ || mVolume.getType() == VolumeInfo.TYPE_STUB) {
details.totalSize = mVolume.getPath().getTotalSpace();
details.availSize = mVolume.getPath().getUsableSpace();
return details;
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
index fa59688..43c97df 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
@@ -81,6 +81,30 @@
return null;
}
+ /**
+ * Method to produce a shortened string describing the remaining battery. Suitable for Quick
+ * Settings and other areas where space is constrained.
+ *
+ * @param context context to fetch descriptions from
+ * @param drainTimeMs The estimated time remaining before the phone dies in milliseconds.
+ *
+ * @return a properly formatted and localized short string describing how much time remains
+ * before the battery runs out.
+ */
+ @Nullable
+ public static String getBatteryRemainingShortStringFormatted(
+ Context context, long drainTimeMs) {
+ if (drainTimeMs <= 0) {
+ return null;
+ }
+
+ if (drainTimeMs <= ONE_DAY_MILLIS) {
+ return getRegularTimeRemainingShortString(context, drainTimeMs);
+ } else {
+ return getMoreThanOneDayShortString(context, drainTimeMs);
+ }
+ }
+
private static String getShutdownImminentString(Context context, String percentageString) {
return TextUtils.isEmpty(percentageString)
? context.getString(R.string.power_remaining_duration_only_shutdown_imminent)
@@ -120,6 +144,14 @@
}
}
+ private static String getMoreThanOneDayShortString(Context context, long drainTimeMs) {
+ final long roundedTimeMs = roundTimeToNearestThreshold(drainTimeMs, ONE_HOUR_MILLIS);
+ CharSequence timeString = StringUtil.formatElapsedTime(context, roundedTimeMs,
+ false /* withSeconds */);
+
+ return context.getString(R.string.power_remaining_duration_only_short, timeString);
+ }
+
private static String getMoreThanTwoDaysString(Context context, String percentageString) {
final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);
final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);
@@ -162,6 +194,22 @@
}
}
+ private static String getRegularTimeRemainingShortString(Context context, long drainTimeMs) {
+ // Get the time of day we think device will die rounded to the nearest 15 min.
+ final long roundedTimeOfDayMs =
+ roundTimeToNearestThreshold(
+ System.currentTimeMillis() + drainTimeMs,
+ FIFTEEN_MINUTES_MILLIS);
+
+ // convert the time to a properly formatted string.
+ String skeleton = android.text.format.DateFormat.getTimeFormatString(context);
+ DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);
+ Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs));
+ CharSequence timeString = fmt.format(date);
+
+ return context.getString(R.string.power_discharge_by_only_short, timeString);
+ }
+
public static long convertUsToMs(long timeUs) {
return timeUs / 1000;
}
diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
index 94189bb..2000104 100644
--- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml
+++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
@@ -42,6 +42,20 @@
android:id="@+id/statusIcons"
android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="1" />
+ android:layout_weight="1"
+ android:paddingEnd="@dimen/signal_cluster_battery_padding" />
+
+ <com.android.systemui.BatteryMeterView
+ android:id="@+id/batteryRemainingIcon"
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:paddingEnd="2dp" />
+
+ <TextView
+ android:id="@+id/batteryRemainingText"
+ android:textAppearance="@style/TextAppearance.QS.TileLabel"
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:gravity="center_vertical" />
</LinearLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index f6fec54..053ea67 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -19,7 +19,10 @@
import static android.app.StatusBarManager.DISABLE_NONE;
import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
import android.animation.ArgbEvaluator;
+import android.annotation.IntDef;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
@@ -55,15 +58,23 @@
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.Utils.DisableStateTracker;
-import com.android.systemui.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
import java.text.NumberFormat;
public class BatteryMeterView extends LinearLayout implements
BatteryStateChangeCallback, Tunable, DarkReceiver, ConfigurationListener {
+
+ @Retention(SOURCE)
+ @IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF})
+ public @interface BatteryPercentMode {}
+ public static final int MODE_DEFAULT = 0;
+ public static final int MODE_ON = 1;
+ public static final int MODE_OFF = 2;
+
private final BatteryMeterDrawableBase mDrawable;
private final String mSlotBattery;
private final ImageView mBatteryIconView;
@@ -74,6 +85,7 @@
private SettingObserver mSettingObserver;
private int mTextColor;
private int mLevel;
+ private int mShowPercentMode = MODE_DEFAULT;
private boolean mForceShowPercent;
private boolean mShowPercentAvailable;
@@ -154,7 +166,19 @@
}
public void setForceShowPercent(boolean show) {
- mForceShowPercent = show;
+ setPercentShowMode(show ? MODE_ON : MODE_DEFAULT);
+ }
+
+ /**
+ * Force a particular mode of showing percent
+ *
+ * 0 - No preference
+ * 1 - Force on
+ * 2 - Force off
+ * @param mode desired mode (none, on, off)
+ */
+ public void setPercentShowMode(@BatteryPercentMode int mode) {
+ mShowPercentMode = mode;
updateShowPercent();
}
@@ -273,7 +297,8 @@
.getIntForUser(getContext().getContentResolver(),
SHOW_BATTERY_PERCENT, 0, mUser);
- if ((mShowPercentAvailable && systemSetting) || mForceShowPercent) {
+ if ((mShowPercentAvailable && systemSetting && mShowPercentMode != MODE_OFF)
+ || mShowPercentMode == MODE_ON) {
if (!showing) {
mBatteryPercentView = loadPercentView();
if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java
index 30dfd36..4a2e06c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java
@@ -22,11 +22,6 @@
public interface DozeReceiver {
/**
- * If device enters or leaves doze mode
- */
- void setDozing(boolean dozing);
-
- /**
* Invoked every time a minute is elapsed in doze mode
*/
void dozeTimeTick();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 7929099..e3f85d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -15,6 +15,7 @@
package com.android.systemui.qs;
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
+import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -28,12 +29,15 @@
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.Color;
import android.graphics.Rect;
import android.media.AudioManager;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.AlarmClock;
+import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.format.DateUtils;
import android.util.AttributeSet;
@@ -68,6 +72,7 @@
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
@@ -132,6 +137,9 @@
private DateView mDateView;
private OngoingPrivacyChip mPrivacyChip;
private Space mSpace;
+ private BatteryMeterView mBatteryRemainingIcon;
+ private TextView mBatteryRemainingText;
+ private boolean mShowBatteryPercentAndEstimate;
private NextAlarmController mAlarmController;
private ZenModeController mZenController;
@@ -148,6 +156,9 @@
};
private boolean mHasTopCutout = false;
+ private final PercentSettingObserver mPercentSettingObserver =
+ new PercentSettingObserver(new Handler(mContext.getMainLooper()));
+
/**
* Runnable for automatically fading out the long press tooltip (as if it were animating away).
*/
@@ -204,8 +215,12 @@
// Set the correct tint for the status icons so they contrast
mIconManager.setTint(fillColor);
+ mShowBatteryPercentAndEstimate = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_battery_percentage_setting_available);
+
mBatteryMeterView = findViewById(R.id.battery);
- mBatteryMeterView.setForceShowPercent(true);
+ mBatteryMeterView.setPercentShowMode(mShowBatteryPercentAndEstimate
+ ? BatteryMeterView.MODE_ON : BatteryMeterView.MODE_OFF);
mBatteryMeterView.setOnClickListener(this);
mClockView = findViewById(R.id.clock);
mClockView.setOnClickListener(this);
@@ -213,6 +228,15 @@
mPrivacyChip = findViewById(R.id.privacy_chip);
mPrivacyChip.setOnClickListener(this);
mSpace = findViewById(R.id.space);
+
+ // Tint for the battery icons are handled in setupHost()
+ mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
+ mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_OFF);
+
+ mBatteryRemainingText = findViewById(R.id.batteryRemainingText);
+ mBatteryRemainingText.setTextColor(fillColor);
+
+ updateShowPercent();
}
private void updateStatusText() {
@@ -371,6 +395,14 @@
.build();
}
+ private void updateBatteryRemainingText() {
+ if (!mShowBatteryPercentAndEstimate) {
+ return;
+ }
+ mBatteryRemainingText.setText(
+ Dependency.get(BatteryController.class).getEstimatedTimeRemainingString());
+ }
+
public void setExpanded(boolean expanded) {
if (mExpanded == expanded) return;
mExpanded = expanded;
@@ -436,6 +468,9 @@
super.onAttachedToWindow();
Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
requestApplyInsets();
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mPercentSettingObserver,
+ ActivityManager.getCurrentUser());
}
@Override
@@ -475,6 +510,7 @@
public void onDetachedFromWindow() {
setListening(false);
Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
+ mContext.getContentResolver().unregisterContentObserver(mPercentSettingObserver);
super.onDetachedFromWindow();
}
@@ -491,6 +527,7 @@
mAlarmController.addCallback(this);
mContext.registerReceiver(mRingerReceiver,
new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
+ updateBatteryRemainingText();
} else {
mZenController.removeCallback(this);
mAlarmController.removeCallback(this);
@@ -660,6 +697,14 @@
// Use SystemUI context to get battery meter colors, and let it use the default tint (white)
mBatteryMeterView.setColorsFromContext(mHost.getContext());
mBatteryMeterView.onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
+
+ Rect tintArea = new Rect(0, 0, 0, 0);
+ int colorForeground = Utils.getColorAttrDefaultColor(getContext(),
+ android.R.attr.colorForeground);
+ float intensity = getColorIntensity(colorForeground);
+ int fillColor = fillColorForIntensity(intensity, getContext());
+ mBatteryRemainingIcon.setColorsFromContext(mHost.getContext());
+ mBatteryRemainingIcon.onDarkChanged(tintArea, intensity, fillColor);
}
public void setCallback(Callback qsPanelCallback) {
@@ -692,4 +737,39 @@
lp.rightMargin = sideMargins;
}
}
+
+ private void updateShowPercent() {
+ final boolean systemSetting = 0 != Settings.System
+ .getIntForUser(getContext().getContentResolver(),
+ SHOW_BATTERY_PERCENT, 0, ActivityManager.getCurrentUser());
+
+ mShowBatteryPercentAndEstimate = systemSetting;
+
+ updateBatteryViews();
+ }
+
+ private void updateBatteryViews() {
+ if (mShowBatteryPercentAndEstimate) {
+ mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ON);
+ mBatteryRemainingIcon.setVisibility(View.VISIBLE);
+ mBatteryRemainingText.setVisibility(View.VISIBLE);
+ updateBatteryRemainingText();
+ } else {
+ mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_OFF);
+ mBatteryRemainingIcon.setVisibility(View.GONE);
+ mBatteryRemainingText.setVisibility(View.GONE);
+ }
+ }
+
+ private final class PercentSettingObserver extends ContentObserver {
+ PercentSettingObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ updateShowPercent();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 7f3537c..da2828e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -20,6 +20,7 @@
import android.graphics.drawable.Drawable;
import android.service.quicksettings.Tile;
import android.widget.Switch;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.graph.BatteryMeterDrawableBase;
import com.android.systemui.Dependency;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
index 12c0fcb..65476fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
@@ -18,11 +18,17 @@
import static java.lang.annotation.RetentionPolicy.SOURCE;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.annotation.IntDef;
-import android.util.ArraySet;
-import android.util.Log;
+import android.util.FloatProperty;
+import android.view.animation.Interpolator;
+
import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.StatusBar;
+
import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Comparator;
@@ -38,14 +44,51 @@
private static final Comparator <RankedListener> mComparator
= (o1, o2) -> Integer.compare(o1.rank, o2.rank);
+ private static final FloatProperty<StatusBarStateController> SET_DARK_AMOUNT_PROPERTY =
+ new FloatProperty<StatusBarStateController>("mDozeAmount") {
+
+ @Override
+ public void setValue(StatusBarStateController object, float value) {
+ object.setDozeAmountInternal(value);
+ }
+
+ @Override
+ public Float get(StatusBarStateController object) {
+ return object.mDozeAmount;
+ }
+ };
private final ArrayList<RankedListener> mListeners = new ArrayList<>();
- private boolean mIsDozing;
private int mState;
private int mLastState;
private boolean mLeaveOpenOnKeyguardHide;
private boolean mKeyguardRequested;
+ /**
+ * If the device is currently dozing or not.
+ */
+ private boolean mIsDozing;
+
+ /**
+ * Current {@link #mDozeAmount} animator.
+ */
+ private ValueAnimator mDarkAnimator;
+
+ /**
+ * Current doze amount in this frame.
+ */
+ private float mDozeAmount;
+
+ /**
+ * Where the animator will stop.
+ */
+ private float mDozeAmountTarget;
+
+ /**
+ * The type of interpolator that should be used to the doze animation.
+ */
+ private Interpolator mDozeInterpolator = Interpolators.FAST_OUT_SLOW_IN;
+
// TODO: b/115739177 (remove this explicit ordering if we can)
@Retention(SOURCE)
@IntDef({RANK_STATUS_BAR, RANK_STATUS_BAR_WINDOW_CONTROLLER, RANK_STACK_SCROLLER, RANK_SHELF})
@@ -94,6 +137,14 @@
return mIsDozing;
}
+ public float getDozeAmount() {
+ return mDozeAmount;
+ }
+
+ public float getInterpolatedDozeAmount() {
+ return mDozeInterpolator.getInterpolation(mDozeAmount);
+ }
+
/**
* Update the dozing state from {@link StatusBar}'s perspective
* @param isDozing well, are we dozing?
@@ -116,6 +167,51 @@
return true;
}
+ /**
+ * Changes the current doze amount.
+ *
+ * @param dozeAmount New doze/dark amount.
+ * @param animated If change should be animated or not. This will cancel current animations.
+ */
+ public void setDozeAmount(float dozeAmount, boolean animated) {
+ if (mDarkAnimator != null && mDarkAnimator.isRunning()) {
+ if (animated && mDozeAmountTarget == dozeAmount) {
+ return;
+ } else {
+ mDarkAnimator.cancel();
+ }
+ }
+
+ mDozeAmountTarget = dozeAmount;
+ if (animated) {
+ startDozeAnimation();
+ } else {
+ setDozeAmountInternal(dozeAmount);
+ }
+ }
+
+ private void startDozeAnimation() {
+ if (mDozeAmount == 0f || mDozeAmount == 1f) {
+ mDozeInterpolator = mIsDozing
+ ? Interpolators.FAST_OUT_SLOW_IN
+ : Interpolators.TOUCH_RESPONSE_REVERSE;
+ }
+ mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget);
+ mDarkAnimator.setInterpolator(Interpolators.LINEAR);
+ mDarkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
+ mDarkAnimator.start();
+ }
+
+ private void setDozeAmountInternal(float dozeAmount) {
+ mDozeAmount = dozeAmount;
+ float interpolatedAmount = mDozeInterpolator.getInterpolation(dozeAmount);
+ synchronized (mListeners) {
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.listener.onDozeAmountChanged(mDozeAmount, interpolatedAmount);
+ }
+ }
+ }
+
public boolean goingToFullShade() {
return mState == StatusBarState.SHADE && mLeaveOpenOnKeyguardHide;
}
@@ -230,5 +326,12 @@
* @param isDozing {@code true} if dozing according to {@link StatusBar}
*/
public default void onDozingChanged(boolean isDozing) {}
+
+ /**
+ * Callback to be notified when the doze amount changes. Useful for animations.
+ * @param linear A number from 0 to 1, where 1 means that the device is dozing.
+ * @param eased Same as {@code linear} but transformed by an interpolator.
+ */
+ default void onDozeAmountChanged(float linear, float eased) {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index fb362c5..ef042ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -26,7 +26,7 @@
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import java.util.function.Consumer;
@@ -63,13 +63,14 @@
}
}
+ // TODO: this should be using StatusBarStateController#getDozeAmount
public void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
boolean dark, long delay, Animator.AnimatorListener listener) {
float startIntensity = dark ? 0f : 1f;
float endIntensity = dark ? 1f : 0f;
ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
animator.addUpdateListener(updateListener);
- animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
+ animator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
animator.setStartDelay(delay);
if (listener != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 9daba83..3cc17b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -4399,16 +4399,6 @@
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public long getDarkAnimationDuration(boolean dark) {
- long duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
- // Longer animation when sleeping with more than 1 notification
- if (dark && getNotGoneChildCount() > 2) {
- duration *= 1.2f;
- }
- return duration;
- }
-
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) {
if (screenLocation == null || screenLocation.y < mTopPadding) {
return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index ecf6b6a..fa71df2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -22,7 +22,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.Fragment;
@@ -41,7 +40,6 @@
import android.os.PowerManager;
import android.os.SystemProperties;
import android.util.AttributeSet;
-import android.util.FloatProperty;
import android.util.Log;
import android.util.MathUtils;
import android.view.LayoutInflater;
@@ -51,7 +49,6 @@
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityManager;
-import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import com.android.internal.logging.MetricsLogger;
@@ -104,7 +101,7 @@
View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,
OnHeadsUpChangedListener, QS.HeightListener, ZenModeController.Callback,
- ConfigurationController.ConfigurationListener {
+ ConfigurationController.ConfigurationListener, StateListener {
private static final boolean DEBUG = false;
@@ -139,25 +136,9 @@
private static final Rect mDummyDirtyRect = new Rect(0, 0, 1, 1);
- public static final long DOZE_ANIMATION_DURATION = 700;
-
private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties()
.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- private static final FloatProperty<NotificationPanelView> SET_DARK_AMOUNT_PROPERTY =
- new FloatProperty<NotificationPanelView>("mInterpolatedDarkAmount") {
- @Override
- public void setValue(NotificationPanelView object, float value) {
- object.setDarkAmount(value, object.mDarkInterpolator.getInterpolation(value));
- }
-
- @Override
- public Float get(NotificationPanelView object) {
- return object.mLinearDarkAmount;
- }
- };
-
- private Interpolator mDarkInterpolator;
private final PowerManager mPowerManager;
private final AccessibilityManager mAccessibilityManager;
@@ -295,11 +276,9 @@
*/
private boolean mSemiAwake;
- private float mDarkAmountTarget;
private boolean mPulsing;
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private boolean mNoVisibleNotifications = true;
- private ValueAnimator mDarkAnimator;
private boolean mUserSetupComplete;
private int mQsNotificationTopPadding;
private float mExpandOffset;
@@ -339,7 +318,6 @@
private final NotificationEntryManager mEntryManager =
Dependency.get(NotificationEntryManager.class);
- private final StateListener mListener = this::setBarState;
private final CommandQueue mCommandQueue;
private final NotificationLockscreenUserManager mLockscreenUserManager =
Dependency.get(NotificationLockscreenUserManager.class);
@@ -388,7 +366,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
FragmentHostManager.get(this).addTagListener(QS.TAG, mFragmentListener);
- Dependency.get(StatusBarStateController.class).addListener(mListener);
+ Dependency.get(StatusBarStateController.class).addListener(this);
Dependency.get(ZenModeController.class).addCallback(this);
Dependency.get(ConfigurationController.class).addCallback(this);
}
@@ -397,7 +375,7 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
FragmentHostManager.get(this).removeTagListener(QS.TAG, mFragmentListener);
- Dependency.get(StatusBarStateController.class).removeListener(mListener);
+ Dependency.get(StatusBarStateController.class).removeListener(this);
Dependency.get(ZenModeController.class).removeCallback(this);
Dependency.get(ConfigurationController.class).removeCallback(this);
}
@@ -475,7 +453,8 @@
mKeyguardBottomArea.initFrom(oldBottomArea);
addView(mKeyguardBottomArea, index);
initBottomArea();
- setDarkAmount(mLinearDarkAmount, mInterpolatedDarkAmount);
+ onDozeAmountChanged(mStatusBarStateController.getDozeAmount(),
+ mStatusBarStateController.getInterpolatedDozeAmount());
if (mKeyguardStatusBar != null) {
mKeyguardStatusBar.onThemeChanged();
@@ -1221,7 +1200,8 @@
}
}
- private void setBarState(int statusBarState) {
+ @Override
+ public void onStateChanged(int statusBarState) {
boolean goingToFullShade = mStatusBarStateController.goingToFullShade();
boolean keyguardFadingAway = mKeyguardMonitor.isKeyguardFadingAway();
int oldState = mBarState;
@@ -2806,24 +2786,10 @@
updateDozingVisibilities(animate);
}
- final float darkAmount = dozing ? 1 : 0;
- if (mDarkAnimator != null && mDarkAnimator.isRunning()) {
- if (animate && mDarkAmountTarget == darkAmount) {
- return;
- } else {
- mDarkAnimator.cancel();
- }
- if (mSemiAwake) {
- setDarkAmount(0, 0);
- }
- }
- mDarkAmountTarget = darkAmount;
- if (!mSemiAwake) {
- if (animate) {
- startDarkAnimation();
- } else {
- setDarkAmount(darkAmount, darkAmount);
- }
+ final float darkAmount = dozing && !mSemiAwake ? 1 : 0;
+ mStatusBarStateController.setDozeAmount(darkAmount, animate);
+ if (animate) {
+ mNotificationStackScroller.notifyDarkAnimationStart(mDozing);
}
}
@@ -2831,21 +2797,8 @@
return mSemiAwake;
}
- private void startDarkAnimation() {
- if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) {
- mDarkInterpolator = mDozing
- ? Interpolators.FAST_OUT_SLOW_IN
- : Interpolators.TOUCH_RESPONSE_REVERSE;
- }
- mNotificationStackScroller.notifyDarkAnimationStart(mDozing);
- mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozing ? 1 : 0);
- mDarkAnimator.setInterpolator(Interpolators.LINEAR);
- mDarkAnimator.setDuration(
- mNotificationStackScroller.getDarkAnimationDuration(mDozing));
- mDarkAnimator.start();
- }
-
- private void setDarkAmount(float linearAmount, float amount) {
+ @Override
+ public void onDozeAmountChanged(float linearAmount, float amount) {
mInterpolatedDarkAmount = amount;
mLinearDarkAmount = linearAmount;
mKeyguardStatusBar.setDarkAmount(mInterpolatedDarkAmount);
@@ -3047,7 +3000,8 @@
mSemiAwake = false;
mNotificationStackScroller.setDark(false /* dark */, true /* animate */,
null /* touchLocation */);
- startDarkAnimation();
+ mStatusBarStateController.setDozeAmount(0f, true /* animated */);
+ mNotificationStackScroller.notifyDarkAnimationStart(mDozing);
mStatusBar.updateScrimController();
return WAKE_UP_TO_SHADE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 6f4026d..f65f826 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -55,4 +55,11 @@
default void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {}
default void onPowerSaveChanged(boolean isPowerSave) {}
}
+
+ /**
+ * If available, get the estimated battery time remaining as a string
+ */
+ default String getEstimatedTimeRemainingString() {
+ return null;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 7221efa..ddcfbf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -29,9 +29,14 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
+import com.android.settingslib.utils.PowerUtil;
+import com.android.systemui.Dependency;
+import com.android.systemui.power.EnhancedEstimates;
+import com.android.systemui.power.Estimate;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.text.NumberFormat;
import java.util.ArrayList;
/**
@@ -44,7 +49,9 @@
public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int UPDATE_GRANULARITY_MSEC = 1000 * 60;
+ private final EnhancedEstimates mEstimates = Dependency.get(EnhancedEstimates.class);
private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
private final PowerManager mPowerManager;
private final Handler mHandler;
@@ -58,6 +65,8 @@
protected boolean mAodPowerSave;
private boolean mTestmode = false;
private boolean mHasReceivedBattery = false;
+ private Estimate mEstimate;
+ private long mLastEstimateTimestamp = -1;
public BatteryControllerImpl(Context context) {
this(context, context.getSystemService(PowerManager.class));
@@ -71,6 +80,7 @@
registerReceiver();
updatePowerSave();
+ updateEstimate();
}
private void registerReceiver() {
@@ -180,6 +190,26 @@
return mAodPowerSave;
}
+ @Override
+ public String getEstimatedTimeRemainingString() {
+ if (mEstimate == null
+ || System.currentTimeMillis() > mLastEstimateTimestamp + UPDATE_GRANULARITY_MSEC) {
+ updateEstimate();
+ }
+ // Estimates may not exist yet even if we've checked
+ if (mEstimate == null) {
+ return null;
+ }
+ final String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0);
+ return PowerUtil.getBatteryRemainingShortStringFormatted(
+ mContext, mEstimate.estimateMillis);
+ }
+
+ private void updateEstimate() {
+ mEstimate = mEstimates.getEstimate();
+ mLastEstimateTimestamp = System.currentTimeMillis();
+ }
+
private void updatePowerSave() {
setPowerSave(mPowerManager.isPowerSaveMode());
}
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index a947ea1..8ae5872 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -6584,6 +6584,18 @@
// OS: Q
TOP_LEVEL_PRIVACY = 1587;
+ // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
+ // Allow apps to override
+ // CATEGORY: SETTINGS
+ // OS: Q
+ NOTIFICATION_ZEN_MODE_OVERRIDING_APPS = 1588;
+
+ // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions >
+ // Allow apps to override > Choose app
+ // CATEGORY: SETTINGS
+ // OS: Q
+ NOTIFICATION_ZEN_MODE_OVERRIDING_APP = 1589;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d1fe970c..7a65a53 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -218,8 +218,8 @@
ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker);
final View content;
try {
- response.getPresentation().setApplyTheme(mThemeId);
- content = response.getPresentation().apply(mContext, decor, interceptionHandler);
+ content = response.getPresentation().applyWithTheme(
+ mContext, decor, interceptionHandler, mThemeId);
container.addView(content);
} catch (RuntimeException e) {
callback.onCanceled();
@@ -259,8 +259,7 @@
RemoteViews.OnClickHandler clickBlocker = null;
if (headerPresentation != null) {
clickBlocker = newClickBlocker();
- headerPresentation.setApplyTheme(mThemeId);
- mHeader = headerPresentation.apply(mContext, null, clickBlocker);
+ mHeader = headerPresentation.applyWithTheme(mContext, null, clickBlocker, mThemeId);
final LinearLayout headerContainer =
decor.findViewById(R.id.autofill_dataset_header);
if (sVerbose) Slog.v(TAG, "adding header");
@@ -277,8 +276,8 @@
if (clickBlocker == null) { // already set for header
clickBlocker = newClickBlocker();
}
- footerPresentation.setApplyTheme(mThemeId);
- mFooter = footerPresentation.apply(mContext, null, clickBlocker);
+ mFooter = footerPresentation.applyWithTheme(
+ mContext, null, clickBlocker, mThemeId);
// Footer not supported on some platform e.g. TV
if (sVerbose) Slog.v(TAG, "adding footer");
footerContainer.addView(mFooter);
@@ -304,8 +303,8 @@
final View view;
try {
if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
- presentation.setApplyTheme(mThemeId);
- view = presentation.apply(mContext, null, interceptionHandler);
+ view = presentation.applyWithTheme(
+ mContext, null, interceptionHandler, mThemeId);
} catch (RuntimeException e) {
Slog.e(TAG, "Error inflating remote views", e);
continue;
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 1e30c8a..843aa74 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -339,8 +339,8 @@
try {
// Create the remote view peer.
- template.setApplyTheme(mThemeId);
- final View customSubtitleView = template.apply(context, null, handler);
+ final View customSubtitleView = template.applyWithTheme(
+ context, null, handler, mThemeId);
// Apply batch updates (if any).
final ArrayList<Pair<InternalValidator, BatchUpdates>> updates =
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 5b3ab85..78e82b6 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1235,6 +1235,9 @@
} else if (vol.type == VolumeInfo.TYPE_PRIVATE) {
mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
+ } else if (vol.type == VolumeInfo.TYPE_STUB) {
+ vol.mountUserId = mCurrentUserId;
+ mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
} else {
Slog.d(TAG, "Skipping automatic mounting of " + vol);
}
@@ -1245,6 +1248,7 @@
case VolumeInfo.TYPE_PRIVATE:
case VolumeInfo.TYPE_PUBLIC:
case VolumeInfo.TYPE_EMULATED:
+ case VolumeInfo.TYPE_STUB:
break;
default:
return false;
@@ -1321,7 +1325,8 @@
}
}
- if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.state == VolumeInfo.STATE_EJECTING) {
+ if ((vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_STUB)
+ && vol.state == VolumeInfo.STATE_EJECTING) {
// TODO: this should eventually be handled by new ObbVolume state changes
/*
* Some OBBs might have been unmounted when this volume was
@@ -1403,7 +1408,8 @@
}
boolean isTypeRestricted = false;
- if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE) {
+ if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE
+ || vol.type == VolumeInfo.TYPE_STUB) {
isTypeRestricted = userManager
.hasUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
Binder.getCallingUserHandle());
@@ -2834,6 +2840,7 @@
final VolumeInfo vol = mVolumes.valueAt(i);
switch (vol.getType()) {
case VolumeInfo.TYPE_PUBLIC:
+ case VolumeInfo.TYPE_STUB:
case VolumeInfo.TYPE_EMULATED:
break;
default:
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 2d3912b..a33ac70 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -17,40 +17,69 @@
package com.android.server.am;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static com.android.server.am.ActivityManagerDebugConfig.*;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Predicate;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE_EXECUTING;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE_EXECUTING;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
+import android.app.AppGlobals;
import android.app.AppOpsManager;
+import android.app.IApplicationThread;
+import android.app.IServiceConnection;
+import android.app.Notification;
import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
import android.app.ServiceStartArgs;
+import android.content.ComponentName;
import android.content.ComponentName.WithComponentName;
+import android.content.Context;
import android.content.IIntentSender;
+import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.net.Uri;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.TransactionTooLargeException;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.EventLog;
+import android.util.PrintWriterPrinter;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.StatsLog;
+import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
+import android.webkit.WebViewZygote;
import com.android.internal.R;
import com.android.internal.app.procstats.ServiceState;
@@ -64,39 +93,20 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.am.ActivityManagerService.ItemMatcher;
-
-import android.app.ActivityManager;
-import android.app.AppGlobals;
-import android.app.IApplicationThread;
-import android.app.IServiceConnection;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.EventLog;
-import android.util.PrintWriterPrinter;
-import android.util.Slog;
-import android.util.StatsLog;
-import android.util.SparseArray;
-import android.util.TimeUtils;
-import android.util.proto.ProtoOutputStream;
-import android.webkit.WebViewZygote;
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityServiceConnectionsHolder;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+
public final class ActiveServices {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActiveServices" : TAG_AM;
private static final String TAG_MU = TAG + POSTFIX_MU;
@@ -1285,6 +1295,7 @@
StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid, r.shortName,
StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER);
+ mAm.updateForegroundServiceUsageStats(r.name, r.userId, true);
}
r.postNotification();
if (r.app != null) {
@@ -1334,6 +1345,7 @@
StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
r.appInfo.uid, r.shortName,
StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT);
+ mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
if (r.app != null) {
mAm.updateLruProcessLocked(r.app, false, null);
updateServiceForegroundLocked(r.app, true);
@@ -2797,6 +2809,7 @@
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName);
StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName,
StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT);
+ mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
}
r.isForeground = false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2e01983..0bae1f3 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2676,8 +2676,10 @@
}
void updateUsageStats(ComponentName activity, int uid, int userId, boolean resumed) {
- if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
- "updateUsageStats: comp=" + activity + "res=" + resumed);
+ if (DEBUG_SWITCH) {
+ Slog.d(TAG_SWITCH,
+ "updateUsageStats: comp=" + activity + "res=" + resumed);
+ }
final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
uid, activity.getPackageName(),
@@ -2704,6 +2706,20 @@
}
}
+ void updateForegroundServiceUsageStats(ComponentName service, int userId, boolean started) {
+ if (DEBUG_SWITCH) {
+ Slog.d(TAG_SWITCH, "updateForegroundServiceUsageStats: comp="
+ + service + "started=" + started);
+ }
+ synchronized (this) {
+ if (mUsageStatsService != null) {
+ mUsageStatsService.reportEvent(service, userId,
+ started ? UsageEvents.Event.FOREGROUND_SERVICE_START
+ : UsageEvents.Event.FOREGROUND_SERVICE_STOP);
+ }
+ }
+ }
+
CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
return mAtmInternal.compatibilityInfoForPackage(ai);
}
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index b7d2ce2..ded075d 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -104,12 +104,18 @@
@Override
public void onStart() {
publishBinderService(Context.ROLE_SERVICE, new Stub());
+ //TODO add watch for new user creation and run default grants for them
}
@Override
public void onStartUser(@UserIdInt int userId) {
synchronized (mLock) {
+ //TODO only call into PermissionController if it or system upgreaded (for boot time)
+ // (add package changes watch;
+ // we can detect upgrade using build fingerprint and app version)
getUserStateLocked(userId);
+ //TODO call permission grant policy here
+ Slog.i(LOG_TAG, "Granting default permissions...");
}
}
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index caa7c28..becc962 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -73,7 +73,7 @@
* Maps role names to its holders' package names. The values should never be null.
*/
@GuardedBy("RoleManagerService.mLock")
- private ArrayMap<String, ArraySet<String>> mRoles = new ArrayMap<>();
+ private ArrayMap<String, ArraySet<String>> mRoles = null;
@GuardedBy("RoleManagerService.mLock")
private boolean mDestroyed;
@@ -188,7 +188,8 @@
roles.put(roleName, roleHolders);
}
mWriteHandler.removeCallbacksAndMessages(null);
- mWriteHandler.sendMessage(PooledLambda.obtainMessage(this::writeSync, version, roles));
+ mWriteHandler.sendMessage(PooledLambda.obtainMessage(
+ RoleUserState::writeSync, this, version, roles));
}
@WorkerThread
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b88165e..a7542d7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -491,6 +491,11 @@
*/
final boolean mIsWatch;
+ /**
+ * Whether this device has the telephony feature.
+ */
+ final boolean mHasTelephonyFeature;
+
private final CertificateMonitor mCertificateMonitor;
private final SecurityLogMonitor mSecurityLogMonitor;
@@ -2133,6 +2138,8 @@
mHasFeature = mInjector.hasFeature();
mIsWatch = mInjector.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_WATCH);
+ mHasTelephonyFeature = mInjector.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
mBackgroundHandler = BackgroundThread.getHandler();
// Needed when mHasFeature == false, because it controls the certificate warning text.
@@ -12927,7 +12934,7 @@
@Override
public int addOverrideApn(@NonNull ComponentName who, @NonNull ApnSetting apnSetting) {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephonyFeature) {
return -1;
}
Preconditions.checkNotNull(who, "ComponentName is null in addOverrideApn");
@@ -12956,7 +12963,7 @@
@Override
public boolean updateOverrideApn(@NonNull ComponentName who, int apnId,
@NonNull ApnSetting apnSetting) {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephonyFeature) {
return false;
}
Preconditions.checkNotNull(who, "ComponentName is null in updateOverrideApn");
@@ -12978,7 +12985,7 @@
@Override
public boolean removeOverrideApn(@NonNull ComponentName who, int apnId) {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephonyFeature) {
return false;
}
Preconditions.checkNotNull(who, "ComponentName is null in removeOverrideApn");
@@ -13004,7 +13011,7 @@
@Override
public List<ApnSetting> getOverrideApns(@NonNull ComponentName who) {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephonyFeature) {
return Collections.emptyList();
}
Preconditions.checkNotNull(who, "ComponentName is null in getOverrideApns");
@@ -13040,7 +13047,7 @@
@Override
public void setOverrideApnsEnabled(@NonNull ComponentName who, boolean enabled) {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephonyFeature) {
return;
}
Preconditions.checkNotNull(who, "ComponentName is null in setOverrideApnEnabled");
@@ -13063,7 +13070,7 @@
@Override
public boolean isOverrideApnEnabled(@NonNull ComponentName who) {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephonyFeature) {
return false;
}
Preconditions.checkNotNull(who, "ComponentName is null in isOverrideApnEnabled");
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 86eb6f3..73990f8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -118,6 +118,7 @@
import com.android.server.power.ShutdownThread;
import com.android.server.power.ThermalManagerService;
import com.android.server.restrictions.RestrictionsManagerService;
+import com.android.server.role.RoleManagerService;
import com.android.server.security.KeyAttestationApplicationIdProviderService;
import com.android.server.security.KeyChainSystemService;
import com.android.server.soundtrigger.SoundTriggerService;
@@ -1911,6 +1912,11 @@
}
traceEnd();
+ // Grants default permissions and defines roles
+ traceBeginAndSlog("StartRoleManagerService");
+ mSystemServiceManager.startService(RoleManagerService.class);
+ traceEnd();
+
// No dependency on Webview preparation in system server. But this should
// be completed before allowing 3rd party
final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";
diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
index 473682d..bf7f53d 100644
--- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -16,13 +16,12 @@
package com.android.server.usage;
-import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.fail;
import static org.testng.Assert.assertEquals;
import android.app.usage.EventList;
-import android.app.usage.UsageEvents;
+import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
@@ -112,6 +111,8 @@
long time = System.currentTimeMillis() - (numberOfEvents*timeProgression);
mIntervalStats = new IntervalStats();
+ mIntervalStats.majorVersion = 7;
+ mIntervalStats.minorVersion = 8;
mIntervalStats.beginTime = time;
mIntervalStats.interactiveTracker.count = 2;
mIntervalStats.interactiveTracker.duration = 111111;
@@ -127,41 +128,39 @@
}
for (int i = 0; i < numberOfEvents; i++) {
- UsageEvents.Event event = new UsageEvents.Event();
+ Event event = new Event();
final int packageInt = ((i / 3) % 7);
event.mPackage = "fake.package.name" + packageInt; //clusters of 3 events from 7 "apps"
if (packageInt == 3) {
// Third app is an instant app
- event.mFlags |= UsageEvents.Event.FLAG_IS_PACKAGE_INSTANT_APP;
- } else if (packageInt == 2 || packageInt == 4) {
- event.mClass = ".fake.class.name" + i % 11;
+ event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP;
}
-
+ event.mClass = ".fake.class.name" + i % 11;
event.mTimeStamp = time;
event.mEventType = i % 19; //"random" event type
switch (event.mEventType) {
- case UsageEvents.Event.CONFIGURATION_CHANGE:
+ case Event.CONFIGURATION_CHANGE:
//empty config,
event.mConfiguration = new Configuration();
break;
- case UsageEvents.Event.SHORTCUT_INVOCATION:
+ case Event.SHORTCUT_INVOCATION:
//"random" shortcut
event.mShortcutId = "shortcut" + (i % 8);
break;
- case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
+ case Event.STANDBY_BUCKET_CHANGED:
//"random" bucket and reason
event.mBucketAndReason = (((i % 5 + 1) * 10) << 16) & (i % 5 + 1) << 8;
break;
- case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+ case Event.NOTIFICATION_INTERRUPTION:
//"random" channel
event.mNotificationChannelId = "channel" + (i % 5);
break;
}
mIntervalStats.events.insert(event);
- mIntervalStats.update(event.mPackage, event.mTimeStamp, event.mEventType);
+ mIntervalStats.update(event.mPackage, event.mClass, event.mTimeStamp, event.mEventType);
time += timeProgression; // Arbitrary progression of time
}
@@ -221,29 +220,30 @@
// mEndTimeStamp is based on the enclosing IntervalStats, don't bother checking
assertEquals(us1.mLastTimeUsed, us2.mLastTimeUsed);
assertEquals(us1.mTotalTimeInForeground, us2.mTotalTimeInForeground);
+ assertEquals(us1.mLastTimeForegroundServiceUsed, us2.mLastTimeForegroundServiceUsed);
+ assertEquals(us1.mTotalTimeForegroundServiceUsed, us2.mTotalTimeForegroundServiceUsed);
// mLaunchCount not persisted, so skipped
assertEquals(us1.mAppLaunchCount, us2.mAppLaunchCount);
- assertEquals(us1.mLastEvent, us2.mLastEvent);
assertEquals(us1.mChooserCounts, us2.mChooserCounts);
}
- void compareUsageEvent(UsageEvents.Event e1, UsageEvents.Event e2, int debugId) {
+ void compareUsageEvent(Event e1, Event e2, int debugId) {
assertEquals(e1.mPackage, e2.mPackage, "Usage event " + debugId);
assertEquals(e1.mClass, e2.mClass, "Usage event " + debugId);
assertEquals(e1.mTimeStamp, e2.mTimeStamp, "Usage event " + debugId);
assertEquals(e1.mEventType, e2.mEventType, "Usage event " + debugId);
switch (e1.mEventType) {
- case UsageEvents.Event.CONFIGURATION_CHANGE:
+ case Event.CONFIGURATION_CHANGE:
assertEquals(e1.mConfiguration, e2.mConfiguration,
"Usage event " + debugId + e2.mConfiguration.toString());
break;
- case UsageEvents.Event.SHORTCUT_INVOCATION:
+ case Event.SHORTCUT_INVOCATION:
assertEquals(e1.mShortcutId, e2.mShortcutId, "Usage event " + debugId);
break;
- case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
+ case Event.STANDBY_BUCKET_CHANGED:
assertEquals(e1.mBucketAndReason, e2.mBucketAndReason, "Usage event " + debugId);
break;
- case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+ case Event.NOTIFICATION_INTERRUPTION:
assertEquals(e1.mNotificationChannelId, e2.mNotificationChannelId,
"Usage event " + debugId);
break;
@@ -252,6 +252,8 @@
}
void compareIntervalStats(IntervalStats stats1, IntervalStats stats2) {
+ assertEquals(stats1.majorVersion, stats2.majorVersion);
+ assertEquals(stats1.minorVersion, stats2.minorVersion);
assertEquals(stats1.beginTime, stats2.beginTime);
assertEquals(stats1.endTime, stats2.endTime);
assertEquals(stats1.interactiveTracker.count, stats2.interactiveTracker.count);
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 4f573a4..152831f 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -27,6 +27,8 @@
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_START;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_FOREGROUND_SERVICE_START;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_NOTIFICATION_SEEN;
@@ -844,6 +846,8 @@
// Inform listeners if necessary
if ((event.mEventType == UsageEvents.Event.MOVE_TO_FOREGROUND
|| event.mEventType == UsageEvents.Event.MOVE_TO_BACKGROUND
+ || event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_START
+ || event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_STOP
|| event.mEventType == UsageEvents.Event.SYSTEM_INTERACTION
|| event.mEventType == UsageEvents.Event.USER_INTERACTION
|| event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN
@@ -896,6 +900,10 @@
switch (eventType) {
case UsageEvents.Event.MOVE_TO_FOREGROUND: return REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
case UsageEvents.Event.MOVE_TO_BACKGROUND: return REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
+ case UsageEvents.Event.FOREGROUND_SERVICE_START:
+ return REASON_SUB_USAGE_FOREGROUND_SERVICE_START;
+ case UsageEvents.Event.FOREGROUND_SERVICE_STOP:
+ return REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP;
case UsageEvents.Event.SYSTEM_INTERACTION: return REASON_SUB_USAGE_SYSTEM_INTERACTION;
case UsageEvents.Event.USER_INTERACTION: return REASON_SUB_USAGE_USER_INTERACTION;
case UsageEvents.Event.NOTIFICATION_SEEN: return REASON_SUB_USAGE_NOTIFICATION_SEEN;
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index db9972f..8405267 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -18,7 +18,6 @@
import android.app.usage.ConfigurationStats;
import android.app.usage.EventList;
import android.app.usage.EventStats;
-import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.content.res.Configuration;
@@ -26,12 +25,16 @@
import android.util.ArraySet;
import android.util.proto.ProtoInputStream;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.io.IOException;
import java.util.List;
-import com.android.internal.annotations.VisibleForTesting;
-
public class IntervalStats {
+ public static final int CURRENT_MAJOR_VERSION = 1;
+ public static final int CURRENT_MINOR_VERSION = 1;
+ public int majorVersion = CURRENT_MAJOR_VERSION;
+ public int minorVersion = CURRENT_MINOR_VERSION;
public long beginTime;
public long endTime;
public long lastTimeSaved;
@@ -219,8 +222,12 @@
switch (eventType) {
case UsageEvents.Event.MOVE_TO_FOREGROUND:
case UsageEvents.Event.MOVE_TO_BACKGROUND:
+ case UsageEvents.Event.FOREGROUND_SERVICE_START:
+ case UsageEvents.Event.FOREGROUND_SERVICE_STOP:
case UsageEvents.Event.END_OF_DAY:
+ case UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE:
case UsageEvents.Event.CONTINUE_PREVIOUS_DAY:
+ case UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE:
return true;
}
return false;
@@ -239,32 +246,9 @@
* @hide
*/
@VisibleForTesting
- public void update(String packageName, long timeStamp, int eventType) {
+ public void update(String packageName, String className, long timeStamp, int eventType) {
UsageStats usageStats = getOrCreateUsageStats(packageName);
-
- // TODO(adamlesinski): Ensure that we recover from incorrect event sequences
- // like double MOVE_TO_BACKGROUND, etc.
- if (eventType == UsageEvents.Event.MOVE_TO_BACKGROUND ||
- eventType == UsageEvents.Event.END_OF_DAY) {
- if (usageStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND ||
- usageStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) {
- usageStats.mTotalTimeInForeground += timeStamp - usageStats.mLastTimeUsed;
- }
- }
-
- if (isStatefulEvent(eventType)) {
- usageStats.mLastEvent = eventType;
- }
-
- if (isUserVisibleEvent(eventType)) {
- usageStats.mLastTimeUsed = timeStamp;
- }
- usageStats.mEndTimeStamp = timeStamp;
-
- if (eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
- usageStats.mLaunchCount += 1;
- }
-
+ usageStats.update(className, timeStamp, eventType);
endTime = timeStamp;
}
@@ -372,4 +356,19 @@
}
return mStringCache.valueAt(index);
}
+
+ /**
+ * When an IntervalStats object is deserialized, if the object's version number
+ * is lower than current version number, optionally perform a upgrade.
+ */
+ void upgradeIfNeeded() {
+ // We only uprade on majorVersion change, no need to upgrade on minorVersion change.
+ if (!(majorVersion < CURRENT_MAJOR_VERSION)) {
+ return;
+ }
+ /*
+ Optional upgrade code here.
+ */
+ majorVersion = CURRENT_MAJOR_VERSION;
+ }
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProto.java b/services/usage/java/com/android/server/usage/UsageStatsProto.java
index 30d303f..8e1c060 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsProto.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsProto.java
@@ -21,13 +21,12 @@
import android.app.usage.UsageStats;
import android.content.res.Configuration;
import android.util.ArrayMap;
-
import android.util.Slog;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.net.ProtocolException;
import java.util.ArrayList;
@@ -105,6 +104,7 @@
stats = tempPackageIndex;
break;
case (int) IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS:
+ // Time attributes stored is an offset of the beginTime.
stats.mLastTimeUsed = statsOut.beginTime + proto.readLong(
IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS);
break;
@@ -113,7 +113,8 @@
IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS);
break;
case (int) IntervalStatsProto.UsageStats.LAST_EVENT:
- stats.mLastEvent = proto.readInt(IntervalStatsProto.UsageStats.LAST_EVENT);
+ stats.mLastEvent =
+ proto.readInt(IntervalStatsProto.UsageStats.LAST_EVENT);
break;
case (int) IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT:
stats.mAppLaunchCount = proto.readInt(
@@ -125,6 +126,15 @@
loadChooserCounts(proto, stats);
proto.end(chooserToken);
break;
+ case (int) IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS:
+ // Time attributes stored is an offset of the beginTime.
+ stats.mLastTimeForegroundServiceUsed = statsOut.beginTime + proto.readLong(
+ IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS);
+ break;
+ case (int) IntervalStatsProto.UsageStats.TOTAL_TIME_SERVICE_USED_MS:
+ stats.mTotalTimeForegroundServiceUsed = proto.readLong(
+ IntervalStatsProto.UsageStats.TOTAL_TIME_SERVICE_USED_MS);
+ break;
}
}
if (stats.mLastTimeUsed == 0) {
@@ -315,11 +325,18 @@
+ ") not found in IntervalStats string cache");
proto.write(IntervalStatsProto.UsageStats.PACKAGE, usageStats.mPackageName);
}
+ // Time attributes stored as an offset of the beginTime.
proto.write(IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS,
usageStats.mLastTimeUsed - stats.beginTime);
proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS,
usageStats.mTotalTimeInForeground);
- proto.write(IntervalStatsProto.UsageStats.LAST_EVENT, usageStats.mLastEvent);
+ proto.write(IntervalStatsProto.UsageStats.LAST_EVENT,
+ usageStats.mLastEvent);
+ // Time attributes stored as an offset of the beginTime.
+ proto.write(IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS,
+ usageStats.mLastTimeForegroundServiceUsed - stats.beginTime);
+ proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_SERVICE_USED_MS,
+ usageStats.mTotalTimeForegroundServiceUsed);
proto.write(IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT, usageStats.mAppLaunchCount);
writeChooserCounts(proto, usageStats);
proto.end(token);
@@ -471,6 +488,14 @@
statsOut.endTime = statsOut.beginTime + proto.readLong(
IntervalStatsProto.END_TIME_MS);
break;
+ case (int) IntervalStatsProto.MAJOR_VERSION:
+ statsOut.majorVersion = proto.readInt(
+ IntervalStatsProto.MAJOR_VERSION);
+ break;
+ case (int) IntervalStatsProto.MINOR_VERSION:
+ statsOut.minorVersion = proto.readInt(
+ IntervalStatsProto.MINOR_VERSION);
+ break;
case (int) IntervalStatsProto.INTERACTIVE:
loadCountAndTime(proto, IntervalStatsProto.INTERACTIVE,
statsOut.interactiveTracker);
@@ -505,6 +530,7 @@
// endTime not assigned, assume default value of 0 plus beginTime
statsOut.endTime = statsOut.beginTime;
}
+ statsOut.upgradeIfNeeded();
return;
}
}
@@ -519,6 +545,8 @@
public static void write(OutputStream out, IntervalStats stats) throws IOException {
final ProtoOutputStream proto = new ProtoOutputStream(out);
proto.write(IntervalStatsProto.END_TIME_MS, stats.endTime - stats.beginTime);
+ proto.write(IntervalStatsProto.MAJOR_VERSION, stats.majorVersion);
+ proto.write(IntervalStatsProto.MINOR_VERSION, stats.minorVersion);
// String pool should be written before the rest of the usage stats
writeStringPool(proto, stats);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index a68f9d3..d940620 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -15,19 +15,18 @@
*/
package com.android.server.usage;
+import android.app.usage.ConfigurationStats;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStats;
+import android.content.res.Configuration;
+import android.util.ArrayMap;
+
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
-import android.app.usage.ConfigurationStats;
-import android.app.usage.EventList;
-import android.app.usage.UsageEvents;
-import android.app.usage.UsageStats;
-import android.content.res.Configuration;
-import android.util.ArrayMap;
-
import java.io.IOException;
import java.net.ProtocolException;
@@ -61,6 +60,7 @@
private static final String FLAGS_ATTR = "flags";
private static final String CLASS_ATTR = "class";
private static final String TOTAL_TIME_ACTIVE_ATTR = "timeActive";
+ private static final String TOTAL_TIME_SERVICE_USED_ATTR = "timeServiceUsed";
private static final String COUNT_ATTR = "count";
private static final String ACTIVE_ATTR = "active";
private static final String LAST_EVENT_ATTR = "lastEvent";
@@ -69,9 +69,12 @@
private static final String STANDBY_BUCKET_ATTR = "standbyBucket";
private static final String APP_LAUNCH_COUNT_ATTR = "appLaunchCount";
private static final String NOTIFICATION_CHANNEL_ATTR = "notificationChannel";
+ private static final String MAJOR_VERSION_ATTR = "majorVersion";
+ private static final String MINOR_VERSION_ATTR = "minorVersion";
// Time attributes stored as an offset of the beginTime.
private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive";
+ private static final String LAST_TIME_SERVICE_USED_ATTR = "lastTimeServiceUsed";
private static final String END_TIME_ATTR = "endTime";
private static final String TIME_ATTR = "time";
@@ -86,9 +89,14 @@
// Apply the offset to the beginTime to find the absolute time.
stats.mLastTimeUsed = statsOut.beginTime + XmlUtils.readLongAttribute(
parser, LAST_TIME_ACTIVE_ATTR);
+ stats.mLastTimeForegroundServiceUsed = statsOut.beginTime + XmlUtils.readLongAttribute(
+ parser, LAST_TIME_SERVICE_USED_ATTR);
stats.mTotalTimeInForeground = XmlUtils.readLongAttribute(parser, TOTAL_TIME_ACTIVE_ATTR);
+ stats.mTotalTimeForegroundServiceUsed = XmlUtils.readLongAttribute(parser,
+ TOTAL_TIME_SERVICE_USED_ATTR);
stats.mLastEvent = XmlUtils.readIntAttribute(parser, LAST_EVENT_ATTR);
- stats.mAppLaunchCount = XmlUtils.readIntAttribute(parser, APP_LAUNCH_COUNT_ATTR, 0);
+ stats.mAppLaunchCount = XmlUtils.readIntAttribute(parser, APP_LAUNCH_COUNT_ATTR,
+ 0);
int eventCode;
while ((eventCode = parser.next()) != XmlPullParser.END_DOCUMENT) {
final String tag = parser.getName();
@@ -206,9 +214,12 @@
// Write the time offset.
XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR,
usageStats.mLastTimeUsed - stats.beginTime);
-
+ XmlUtils.writeLongAttribute(xml, LAST_TIME_SERVICE_USED_ATTR,
+ usageStats.mLastTimeForegroundServiceUsed - stats.beginTime);
XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, usageStats.mPackageName);
XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, usageStats.mTotalTimeInForeground);
+ XmlUtils.writeLongAttribute(xml, TOTAL_TIME_SERVICE_USED_ATTR,
+ usageStats.mTotalTimeForegroundServiceUsed);
XmlUtils.writeIntAttribute(xml, LAST_EVENT_ATTR, usageStats.mLastEvent);
if (usageStats.mAppLaunchCount > 0) {
XmlUtils.writeIntAttribute(xml, APP_LAUNCH_COUNT_ATTR, usageStats.mAppLaunchCount);
@@ -339,6 +350,8 @@
}
statsOut.endTime = statsOut.beginTime + XmlUtils.readLongAttribute(parser, END_TIME_ATTR);
+ statsOut.majorVersion = XmlUtils.readIntAttribute(parser, MAJOR_VERSION_ATTR);
+ statsOut.minorVersion = XmlUtils.readIntAttribute(parser, MINOR_VERSION_ATTR);
int eventCode;
int outerDepth = parser.getDepth();
@@ -391,6 +404,8 @@
*/
public static void write(XmlSerializer xml, IntervalStats stats) throws IOException {
XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime);
+ XmlUtils.writeIntAttribute(xml, MAJOR_VERSION_ATTR, stats.majorVersion);
+ XmlUtils.writeIntAttribute(xml, MINOR_VERSION_ATTR, stats.minorVersion);
writeCountAndTime(xml, INTERACTIVE_TAG, stats.interactiveTracker.count,
stats.interactiveTracker.duration);
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 1a8aba0..32875da 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -22,9 +22,9 @@
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
+import android.content.Context;
import android.content.res.Configuration;
import android.os.SystemClock;
-import android.content.Context;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -129,11 +129,17 @@
for (IntervalStats stat : mCurrentStats) {
final int pkgCount = stat.packageStats.size();
for (int i = 0; i < pkgCount; i++) {
- UsageStats pkgStats = stat.packageStats.valueAt(i);
- if (pkgStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND ||
- pkgStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) {
- stat.update(pkgStats.mPackageName, stat.lastTimeSaved,
- UsageEvents.Event.END_OF_DAY);
+ final UsageStats pkgStats = stat.packageStats.valueAt(i);
+ if (!pkgStats.mLastForegroundActivityEventMap.isEmpty()
+ || !pkgStats.mLastForegroundServiceEventMap.isEmpty()) {
+ if (!pkgStats.mLastForegroundActivityEventMap.isEmpty()) {
+ stat.update(pkgStats.mPackageName, null, stat.lastTimeSaved,
+ UsageEvents.Event.END_OF_DAY);
+ }
+ if (!pkgStats.mLastForegroundServiceEventMap.isEmpty()) {
+ stat.update(pkgStats.mPackageName, null , stat.lastTimeSaved,
+ UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE);
+ }
notifyStatsChanged();
}
}
@@ -218,7 +224,8 @@
stats.updateKeyguardHidden(event.mTimeStamp);
} break;
default: {
- stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
+ stats.update(event.mPackage, event.getClassName(),
+ event.mTimeStamp, event.mEventType);
if (incrementAppLaunch) {
stats.incrementAppLaunchCount(event.mPackage);
}
@@ -481,25 +488,43 @@
final long startTime = SystemClock.elapsedRealtime();
Slog.i(TAG, mLogPrefix + "Rolling over usage stats");
- // Finish any ongoing events with an END_OF_DAY event. Make a note of which components
- // need a new CONTINUE_PREVIOUS_DAY entry.
+ // Finish any ongoing events with an END_OF_DAY or ROLLOVER_FOREGROUND_SERVICE event.
+ // Make a note of which components need a new CONTINUE_PREVIOUS_DAY or
+ // CONTINUING_FOREGROUND_SERVICE entry.
final Configuration previousConfig =
mCurrentStats[UsageStatsManager.INTERVAL_DAILY].activeConfiguration;
ArraySet<String> continuePreviousDay = new ArraySet<>();
+ ArrayMap<String, ArrayMap<String, Integer>> continuePreviousDayForegroundActivity =
+ new ArrayMap<>();
+ ArrayMap<String, ArrayMap<String, Integer>> continuePreviousDayForegroundService =
+ new ArrayMap<>();
for (IntervalStats stat : mCurrentStats) {
final int pkgCount = stat.packageStats.size();
for (int i = 0; i < pkgCount; i++) {
- UsageStats pkgStats = stat.packageStats.valueAt(i);
- if (pkgStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND ||
- pkgStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) {
+ final UsageStats pkgStats = stat.packageStats.valueAt(i);
+ if (!pkgStats.mLastForegroundActivityEventMap.isEmpty()
+ || !pkgStats.mLastForegroundServiceEventMap.isEmpty()) {
+ if (!pkgStats.mLastForegroundActivityEventMap.isEmpty()) {
+ continuePreviousDayForegroundActivity.put(pkgStats.mPackageName,
+ pkgStats.mLastForegroundActivityEventMap);
+ stat.update(pkgStats.mPackageName, null,
+ mDailyExpiryDate.getTimeInMillis() - 1,
+ UsageEvents.Event.END_OF_DAY);
+ }
+ if (!pkgStats.mLastForegroundServiceEventMap.isEmpty()) {
+ continuePreviousDayForegroundService.put(pkgStats.mPackageName,
+ pkgStats.mLastForegroundServiceEventMap);
+ stat.update(pkgStats.mPackageName, null,
+ mDailyExpiryDate.getTimeInMillis() - 1,
+ UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE);
+ }
continuePreviousDay.add(pkgStats.mPackageName);
- stat.update(pkgStats.mPackageName, mDailyExpiryDate.getTimeInMillis() - 1,
- UsageEvents.Event.END_OF_DAY);
notifyStatsChanged();
}
}
- stat.updateConfigurationStats(null, mDailyExpiryDate.getTimeInMillis() - 1);
+ stat.updateConfigurationStats(null,
+ mDailyExpiryDate.getTimeInMillis() - 1);
stat.commitTime(mDailyExpiryDate.getTimeInMillis() - 1);
}
@@ -509,10 +534,27 @@
final int continueCount = continuePreviousDay.size();
for (int i = 0; i < continueCount; i++) {
- String name = continuePreviousDay.valueAt(i);
+ String pkgName = continuePreviousDay.valueAt(i);
final long beginTime = mCurrentStats[UsageStatsManager.INTERVAL_DAILY].beginTime;
for (IntervalStats stat : mCurrentStats) {
- stat.update(name, beginTime, UsageEvents.Event.CONTINUE_PREVIOUS_DAY);
+ if (continuePreviousDayForegroundActivity.containsKey(pkgName)) {
+ final ArrayMap<String, Integer> foregroundActivityEventMap =
+ continuePreviousDayForegroundActivity.get(pkgName);
+ final int size = foregroundActivityEventMap.size();
+ for (int j = 0; j < size; j++) {
+ stat.update(pkgName, foregroundActivityEventMap.keyAt(j), beginTime,
+ UsageEvents.Event.CONTINUE_PREVIOUS_DAY);
+ }
+ }
+ if (continuePreviousDayForegroundService.containsKey(pkgName)) {
+ final ArrayMap<String, Integer> foregroundServiceEventMap =
+ continuePreviousDayForegroundService.get(pkgName);
+ final int size = foregroundServiceEventMap.size();
+ for (int j = 0; j < size; j++) {
+ stat.update(pkgName, foregroundServiceEventMap.keyAt(j), beginTime,
+ UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE);
+ }
+ }
stat.updateConfigurationStats(previousConfig, beginTime);
notifyStatsChanged();
}
@@ -837,10 +879,18 @@
return "MOVE_TO_BACKGROUND";
case UsageEvents.Event.MOVE_TO_FOREGROUND:
return "MOVE_TO_FOREGROUND";
+ case UsageEvents.Event.FOREGROUND_SERVICE_START:
+ return "FOREGROUND_SERVICE_START";
+ case UsageEvents.Event.FOREGROUND_SERVICE_STOP:
+ return "FOREGROUND_SERVICE_STOP";
case UsageEvents.Event.END_OF_DAY:
return "END_OF_DAY";
+ case UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE:
+ return "ROLLOVER_FOREGROUND_SERVICE";
case UsageEvents.Event.CONTINUE_PREVIOUS_DAY:
return "CONTINUE_PREVIOUS_DAY";
+ case UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE:
+ return "CONTINUING_FOREGROUND_SERVICE";
case UsageEvents.Event.CONFIGURATION_CHANGE:
return "CONFIGURATION_CHANGE";
case UsageEvents.Event.SYSTEM_INTERACTION:
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index b6ac91d..cef99865 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -21,6 +21,7 @@
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
@@ -322,8 +323,11 @@
/**
* Call can be upgraded to a video call.
* @hide
+ * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
+ * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call
+ * whether or not video calling is supported.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590)
public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
/**
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 34603a3..0589cd4 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -272,6 +272,9 @@
/**
* Call can be upgraded to a video call.
+ * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and
+ * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call whether or not
+ * video calling is supported.
*/
public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000;
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 9a4ea9e7..2ffad03 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -985,10 +985,10 @@
/**
* Generates a string representation of a capabilities bitmask.
*
- * @param capabilities The capabilities bitmask.
* @return String representation of the capabilities bitmask.
+ * @hide
*/
- private String capabilitiesToString() {
+ public String capabilitiesToString() {
StringBuilder sb = new StringBuilder();
if (hasCapabilities(CAPABILITY_SELF_MANAGED)) {
sb.append("SelfManaged ");
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index fa16bfe..9f0bdd7 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -15,6 +15,7 @@
package android.telecom;
import android.Manifest;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SuppressAutoDoc;
@@ -36,6 +37,8 @@
import com.android.internal.telecom.ITelecomService;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -413,8 +416,10 @@
* <p>
* The phone number of the call used by Telecom to determine which call should be handed over.
* @hide
+ * @deprecated Use the public handover APIs. See
+ * {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} for more information.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590)
public static final String EXTRA_IS_HANDOVER = "android.telecom.extra.IS_HANDOVER";
/**
@@ -528,11 +533,19 @@
public static final char DTMF_CHARACTER_WAIT = ';';
/**
+ * @hide
+ */
+ @IntDef(prefix = { "TTY_MODE_" },
+ value = {TTY_MODE_OFF, TTY_MODE_FULL, TTY_MODE_HCO, TTY_MODE_VCO})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TtyMode {}
+
+ /**
* TTY (teletypewriter) mode is off.
*
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public static final int TTY_MODE_OFF = 0;
/**
@@ -541,6 +554,7 @@
*
* @hide
*/
+ @SystemApi
public static final int TTY_MODE_FULL = 1;
/**
@@ -550,6 +564,7 @@
*
* @hide
*/
+ @SystemApi
public static final int TTY_MODE_HCO = 2;
/**
@@ -559,6 +574,7 @@
*
* @hide
*/
+ @SystemApi
public static final int TTY_MODE_VCO = 3;
/**
@@ -827,8 +843,9 @@
* @return The phone account handle of the current sim call manager.
*
* @hide
+ * @deprecated Use {@link #getSimCallManager()}.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590)
public PhoneAccountHandle getSimCallManager(int userId) {
try {
if (isServiceConnected()) {
@@ -929,10 +946,12 @@
* Returns a list of {@link PhoneAccountHandle}s including those which have not been enabled
* by the user.
*
+ * @param includeDisabledAccounts When {@code true}, disabled phone accounts will be included,
+ * when {@code false}, only
* @return A list of {@code PhoneAccountHandle} objects.
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590)
public List<PhoneAccountHandle> getCallCapablePhoneAccounts(boolean includeDisabledAccounts) {
try {
if (isServiceConnected()) {
@@ -1155,7 +1174,7 @@
/**
* Used to set the default dialer package.
*
- * @param packageName to set the default dialer to..
+ * @param packageName to set the default dialer to.
*
* @result {@code true} if the default dialer was successfully changed, {@code false} if
* the specified package does not correspond to an installed dialer, or is already
@@ -1166,7 +1185,10 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.MODIFY_PHONE_STATE,
+ android.Manifest.permission.WRITE_SECURE_SETTINGS})
public boolean setDefaultDialer(String packageName) {
try {
if (isServiceConnected()) {
@@ -1179,12 +1201,10 @@
}
/**
- * Used to determine the dialer package that is preloaded on the system partition.
+ * Determines the package name of the system-provided default phone app.
*
* @return package name for the system dialer package or null if no system dialer is preloaded.
- * @hide
*/
- @UnsupportedAppUsage
public String getSystemDialerPackage() {
try {
if (isServiceConnected()) {
@@ -1545,8 +1565,9 @@
* - {@link TelecomManager#TTY_MODE_VCO}
* @hide
*/
- @UnsupportedAppUsage
- public int getCurrentTtyMode() {
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public @TtyMode int getCurrentTtyMode() {
try {
if (isServiceConnected()) {
return getTelecomService().getCurrentTtyMode(mContext.getOpPackageName());
diff --git a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java
index 8467bee..be74a6d 100644
--- a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java
+++ b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java
@@ -18,10 +18,6 @@
import static junit.framework.Assert.assertEquals;
-import com.android.server.usage.UsageStatsDatabase;
-import com.android.server.usage.UsageStatsDatabase.StatCombiner;
-import com.android.server.usage.IntervalStats;
-
import android.app.usage.EventList;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
@@ -29,10 +25,14 @@
import android.os.SystemClock;
import android.perftests.utils.ManualBenchmarkState;
import android.perftests.utils.PerfManualStatusReporter;
-import android.support.test.filters.LargeTest;
import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4;
+import com.android.server.usage.IntervalStats;
+import com.android.server.usage.UsageStatsDatabase;
+import com.android.server.usage.UsageStatsDatabase.StatCombiner;
+
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
@@ -90,11 +90,13 @@
for (int pkg = 0; pkg < packageCount; pkg++) {
UsageEvents.Event event = new UsageEvents.Event();
event.mPackage = "fake.package.name" + pkg;
+ event.mClass = event.mPackage + ".class1";
event.mTimeStamp = 1;
event.mEventType = UsageEvents.Event.MOVE_TO_FOREGROUND;
for (int evt = 0; evt < eventsPerPackage; evt++) {
intervalStats.events.insert(event);
- intervalStats.update(event.mPackage, event.mTimeStamp, event.mEventType);
+ intervalStats.update(event.mPackage, event.mClass, event.mTimeStamp,
+ event.mEventType);
}
}
}