Merge "Implement back to launcher animation from shell and WM animation controllers." into tm-dev
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 90ec700..528be3c 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -4891,13 +4891,15 @@
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
filter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
- getContext().registerReceiver(this, filter);
+ getContext().registerReceiverForAllUsers(this, filter,
+ /* broadcastPermission */ null, /* scheduler */ null);
// Register for events related to sdcard installation.
IntentFilter sdFilter = new IntentFilter();
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
sdFilter.addAction(Intent.ACTION_USER_STOPPED);
sdFilter.addAction(Intent.ACTION_UID_REMOVED);
- getContext().registerReceiver(this, sdFilter);
+ getContext().registerReceiverForAllUsers(this, sdFilter,
+ /* broadcastPermission */ null, /* scheduler */ null);
}
@Override
@@ -4915,9 +4917,6 @@
}
}
return;
- case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
- pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
- break;
case Intent.ACTION_USER_STOPPED:
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (userHandle >= 0) {
@@ -4932,6 +4931,18 @@
mRemovalHistory.delete(uid);
mLastOpScheduleExactAlarm.delete(uid);
return;
+ case Intent.ACTION_PACKAGE_ADDED:
+ if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ final String packageUpdated = intent.getData().getSchemeSpecificPart();
+ mHandler.obtainMessage(
+ AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1,
+ packageUpdated).sendToTarget();
+ }
+ mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
+ return;
+ case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
+ pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ break;
case Intent.ACTION_PACKAGE_REMOVED:
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
// This package is being updated; don't kill its alarms.
@@ -4950,15 +4961,6 @@
}
}
break;
- case Intent.ACTION_PACKAGE_ADDED:
- if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
- final String packageUpdated = intent.getData().getSchemeSpecificPart();
- mHandler.obtainMessage(
- AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1,
- packageUpdated).sendToTarget();
- }
- mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
- return;
}
if (pkgList != null && (pkgList.length > 0)) {
for (String pkg : pkgList) {
diff --git a/core/api/current.txt b/core/api/current.txt
index 3d5ab21..45f7cf2 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -3901,7 +3901,7 @@
method public Object getAnimatedValue(String);
method public long getCurrentPlayTime();
method public long getDuration();
- method @FloatRange(from=0, to=1) public static float getDurationScale();
+ method @FloatRange(from=0) public static float getDurationScale();
method public static long getFrameDelay();
method public int getRepeatCount();
method public int getRepeatMode();
@@ -3941,7 +3941,7 @@
}
public static interface ValueAnimator.DurationScaleChangeListener {
- method public void onChanged(float);
+ method public void onChanged(@FloatRange(from=0) float);
}
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 09d1114..2e73ef3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9791,6 +9791,7 @@
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isManagedProfile(int);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isMediaSharedWithParent();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isPrimaryUser();
+ method public static boolean isRemoveResultSuccessful(int);
method public boolean isRestrictedProfile();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional=true) public boolean isRestrictedProfile(@NonNull android.os.UserHandle);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isSameProfileGroup(@NonNull android.os.UserHandle, @NonNull android.os.UserHandle);
@@ -9808,7 +9809,10 @@
field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background";
field public static final int REMOVE_RESULT_ALREADY_BEING_REMOVED = 2; // 0x2
field public static final int REMOVE_RESULT_DEFERRED = 1; // 0x1
- field public static final int REMOVE_RESULT_ERROR = 3; // 0x3
+ field public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4; // 0xfffffffc
+ field public static final int REMOVE_RESULT_ERROR_UNKNOWN = -1; // 0xffffffff
+ field public static final int REMOVE_RESULT_ERROR_USER_NOT_FOUND = -3; // 0xfffffffd
+ field public static final int REMOVE_RESULT_ERROR_USER_RESTRICTION = -2; // 0xfffffffe
field public static final int REMOVE_RESULT_REMOVED = 0; // 0x0
field public static final int RESTRICTION_NOT_SET = 0; // 0x0
field public static final int RESTRICTION_SOURCE_DEVICE_OWNER = 2; // 0x2
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 66f893d..db95a1f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -96,7 +96,7 @@
package android.animation {
public class ValueAnimator extends android.animation.Animator {
- method @MainThread public static void setDurationScale(@FloatRange(from=0, to=1) float);
+ method @MainThread public static void setDurationScale(@FloatRange(from=0) float);
}
}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index bca6b6a..6ab7ae6 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -316,7 +316,7 @@
@UnsupportedAppUsage
@TestApi
@MainThread
- public static void setDurationScale(@FloatRange(from = 0, to = 1) float durationScale) {
+ public static void setDurationScale(@FloatRange(from = 0) float durationScale) {
sDurationScale = durationScale;
List<WeakReference<DurationScaleChangeListener>> listenerCopy;
@@ -340,7 +340,7 @@
*
* @return the duration scale.
*/
- @FloatRange(from = 0, to = 1)
+ @FloatRange(from = 0)
public static float getDurationScale() {
return sDurationScale;
}
@@ -1798,8 +1798,8 @@
public interface DurationScaleChangeListener {
/**
* Called when the duration scale changes.
- * @param scale the duration scalel
+ * @param scale the duration scale
*/
- void onChanged(float scale);
+ void onChanged(@FloatRange(from = 0) float scale);
}
}
diff --git a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
index 2dd3aaa1..5c9989e 100644
--- a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
+++ b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
@@ -27,6 +27,7 @@
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import android.annotation.NonNull;
+import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.net.NetworkIdentity;
import android.net.NetworkStatsCollection;
@@ -47,6 +48,8 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -76,6 +79,15 @@
*/
public static final String PREFIX_UID_TAG = "uid_tag";
+ /** @hide */
+ @StringDef(prefix = {"PREFIX_"}, value = {
+ PREFIX_XT,
+ PREFIX_UID,
+ PREFIX_UID_TAG,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Prefix {}
+
private static final HashMap<String, String> sPrefixLegacyFileNameMap =
new HashMap<String, String>() {{
put(PREFIX_XT, "netstats_xt.bin");
@@ -141,13 +153,13 @@
// Get /data/system/netstats_*.bin legacy files. Does not check for existence.
@NonNull
- private static File getLegacyBinFileForPrefix(@NonNull String prefix) {
+ private static File getLegacyBinFileForPrefix(@NonNull @Prefix String prefix) {
return new File(getPlatformSystemDir(), sPrefixLegacyFileNameMap.get(prefix));
}
// List /data/system/netstats/[xt|uid|uid_tag].<start>-<end> legacy files.
@NonNull
- private static ArrayList<File> getPlatformFileListForPrefix(@NonNull String prefix) {
+ private static ArrayList<File> getPlatformFileListForPrefix(@NonNull @Prefix String prefix) {
final ArrayList<File> list = new ArrayList<>();
final File platformFiles = new File(getPlatformBaseDir(), "netstats");
if (platformFiles.exists()) {
@@ -207,7 +219,7 @@
*/
@NonNull
public static NetworkStatsCollection readPlatformCollection(
- @NonNull String prefix, long bucketDuration) throws IOException {
+ @NonNull @Prefix String prefix, long bucketDuration) throws IOException {
final NetworkStatsCollection.Builder builder =
new NetworkStatsCollection.Builder(bucketDuration);
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 8263149..68d1a0b 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2702,6 +2702,46 @@
@ServiceState.FrequencyRange int frequencyRange, int signalStrength,
long elapsedRealtimeMs);
+ /**
+ * Returns the time in microseconds that the mobile radio has been actively transmitting data on
+ * a given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given
+ * transmission power level.
+ *
+ * @param rat Radio Access Technology {@see RadioAccessTechnology}
+ * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for
+ * RADIO_ACCESS_TECHNOLOGY_NR. Use
+ * {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access
+ * Technologies.
+ * @param signalStrength the cellular signal strength. {@see CellSignalStrength#getLevel()}
+ * @param elapsedRealtimeMs current elapsed realtime
+ * @return time (in milliseconds) the mobile radio spent actively transmitting data in the
+ * specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if
+ * data unavailable.
+ * @hide
+ */
+ public abstract long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat,
+ @ServiceState.FrequencyRange int frequencyRange, int signalStrength,
+ long elapsedRealtimeMs);
+
+ /**
+ * Returns the time in microseconds that the mobile radio has been actively receiving data on a
+ * given Radio Access Technology (RAT), at a given frequency (NR RAT only), for a given
+ * transmission power level.
+ *
+ * @param rat Radio Access Technology {@see RadioAccessTechnology}
+ * @param frequencyRange frequency range {@see ServiceState.FrequencyRange}, only needed for
+ * RADIO_ACCESS_TECHNOLOGY_NR. Use
+ * {@link ServiceState.FREQUENCY_RANGE_UNKNOWN} for other Radio Access
+ * Technologies.
+ * @param elapsedRealtimeMs current elapsed realtime
+ * @return time (in milliseconds) the mobile radio spent actively receiving data in the
+ * specified state, while on battery. Returns {@link DURATION_UNAVAILABLE} if
+ * data unavailable.
+ * @hide
+ */
+ public abstract long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat,
+ @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs);
+
static final String[] WIFI_SUPPL_STATE_NAMES = {
"invalid", "disconn", "disabled", "inactive", "scanning",
"authenticating", "associating", "associated", "4-way-handshake",
@@ -2722,6 +2762,13 @@
public static final long POWER_DATA_UNAVAILABLE = -1L;
/**
+ * Returned value if duration data is unavailable.
+ *
+ * {@hide}
+ */
+ public static final long DURATION_UNAVAILABLE = -1L;
+
+ /**
* Returns the battery consumption (in microcoulombs) of bluetooth, derived from on
* device power measurement data.
* Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
@@ -4095,6 +4142,10 @@
" Mmwave frequency (greater than 6GHz):\n"};
final String signalStrengthHeader =
" Signal Strength Time:\n";
+ final String txHeader =
+ " Tx Time:\n";
+ final String rxHeader =
+ " Rx Time: ";
final String[] signalStrengthDescription = new String[]{
" unknown: ",
" poor: ",
@@ -4146,6 +4197,29 @@
sb.append(")\n");
}
+ sb.append(prefix);
+ sb.append(txHeader);
+ for (int strength = 0; strength < numSignalStrength; strength++) {
+ final long timeMs = getActiveTxRadioDurationMs(rat, freqLvl, strength,
+ rawRealtimeMs);
+ if (timeMs <= 0) continue;
+ hasFreqData = true;
+ sb.append(prefix);
+ sb.append(signalStrengthDescription[strength]);
+ formatTimeMs(sb, timeMs);
+ sb.append("(");
+ sb.append(formatRatioLocked(timeMs, totalActiveTimesMs));
+ sb.append(")\n");
+ }
+
+ sb.append(prefix);
+ sb.append(rxHeader);
+ final long rxTimeMs = getActiveRxRadioDurationMs(rat, freqLvl, rawRealtimeMs);
+ formatTimeMs(sb, rxTimeMs);
+ sb.append("(");
+ sb.append(formatRatioLocked(rxTimeMs, totalActiveTimesMs));
+ sb.append(")\n");
+
if (hasFreqData) {
hasData = true;
pw.print(sb);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 276578e..2448a05 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1703,12 +1703,40 @@
/**
* A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
- * an error occurred that prevented the user from being removed or set as ephemeral.
+ * an unknown error occurred that prevented the user from being removed or set as ephemeral.
*
* @hide
*/
@SystemApi
- public static final int REMOVE_RESULT_ERROR = 3;
+ public static final int REMOVE_RESULT_ERROR_UNKNOWN = -1;
+
+ /**
+ * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
+ * the user could not be removed due to a {@link #DISALLOW_REMOVE_MANAGED_PROFILE} or
+ * {@link #DISALLOW_REMOVE_USER} user restriction.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int REMOVE_RESULT_ERROR_USER_RESTRICTION = -2;
+
+ /**
+ * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
+ * user being removed does not exist.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int REMOVE_RESULT_ERROR_USER_NOT_FOUND = -3;
+
+ /**
+ * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
+ * user being removed is a {@link UserHandle#SYSTEM} user which can't be removed.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4;
/**
* Possible response codes from {@link #removeUserWhenPossible(UserHandle, boolean)}.
@@ -1719,7 +1747,10 @@
REMOVE_RESULT_REMOVED,
REMOVE_RESULT_DEFERRED,
REMOVE_RESULT_ALREADY_BEING_REMOVED,
- REMOVE_RESULT_ERROR,
+ REMOVE_RESULT_ERROR_USER_RESTRICTION,
+ REMOVE_RESULT_ERROR_USER_NOT_FOUND,
+ REMOVE_RESULT_ERROR_SYSTEM_USER,
+ REMOVE_RESULT_ERROR_UNKNOWN,
})
@Retention(RetentionPolicy.SOURCE)
public @interface RemoveResult {}
@@ -4846,8 +4877,10 @@
* the {@link #DISALLOW_REMOVE_USER} or {@link #DISALLOW_REMOVE_MANAGED_PROFILE} restriction
*
* @return the {@link RemoveResult} code: {@link #REMOVE_RESULT_REMOVED},
- * {@link #REMOVE_RESULT_DEFERRED}, {@link #REMOVE_RESULT_ALREADY_BEING_REMOVED}, or
- * {@link #REMOVE_RESULT_ERROR}.
+ * {@link #REMOVE_RESULT_DEFERRED}, {@link #REMOVE_RESULT_ALREADY_BEING_REMOVED},
+ * {@link #REMOVE_RESULT_ERROR_USER_RESTRICTION}, {@link #REMOVE_RESULT_ERROR_USER_NOT_FOUND},
+ * {@link #REMOVE_RESULT_ERROR_SYSTEM_USER}, or {@link #REMOVE_RESULT_ERROR_UNKNOWN}. All error
+ * codes have negative values.
*
* @hide
*/
@@ -4864,6 +4897,19 @@
}
/**
+ * Check if {@link #removeUserWhenPossible} returned a success code which means that the user
+ * has been removed or is slated for removal.
+ *
+ * @param result is {@link #RemoveResult} code return by {@link #removeUserWhenPossible}.
+ * @return {@code true} if it is a success code.
+ * @hide
+ */
+ @SystemApi
+ public static boolean isRemoveResultSuccessful(@RemoveResult int result) {
+ return result >= 0;
+ }
+
+ /**
* Updates the user's name.
*
* @param userId the user's integer id
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index c1413be..190adbd 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -249,19 +249,19 @@
return;
}
- Rect handwritingArea = getViewHandwritingArea(connectedView);
- if (handwritingArea != null) {
- if (contains(handwritingArea, mState.mStylusDownX, mState.mStylusDownY)) {
- startHandwriting(connectedView);
- }
+ final Rect handwritingArea = getViewHandwritingArea(connectedView);
+ if (contains(handwritingArea, mState.mStylusDownX, mState.mStylusDownY)) {
+ startHandwriting(connectedView);
+ } else {
+ reset();
}
- reset();
}
/** For test only. */
@VisibleForTesting
public void startHandwriting(@NonNull View view) {
mImm.startStylusHandwriting(view);
+ reset();
}
/**
@@ -287,7 +287,7 @@
final View connectedView = getConnectedView();
if (connectedView != null && connectedView.isAutoHandwritingEnabled()) {
final Rect handwritingArea = getViewHandwritingArea(connectedView);
- if (handwritingArea != null && contains(handwritingArea, x, y)) {
+ if (contains(handwritingArea, x, y)) {
return connectedView;
}
}
@@ -298,8 +298,7 @@
for (HandwritableViewInfo viewInfo : handwritableViewInfos) {
final View view = viewInfo.getView();
if (!view.isAutoHandwritingEnabled()) continue;
- final Rect rect = viewInfo.getHandwritingArea();
- if (rect != null && contains(rect, x, y)) {
+ if (contains(viewInfo.getHandwritingArea(), x, y)) {
return viewInfo.getView();
}
}
@@ -315,12 +314,15 @@
private static Rect getViewHandwritingArea(@NonNull View view) {
final ViewParent viewParent = view.getParent();
if (viewParent != null && view.isAttachedToWindow() && view.isAggregatedVisible()) {
- Rect handwritingArea = view.getHandwritingArea();
- if (handwritingArea == null) {
- handwritingArea = new Rect(0, 0, view.getWidth(), view.getHeight());
+ final Rect localHandwritingArea = view.getHandwritingArea();
+ final Rect globalHandwritingArea = new Rect();
+ if (localHandwritingArea != null) {
+ globalHandwritingArea.set(localHandwritingArea);
+ } else {
+ globalHandwritingArea.set(0, 0, view.getWidth(), view.getHeight());
}
- if (viewParent.getChildVisibleRect(view, handwritingArea, null)) {
- return handwritingArea;
+ if (viewParent.getChildVisibleRect(view, globalHandwritingArea, null)) {
+ return globalHandwritingArea;
}
}
return null;
@@ -329,7 +331,8 @@
/**
* Return true if the (x, y) is inside by the given {@link Rect}.
*/
- private boolean contains(@NonNull Rect rect, float x, float y) {
+ private boolean contains(@Nullable Rect rect, float x, float y) {
+ if (rect == null) return false;
return x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom;
}
@@ -481,17 +484,18 @@
if (!mIsDirty) {
return true;
}
- final Rect localRect = view.getHandwritingArea();
- if (localRect == null) {
+ final Rect handwritingArea = view.getHandwritingArea();
+ if (handwritingArea == null) {
return false;
}
ViewParent parent = view.getParent();
if (parent != null) {
- final Rect newRect = new Rect(localRect);
- if (parent.getChildVisibleRect(view, newRect, null /* offset */)) {
- mHandwritingArea = newRect;
- } else {
+ if (mHandwritingArea == null) {
+ mHandwritingArea = new Rect();
+ }
+ mHandwritingArea.set(handwritingArea);
+ if (!parent.getChildVisibleRect(view, mHandwritingArea, null /* offset */)) {
mHandwritingArea = null;
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c222991..0a61f28e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12016,7 +12016,6 @@
/**
* Return the handwriting areas set on this view, in its local coordinates.
- * Notice: the caller of this method should not modify the Rect returned.
* @see #setHandwritingArea(Rect)
*
* @hide
@@ -12025,7 +12024,7 @@
public Rect getHandwritingArea() {
final ListenerInfo info = mListenerInfo;
if (info != null) {
- return info.mHandwritingArea;
+ return new Rect(info.mHandwritingArea);
}
return null;
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index a5937a6..3b46f62 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -166,7 +166,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- static final int VERSION = 206;
+ static final int VERSION = 207;
// The maximum number of names wakelocks we will keep track of
// per uid; once the limit is reached, we batch the remaining wakelocks
@@ -964,6 +964,16 @@
* Timers for each combination of frequency range and signal strength.
*/
public final StopwatchTimer[][] perStateTimers;
+ /**
+ * Counters tracking the time (in milliseconds) spent transmitting data in a given state.
+ */
+ @Nullable
+ private LongSamplingCounter[][] mPerStateTxDurationMs = null;
+ /**
+ * Counters tracking the time (in milliseconds) spent receiving data in at given frequency.
+ */
+ @Nullable
+ private LongSamplingCounter[] mPerFrequencyRxDurationMs = null;
RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) {
perStateTimers =
@@ -1024,15 +1034,198 @@
}
/**
- * Reset display timers.
+ * Returns the duration in milliseconds spent in a given state since the last mark.
+ */
+ public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange,
+ int signalStrength, long elapsedRealtimeMs) {
+ return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked(
+ elapsedRealtimeMs * 1000) / 1000;
+ }
+
+ /**
+ * Set mark for all timers.
+ */
+ public void setMark(long elapsedRealtimeMs) {
+ final int size = perStateTimers.length;
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
+ perStateTimers[i][j].setMark(elapsedRealtimeMs);
+ }
+ }
+ }
+
+ /**
+ * Returns numbers of frequencies tracked for this RAT.
+ */
+ public int getFrequencyRangeCount() {
+ return perStateTimers.length;
+ }
+
+ /**
+ * Add TX time for a given state.
+ */
+ public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange,
+ int signalStrength, long durationMs) {
+ getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs);
+ }
+
+ /**
+ * Add TX time for a given frequency.
+ */
+ public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange,
+ long durationMs) {
+ getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs);
+ }
+
+ /**
+ * Reset radio access technology timers and counts.
*/
public void reset(long elapsedRealtimeUs) {
final int size = perStateTimers.length;
for (int i = 0; i < size; i++) {
for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
perStateTimers[i][j].reset(false, elapsedRealtimeUs);
+ if (mPerStateTxDurationMs == null) continue;
+ mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs);
+ }
+ if (mPerFrequencyRxDurationMs == null) continue;
+ mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs);
+ }
+ }
+
+ /**
+ * Write data to summary parcel
+ */
+ public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) {
+ final int freqCount = perStateTimers.length;
+ out.writeInt(freqCount);
+ out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS);
+ for (int i = 0; i < freqCount; i++) {
+ for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
+ perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
}
}
+
+ if (mPerStateTxDurationMs == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ for (int i = 0; i < freqCount; i++) {
+ for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) {
+ mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out);
+ }
+ }
+ }
+
+ if (mPerFrequencyRxDurationMs == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ for (int i = 0; i < freqCount; i++) {
+ mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out);
+ }
+ }
+ }
+
+ /**
+ * Read data from summary parcel
+ */
+ public void readSummaryFromParcel(Parcel in) {
+ final int oldFreqCount = in.readInt();
+ final int oldSignalStrengthCount = in.readInt();
+ final int currFreqCount = perStateTimers.length;
+ final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+
+ for (int freq = 0; freq < oldFreqCount; freq++) {
+ for (int strength = 0; strength < oldSignalStrengthCount; strength++) {
+ if (freq >= currFreqCount || strength >= currSignalStrengthCount) {
+ // Mismatch with the summary parcel. Consume the data but don't use it.
+ final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null,
+ new TimeBase());
+ // Consume perStateTimers data.
+ temp.readSummaryFromParcelLocked(in);
+ } else {
+ perStateTimers[freq][strength].readSummaryFromParcelLocked(in);
+ }
+ }
+ }
+
+ if (in.readInt() == 1) {
+ for (int freq = 0; freq < oldFreqCount; freq++) {
+ for (int strength = 0; strength < oldSignalStrengthCount; strength++) {
+ if (freq >= currFreqCount || strength >= currSignalStrengthCount) {
+ // Mismatch with the summary parcel. Consume the data but don't use it.
+ final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null,
+ new TimeBase());
+ // Consume mPerStateTxDurationMs data.
+ temp.readSummaryFromParcelLocked(in);
+ }
+ getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in);
+ }
+ }
+ }
+
+ if (in.readInt() == 1) {
+ for (int freq = 0; freq < oldFreqCount; freq++) {
+ if (freq >= currFreqCount) {
+ // Mismatch with the summary parcel. Consume the data but don't use it.
+ final StopwatchTimer
+ temp = new StopwatchTimer(null, null, -1, null, new TimeBase());
+ // Consume mPerFrequencyRxDurationMs data.
+ temp.readSummaryFromParcelLocked(in);
+ continue;
+ }
+ getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in);
+ }
+ }
+ }
+
+ private LongSamplingCounter getTxDurationCounter(
+ @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) {
+ if (mPerStateTxDurationMs == null) {
+ if (!make) return null;
+
+ final int freqCount = getFrequencyRangeCount();
+ final int signalStrengthCount = perStateTimers[0].length;
+ final TimeBase timeBase = perStateTimers[0][0].mTimeBase;
+ mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount];
+ for (int freq = 0; freq < freqCount; freq++) {
+ for (int strength = 0; strength < signalStrengthCount; strength++) {
+ mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase);
+ }
+ }
+ }
+ if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) {
+ Slog.w(TAG, "Unexpected frequency range (" + frequencyRange
+ + ") requested in getTxDurationCounter");
+ return null;
+ }
+ if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) {
+ Slog.w(TAG, "Unexpected signal strength (" + signalStrength
+ + ") requested in getTxDurationCounter");
+ return null;
+ }
+ return mPerStateTxDurationMs[frequencyRange][signalStrength];
+ }
+
+ private LongSamplingCounter getRxDurationCounter(
+ @ServiceState.FrequencyRange int frequencyRange, boolean make) {
+ if (mPerFrequencyRxDurationMs == null) {
+ if (!make) return null;
+
+ final int freqCount = getFrequencyRangeCount();
+ final TimeBase timeBase = perStateTimers[0][0].mTimeBase;
+ mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount];
+ for (int freq = 0; freq < freqCount; freq++) {
+ mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase);
+ }
+ }
+ if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) {
+ Slog.w(TAG, "Unexpected frequency range (" + frequencyRange
+ + ") requested in getRxDurationCounter");
+ return null;
+ }
+ return mPerFrequencyRxDurationMs[frequencyRange];
}
}
@@ -8006,6 +8199,32 @@
elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000;
}
+ @Override
+ public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat,
+ @ServiceState.FrequencyRange int frequencyRange, int signalStrength,
+ long elapsedRealtimeMs) {
+ final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat];
+ if (stats == null) return DURATION_UNAVAILABLE;
+
+ final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange,
+ signalStrength, false);
+ if (counter == null) return DURATION_UNAVAILABLE;
+
+ return counter.getCountLocked(STATS_SINCE_CHARGED);
+ }
+
+ @Override
+ public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat,
+ @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) {
+ final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat];
+ if (stats == null) return DURATION_UNAVAILABLE;
+
+ final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false);
+ if (counter == null) return DURATION_UNAVAILABLE;
+
+ return counter.getCountLocked(STATS_SINCE_CHARGED);
+ }
+
@UnsupportedAppUsage
@Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
@@ -13484,6 +13703,67 @@
addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
mTmpRailStats.resetCellularTotalEnergyUsed();
}
+
+ // Proportionally smear Rx and Tx times across each RAt
+ final int levelCount = CellSignalStrength.getNumSignalStrengthLevels();
+ long[] perSignalStrengthActiveTimeMs = new long[levelCount];
+ long totalActiveTimeMs = 0;
+
+ for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+ final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+ if (ratStats == null) continue;
+
+ final int freqCount = ratStats.getFrequencyRangeCount();
+ for (int freq = 0; freq < freqCount; freq++) {
+ for (int level = 0; level < levelCount; level++) {
+ final long durationMs = ratStats.getTimeSinceMark(freq, level,
+ elapsedRealtimeMs);
+ perSignalStrengthActiveTimeMs[level] += durationMs;
+ totalActiveTimeMs += durationMs;
+ }
+ }
+ }
+
+ if (totalActiveTimeMs != 0) {
+ // Smear the provided Tx/Rx durations across each RAT, frequency, and signal
+ // strength.
+ for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) {
+ final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat];
+ if (ratStats == null) continue;
+
+ final int freqCount = ratStats.getFrequencyRangeCount();
+ for (int freq = 0; freq < freqCount; freq++) {
+ long frequencyDurationMs = 0;
+ for (int level = 0; level < levelCount; level++) {
+ final long durationMs = ratStats.getTimeSinceMark(freq, level,
+ elapsedRealtimeMs);
+ final long totalLvlDurationMs =
+ perSignalStrengthActiveTimeMs[level];
+ if (totalLvlDurationMs == 0) continue;
+ final long totalTxLvlDurations =
+ deltaInfo.getTransmitDurationMillisAtPowerLevel(level);
+ // Smear HAL provided Tx power level duration based on active modem
+ // duration in a given state. (Add totalLvlDurationMs / 2 before
+ // the integer division with totalLvlDurationMs for rounding.)
+ final long proportionalTxDurationMs =
+ (durationMs * totalTxLvlDurations
+ + (totalLvlDurationMs / 2)) / totalLvlDurationMs;
+ ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs);
+ frequencyDurationMs += durationMs;
+ }
+ final long totalRxDuration = deltaInfo.getReceiveTimeMillis();
+ // Smear HAL provided Rx power duration based on active modem
+ // duration in a given state. (Add totalActiveTimeMs / 2 before the
+ // integer division with totalActiveTimeMs for rounding.)
+ final long proportionalRxDurationMs =
+ (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs
+ / 2)) / totalActiveTimeMs;
+ ratStats.incrementRxDuration(freq, proportionalRxDurationMs);
+ }
+
+ ratStats.setMark(elapsedRealtimeMs);
+ }
+ }
}
long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
elapsedRealtimeMs * 1000);
@@ -16932,6 +17212,13 @@
mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
}
+
+ final int numRat = in.readInt();
+ for (int i = 0; i < numRat; i++) {
+ if (in.readInt() == 0) continue;
+ getRatBatteryStatsLocked(i).readSummaryFromParcel(in);
+ }
+
mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
@@ -17432,6 +17719,17 @@
mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
}
+ final int numRat = mPerRatBatteryStats.length;
+ out.writeInt(numRat);
+ for (int i = 0; i < numRat; i++) {
+ final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i];
+ if (ratStat == null) {
+ out.writeInt(0);
+ continue;
+ }
+ out.writeInt(1);
+ ratStat.writeSummaryToParcel(out, nowRealtime);
+ }
mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime);
mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime);
mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 4aa00f6..3a76745 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -361,7 +361,7 @@
"libwuffs_mirror_release_c",
],
},
- linux_glibc: {
+ host_linux: {
srcs: [
"android_content_res_ApkAssets.cpp",
"android_database_CursorWindow.cpp",
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index f5cbffb..7ccb9d9 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -17,6 +17,8 @@
package com.android.internal.os;
import static android.os.BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
+import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
+import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT;
import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR;
import static android.os.BatteryStats.STATS_SINCE_CHARGED;
import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;
@@ -24,7 +26,10 @@
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
+import static org.mockito.Mockito.mock;
+
import android.app.ActivityManager;
+import android.app.usage.NetworkStatsManager;
import android.os.BatteryStats;
import android.os.BatteryStats.HistoryItem;
import android.os.BatteryStats.Uid.Sensor;
@@ -34,6 +39,7 @@
import android.telephony.Annotation;
import android.telephony.CellSignalStrength;
import android.telephony.DataConnectionRealTimeInfo;
+import android.telephony.ModemActivityInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.SparseIntArray;
@@ -48,6 +54,8 @@
import junit.framework.TestCase;
+import org.mockito.Mock;
+
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -72,6 +80,13 @@
private static final int ISOLATED_UID = UserHandle.getUid(0, ISOLATED_APP_ID);
private static final WorkSource WS = new WorkSource(UID);
+ enum ModemState {
+ SLEEP, IDLE, RECEIVING, TRANSMITTING
+ }
+
+ @Mock
+ NetworkStatsManager mNetworkStatsManager;
+
/**
* Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked.
*/
@@ -1173,69 +1188,29 @@
}
@SmallTest
- public void testGetPerStateActiveRadioDurationMs() {
+ public void testGetPerStateActiveRadioDurationMs_noModemActivity() {
final MockClock clock = new MockClock(); // holds realtime and uptime in ms
final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
- final int ratCount = BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT;
+ final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+ final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
+ final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
for (int rat = 0; rat < ratCount; rat++) {
for (int freq = 0; freq < frequencyCount; freq++) {
+ // Should have no RX data without Modem Activity Info
+ expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
expectedDurationsMs[rat][freq][txLvl] = 0;
+ // Should have no TX data without Modem Activity Info
+ expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
}
}
}
- class ModemAndBatteryState {
- public long currentTimeMs = 100;
- public boolean onBattery = false;
- public boolean modemActive = false;
- @Annotation.NetworkType
- public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- @BatteryStats.RadioAccessTechnology
- public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER;
- @ServiceState.FrequencyRange
- public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
- public SparseIntArray currentSignalStrengths = new SparseIntArray();
-
- void setOnBattery(boolean onBattery) {
- this.onBattery = onBattery;
- bi.updateTimeBasesLocked(onBattery, Display.STATE_OFF, currentTimeMs * 1000,
- currentTimeMs * 1000);
- }
-
- void setModemActive(boolean active) {
- modemActive = active;
- final int state = active ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
- : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
- bi.noteMobileRadioPowerStateLocked(state, currentTimeMs * 1000_000L, UID);
- }
-
- void setRatType(@Annotation.NetworkType int dataType,
- @BatteryStats.RadioAccessTechnology int rat) {
- currentNetworkDataType = dataType;
- currentRat = rat;
- bi.notePhoneDataConnectionStateLocked(dataType, true, ServiceState.STATE_IN_SERVICE,
- currentFrequencyRange);
- }
-
- void setFrequencyRange(@ServiceState.FrequencyRange int frequency) {
- currentFrequencyRange = frequency;
- bi.notePhoneDataConnectionStateLocked(currentNetworkDataType, true,
- ServiceState.STATE_IN_SERVICE, frequency);
- }
-
- void setSignalStrength(@BatteryStats.RadioAccessTechnology int rat, int strength) {
- currentSignalStrengths.put(rat, strength);
- final int size = currentSignalStrengths.size();
- final int newestGenSignalStrength = currentSignalStrengths.valueAt(size - 1);
- bi.notePhoneSignalStrengthLocked(newestGenSignalStrength, currentSignalStrengths);
- }
- }
- final ModemAndBatteryState state = new ModemAndBatteryState();
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, null);
IntConsumer incrementTime = inc -> {
state.currentTimeMs += inc;
@@ -1253,6 +1228,7 @@
expectedDurationsMs[currentRat][currentFrequencyRange][currentSignalStrength] += inc;
};
+
state.setOnBattery(false);
state.setModemActive(false);
state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
@@ -1260,95 +1236,367 @@
state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// While not on battery, the timers should not increase.
state.setModemActive(true);
incrementTime.accept(100);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
incrementTime.accept(200);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
CellSignalStrength.SIGNAL_STRENGTH_GOOD);
incrementTime.accept(500);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
incrementTime.accept(300);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE);
incrementTime.accept(400);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
incrementTime.accept(500);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
// start counting up.
state.setOnBattery(true);
incrementTime.accept(600);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
-
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// Changing LTE signal strength should be tracked.
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
CellSignalStrength.SIGNAL_STRENGTH_POOR);
incrementTime.accept(700);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
incrementTime.accept(800);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
CellSignalStrength.SIGNAL_STRENGTH_GOOD);
incrementTime.accept(900);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
CellSignalStrength.SIGNAL_STRENGTH_GREAT);
incrementTime.accept(1000);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// Change in the signal strength of nonactive RAT should not affect anything.
state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
CellSignalStrength.SIGNAL_STRENGTH_POOR);
incrementTime.accept(1100);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// Changing to OTHER Rat should start tracking the poor signal strength.
state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
incrementTime.accept(1200);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// Noting frequency change should not affect non NR Rat.
state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
incrementTime.accept(1300);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// Now the NR Rat, HIGH frequency range, good signal strength should start counting.
state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
incrementTime.accept(1400);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// Noting frequency change should not affect non NR Rat.
state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
incrementTime.accept(1500);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
// Modem no longer active, should not be tracking any more.
state.setModemActive(false);
incrementTime.accept(1500);
- checkPerStateActiveRadioDurations(expectedDurationsMs, bi, state.currentTimeMs);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+ }
+ @SmallTest
+ public void testGetPerStateActiveRadioDurationMs_withModemActivity() {
+ final MockClock clock = new MockClock(); // holds realtime and uptime in ms
+ final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
+ bi.setPowerProfile(mock(PowerProfile.class));
+ final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
+ final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
+ final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
+
+ final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+ final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
+ final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
+ for (int rat = 0; rat < ratCount; rat++) {
+ for (int freq = 0; freq < frequencyCount; freq++) {
+ if (rat != RADIO_ACCESS_TECHNOLOGY_NR
+ && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
+ } else {
+ expectedRxDurationsMs[rat][freq] = 0;
+ }
+ expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
+
+ for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+ expectedDurationsMs[rat][freq][txLvl] = 0;
+
+ if (rat != RADIO_ACCESS_TECHNOLOGY_NR
+ && freq != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
+ } else {
+ expectedTxDurationsMs[rat][freq][txLvl] = 0;
+ }
+ expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
+ }
+ }
+ }
+
+ final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L);
+ final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai);
+
+ IntConsumer incrementTime = inc -> {
+ state.currentTimeMs += inc;
+ clock.realtime = clock.uptime = state.currentTimeMs;
+
+ // If the device is not on battery, no timers should increment.
+ if (!state.onBattery) return;
+ // If the modem is not active, no timers should increment.
+ if (!state.modemActive) return;
+
+ final int currRat = state.currentRat;
+ final int currFreqRange =
+ currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
+ int currSignalStrength = state.currentSignalStrengths.get(currRat);
+
+ expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+
+ // Evaluate the HAL provided time in states.
+ switch (state.modemState) {
+ case SLEEP:
+ long sleepMs = state.modemActivityInfo.getSleepTimeMillis();
+ state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc);
+ break;
+ case IDLE:
+ long idleMs = state.modemActivityInfo.getIdleTimeMillis();
+ state.modemActivityInfo.setIdleTimeMillis(idleMs + inc);
+ break;
+ case RECEIVING:
+ long rxMs = state.modemActivityInfo.getReceiveTimeMillis();
+ state.modemActivityInfo.setReceiveTimeMillis(rxMs + inc);
+ expectedRxDurationsMs[currRat][currFreqRange] += inc;
+ break;
+ case TRANSMITTING:
+ int[] txMs = state.modemActivityInfo.getTransmitTimeMillis();
+ txMs[currSignalStrength] += inc;
+ state.modemActivityInfo.setTransmitTimeMillis(txMs);
+ expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
+ break;
+ }
+ };
+
+ state.setOnBattery(false);
+ state.setModemActive(false);
+ state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // While not on battery, the timers should not increase.
+ state.setModemActive(true);
+ incrementTime.accept(100);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
+ incrementTime.accept(200);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
+ CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+ incrementTime.accept(500);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
+ incrementTime.accept(300);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE);
+ incrementTime.accept(400);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
+ incrementTime.accept(500);
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Data will now be available.
+ for (int rat = 0; rat < ratCount; rat++) {
+ for (int freq = 0; freq < frequencyCount; freq++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedRxDurationsMs[rat][freq] = 0;
+ }
+ for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
+ if (rat == RADIO_ACCESS_TECHNOLOGY_NR
+ || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
+ // Only the NR RAT should have per frequency data.
+ expectedTxDurationsMs[rat][freq][txLvl] = 0;
+ }
+ }
+ }
+ }
+
+ // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
+ // start counting up.
+ state.setOnBattery(true);
+ incrementTime.accept(300);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(500);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(600);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+ // Changing LTE signal strength should be tracked.
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_POOR);
+ incrementTime.accept(300);
+ state.setModemState(ModemState.SLEEP);
+ incrementTime.accept(1000);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(700);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
+ incrementTime.accept(800);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(222);
+ state.setModemState(ModemState.IDLE);
+ incrementTime.accept(111);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(7777);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+ incrementTime.accept(88);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(900);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
+ CellSignalStrength.SIGNAL_STRENGTH_GREAT);
+ incrementTime.accept(123);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(333);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1000);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(555);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Change in the signal strength of nonactive RAT should not affect anything.
+ state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
+ CellSignalStrength.SIGNAL_STRENGTH_POOR);
+ incrementTime.accept(631);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(321);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(99);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Changing to OTHER Rat should start tracking the poor signal strength.
+ state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
+ BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
+ incrementTime.accept(1200);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Noting frequency change should not affect non NR Rat.
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
+ incrementTime.accept(444);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1300);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
+ state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
+ incrementTime.accept(1400);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Frequency changed to low.
+ state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
+ incrementTime.accept(852);
+ state.setModemState(ModemState.RECEIVING);
+ incrementTime.accept(157);
+ state.setModemState(ModemState.TRANSMITTING);
+ incrementTime.accept(1500);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
+
+ // Modem no longer active, should not be tracking any more.
+ state.setModemActive(false);
+ incrementTime.accept(1500);
+ state.noteModemControllerActivity();
+ checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
+ expectedTxDurationsMs, bi, state.currentTimeMs);
}
private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
@@ -1426,28 +1674,124 @@
}
private void checkPerStateActiveRadioDurations(long[][][] expectedDurationsMs,
+ long[][] expectedRxDurationsMs, long[][][] expectedTxDurationsMs,
BatteryStatsImpl bi, long currentTimeMs) {
for (int rat = 0; rat < expectedDurationsMs.length; rat++) {
final long[][] expectedRatDurationsMs = expectedDurationsMs[rat];
for (int freq = 0; freq < expectedRatDurationsMs.length; freq++) {
+ final long expectedRxDurationMs = expectedRxDurationsMs[rat][freq];
+
+ // Build a verbose fail message, just in case.
+ final StringBuilder rxFailSb = new StringBuilder();
+ rxFailSb.append("Wrong time in Rx state for RAT:");
+ rxFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
+ rxFailSb.append(", frequency:");
+ rxFailSb.append(ServiceState.frequencyRangeToString(freq));
+ assertEquals(rxFailSb.toString(), expectedRxDurationMs,
+ bi.getActiveRxRadioDurationMs(rat, freq, currentTimeMs));
+
final long[] expectedFreqDurationsMs = expectedRatDurationsMs[freq];
for (int strength = 0; strength < expectedFreqDurationsMs.length; strength++) {
final long expectedSignalStrengthDurationMs = expectedFreqDurationsMs[strength];
+ final long expectedTxDurationMs = expectedTxDurationsMs[rat][freq][strength];
final long actualDurationMs = bi.getActiveRadioDurationMs(rat, freq,
strength, currentTimeMs);
- // Build a verbose fail message, just in case.
- final StringBuilder sb = new StringBuilder();
- sb.append("Wrong time in state for RAT:");
- sb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
- sb.append(", frequency:");
- sb.append(ServiceState.frequencyRangeToString(freq));
- sb.append(", strength:");
- sb.append(strength);
+ final StringBuilder failSb = new StringBuilder();
+ failSb.append("Wrong time in state for RAT:");
+ failSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
+ failSb.append(", frequency:");
+ failSb.append(ServiceState.frequencyRangeToString(freq));
+ failSb.append(", strength:");
+ failSb.append(strength);
+ assertEquals(failSb.toString(), expectedSignalStrengthDurationMs,
+ actualDurationMs);
- assertEquals(sb.toString(), expectedSignalStrengthDurationMs, actualDurationMs);
+ final StringBuilder txFailSb = new StringBuilder();
+ txFailSb.append("Wrong time in Tx state for RAT:");
+ txFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
+ txFailSb.append(", frequency:");
+ txFailSb.append(ServiceState.frequencyRangeToString(freq));
+ txFailSb.append(", strength:");
+ txFailSb.append(strength);
+ assertEquals(txFailSb.toString(), expectedTxDurationMs,
+ bi.getActiveTxRadioDurationMs(rat, freq, strength, currentTimeMs));
}
}
}
}
+
+ private class ModemAndBatteryState {
+ public long currentTimeMs = 100;
+ public boolean onBattery = false;
+ public boolean modemActive = false;
+ @Annotation.NetworkType
+ public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ @BatteryStats.RadioAccessTechnology
+ public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER;
+ @ServiceState.FrequencyRange
+ public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
+ public SparseIntArray currentSignalStrengths = new SparseIntArray();
+ public ModemState modemState = ModemState.SLEEP;
+ public ModemActivityInfo modemActivityInfo;
+
+ private final MockBatteryStatsImpl mBsi;
+
+ ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai) {
+ mBsi = bsi;
+ modemActivityInfo = mai;
+ }
+
+ void setOnBattery(boolean onBattery) {
+ this.onBattery = onBattery;
+ mBsi.updateTimeBasesLocked(onBattery, Display.STATE_OFF, currentTimeMs * 1000,
+ currentTimeMs * 1000);
+ mBsi.setOnBatteryInternal(onBattery);
+ noteModemControllerActivity();
+ }
+
+ void setModemActive(boolean active) {
+ modemActive = active;
+ final int state = active ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
+ : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
+ mBsi.noteMobileRadioPowerStateLocked(state, currentTimeMs * 1000_000L, UID);
+ noteModemControllerActivity();
+ }
+
+ void setRatType(@Annotation.NetworkType int dataType,
+ @BatteryStats.RadioAccessTechnology int rat) {
+ currentNetworkDataType = dataType;
+ currentRat = rat;
+ mBsi.notePhoneDataConnectionStateLocked(dataType, true, ServiceState.STATE_IN_SERVICE,
+ currentFrequencyRange);
+ }
+
+ void setFrequencyRange(@ServiceState.FrequencyRange int frequency) {
+ currentFrequencyRange = frequency;
+ mBsi.notePhoneDataConnectionStateLocked(currentNetworkDataType, true,
+ ServiceState.STATE_IN_SERVICE, frequency);
+ }
+
+ void setSignalStrength(@BatteryStats.RadioAccessTechnology int rat, int strength) {
+ currentSignalStrengths.put(rat, strength);
+ final int size = currentSignalStrengths.size();
+ final int newestGenSignalStrength = currentSignalStrengths.valueAt(size - 1);
+ mBsi.notePhoneSignalStrengthLocked(newestGenSignalStrength, currentSignalStrengths);
+ }
+
+ void setModemState(ModemState state) {
+ modemState = state;
+ }
+
+ void noteModemControllerActivity() {
+ if (modemActivityInfo == null) return;
+ modemActivityInfo.setTimestamp(currentTimeMs);
+ ModemActivityInfo copy = new ModemActivityInfo(modemActivityInfo.getTimestampMillis(),
+ modemActivityInfo.getSleepTimeMillis(), modemActivityInfo.getIdleTimeMillis(),
+ modemActivityInfo.getTransmitTimeMillis().clone(),
+ modemActivityInfo.getReceiveTimeMillis());
+ mBsi.noteModemControllerActivity(copy, POWER_DATA_UNAVAILABLE,
+ currentTimeMs, currentTimeMs, mNetworkStatsManager);
+ }
+ }
}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index c3b0017..3e91eed 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -452,6 +452,7 @@
<permission name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" />
<permission name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
<permission name="android.permission.NEARBY_WIFI_DEVICES" />
+ <permission name="android.permission.MANAGE_WIFI_INTERFACES" />
<permission name="android.permission.OVERRIDE_WIFI_CONFIG" />
<!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover
P2P external approver API sets require MANAGE_WIFI_NETWORK_SELECTION permission. -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
index 3115f8a..11633a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
@@ -253,11 +253,11 @@
private WindowManager.LayoutParams getDismissTargetLayoutParams() {
final Point windowSize = new Point();
mWindowManager.getDefaultDisplay().getRealSize(windowSize);
-
+ int height = Math.min(windowSize.y, mDismissAreaHeight);
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
- mDismissAreaHeight,
- 0, windowSize.y - mDismissAreaHeight,
+ height,
+ 0, windowSize.y - height,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 63b831d..c80fb18 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -118,7 +118,7 @@
"libz",
],
},
- linux_glibc: {
+ host_linux: {
srcs: [
"CursorWindow.cpp",
],
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
index f681ba1..06f2a62 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java
@@ -327,16 +327,11 @@
* @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is
* for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only
* counting iface stats.
- * @param set usage state of this {@link Entry}. Should be one of the following
- * values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+ * @param set usage state of this {@link Entry}.
* @param tag tag of this {@link Entry}.
- * @param metered metered state of this {@link Entry}. Should be one of the following
- * values: {link #METERED_YES}, {link #METERED_NO}.
- * @param roaming roaming state of this {@link Entry}. Should be one of the following
- * values: {link #ROAMING_YES}, {link #ROAMING_NO}.
- * @param defaultNetwork default network status of this {@link Entry}. Should be one
- * of the following values: {link #DEFAULT_NETWORK_YES},
- * {link #DEFAULT_NETWORK_NO}.
+ * @param metered metered state of this {@link Entry}.
+ * @param roaming roaming state of this {@link Entry}.
+ * @param defaultNetwork default network status of this {@link Entry}.
* @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
* represent the contents of IP packets, including IP headers.
* @param rxPackets Number of packets received for this {@link Entry}. Statistics should
@@ -401,8 +396,7 @@
}
/**
- * @return the set state of this entry. Should be one of the following
- * values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+ * @return the set state of this entry.
*/
@State public int getSet() {
return set;
@@ -416,24 +410,21 @@
}
/**
- * @return the metered state. Should be one of the following
- * values: {link #METERED_YES}, {link #METERED_NO}.
+ * @return the metered state.
*/
@Meteredness public int getMetered() {
return metered;
}
/**
- * @return the roaming state. Should be one of the following
- * values: {link #ROAMING_YES}, {link #ROAMING_NO}.
+ * @return the roaming state.
*/
@Roaming public int getRoaming() {
return roaming;
}
/**
- * @return the default network state. Should be one of the following
- * values: {link #DEFAULT_NETWORK_YES}, {link #DEFAULT_NETWORK_NO}.
+ * @return the default network state.
*/
@DefaultNetwork public int getDefaultNetwork() {
return defaultNetwork;
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index e7765e6..e93371d 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -536,6 +536,7 @@
<uses-permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" />
<uses-permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
+ <uses-permission android:name="android.permission.MANAGE_WIFI_INTERFACES" />
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
<!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover
P2P external approver API sets require MANAGE_WIFI_NETWORK_SELECTION permission. -->
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml b/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
index 91d81a2..cb63300 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
@@ -19,6 +19,7 @@
android:id="@+id/date_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingHorizontal="@dimen/dream_overlay_complication_shadow_padding"
android:gravity="center_horizontal"
android:textColor="@android:color/white"
android:shadowColor="@color/keyguard_shadow_color"
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml b/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml
index 3900ea5..76fe58c 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_weather.xml
@@ -19,6 +19,7 @@
android:id="@+id/weather_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingHorizontal="@dimen/dream_overlay_complication_shadow_padding"
android:textColor="@android:color/white"
android:shadowColor="@color/keyguard_shadow_color"
android:shadowRadius="?attr/shadowRadius"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 52ec516..ffae601 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1376,6 +1376,7 @@
<dimen name="dream_overlay_complication_weather_text_size">18sp</dimen>
<dimen name="dream_overlay_complication_preview_text_size">36sp</dimen>
<dimen name="dream_overlay_complication_preview_icon_padding">28dp</dimen>
+ <dimen name="dream_overlay_complication_shadow_padding">2dp</dimen>
<!-- The position of the end guide, which dream overlay complications can align their start with
if their end is aligned with the parent end. Represented as the percentage over from the
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1ef6dea..3858f9c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -326,7 +326,6 @@
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private final Executor mBackgroundExecutor;
private SensorPrivacyManager mSensorPrivacyManager;
- private int mFaceAuthUserId;
/**
* Short delay before restarting fingerprint authentication after a successful try. This should
@@ -1030,8 +1029,8 @@
boolean cameraPrivacyEnabled = false;
if (mSensorPrivacyManager != null) {
cameraPrivacyEnabled = mSensorPrivacyManager
- .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
- mFaceAuthUserId);
+ .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+ SensorPrivacyManager.Sensors.CAMERA);
}
if (msgId == FaceManager.FACE_ERROR_CANCELED
@@ -2599,7 +2598,6 @@
// This would need to be updated for multi-sensor devices
final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
&& mFaceSensorProperties.get(0).supportsFaceDetection;
- mFaceAuthUserId = userId;
if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
index 4b86862..498e715 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
@@ -119,9 +119,13 @@
if (useInvertedAlphaColor) {
canvas.drawColor(bgColor)
}
+
+ // We may clear the color(if useInvertedAlphaColor is true) of the rounded corner rects
+ // before drawing rounded corners. If the cutout happens to be inside one of these rects, it
+ // will be cleared, so we have to draw rounded corners before cutout.
+ drawRoundedCorners(canvas)
// Cutouts are drawn in DisplayCutoutBaseView.onDraw()
super.onDraw(canvas)
- drawRoundedCorners(canvas)
debugTransparentRegionPaint?.let {
calculateTransparentRect()
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 086cca1..ec6094d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -47,7 +47,6 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
-import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
@@ -62,6 +61,7 @@
import android.app.IActivityTaskManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -107,15 +107,13 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
import com.android.internal.view.AppearanceRegion;
-import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
+import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener;
import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.DeadZone;
import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.navigationbar.buttons.RotationContextButton;
import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
@@ -127,7 +125,6 @@
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -149,15 +146,15 @@
import java.util.Optional;
import java.util.function.Consumer;
+import javax.inject.Inject;
+
import dagger.Lazy;
-import dagger.assisted.Assisted;
-import dagger.assisted.AssistedFactory;
-import dagger.assisted.AssistedInject;
/**
* Contains logic for a navigation bar view.
*/
-public class NavigationBar implements View.OnAttachStateChangeListener, Callbacks {
+public class NavigationBar implements View.OnAttachStateChangeListener,
+ Callbacks, NavigationModeController.ModeChangedListener {
public static final String TAG = "NavigationBar";
private static final boolean DEBUG = false;
@@ -184,6 +181,7 @@
private final NotificationRemoteInputManager mNotificationRemoteInputManager;
private final OverviewProxyService mOverviewProxyService;
private final NavigationModeController mNavigationModeController;
+ private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
private final BroadcastDispatcher mBroadcastDispatcher;
private final CommandQueue mCommandQueue;
private final Optional<Pip> mPipOptional;
@@ -202,7 +200,8 @@
private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
private int mNavigationIconHints = 0;
- private @TransitionMode int mTransitionMode;
+ private @TransitionMode int mNavigationBarMode;
+ private ContentResolver mContentResolver;
private boolean mLongPressHomeEnabled;
private int mDisabledFlags1;
@@ -256,8 +255,7 @@
private int mCurrentRotation;
private ViewTreeObserver.OnGlobalLayoutListener mOrientationHandleGlobalLayoutListener;
private boolean mShowOrientedHandleForImmersiveMode;
- private DeadZone mDeadZone;
- private boolean mImeVisible;
+
@com.android.internal.annotations.VisibleForTesting
public enum NavBarActionEvent implements UiEventLogger.UiEventEnum {
@@ -473,9 +471,7 @@
}
};
- @AssistedInject
- NavigationBar(
- @Assisted Context context,
+ private NavigationBar(Context context,
WindowManager windowManager,
Lazy<AssistManager> assistManagerLazy,
AccessibilityManager accessibilityManager,
@@ -483,6 +479,7 @@
MetricsLogger metricsLogger,
OverviewProxyService overviewProxyService,
NavigationModeController navigationModeController,
+ AccessibilityButtonModeObserver accessibilityButtonModeObserver,
StatusBarStateController statusBarStateController,
SysUiState sysUiFlagsContainer,
BroadcastDispatcher broadcastDispatcher,
@@ -517,6 +514,7 @@
mNotificationRemoteInputManager = notificationRemoteInputManager;
mOverviewProxyService = overviewProxyService;
mNavigationModeController = navigationModeController;
+ mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
mPipOptional = pipOptional;
@@ -534,7 +532,7 @@
mTelecomManagerOptional = telecomManagerOptional;
mInputMethodManager = inputMethodManager;
- mNavBarMode = mNavigationModeController.addListener(mModeChangedListener);
+ mNavBarMode = mNavigationModeController.addListener(this);
}
public NavigationBarView getView() {
@@ -548,11 +546,6 @@
R.layout.navigation_bar, mFrame);
barView.addOnAttachStateChangeListener(this);
mNavigationBarView = barView.findViewById(R.id.navigation_bar_view);
- mDeadZone = new DeadZone(mNavigationBarView);
- mNavigationBarView.setTouchHandler(mTouchHandler);
- mNavigationBarView.setNavBarMode(mNavBarMode);
-
- mNavigationBarView.updateRotationButton();
mNavigationBarView.setVisibility(initialVisibility ? View.VISIBLE : View.INVISIBLE);
@@ -565,6 +558,7 @@
mCommandQueue.addCallback(this);
mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled();
+ mContentResolver = mContext.getContentResolver();
mNavBarHelper.init();
mAllowForceNavBarHandleOpaque = mContext.getResources().getBoolean(
R.bool.allow_force_nav_bar_handle_opaque);
@@ -603,7 +597,7 @@
setAutoHideController(/* autoHideController */ null);
mCommandQueue.removeCallback(this);
mWindowManager.removeViewImmediate(mNavigationBarView.getRootView());
- mNavigationModeController.removeListener(mModeChangedListener);
+ mNavigationModeController.removeListener(this);
mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.destroy();
@@ -618,16 +612,15 @@
final Display display = v.getDisplay();
mNavigationBarView.setComponents(mRecentsOptional);
mNavigationBarView.setComponents(mCentralSurfacesOptionalLazy.get().get().getPanelController());
- mNavigationBarView.setDisabledFlags(mDisabledFlags1, mSysUiFlagsContainer);
+ mNavigationBarView.setDisabledFlags(mDisabledFlags1);
mNavigationBarView.setOnVerticalChangedListener(this::onVerticalChanged);
mNavigationBarView.setOnTouchListener(this::onNavigationTouch);
if (mSavedState != null) {
mNavigationBarView.getLightTransitionsController().restoreState(mSavedState);
}
- setNavigationIconHints(mNavigationIconHints);
+ mNavigationBarView.setNavigationIconHints(mNavigationIconHints);
mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
mNavigationBarView.setBehavior(mBehavior);
- mNavigationBarView.setNavBarMode(mNavBarMode);
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
@@ -872,8 +865,8 @@
pw.println(" mLongPressHomeEnabled=" + mLongPressHomeEnabled);
pw.println(" mNavigationBarWindowState="
+ windowStateToString(mNavigationBarWindowState));
- pw.println(" mTransitionMode="
- + BarTransitions.modeToString(mTransitionMode));
+ pw.println(" mNavigationBarMode="
+ + BarTransitions.modeToString(mNavigationBarMode));
pw.println(" mTransientShown=" + mTransientShown);
pw.println(" mTransientShownFromGestureOnSystemBar="
+ mTransientShownFromGestureOnSystemBar);
@@ -895,7 +888,11 @@
imeShown, showImeSwitcher);
if (hints == mNavigationIconHints) return;
- setNavigationIconHints(hints);
+ mNavigationIconHints = hints;
+ if (!isTablet(mContext)) {
+ // All IME functions handled by launcher via Sysui flags for large screen
+ mNavigationBarView.setNavigationIconHints(hints);
+ }
checkBarModes();
updateSystemUiStateFlags();
}
@@ -955,15 +952,15 @@
/** Restores the appearance and the transient saved state to {@link NavigationBar}. */
public void restoreAppearanceAndTransientState() {
- final int transitionMode = transitionMode(mTransientShown, mAppearance);
- mTransitionMode = transitionMode;
+ final int barMode = barMode(mTransientShown, mAppearance);
+ mNavigationBarMode = barMode;
checkNavBarModes();
if (mAutoHideController != null) {
mAutoHideController.touchAutoHide();
}
if (mLightBarController != null) {
mLightBarController.onNavigationBarAppearanceChanged(mAppearance,
- true /* nbModeChanged */, transitionMode, false /* navbarColorManagedByIme */);
+ true /* nbModeChanged */, barMode, false /* navbarColorManagedByIme */);
}
}
@@ -977,11 +974,11 @@
boolean nbModeChanged = false;
if (mAppearance != appearance) {
mAppearance = appearance;
- nbModeChanged = updateTransitionMode(transitionMode(mTransientShown, appearance));
+ nbModeChanged = updateBarMode(barMode(mTransientShown, appearance));
}
if (mLightBarController != null) {
mLightBarController.onNavigationBarAppearanceChanged(appearance, nbModeChanged,
- mTransitionMode, navbarColorManagedByIme);
+ mNavigationBarMode, navbarColorManagedByIme);
}
if (mBehavior != behavior) {
mBehavior = behavior;
@@ -1028,16 +1025,16 @@
private void handleTransientChanged() {
mNavigationBarView.onTransientStateChanged(mTransientShown,
mTransientShownFromGestureOnSystemBar);
- final int transitionMode = transitionMode(mTransientShown, mAppearance);
- if (updateTransitionMode(transitionMode) && mLightBarController != null) {
- mLightBarController.onNavigationBarModeChanged(transitionMode);
+ final int barMode = barMode(mTransientShown, mAppearance);
+ if (updateBarMode(barMode) && mLightBarController != null) {
+ mLightBarController.onNavigationBarModeChanged(barMode);
}
}
// Returns true if the bar mode is changed.
- private boolean updateTransitionMode(int barMode) {
- if (mTransitionMode != barMode) {
- mTransitionMode = barMode;
+ private boolean updateBarMode(int barMode) {
+ if (mNavigationBarMode != barMode) {
+ mNavigationBarMode = barMode;
checkNavBarModes();
if (mAutoHideController != null) {
mAutoHideController.touchAutoHide();
@@ -1047,7 +1044,7 @@
return false;
}
- private static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
+ private static @TransitionMode int barMode(boolean isTransient, int appearance) {
final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS;
if (isTransient) {
return MODE_SEMI_TRANSPARENT;
@@ -1076,7 +1073,7 @@
| StatusBarManager.DISABLE_SEARCH);
if (masked != mDisabledFlags1) {
mDisabledFlags1 = masked;
- mNavigationBarView.setDisabledFlags(state1, mSysUiFlagsContainer);
+ mNavigationBarView.setDisabledFlags(state1);
updateScreenPinningGestures();
}
@@ -1458,7 +1455,24 @@
mCentralSurfacesOptionalLazy.get().map(CentralSurfaces::isDeviceInteractive)
.orElse(false)
&& mNavigationBarWindowState != WINDOW_STATE_HIDDEN;
- mNavigationBarView.getBarTransitions().transitionTo(mTransitionMode, anim);
+ mNavigationBarView.getBarTransitions().transitionTo(mNavigationBarMode, anim);
+ }
+
+ @Override
+ public void onNavigationModeChanged(int mode) {
+ mNavBarMode = mode;
+
+ if (!QuickStepContract.isGesturalMode(mode)) {
+ // Reset the override alpha
+ if (getBarTransitions() != null) {
+ getBarTransitions().setBackgroundOverrideAlpha(1f);
+ }
+ }
+ updateScreenPinningGestures();
+
+ if (!canShowSecondaryHandle()) {
+ resetSecondaryHandle();
+ }
}
public void disableAnimationsDuringHide(long delay) {
@@ -1599,102 +1613,114 @@
return mNavigationIconHints;
}
- private void setNavigationIconHints(int hints) {
- if (hints == mNavigationIconHints) return;
- if (!isTablet(mContext)) {
- // All IME functions handled by launcher via Sysui flags for large screen
- final boolean newBackAlt = (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
- final boolean oldBackAlt =
- (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
- if (newBackAlt != oldBackAlt) {
- mNavigationBarView.onImeVisibilityChanged(newBackAlt);
- mImeVisible = newBackAlt;
- }
-
- mNavigationBarView.setNavigationIconHints(hints);
- }
- if (DEBUG) {
- android.widget.Toast.makeText(mContext,
- "Navigation icon hints = " + hints,
- 500).show();
- }
- mNavigationIconHints = hints;
- }
-
- private final ModeChangedListener mModeChangedListener = new ModeChangedListener() {
- @Override
- public void onNavigationModeChanged(int mode) {
- mNavBarMode = mode;
-
- if (!QuickStepContract.isGesturalMode(mode)) {
- // Reset the override alpha
- if (getBarTransitions() != null) {
- getBarTransitions().setBackgroundOverrideAlpha(1f);
- }
- }
- updateScreenPinningGestures();
-
- if (!canShowSecondaryHandle()) {
- resetSecondaryHandle();
- }
- if (mNavigationBarView != null) {
- mNavigationBarView.setNavBarMode(mode);
- }
- }
- };
-
- private final Gefingerpoken mTouchHandler = new Gefingerpoken() {
- private boolean mDeadZoneConsuming;
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (isGesturalMode(mNavBarMode) && mImeVisible
- && ev.getAction() == MotionEvent.ACTION_DOWN) {
- SysUiStatsLog.write(SysUiStatsLog.IME_TOUCH_REPORTED,
- (int) ev.getX(), (int) ev.getY());
- }
- return shouldDeadZoneConsumeTouchEvents(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- shouldDeadZoneConsumeTouchEvents(ev);
- return false;
- }
-
- private boolean shouldDeadZoneConsumeTouchEvents(MotionEvent event) {
- int action = event.getActionMasked();
- if (action == MotionEvent.ACTION_DOWN) {
- mDeadZoneConsuming = false;
- }
- if (mDeadZone.onTouchEvent(event) || mDeadZoneConsuming) {
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- // Allow gestures starting in the deadzone to be slippery
- mNavigationBarView.setSlippery(true);
- mDeadZoneConsuming = true;
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- // When a gesture started in the deadzone is finished, restore
- // slippery state
- mNavigationBarView.updateSlippery();
- mDeadZoneConsuming = false;
- break;
- }
- return true;
- }
- return false;
- }
- };
-
-
/**
* Injectable factory for construction a {@link NavigationBar}.
*/
- @AssistedFactory
- public interface Factory {
+ public static class Factory {
+ private final Lazy<AssistManager> mAssistManagerLazy;
+ private final AccessibilityManager mAccessibilityManager;
+ private final DeviceProvisionedController mDeviceProvisionedController;
+ private final MetricsLogger mMetricsLogger;
+ private final OverviewProxyService mOverviewProxyService;
+ private final NavigationModeController mNavigationModeController;
+ private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
+ private final StatusBarStateController mStatusBarStateController;
+ private final SysUiState mSysUiFlagsContainer;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final CommandQueue mCommandQueue;
+ private final Optional<Pip> mPipOptional;
+ private final Optional<Recents> mRecentsOptional;
+ private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
+ private final ShadeController mShadeController;
+ private final NotificationRemoteInputManager mNotificationRemoteInputManager;
+ private final NotificationShadeDepthController mNotificationShadeDepthController;
+ private final Handler mMainHandler;
+ private final NavigationBarOverlayController mNavbarOverlayController;
+ private final UiEventLogger mUiEventLogger;
+ private final NavBarHelper mNavBarHelper;
+ private final LightBarController mMainLightBarController;
+ private final LightBarController.Factory mLightBarControllerFactory;
+ private final AutoHideController mMainAutoHideController;
+ private final AutoHideController.Factory mAutoHideControllerFactory;
+ private final Optional<TelecomManager> mTelecomManagerOptional;
+ private final InputMethodManager mInputMethodManager;
+ private final Optional<BackAnimation> mBackAnimation;
+
+ @Inject
+ public Factory(
+ Lazy<AssistManager> assistManagerLazy,
+ AccessibilityManager accessibilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ MetricsLogger metricsLogger,
+ OverviewProxyService overviewProxyService,
+ NavigationModeController navigationModeController,
+ AccessibilityButtonModeObserver accessibilityButtonModeObserver,
+ StatusBarStateController statusBarStateController,
+ SysUiState sysUiFlagsContainer,
+ BroadcastDispatcher broadcastDispatcher,
+ CommandQueue commandQueue,
+ Optional<Pip> pipOptional,
+ Optional<Recents> recentsOptional,
+ Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
+ ShadeController shadeController,
+ NotificationRemoteInputManager notificationRemoteInputManager,
+ NotificationShadeDepthController notificationShadeDepthController,
+ @Main Handler mainHandler,
+ NavigationBarOverlayController navbarOverlayController,
+ UiEventLogger uiEventLogger,
+ NavBarHelper navBarHelper,
+ LightBarController mainLightBarController,
+ LightBarController.Factory lightBarControllerFactory,
+ AutoHideController mainAutoHideController,
+ AutoHideController.Factory autoHideControllerFactory,
+ Optional<TelecomManager> telecomManagerOptional,
+ InputMethodManager inputMethodManager,
+ Optional<BackAnimation> backAnimation) {
+ mAssistManagerLazy = assistManagerLazy;
+ mAccessibilityManager = accessibilityManager;
+ mDeviceProvisionedController = deviceProvisionedController;
+ mMetricsLogger = metricsLogger;
+ mOverviewProxyService = overviewProxyService;
+ mNavigationModeController = navigationModeController;
+ mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
+ mStatusBarStateController = statusBarStateController;
+ mSysUiFlagsContainer = sysUiFlagsContainer;
+ mBroadcastDispatcher = broadcastDispatcher;
+ mCommandQueue = commandQueue;
+ mPipOptional = pipOptional;
+ mRecentsOptional = recentsOptional;
+ mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
+ mShadeController = shadeController;
+ mNotificationRemoteInputManager = notificationRemoteInputManager;
+ mNotificationShadeDepthController = notificationShadeDepthController;
+ mMainHandler = mainHandler;
+ mNavbarOverlayController = navbarOverlayController;
+ mUiEventLogger = uiEventLogger;
+ mNavBarHelper = navBarHelper;
+ mMainLightBarController = mainLightBarController;
+ mLightBarControllerFactory = lightBarControllerFactory;
+ mMainAutoHideController = mainAutoHideController;
+ mAutoHideControllerFactory = autoHideControllerFactory;
+ mTelecomManagerOptional = telecomManagerOptional;
+ mInputMethodManager = inputMethodManager;
+ mBackAnimation = backAnimation;
+ }
+
/** Construct a {@link NavigationBar} */
- NavigationBar create(Context context);
+ public NavigationBar create(Context context) {
+ final WindowManager wm = context.getSystemService(WindowManager.class);
+ return new NavigationBar(context, wm, mAssistManagerLazy,
+ mAccessibilityManager, mDeviceProvisionedController, mMetricsLogger,
+ mOverviewProxyService, mNavigationModeController,
+ mAccessibilityButtonModeObserver, mStatusBarStateController,
+ mSysUiFlagsContainer, mBroadcastDispatcher, mCommandQueue, mPipOptional,
+ mRecentsOptional, mCentralSurfacesOptionalLazy,
+ mShadeController, mNotificationRemoteInputManager,
+ mNotificationShadeDepthController, mMainHandler,
+ mNavbarOverlayController, mUiEventLogger, mNavBarHelper,
+ mMainLightBarController, mLightBarControllerFactory,
+ mMainAutoHideController, mAutoHideControllerFactory, mTelecomManagerOptional,
+ mInputMethodManager, mBackAnimation);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index f5abe28..017bbdf 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -65,7 +65,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
-import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.model.SysUiState;
@@ -85,12 +84,13 @@
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.pip.Pip;
@@ -101,14 +101,15 @@
import java.util.concurrent.Executor;
import java.util.function.Consumer;
-/** */
-public class NavigationBarView extends FrameLayout {
+public class NavigationBarView extends FrameLayout implements
+ NavigationModeController.ModeChangedListener {
final static boolean DEBUG = false;
final static String TAG = "NavBarView";
final static boolean ALTERNATE_CAR_MODE_UI = false;
private final RegionSamplingHelper mRegionSamplingHelper;
private final int mNavColorSampleMargin;
+ private final SysUiState mSysUiFlagContainer;
// The current view is one of mHorizontal or mVertical depending on the current configuration
View mCurrentView = null;
@@ -196,7 +197,6 @@
* <p>Cache the value here for better performance.</p>
*/
private final boolean mImeCanRenderGesturalNavButtons = canImeRenderGesturalNavButtons();
- private Gefingerpoken mTouchHandler;
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
@@ -333,8 +333,10 @@
mDarkIconColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
mIsVertical = false;
mLongClickableAccessibilityButton = false;
+ mNavBarMode = Dependency.get(NavigationModeController.class).addListener(this);
mImeDrawsImeNavBar = Dependency.get(NavigationModeController.class).getImeDrawsImeNavBar();
+ mSysUiFlagContainer = Dependency.get(SysUiState.class);
// Set up the context group of buttons
mContextualButtonGroup = new ContextualButtonGroup(R.id.menu_container);
final ContextualButton imeSwitcherButton = new ContextualButton(R.id.ime_switcher,
@@ -363,6 +365,8 @@
R.drawable.ic_sysbar_rotate_button_cw_start_90,
() -> getDisplay().getRotation());
+ updateRotationButton();
+
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
mConfiguration = new Configuration();
@@ -444,18 +448,19 @@
notifyVerticalChangedListener(mIsVertical);
}
- public void setTouchHandler(Gefingerpoken touchHandler) {
- mTouchHandler = touchHandler;
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- return mTouchHandler.onInterceptTouchEvent(event) || super.onInterceptTouchEvent(event);
+ if (isGesturalMode(mNavBarMode) && mImeVisible
+ && event.getAction() == MotionEvent.ACTION_DOWN) {
+ SysUiStatsLog.write(SysUiStatsLog.IME_TOUCH_REPORTED,
+ (int) event.getX(), (int) event.getY());
+ }
+ return shouldDeadZoneConsumeTouchEvents(event) || super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
- mTouchHandler.onTouchEvent(event);
+ shouldDeadZoneConsumeTouchEvents(event);
return super.onTouchEvent(event);
}
@@ -492,6 +497,30 @@
}
}
+ private boolean shouldDeadZoneConsumeTouchEvents(MotionEvent event) {
+ int action = event.getActionMasked();
+ if (action == MotionEvent.ACTION_DOWN) {
+ mDeadZoneConsuming = false;
+ }
+ if (mDeadZone.onTouchEvent(event) || mDeadZoneConsuming) {
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ // Allow gestures starting in the deadzone to be slippery
+ setSlippery(true);
+ mDeadZoneConsuming = true;
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ // When a gesture started in the deadzone is finished, restore slippery state
+ updateSlippery();
+ mDeadZoneConsuming = false;
+ break;
+ }
+ return true;
+ }
+ return false;
+ }
+
public void abortCurrentGesture() {
getHomeButton().abortCurrentGesture();
}
@@ -560,7 +589,7 @@
return (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) == 0;
}
- private boolean isQuickStepSwipeUpEnabled() {
+ public boolean isQuickStepSwipeUpEnabled() {
return mOverviewProxyService.shouldShowSwipeUpUI() && isOverviewEnabled();
}
@@ -589,7 +618,7 @@
/**
* Updates the rotation button based on the current navigation mode.
*/
- void updateRotationButton() {
+ private void updateRotationButton() {
if (isGesturalMode(mNavBarMode)) {
mContextualButtonGroup.removeButton(R.id.rotate_suggestion);
mButtonDispatchers.remove(R.id.rotate_suggestion);
@@ -693,13 +722,25 @@
super.setLayoutDirection(layoutDirection);
}
- void setNavigationIconHints(int hints) {
+ public void setNavigationIconHints(int hints) {
if (hints == mNavigationIconHints) return;
+ final boolean newBackAlt = (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+ final boolean oldBackAlt =
+ (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+ if (newBackAlt != oldBackAlt) {
+ onImeVisibilityChanged(newBackAlt);
+ }
+
+ if (DEBUG) {
+ android.widget.Toast.makeText(getContext(),
+ "Navigation icon hints = " + hints,
+ 500).show();
+ }
mNavigationIconHints = hints;
updateNavButtonIcons();
}
- void onImeVisibilityChanged(boolean visible) {
+ private void onImeVisibilityChanged(boolean visible) {
if (!visible) {
mTransitionListener.onBackAltCleared();
}
@@ -710,7 +751,7 @@
}
}
- void setDisabledFlags(int disabledFlags, SysUiState sysUiState) {
+ public void setDisabledFlags(int disabledFlags) {
if (mDisabledFlags == disabledFlags) return;
final boolean overviewEnabledBefore = isOverviewEnabled();
@@ -723,7 +764,7 @@
updateNavButtonIcons();
updateSlippery();
- updateDisabledSystemUiStateFlags(sysUiState);
+ updateDisabledSystemUiStateFlags();
}
public void updateNavButtonIcons() {
@@ -866,11 +907,10 @@
updateSlippery();
}
- /** */
- public void updateDisabledSystemUiStateFlags(SysUiState sysUiState) {
+ public void updateDisabledSystemUiStateFlags() {
int displayId = mContext.getDisplayId();
- sysUiState.setFlag(SYSUI_STATE_SCREEN_PINNING,
+ mSysUiFlagContainer.setFlag(SYSUI_STATE_SCREEN_PINNING,
ActivityManagerWrapper.getInstance().isScreenPinningActive())
.setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
(mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0)
@@ -912,12 +952,12 @@
* slippery is enabled, touch events will leave the nav bar window and enter into the fullscreen
* app/home window, if not nav bar will receive a cancelled touch event once gesture leaves bar.
*/
- void updateSlippery() {
+ public void updateSlippery() {
setSlippery(!isQuickStepSwipeUpEnabled() ||
(mPanelView != null && mPanelView.isFullyExpanded() && !mPanelView.isCollapsing()));
}
- void setSlippery(boolean slippery) {
+ private void setSlippery(boolean slippery) {
setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery);
}
@@ -939,7 +979,8 @@
wm.updateViewLayout(navbarView, lp);
}
- void setNavBarMode(int mode) {
+ @Override
+ public void onNavigationModeChanged(int mode) {
mNavBarMode = mode;
mImeDrawsImeNavBar = Dependency.get(NavigationModeController.class).getImeDrawsImeNavBar();
mBarTransitions.onNavigationModeChanged(mNavBarMode);
@@ -1282,6 +1323,7 @@
mEdgeBackGestureHandler.onNavBarAttached();
requestApplyInsets();
reorient();
+ onNavigationModeChanged(mNavBarMode);
if (mRotationButtonController != null) {
mRotationButtonController.registerListeners();
}
@@ -1296,6 +1338,7 @@
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
+ Dependency.get(NavigationModeController.class).removeListener(this);
for (int i = 0; i < mButtonDispatchers.size(); ++i) {
mButtonDispatchers.valueAt(i).onDestroy();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 53a27ff..a3dea1c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -101,8 +101,8 @@
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
import com.android.systemui.statusbar.policy.CallbackController;
import com.android.wm.shell.back.BackAnimation;
@@ -675,7 +675,7 @@
navBarFragment.updateSystemUiStateFlags();
}
if (navBarView != null) {
- navBarView.updateDisabledSystemUiStateFlags(mSysUiState);
+ navBarView.updateDisabledSystemUiStateFlags();
}
if (panelController != null) {
panelController.updateSystemUiStateFlags();
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 be1aa10..27cc326 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
@@ -758,29 +758,30 @@
mDebugTextUsedYPositions.clear();
}
int y = mTopPadding;
- drawDebugInfo(canvas, y, Color.RED, /* label= */ "mTopPadding");
+ drawDebugInfo(canvas, y, Color.RED, /* label= */ "mTopPadding = "+y);
y = getLayoutHeight();
- drawDebugInfo(canvas, y, Color.YELLOW, /* label= */ "getLayoutHeight()");
+ drawDebugInfo(canvas, y, Color.YELLOW, /* label= */ "getLayoutHeight() = "+y);
y = (int) mMaxLayoutHeight;
- drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "mMaxLayoutHeight");
+ drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "mMaxLayoutHeight = "+y);
if (mKeyguardBottomPadding >= 0) {
y = getHeight() - (int) mKeyguardBottomPadding;
drawDebugInfo(canvas, y, Color.GRAY,
- /* label= */ "getHeight() - mKeyguardBottomPadding");
+ /* label= */ "getHeight() - mKeyguardBottomPadding = "+y);
}
y = getHeight() - getEmptyBottomMargin();
- drawDebugInfo(canvas, y, Color.GREEN, /* label= */ "getHeight() - getEmptyBottomMargin()");
+ drawDebugInfo(canvas, y, Color.GREEN,
+ /* label= */ "getHeight() - getEmptyBottomMargin() = "+y);
y = (int) (mAmbientState.getStackY());
- drawDebugInfo(canvas, y, Color.CYAN, /* label= */ "mAmbientState.getStackY()");
+ drawDebugInfo(canvas, y, Color.CYAN, /* label= */ "mAmbientState.getStackY() = "+y);
y = (int) (mAmbientState.getStackY() + mAmbientState.getStackHeight());
drawDebugInfo(canvas, y, Color.BLUE,
- /* label= */ "mAmbientState.getStackY() + mAmbientState.getStackHeight()");
+ /* label= */ "mAmbientState.getStackY() + mAmbientState.getStackHeight() = "+y);
}
private void drawDebugInfo(Canvas canvas, int y, int color, String label) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 952cd9a..e1f8c35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -202,12 +202,10 @@
float newHeight = state.height;
float newNotificationEnd = newYTranslation + newHeight;
boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned();
- final boolean shadeClosedWithHUN =
- ambientState.isShadeOpening() && !ambientState.isShadeExpanded();
if (mClipNotificationScrollToTop
&& (!state.inShelf || (isHeadsUp && !firstHeadsUp))
&& newYTranslation < clipStart
- && shadeClosedWithHUN) {
+ && !ambientState.isShadeExpanded()) {
// The previous view is overlapping on top, clip!
float overlapAmount = clipStart - newYTranslation;
state.clipTopAmount = (int) overlapAmount;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index a0aa267..eb1e1a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -91,10 +91,10 @@
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.utils.leaks.LeakCheckedTest;
@@ -387,14 +387,14 @@
DeviceProvisionedController deviceProvisionedController =
mock(DeviceProvisionedController.class);
when(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
- return spy(new NavigationBar(context,
- mWindowManager,
+ NavigationBar.Factory factory = new NavigationBar.Factory(
() -> mAssistManager,
mock(AccessibilityManager.class),
deviceProvisionedController,
new MetricsLogger(),
mOverviewProxyService,
mNavigationModeController,
+ mock(AccessibilityButtonModeObserver.class),
mStatusBarStateController,
mMockSysUiState,
mBroadcastDispatcher,
@@ -415,7 +415,8 @@
mAutoHideControllerFactory,
Optional.of(mTelecomManager),
mInputMethodManager,
- Optional.of(mock(BackAnimation.class))));
+ Optional.of(mock(BackAnimation.class)));
+ return spy(factory.create(context));
}
private void processAllMessages() {
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index be2b7f7..f1fa982 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -131,7 +131,7 @@
final UserManager userManager = context.getSystemService(UserManager.class);
final int result = userManager.removeUserWhenPossible(
UserHandle.of(userId), /* overrideDevicePolicy= */ false);
- if (result == UserManager.REMOVE_RESULT_ERROR) {
+ if (!UserManager.isRemoveResultSuccessful(result)) {
Slogf.e(TAG, "Can't remove user %d", userId);
return false;
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 7765ab3..9ae6750 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -136,8 +136,8 @@
try {
if (mSensorPrivacyManager != null
&& mSensorPrivacyManager
- .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
- getTargetUserId())) {
+ .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+ SensorPrivacyManager.Sensors.CAMERA)) {
onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
index efedcf8..ded1810 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
@@ -96,7 +96,8 @@
protected void startHalOperation() {
if (mSensorPrivacyManager != null
&& mSensorPrivacyManager
- .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, getTargetUserId())) {
+ .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+ SensorPrivacyManager.Sensors.CAMERA)) {
onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
return;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
index 8d76e9f..1935a5b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
@@ -109,7 +109,8 @@
if (mSensorPrivacyManager != null
&& mSensorPrivacyManager
- .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, getTargetUserId())) {
+ .isSensorPrivacyEnabled(SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE,
+ SensorPrivacyManager.Sensors.CAMERA)) {
onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
return;
diff --git a/services/core/java/com/android/server/pm/AppIdSettingMap.java b/services/core/java/com/android/server/pm/AppIdSettingMap.java
index bbef237..b41a0b8 100644
--- a/services/core/java/com/android/server/pm/AppIdSettingMap.java
+++ b/services/core/java/com/android/server/pm/AppIdSettingMap.java
@@ -17,46 +17,131 @@
package com.android.server.pm;
import android.os.Process;
+import android.util.Log;
+import com.android.server.utils.WatchedArrayList;
import com.android.server.utils.WatchedSparseArray;
+import com.android.server.utils.Watcher;
/**
- * A wrapper over {@link WatchedSparseArray} that tracks the current maximum App ID.
+ * A wrapper over {@link WatchedArrayList} that tracks the current (app ID -> SettingBase) mapping
+ * for non-system apps. Also tracks system app settings in an {@link WatchedSparseArray}.
*/
-public class AppIdSettingMap extends WatchedSparseArray<SettingBase> {
- private int mCurrentMaxAppId;
+final class AppIdSettingMap {
+ /**
+ * We use an ArrayList instead of an SparseArray for non system apps because the number of apps
+ * might be big, and only ArrayList gives us a constant lookup time. For a given app ID, the
+ * index to the corresponding SettingBase object is (appId - FIRST_APPLICATION_ID). If an app ID
+ * doesn't exist (i.e., app is not installed), we fill the corresponding entry with null.
+ */
+ private WatchedArrayList<SettingBase> mNonSystemSettings = new WatchedArrayList<>();
+ private WatchedSparseArray<SettingBase> mSystemSettings = new WatchedSparseArray<>();
+ private int mFirstAvailableAppId = Process.FIRST_APPLICATION_UID;
- @Override
- public void put(int key, SettingBase value) {
- if (key > mCurrentMaxAppId) {
- mCurrentMaxAppId = key;
+ /** Returns true if the requested AppID was valid and not already registered. */
+ public boolean registerExistingAppId(int appId, SettingBase setting, Object name) {
+ if (appId >= Process.FIRST_APPLICATION_UID) {
+ int size = mNonSystemSettings.size();
+ final int index = appId - Process.FIRST_APPLICATION_UID;
+ // fill the array until our index becomes valid
+ while (index >= size) {
+ mNonSystemSettings.add(null);
+ size++;
+ }
+ if (mNonSystemSettings.get(index) != null) {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Adding duplicate app id: " + appId
+ + " name=" + name);
+ return false;
+ }
+ mNonSystemSettings.set(index, setting);
+ } else {
+ if (mSystemSettings.get(appId) != null) {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Adding duplicate shared id: " + appId
+ + " name=" + name);
+ return false;
+ }
+ mSystemSettings.put(appId, setting);
}
- super.put(key, value);
+ return true;
}
- @Override
+ public SettingBase getSetting(int appId) {
+ if (appId >= Process.FIRST_APPLICATION_UID) {
+ final int size = mNonSystemSettings.size();
+ final int index = appId - Process.FIRST_APPLICATION_UID;
+ return index < size ? mNonSystemSettings.get(index) : null;
+ } else {
+ return mSystemSettings.get(appId);
+ }
+ }
+
+ public void removeSetting(int appId) {
+ if (appId >= Process.FIRST_APPLICATION_UID) {
+ final int size = mNonSystemSettings.size();
+ final int index = appId - Process.FIRST_APPLICATION_UID;
+ if (index < size) {
+ mNonSystemSettings.set(index, null);
+ }
+ } else {
+ mSystemSettings.remove(appId);
+ }
+ setFirstAvailableAppId(appId + 1);
+ }
+
+ // This should be called (at least) whenever an application is removed
+ private void setFirstAvailableAppId(int uid) {
+ if (uid > mFirstAvailableAppId) {
+ mFirstAvailableAppId = uid;
+ }
+ }
+
+ public void replaceSetting(int appId, SettingBase setting) {
+ if (appId >= Process.FIRST_APPLICATION_UID) {
+ final int size = mNonSystemSettings.size();
+ final int index = appId - Process.FIRST_APPLICATION_UID;
+ if (index < size) {
+ mNonSystemSettings.set(index, setting);
+ } else {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Error in package manager settings: calling replaceAppIdLpw to"
+ + " replace SettingBase at appId=" + appId
+ + " but nothing is replaced.");
+ }
+ } else {
+ mSystemSettings.put(appId, setting);
+ }
+ }
+
+ /** Returns a new AppID or -1 if we could not find an available AppID to assign */
+ public int acquireAndRegisterNewAppId(SettingBase obj) {
+ final int size = mNonSystemSettings.size();
+ for (int i = mFirstAvailableAppId - Process.FIRST_APPLICATION_UID; i < size; i++) {
+ if (mNonSystemSettings.get(i) == null) {
+ mNonSystemSettings.set(i, obj);
+ return Process.FIRST_APPLICATION_UID + i;
+ }
+ }
+
+ // None left?
+ if (size > (Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID)) {
+ return -1;
+ }
+
+ mNonSystemSettings.add(obj);
+ return Process.FIRST_APPLICATION_UID + size;
+ }
+
public AppIdSettingMap snapshot() {
AppIdSettingMap l = new AppIdSettingMap();
- snapshot(l, this);
+ mNonSystemSettings.snapshot(l.mNonSystemSettings, mNonSystemSettings);
+ mSystemSettings.snapshot(l.mSystemSettings, mSystemSettings);
return l;
}
- /**
- * @return the maximum of all the App IDs that have been added to the map. 0 if map is empty.
- */
- public int getCurrentMaxAppId() {
- return mCurrentMaxAppId;
- }
-
- /**
- * @return the next available App ID that has not been added to the map
- */
- public int getNextAvailableAppId() {
- if (mCurrentMaxAppId == 0) {
- // No app id has been added yet
- return Process.FIRST_APPLICATION_UID;
- } else {
- return mCurrentMaxAppId + 1;
- }
+ public void registerObserver(Watcher observer) {
+ mNonSystemSettings.registerObserver(observer);
+ mSystemSettings.registerObserver(observer);
}
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6ccaae1..698dbe9 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -62,7 +62,6 @@
import android.os.Message;
import android.os.PatternMatcher;
import android.os.PersistableBundle;
-import android.os.Process;
import android.os.SELinux;
import android.os.SystemClock;
import android.os.Trace;
@@ -408,8 +407,6 @@
int[] excludedUserIds;
}
- private static int mFirstAvailableUid = Process.FIRST_APPLICATION_UID;
-
/** Map from volume UUID to {@link VersionInfo} */
@Watched
private final WatchedArrayMap<String, VersionInfo> mVersion = new WatchedArrayMap<>();
@@ -472,10 +469,8 @@
@Watched
final WatchedArrayMap<String, SharedUserSetting> mSharedUsers = new WatchedArrayMap<>();
- @Watched
+ @Watched(manual = true)
private final AppIdSettingMap mAppIds;
- @Watched
- private final AppIdSettingMap mOtherAppIds;
// For reading/writing settings file.
@Watched
@@ -565,7 +560,6 @@
mCrossProfileIntentResolvers.registerObserver(mObserver);
mSharedUsers.registerObserver(mObserver);
mAppIds.registerObserver(mObserver);
- mOtherAppIds.registerObserver(mObserver);
mRenamedPackages.registerObserver(mObserver);
mNextAppLinkGeneration.registerObserver(mObserver);
mDefaultBrowserApp.registerObserver(mObserver);
@@ -592,7 +586,6 @@
mLock = new PackageManagerTracedLock();
mPackages.putAll(pkgSettings);
mAppIds = new AppIdSettingMap();
- mOtherAppIds = new AppIdSettingMap();
mSystemDir = null;
mPermissions = null;
mRuntimePermissionsPersistence = null;
@@ -629,7 +622,6 @@
mLock = lock;
mAppIds = new AppIdSettingMap();
- mOtherAppIds = new AppIdSettingMap();
mPermissions = new LegacyPermissionSettings(lock);
mRuntimePermissionsPersistence = new RuntimePermissionPersistence(
runtimePermissionsPersistence, new Consumer<Integer>() {
@@ -710,7 +702,6 @@
mCrossProfileIntentResolvers, r.mCrossProfileIntentResolvers);
mSharedUsers.snapshot(r.mSharedUsers);
mAppIds = r.mAppIds.snapshot();
- mOtherAppIds = r.mOtherAppIds.snapshot();
WatchedArrayList.snapshot(
mPastSignatures, r.mPastSignatures);
WatchedArrayMap.snapshot(
@@ -782,7 +773,7 @@
SharedUserSetting s = mSharedUsers.get(name);
if (s == null && create) {
s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
- s.mAppId = acquireAndRegisterNewAppIdLPw(s);
+ s.mAppId = mAppIds.acquireAndRegisterNewAppId(s);
if (s.mAppId < 0) {
// < 0 means we couldn't assign a userid; throw exception
throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
@@ -890,7 +881,7 @@
pkgPrivateFlags, 0 /*userId*/, usesSdkLibraries, usesSdkLibrariesVersions,
usesStaticLibraries, usesStaticLibrariesVersions, mimeGroups, domainSetId);
p.setAppId(uid);
- if (registerExistingAppIdLPw(uid, p, name)) {
+ if (mAppIds.registerExistingAppId(uid, p, name)) {
mPackages.put(name, p);
return p;
}
@@ -909,7 +900,7 @@
}
s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
s.mAppId = uid;
- if (registerExistingAppIdLPw(uid, s, name)) {
+ if (mAppIds.registerExistingAppId(uid, s, name)) {
mSharedUsers.put(name, s);
return s;
}
@@ -1210,11 +1201,11 @@
final boolean createdNew;
if (p.getAppId() == 0 || forceNew) {
// Assign new user ID
- p.setAppId(acquireAndRegisterNewAppIdLPw(p));
+ p.setAppId(mAppIds.acquireAndRegisterNewAppId(p));
createdNew = true;
} else {
// Add new setting to list of user IDs
- createdNew = registerExistingAppIdLPw(p.getAppId(), p, p.getPackageName());
+ createdNew = mAppIds.registerExistingAppId(p.getAppId(), p, p.getPackageName());
}
if (p.getAppId() < 0) {
PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -1304,11 +1295,11 @@
Object userIdPs = getSettingLPr(p.getAppId());
if (sharedUser == null) {
if (userIdPs != null && userIdPs != p) {
- replaceAppIdLPw(p.getAppId(), p);
+ mAppIds.replaceSetting(p.getAppId(), p);
}
} else {
if (userIdPs != null && userIdPs != sharedUser) {
- replaceAppIdLPw(p.getAppId(), sharedUser);
+ mAppIds.replaceSetting(p.getAppId(), sharedUser);
}
}
}
@@ -1357,73 +1348,22 @@
mInstallerPackages.remove(packageName);
}
- /** Returns true if the requested AppID was valid and not already registered. */
- private boolean registerExistingAppIdLPw(int appId, SettingBase obj, Object name) {
- if (appId > Process.LAST_APPLICATION_UID) {
- return false;
- }
-
- if (appId >= Process.FIRST_APPLICATION_UID) {
- if (mAppIds.get(appId) != null) {
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "Adding duplicate app id: " + appId
- + " name=" + name);
- return false;
- }
- mAppIds.put(appId, obj);
- } else {
- if (mOtherAppIds.get(appId) != null) {
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "Adding duplicate shared id: " + appId
- + " name=" + name);
- return false;
- }
- mOtherAppIds.put(appId, obj);
- }
- return true;
- }
-
/** Gets the setting associated with the provided App ID */
public SettingBase getSettingLPr(int appId) {
- if (appId >= Process.FIRST_APPLICATION_UID) {
- return mAppIds.get(appId);
- } else {
- return mOtherAppIds.get(appId);
- }
+ return mAppIds.getSetting(appId);
}
/** Unregisters the provided app ID. */
void removeAppIdLPw(int appId) {
- if (appId >= Process.FIRST_APPLICATION_UID) {
- mAppIds.remove(appId);
- } else {
- mOtherAppIds.remove(appId);
- }
- setFirstAvailableUid(appId + 1);
+ mAppIds.removeSetting(appId);
}
-
- private void replaceAppIdLPw(int appId, SettingBase obj) {
- if (appId >= Process.FIRST_APPLICATION_UID) {
- if (appId <= mAppIds.getCurrentMaxAppId()) {
- mAppIds.put(appId, obj);
- } else {
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "Error in package manager settings: calling replaceAppIdLpw to"
- + " replace SettingBase at appId=" + appId
- + " but nothing is replaced.");
- }
- } else {
- mOtherAppIds.put(appId, obj);
- }
- }
-
/**
* Transparently convert a SharedUserSetting into PackageSettings without changing appId.
* The sharedUser passed to this method has to be {@link SharedUserSetting#isSingleUser()}.
*/
void convertSharedUserSettingsLPw(SharedUserSetting sharedUser) {
final PackageSetting ps = sharedUser.getPackageSettings().valueAt(0);
- replaceAppIdLPw(sharedUser.getAppId(), ps);
+ mAppIds.replaceSetting(sharedUser.getAppId(), ps);
// Unlink the SharedUserSetting
ps.setSharedUserAppId(INVALID_UID);
@@ -4287,32 +4227,6 @@
}
}
- // This should be called (at least) whenever an application is removed
- private void setFirstAvailableUid(int uid) {
- if (uid > mFirstAvailableUid) {
- mFirstAvailableUid = uid;
- }
- }
-
- /** Returns a new AppID or -1 if we could not find an available AppID to assign */
- private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
- final int nextAvailableAppId = mAppIds.getNextAvailableAppId();
- for (int uid = mFirstAvailableUid; uid < nextAvailableAppId; uid++) {
- if (mAppIds.get(uid) == null) {
- mAppIds.put(uid, obj);
- return uid;
- }
- }
-
- // None left?
- if (nextAvailableAppId > Process.LAST_APPLICATION_UID) {
- return -1;
- }
-
- mAppIds.put(nextAvailableAppId, obj);
- return nextAvailableAppId;
- }
-
public VerifierDeviceIdentity getVerifierDeviceIdentityLPw(@NonNull Computer computer) {
if (mVerifierDeviceIdentity == null) {
mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index eae7658..34b7ad4 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -4638,12 +4638,12 @@
final String restriction = getUserRemovalRestriction(userId);
if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) {
Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
- return UserManager.REMOVE_RESULT_ERROR;
+ return UserManager.REMOVE_RESULT_ERROR_USER_RESTRICTION;
}
}
if (userId == UserHandle.USER_SYSTEM) {
Slog.e(LOG_TAG, "System user cannot be removed.");
- return UserManager.REMOVE_RESULT_ERROR;
+ return UserManager.REMOVE_RESULT_ERROR_SYSTEM_USER;
}
final long ident = Binder.clearCallingIdentity();
@@ -4655,7 +4655,7 @@
if (userData == null) {
Slog.e(LOG_TAG,
"Cannot remove user " + userId + ", invalid user id provided.");
- return UserManager.REMOVE_RESULT_ERROR;
+ return UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND;
}
if (mRemovingUserIds.get(userId)) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index f05658b..e096687 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -494,9 +494,9 @@
final ArgumentCaptor<AlarmManagerService.UninstallReceiver> packageReceiverCaptor =
ArgumentCaptor.forClass(AlarmManagerService.UninstallReceiver.class);
- verify(mMockContext).registerReceiver(packageReceiverCaptor.capture(),
+ verify(mMockContext).registerReceiverForAllUsers(packageReceiverCaptor.capture(),
argThat((filter) -> filter.hasAction(Intent.ACTION_PACKAGE_ADDED)
- && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)));
+ && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)), isNull(), isNull());
mPackageChangesReceiver = packageReceiverCaptor.getValue();
assertEquals(mService.mExactAlarmCandidates, Collections.emptySet());
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
index 41d46f2..534d0a1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
@@ -21,7 +21,6 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import android.app.AlarmManager;
import android.content.Context;
@@ -71,10 +70,10 @@
.strictness(Strictness.LENIENT)
.mockStatic(LocalServices.class)
.startMocking();
- when(mIrs.getContext()).thenReturn(mContext);
- when(mIrs.getCompleteEconomicPolicyLocked()).thenReturn(mEconomicPolicy);
- when(mIrs.getLock()).thenReturn(mIrs);
- when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mock(AlarmManager.class));
+ doReturn(mContext).when(mIrs).getContext();
+ doReturn(mEconomicPolicy).when(mIrs).getCompleteEconomicPolicyLocked();
+ doReturn(mIrs).when(mIrs).getLock();
+ doReturn(mock(AlarmManager.class)).when(mContext).getSystemService(Context.ALARM_SERVICE);
mScribe = new MockScribe(mIrs);
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 1f016fb..56c5150 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -28,6 +28,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -61,10 +63,12 @@
import androidx.test.filters.SmallTest;
import com.android.compatibility.common.util.TestUtils;
+import com.android.internal.compat.IPlatformCompat;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
import com.android.server.accessibility.magnification.MagnificationController;
+import com.android.server.accessibility.magnification.MagnificationProcessor;
import com.android.server.accessibility.magnification.WindowMagnificationManager;
import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.pm.UserManagerInternal;
@@ -185,7 +189,7 @@
mA11yms.mUserStates.put(mA11yms.getCurrentUserIdLocked(), userState);
}
- private void setupAccessibilityServiceConnection() {
+ private void setupAccessibilityServiceConnection(int serviceInfoFlag) {
final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked());
when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
@@ -193,7 +197,12 @@
mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
when(mMockBinder.queryLocalInterface(any())).thenReturn(mMockServiceClient);
+ when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mock(KeyEventDispatcher.class));
+ when(mMockSystemSupport.getMagnificationProcessor()).thenReturn(
+ mock(MagnificationProcessor.class));
mTestableContext.addMockService(COMPONENT_NAME, mMockBinder);
+
+ mMockServiceInfo.flags = serviceInfoFlag;
mAccessibilityServiceConnection = new AccessibilityServiceConnection(
userState,
mTestableContext,
@@ -256,7 +265,7 @@
@SmallTest
@Test
public void testOnSystemActionsChanged() throws Exception {
- setupAccessibilityServiceConnection();
+ setupAccessibilityServiceConnection(0);
final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked());
@@ -376,7 +385,7 @@
@SmallTest
@Test
public void testOnClientChange_boundServiceCanControlMagnification_requestConnection() {
- setupAccessibilityServiceConnection();
+ setupAccessibilityServiceConnection(0);
when(mMockSecurityPolicy.canControlMagnification(any())).thenReturn(true);
// Invokes client change to trigger onUserStateChanged.
@@ -385,6 +394,29 @@
verify(mMockWindowMagnificationMgr).requestConnection(true);
}
+ @Test
+ public void testUnbindIme_whenServiceUnbinds() {
+ setupAccessibilityServiceConnection(AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR);
+ mAccessibilityServiceConnection.unbindLocked();
+ verify(mMockSystemSupport, atLeastOnce()).unbindImeLocked(mAccessibilityServiceConnection);
+ }
+
+ @Test
+ public void testUnbindIme_whenServiceCrashed() {
+ setupAccessibilityServiceConnection(AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR);
+ mAccessibilityServiceConnection.binderDied();
+ verify(mMockSystemSupport).unbindImeLocked(mAccessibilityServiceConnection);
+ }
+
+ @Test
+ public void testUnbindIme_whenServiceStopsRequestingIme() {
+ setupAccessibilityServiceConnection(AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR);
+ doCallRealMethod().when(mMockServiceInfo).updateDynamicallyConfigurableProperties(
+ any(IPlatformCompat.class), any(AccessibilityServiceInfo.class));
+ mAccessibilityServiceConnection.setServiceInfo(new AccessibilityServiceInfo());
+ verify(mMockSystemSupport).unbindImeLocked(mAccessibilityServiceConnection);
+ }
+
public static class FakeInputFilter extends AccessibilityInputFilter {
FakeInputFilter(Context context,
AccessibilityManagerService service) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index c7b5547..06b7112 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -316,7 +316,8 @@
asHandle(currentUser));
try {
assertThat(mUserManager.removeUserWhenPossible(user1.getUserHandle(),
- /* overrideDevicePolicy= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
+ /* overrideDevicePolicy= */ false))
+ .isEqualTo(UserManager.REMOVE_RESULT_ERROR_USER_RESTRICTION);
} finally {
mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ false,
asHandle(currentUser));
@@ -353,7 +354,8 @@
@Test
public void testRemoveUserWhenPossible_systemUserReturnsError() throws Exception {
assertThat(mUserManager.removeUserWhenPossible(UserHandle.SYSTEM,
- /* overrideDevicePolicy= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
+ /* overrideDevicePolicy= */ false))
+ .isEqualTo(UserManager.REMOVE_RESULT_ERROR_SYSTEM_USER);
assertThat(hasUser(UserHandle.USER_SYSTEM)).isTrue();
}
@@ -363,7 +365,8 @@
public void testRemoveUserWhenPossible_invalidUserReturnsError() throws Exception {
assertThat(hasUser(Integer.MAX_VALUE)).isFalse();
assertThat(mUserManager.removeUserWhenPossible(UserHandle.of(Integer.MAX_VALUE),
- /* overrideDevicePolicy= */ false)).isEqualTo(UserManager.REMOVE_RESULT_ERROR);
+ /* overrideDevicePolicy= */ false))
+ .isEqualTo(UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND);
}
@MediumTest
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index 3a3b363..d2a4c3e 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1090,6 +1090,13 @@
*/
public static final int NO_RETRY_FAILURE = 0x1000B;
+ /**
+ * Traffic descriptors in DataCallResponse is empty.
+ *
+ * @hide
+ */
+ public static final int NO_TRAFFIC_DESCRIPTORS = 0x1000C;
+
private static final Map<Integer, String> sFailCauseMap;
static {
sFailCauseMap = new HashMap<>();
@@ -1524,6 +1531,7 @@
sFailCauseMap.put(SERVICE_TEMPORARILY_UNAVAILABLE, "SERVICE_TEMPORARILY_UNAVAILABLE");
sFailCauseMap.put(REQUEST_NOT_SUPPORTED, "REQUEST_NOT_SUPPORTED");
sFailCauseMap.put(NO_RETRY_FAILURE, "NO_RETRY_FAILURE");
+ sFailCauseMap.put(NO_TRAFFIC_DESCRIPTORS, "NO_TRAFFIC_DESCRIPTORS");
}
private DataFailCause() {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5ef22de..3f430ab 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8352,24 +8352,6 @@
}
/**
- * Get P-CSCF address from PCO after data connection is established or modified.
- * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
- * @return array of P-CSCF address
- * @hide
- */
- public String[] getPcscfAddress(String apnType) {
- try {
- ITelephony telephony = getITelephony();
- if (telephony == null)
- return new String[0];
- return telephony.getPcscfAddress(apnType, getOpPackageName(), getAttributionTag());
- } catch (RemoteException e) {
- return new String[0];
- }
- }
-
-
- /**
* Resets the {@link android.telephony.ims.ImsService} associated with the specified sim slot.
* Used by diagnostic apps to force the IMS stack to be disabled and re-enabled in an effort to
* recover from scenarios where the {@link android.telephony.ims.ImsService} gets in to a bad
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index dc96b35..a5e2c1f 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -978,14 +978,6 @@
boolean isManualNetworkSelectionAllowed(int subId);
/**
- * Get P-CSCF address from PCO after data connection is established or modified.
- * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
- * @param callingPackage The package making the call.
- * @param callingFeatureId The feature in the package.
- */
- String[] getPcscfAddress(String apnType, String callingPackage, String callingFeatureId);
-
- /**
* Set IMS registration state
*/
void setImsRegistrationState(boolean registered);
diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp
index 0423b7a..ff24d16 100644
--- a/tools/validatekeymaps/Android.bp
+++ b/tools/validatekeymaps/Android.bp
@@ -32,7 +32,7 @@
"libui-types",
],
target: {
- linux_glibc: {
+ host_linux: {
static_libs: [
// libbinder is only available for linux
"libbinder",