diff options
179 files changed, 2733 insertions, 1476 deletions
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 4e31e44d6e75..e686a89accef 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -1397,7 +1397,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio if (mStartTime < 0) { // First frame. If there is start delay, start delay count down will happen *after* this // frame. - mStartTime = mReversing ? frameTime : frameTime + mStartDelay; + mStartTime = mReversing ? frameTime : frameTime + (long) (mStartDelay * sDurationScale); } // Handle pause/resume diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index b439c1dc02c4..b360c82374d0 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6142,6 +6142,7 @@ public class Activity extends ContextThemeWrapper * * @param action the action to run on the UI thread */ + @Override public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 1ee97eb7cb30..369968f3c33b 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1152,8 +1152,12 @@ public class ActivityManager { * E.g. freeform, split-screen, picture-in-picture. * @hide */ - static public boolean supportsMultiWindow() { - return !isLowRamDeviceStatic() + static public boolean supportsMultiWindow(Context context) { + // On watches, multi-window is used to present essential system UI, and thus it must be + // supported regardless of device memory characteristics. + boolean isWatch = context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WATCH); + return (!isLowRamDeviceStatic() || isWatch) && Resources.getSystem().getBoolean( com.android.internal.R.bool.config_supportsMultiWindow); } @@ -1162,8 +1166,8 @@ public class ActivityManager { * Returns true if the system supports split screen multi-window. * @hide */ - static public boolean supportsSplitScreenMultiWindow() { - return supportsMultiWindow() + static public boolean supportsSplitScreenMultiWindow(Context context) { + return supportsMultiWindow(context) && Resources.getSystem().getBoolean( com.android.internal.R.bool.config_supportsSplitScreenMultiWindow); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c626ae9630b8..31f52dbea548 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1168,7 +1168,7 @@ public class Notification implements Parcelable */ public static final int GROUP_ALERT_CHILDREN = 2; - private int mGroupAlertBehavior = GROUP_ALERT_ALL; + private int mGroupAlertBehavior = GROUP_ALERT_CHILDREN; /** * If this notification is being shown as a badge, always show as a number. diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java index 8a4f8a626c71..0f006b6618b3 100644 --- a/core/java/android/app/TimePickerDialog.java +++ b/core/java/android/app/TimePickerDialog.java @@ -151,10 +151,7 @@ public class TimePickerDialog extends AlertDialog implements OnClickListener, @Override public void onClick(View view) { if (mTimePicker.validateInput()) { - if (mTimeSetListener != null) { - mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(), - mTimePicker.getCurrentMinute()); - } + TimePickerDialog.this.onClick(TimePickerDialog.this, BUTTON_POSITIVE); dismiss(); } } diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 499d6bbdf535..ecc4dec47af7 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -162,6 +162,11 @@ public abstract class BatteryStats implements Parcelable { public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20; /** + * A constant indicating a bluetooth scan timer for unoptimized scans. + */ + public static final int BLUETOOTH_UNOPTIMIZED_SCAN_ON = 21; + + /** * Include all of the data in the stats, including previously saved data. */ public static final int STATS_SINCE_CHARGED = 0; @@ -191,8 +196,12 @@ public abstract class BatteryStats implements Parcelable { * New in version 21: * - Actual (not just apportioned) Wakelock time is also recorded. * - Aggregated partial wakelock time (per uid, instead of per wakelock) is recorded. + * - BLE scan result count + * - CPU frequency time per uid + * New in version 22: + * - BLE scan result background count, BLE unoptimized scan time */ - static final String CHECKIN_VERSION = "21"; + static final String CHECKIN_VERSION = "22"; /** * Old version, we hit 9 and ran out of room, need to remove. @@ -217,9 +226,10 @@ public abstract class BatteryStats implements Parcelable { private static final String STATE_TIME_DATA = "st"; // wl line is: // BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name, - // full totalTime, 'f', count, current duration, max duration, total duration, - // partial totalTime, 'p', count, current duration, max duration, total duration, - // window totalTime, 'w', count, current duration, max duration, total duration + // full totalTime, 'f', count, current duration, max duration, total duration, + // partial totalTime, 'p', count, current duration, max duration, total duration, + // bg partial totalTime, 'bp', count, current duration, max duration, total duration, + // window totalTime, 'w', count, current duration, max duration, total duration // [Currently, full and window wakelocks have durations current = max = total = -1] private static final String WAKELOCK_DATA = "wl"; // awl line is: @@ -565,7 +575,10 @@ public abstract class BatteryStats implements Parcelable { public abstract Timer getForegroundActivityTimer(); public abstract Timer getBluetoothScanTimer(); public abstract Timer getBluetoothScanBackgroundTimer(); + public abstract Timer getBluetoothUnoptimizedScanTimer(); + public abstract Timer getBluetoothUnoptimizedScanBackgroundTimer(); public abstract Counter getBluetoothScanResultCounter(); + public abstract Counter getBluetoothScanResultBgCounter(); public abstract long[] getCpuFreqTimes(int which); public abstract long[] getScreenOffCpuFreqTimes(int which); @@ -3429,10 +3442,29 @@ public abstract class BatteryStats implements Parcelable { final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs); final long actualTimeBg = bleTimerBg != null ? bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0; + // Result counters final int resultCount = u.getBluetoothScanResultCounter() != null ? u.getBluetoothScanResultCounter().getCountLocked(which) : 0; + final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ? + u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0; + // Unoptimized scan timer. Unpooled and since reset (regardless of 'which'). + final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer(); + final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ? + unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0; + final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ? + unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0; + // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which'). + final Timer unoptimizedScanTimerBg = + u.getBluetoothUnoptimizedScanBackgroundTimer(); + final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ? + unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0; + final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ? + unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0; + dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count, - countBg, actualTime, actualTimeBg, resultCount); + countBg, actualTime, actualTimeBg, resultCount, resultCountBg, + unoptimizedScanTotalTime, unoptimizedScanTotalTimeBg, + unoptimizedScanMaxTime, unoptimizedScanMaxTimeBg); } } @@ -3469,8 +3501,11 @@ public abstract class BatteryStats implements Parcelable { sb.setLength(0); linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, "f", which, linePrefix); - linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), + final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); + linePrefix = printWakeLockCheckin(sb, pTimer, rawRealtime, "p", which, linePrefix); + linePrefix = printWakeLockCheckin(sb, pTimer != null ? pTimer.getSubTimer() : null, + rawRealtime, "bp", which, linePrefix); linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "w", which, linePrefix); @@ -4625,34 +4660,94 @@ public abstract class BatteryStats implements Parcelable { final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs); final long actualTimeMsBg = bleTimerBg != null ? bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0; + // Result counters final int resultCount = u.getBluetoothScanResultCounter() != null ? u.getBluetoothScanResultCounter().getCountLocked(which) : 0; + final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ? + u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0; + // Unoptimized scan timer. Unpooled and since reset (regardless of 'which'). + final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer(); + final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ? + unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0; + final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ? + unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0; + // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which'). + final Timer unoptimizedScanTimerBg = + u.getBluetoothUnoptimizedScanBackgroundTimer(); + final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ? + unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0; + final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ? + unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0; sb.setLength(0); - sb.append(prefix); - sb.append(" "); - sb.append("Bluetooth Scan"); - sb.append(": "); if (actualTimeMs != totalTimeMs) { + sb.append(prefix); + sb.append(" Bluetooth Scan (total blamed realtime): "); formatTimeMs(sb, totalTimeMs); - sb.append("blamed realtime, "); + sb.append(" ("); + sb.append(count); + sb.append(" times)"); + if (bleTimer.isRunningLocked()) { + sb.append(" (currently running)"); + } + sb.append("\n"); } - formatTimeMs(sb, actualTimeMs); // since reset, regardless of 'which' - sb.append("realtime ("); + + sb.append(prefix); + sb.append(" Bluetooth Scan (total actual realtime): "); + formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which' + sb.append(" ("); sb.append(count); sb.append(" times)"); if (bleTimer.isRunningLocked()) { - sb.append(" (running)"); + sb.append(" (currently running)"); } - if (actualTimeMsBg != 0 || countBg > 0) { - sb.append(", "); - formatTimeMs(sb, actualTimeMsBg); // since reset, regardless of 'which' - sb.append("background ("); + sb.append("\n"); + if (actualTimeMsBg > 0 || countBg > 0) { + sb.append(prefix); + sb.append(" Bluetooth Scan (background realtime): "); + formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which' + sb.append(" ("); sb.append(countBg); sb.append(" times)"); + if (bleTimerBg != null && bleTimerBg.isRunningLocked()) { + sb.append(" (currently running in background)"); + } + sb.append("\n"); } - sb.append("; Results count "); + + sb.append(prefix); + sb.append(" Bluetooth Scan Results: "); sb.append(resultCount); + sb.append(" ("); + sb.append(resultCountBg); + sb.append(" in background)"); + + if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) { + sb.append("\n"); + sb.append(prefix); + sb.append(" Unoptimized Bluetooth Scan (realtime): "); + formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which' + sb.append(" (max "); + formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which' + sb.append(")"); + if (unoptimizedScanTimer != null + && unoptimizedScanTimer.isRunningLocked()) { + sb.append(" (currently running unoptimized)"); + } + if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) { + sb.append("\n"); + sb.append(prefix); + sb.append(" Unoptimized Bluetooth Scan (background realtime): "); + formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset + sb.append(" (max "); + formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset + sb.append(")"); + if (unoptimizedScanTimerBg.isRunningLocked()) { + sb.append(" (currently running unoptimized in background)"); + } + } + } pw.println(sb.toString()); uidActivity = true; } @@ -4696,8 +4791,11 @@ public abstract class BatteryStats implements Parcelable { sb.append(wakelocks.keyAt(iw)); linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime, "full", which, linePrefix); - linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime, + final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL); + linePrefix = printWakeLock(sb, pTimer, rawRealtime, "partial", which, linePrefix); + linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null, + rawRealtime, "background partial", which, linePrefix); linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "window", which, linePrefix); linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime, diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index a2aff931ccff..02ecc501ea39 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -258,6 +258,11 @@ public final class AutofillManager { * @return The view, or {@code null} if not found */ @Nullable View findViewByAccessibilityIdTraversal(int viewId); + + /** + * Runs the specified action on the UI thread. + */ + void runOnUiThread(Runnable action); } /** @@ -1233,6 +1238,15 @@ public final class AutofillManager { return mService != null; } + private void post(Runnable runnable) { + final AutofillClient client = getClientLocked(); + if (client == null) { + if (sVerbose) Log.v(TAG, "ignoring post() because client is null"); + return; + } + client.runOnUiThread(runnable); + } + /** * View tracking information. Once all tracked views become invisible the session is finished. */ @@ -1516,8 +1530,7 @@ public final class AutofillManager { public void setState(boolean enabled, boolean resetSession, boolean resetClient) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post( - () -> afm.setState(enabled, resetSession, resetClient)); + afm.post(() -> afm.setState(enabled, resetSession, resetClient)); } } @@ -1525,8 +1538,7 @@ public final class AutofillManager { public void autofill(int sessionId, List<AutofillId> ids, List<AutofillValue> values) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post( - () -> afm.autofill(sessionId, ids, values)); + afm.post(() -> afm.autofill(sessionId, ids, values)); } } @@ -1535,8 +1547,7 @@ public final class AutofillManager { Intent fillInIntent) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post( - () -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent)); + afm.post(() -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent)); } } @@ -1545,9 +1556,8 @@ public final class AutofillManager { Rect anchorBounds, IAutofillWindowPresenter presenter) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post( - () -> afm.requestShowFillUi(sessionId, id, width, height, anchorBounds, - presenter)); + afm.post(() -> afm.requestShowFillUi(sessionId, id, width, height, anchorBounds, + presenter)); } } @@ -1555,7 +1565,7 @@ public final class AutofillManager { public void requestHideFillUi(int sessionId, AutofillId id) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post(() -> afm.requestHideFillUi(id)); + afm.post(() -> afm.requestHideFillUi(id)); } } @@ -1563,7 +1573,7 @@ public final class AutofillManager { public void notifyNoFillUi(int sessionId, AutofillId id) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post(() -> afm.notifyNoFillUi(sessionId, id)); + afm.post(() -> afm.notifyNoFillUi(sessionId, id)); } } @@ -1571,7 +1581,7 @@ public final class AutofillManager { public void startIntentSender(IntentSender intentSender) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post(() -> { + afm.post(() -> { try { afm.mContext.startIntentSender(intentSender, null, 0, 0, 0); } catch (IntentSender.SendIntentException e) { @@ -1586,7 +1596,7 @@ public final class AutofillManager { boolean saveOnAllViewsInvisible, AutofillId[] fillableIds) { final AutofillManager afm = mAfm.get(); if (afm != null) { - afm.mContext.getMainThreadHandler().post(() -> + afm.post(() -> afm.setTrackedViews(sessionId, ids, saveOnAllViewsInvisible, fillableIds) ); } diff --git a/core/java/android/view/autofill/AutofillPopupWindow.java b/core/java/android/view/autofill/AutofillPopupWindow.java index cd16a245c9b4..5f476380b1c3 100644 --- a/core/java/android/view/autofill/AutofillPopupWindow.java +++ b/core/java/android/view/autofill/AutofillPopupWindow.java @@ -16,6 +16,8 @@ package android.view.autofill; +import static android.view.autofill.Helper.sVerbose; + import android.annotation.NonNull; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -186,6 +188,10 @@ public class AutofillPopupWindow extends PopupWindow { @Override public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { + if (sVerbose) { + Log.v(TAG, "showAsDropDown(): anchor=" + anchor + ", xoff=" + xoff + ", yoff=" + yoff + + ", isShowing(): " + isShowing()); + } if (isShowing()) { return; } diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java index 82071d747775..fcb44af672d5 100644 --- a/core/java/android/widget/GridView.java +++ b/core/java/android/widget/GridView.java @@ -1718,20 +1718,17 @@ public class GridView extends AbsListView { break; case KeyEvent.KEYCODE_TAB: - // XXX Sometimes it is useful to be able to TAB through the items in + // TODO: Sometimes it is useful to be able to TAB through the items in // a GridView sequentially. Unfortunately this can create an // asymmetry in TAB navigation order unless the list selection // always reverts to the top or bottom when receiving TAB focus from - // another widget. Leaving this behavior disabled for now but - // perhaps it should be configurable (and more comprehensive). - if (false) { - if (event.hasNoModifiers()) { - handled = resurrectSelectionIfNeeded() - || sequenceScroll(FOCUS_FORWARD); - } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) { - handled = resurrectSelectionIfNeeded() - || sequenceScroll(FOCUS_BACKWARD); - } + // another widget. + if (event.hasNoModifiers()) { + handled = resurrectSelectionIfNeeded() + || sequenceScroll(FOCUS_FORWARD); + } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) { + handled = resurrectSelectionIfNeeded() + || sequenceScroll(FOCUS_BACKWARD); } break; } @@ -1991,7 +1988,7 @@ public class GridView extends AbsListView { if (!mStackFromBottom) { rowStart = childIndex - (childIndex % mNumColumns); - rowEnd = Math.max(rowStart + mNumColumns - 1, count); + rowEnd = Math.min(rowStart + mNumColumns - 1, count); } else { rowEnd = count - 1 - (invertedIndex - (invertedIndex % mNumColumns)); rowStart = Math.max(0, rowEnd - mNumColumns + 1); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index de560920b8ca..6b328ea01997 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -1587,7 +1587,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (textColorHighlight != 0) { setHighlightColor(textColorHighlight); } - setRawTextSize(textSize); + setRawTextSize(textSize, true /* shouldRequestLayout */); setElegantTextHeight(elegant); setLetterSpacing(letterSpacing); setFontFeatureSettings(fontFeatureSettings); @@ -1757,7 +1757,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener autoSizeMinTextSizeInPx, autoSizeMaxTextSizeInPx, DEFAULT_AUTO_SIZE_GRANULARITY_IN_PX); - setupAutoSizeText(); + if (setupAutoSizeText()) { + autoSizeText(); + invalidate(); + } break; default: throw new IllegalArgumentException( @@ -1807,7 +1810,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener validateAndSetAutoSizeTextTypeUniformConfiguration(autoSizeMinTextSizeInPx, autoSizeMaxTextSizeInPx, autoSizeStepGranularityInPx); - setupAutoSizeText(); + + if (setupAutoSizeText()) { + autoSizeText(); + invalidate(); + } } } @@ -1856,7 +1863,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } else { mHasPresetAutoSizeValues = false; } - setupAutoSizeText(); + + if (setupAutoSizeText()) { + autoSizeText(); + invalidate(); + } } } @@ -2014,20 +2025,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener : uniqueValidSizes.toArray(); } - private void setupAutoSizeText() { + private boolean setupAutoSizeText() { if (supportsAutoSizeText() && mAutoSizeTextType == AUTO_SIZE_TEXT_TYPE_UNIFORM) { // Calculate the sizes set based on minimum size, maximum size and step size if we do // not have a predefined set of sizes or if the current sizes array is empty. if (!mHasPresetAutoSizeValues || mAutoSizeTextSizesInPx.length == 0) { - // Calculate sizes to choose from based on the current auto-size configuration. - int autoSizeValuesLength = (int) Math.ceil( - (mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx) - / mAutoSizeStepGranularityInPx); - // Also reserve a slot for the max size if it fits. - if ((mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx) - % mAutoSizeStepGranularityInPx == 0) { + int autoSizeValuesLength = 1; + float currentSize = Math.round(mAutoSizeMinTextSizeInPx); + while (Math.round(currentSize + mAutoSizeStepGranularityInPx) + <= Math.round(mAutoSizeMaxTextSizeInPx)) { autoSizeValuesLength++; + currentSize += mAutoSizeStepGranularityInPx; } + int[] autoSizeTextSizesInPx = new int[autoSizeValuesLength]; float sizeToAdd = mAutoSizeMinTextSizeInPx; for (int i = 0; i < autoSizeValuesLength; i++) { @@ -2038,8 +2048,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } mNeedsAutoSizeText = true; - autoSizeText(); + } else { + mNeedsAutoSizeText = false; } + + return mNeedsAutoSizeText; } private int[] parseDimensionArray(TypedArray dimens) { @@ -3387,7 +3400,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final int textSize = ta.getDimensionPixelSize(R.styleable.TextAppearance_textSize, 0); if (textSize != 0) { - setRawTextSize(textSize); + setRawTextSize(textSize, true /* shouldRequestLayout */); } final ColorStateList textColorHint = ta.getColorStateList( @@ -3612,11 +3625,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ public void setTextSize(int unit, float size) { if (!isAutoSizeEnabled()) { - setTextSizeInternal(unit, size); + setTextSizeInternal(unit, size, true /* shouldRequestLayout */); } } - private void setTextSizeInternal(int unit, float size) { + private void setTextSizeInternal(int unit, float size, boolean shouldRequestLayout) { Context c = getContext(); Resources r; @@ -3626,15 +3639,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener r = c.getResources(); } - setRawTextSize(TypedValue.applyDimension( - unit, size, r.getDisplayMetrics())); + setRawTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics()), + shouldRequestLayout); } - private void setRawTextSize(float size) { + private void setRawTextSize(float size, boolean shouldRequestLayout) { if (size != mTextPaint.getTextSize()) { mTextPaint.setTextSize(size); - if (mLayout != null) { + if (shouldRequestLayout && mLayout != null) { // Do not auto-size right after setting the text size. mNeedsAutoSizeText = false; nullLayouts(); @@ -8257,23 +8270,44 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * Automatically computes and sets the text size. */ private void autoSizeText() { - if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0) return; - final int maxWidth = getWidth() - getTotalPaddingLeft() - getTotalPaddingRight(); - final int maxHeight = getHeight() - getExtendedPaddingBottom() - getExtendedPaddingTop(); - - if (maxWidth <= 0 || maxHeight <= 0) { + if (!isAutoSizeEnabled()) { return; } - synchronized (TEMP_RECTF) { - TEMP_RECTF.setEmpty(); - TEMP_RECTF.right = maxWidth; - TEMP_RECTF.bottom = maxHeight; - final float optimalTextSize = findLargestTextSizeWhichFits(TEMP_RECTF); - if (optimalTextSize != getTextSize()) { - setTextSizeInternal(TypedValue.COMPLEX_UNIT_PX, optimalTextSize); + if (mNeedsAutoSizeText) { + if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0) { + return; + } + + final int availableWidth = mHorizontallyScrolling + ? VERY_WIDE + : getMeasuredWidth() - getTotalPaddingLeft() - getTotalPaddingRight(); + final int availableHeight = getMeasuredHeight() - getExtendedPaddingBottom() + - getExtendedPaddingTop(); + + if (availableWidth <= 0 || availableHeight <= 0) { + return; + } + + synchronized (TEMP_RECTF) { + TEMP_RECTF.setEmpty(); + TEMP_RECTF.right = availableWidth; + TEMP_RECTF.bottom = availableHeight; + final float optimalTextSize = findLargestTextSizeWhichFits(TEMP_RECTF); + + if (optimalTextSize != getTextSize()) { + setTextSizeInternal(TypedValue.COMPLEX_UNIT_PX, optimalTextSize, + false /* shouldRequestLayout */); + + makeNewLayout(availableWidth, 0 /* hintWidth */, UNKNOWN_BORING, UNKNOWN_BORING, + mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(), + false /* bringIntoView */); + } } } + // Always try to auto-size if enabled. Functions that do not want to trigger auto-sizing + // after the next layout pass should set this to false. + mNeedsAutoSizeText = true; } /** @@ -8315,11 +8349,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mTempTextPaint.set(getPaint()); mTempTextPaint.setTextSize(suggestedSizeInPx); - final int availableWidth = mHorizontallyScrolling - ? VERY_WIDE - : getMeasuredWidth() - getTotalPaddingLeft() - getTotalPaddingRight(); final StaticLayout.Builder layoutBuilder = StaticLayout.Builder.obtain( - text, 0, text.length(), mTempTextPaint, availableWidth); + text, 0, text.length(), mTempTextPaint, Math.round(availableSpace.right)); layoutBuilder.setAlignment(getLayoutAlignment()) .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier()) @@ -8469,6 +8500,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // In a fixed-height view, so use our new text layout. if (mLayoutParams.height != LayoutParams.WRAP_CONTENT && mLayoutParams.height != LayoutParams.MATCH_PARENT) { + autoSizeText(); invalidate(); return; } @@ -8477,6 +8509,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // so use our new text layout. if (mLayout.getHeight() == oldht && (mHintLayout == null || mHintLayout.getHeight() == oldht)) { + autoSizeText(); invalidate(); return; } @@ -8503,16 +8536,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mDeferScroll = -1; bringPointIntoView(Math.min(curs, mText.length())); } - - if (isAutoSizeEnabled()) { - if (mNeedsAutoSizeText) { - // Call auto-size after the width and height have been calculated. - autoSizeText(); - } - // Always try to auto-size if enabled. Functions that do not want to trigger auto-sizing - // after the next layout round should set this to false. - mNeedsAutoSizeText = true; - } + // Call auto-size after the width and height have been calculated. + autoSizeText(); } private boolean isShowingHint() { diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 78566dfc458e..04f7c76c8e74 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -129,7 +129,7 @@ interface IBatteryStats { long getAwakeTimeBattery(); long getAwakeTimePlugged(); - void noteBleScanStarted(in WorkSource ws); + void noteBleScanStarted(in WorkSource ws, boolean isUnoptimized); void noteBleScanStopped(in WorkSource ws); void noteResetBleScan(); void noteBleScanResults(in WorkSource ws, int numNewResults); diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java index d19f1ecfbd13..bb54085ac3bf 100644 --- a/core/java/com/android/internal/app/NightDisplayController.java +++ b/core/java/com/android/internal/app/NightDisplayController.java @@ -109,17 +109,39 @@ public final class NightDisplayController { } /** - * Sets whether Night display should be activated. + * Sets whether Night display should be activated. This also sets the last activated time. * * @param activated {@code true} if Night display should be activated * @return {@code true} if the activated value was set successfully */ public boolean setActivated(boolean activated) { + if (isActivated() != activated) { + Secure.putLongForUser(mContext.getContentResolver(), + Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(), + mUserId); + } return Secure.putIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_ACTIVATED, activated ? 1 : 0, mUserId); } /** + * Returns the time when Night display's activation state last changed, or {@code null} if it + * has never been changed. + */ + public Calendar getLastActivatedTime() { + final ContentResolver cr = mContext.getContentResolver(); + final long lastActivatedTimeMillis = Secure.getLongForUser( + cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1, mUserId); + if (lastActivatedTimeMillis < 0) { + return null; + } + + final Calendar lastActivatedTime = Calendar.getInstance(); + lastActivatedTime.setTimeInMillis(lastActivatedTimeMillis); + return lastActivatedTime; + } + + /** * Returns the current auto mode value controlling when Night display will be automatically * activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM}, or * {@link #AUTO_MODE_TWILIGHT}. diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 31064ac73dff..1b0d3323b3d0 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -56,6 +56,7 @@ import android.util.LogWriter; import android.util.LongSparseArray; import android.util.LongSparseLongArray; import android.util.MutableInt; +import android.util.Pools; import android.util.PrintWriterPrinter; import android.util.Printer; import android.util.Slog; @@ -66,6 +67,7 @@ import android.util.TimeUtils; import android.util.Xml; import android.view.Display; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.util.ArrayUtils; @@ -116,7 +118,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 158 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 159 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -173,7 +175,6 @@ public class BatteryStatsImpl extends BatteryStats { private final PlatformIdleStateCallback mPlatformIdleStateCallback; - final class MyHandler extends Handler { public MyHandler(Looper looper) { super(looper, null, true); @@ -228,11 +229,11 @@ public class BatteryStatsImpl extends BatteryStats { } public interface ExternalStatsSync { - public static final int UPDATE_CPU = 0x01; - public static final int UPDATE_WIFI = 0x02; - public static final int UPDATE_RADIO = 0x04; - public static final int UPDATE_BT = 0x08; - public static final int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; + int UPDATE_CPU = 0x01; + int UPDATE_WIFI = 0x02; + int UPDATE_RADIO = 0x04; + int UPDATE_BT = 0x08; + int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; void scheduleSync(String reason, int flags); void scheduleCpuSyncDueToRemovedUid(int uid); @@ -572,8 +573,6 @@ public class BatteryStatsImpl extends BatteryStats { private int mMinLearnedBatteryCapacity = -1; private int mMaxLearnedBatteryCapacity = -1; - private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry(); - private long[] mCpuFreqs; private PowerProfile mPowerProfile; @@ -637,19 +636,9 @@ public class BatteryStatsImpl extends BatteryStats { private void init(Clocks clocks) { mClocks = clocks; - mMobileNetworkStats = new NetworkStats[] { - new NetworkStats(mClocks.elapsedRealtime(), 50), - new NetworkStats(mClocks.elapsedRealtime(), 50), - new NetworkStats(mClocks.elapsedRealtime(), 50) - }; - mWifiNetworkStats = new NetworkStats[] { - new NetworkStats(mClocks.elapsedRealtime(), 50), - new NetworkStats(mClocks.elapsedRealtime(), 50), - new NetworkStats(mClocks.elapsedRealtime(), 50) - }; } - public static interface TimeBaseObs { + public interface TimeBaseObs { void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); } @@ -862,21 +851,19 @@ public class BatteryStatsImpl extends BatteryStats { final AtomicInteger mCount = new AtomicInteger(); final TimeBase mTimeBase; int mLoadedCount; - int mLastCount; int mUnpluggedCount; int mPluggedCount; - Counter(TimeBase timeBase, Parcel in) { + public Counter(TimeBase timeBase, Parcel in) { mTimeBase = timeBase; mPluggedCount = in.readInt(); mCount.set(mPluggedCount); mLoadedCount = in.readInt(); - mLastCount = 0; mUnpluggedCount = in.readInt(); timeBase.add(this); } - Counter(TimeBase timeBase) { + public Counter(TimeBase timeBase) { mTimeBase = timeBase; timeBase.add(this); } @@ -887,11 +874,12 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(mUnpluggedCount); } + @Override public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { mUnpluggedCount = mPluggedCount; - mCount.set(mPluggedCount); } + @Override public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { mPluggedCount = mCount.get(); } @@ -926,17 +914,22 @@ public class BatteryStatsImpl extends BatteryStats { public void logState(Printer pw, String prefix) { pw.println(prefix + "mCount=" + mCount.get() - + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount + + " mLoadedCount=" + mLoadedCount + " mUnpluggedCount=" + mUnpluggedCount + " mPluggedCount=" + mPluggedCount); } - void stepAtomic() { - mCount.incrementAndGet(); + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public void stepAtomic() { + if (mTimeBase.isRunning()) { + mCount.incrementAndGet(); + } } void addAtomic(int delta) { - mCount.addAndGet(delta); + if (mTimeBase.isRunning()) { + mCount.addAndGet(delta); + } } /** @@ -944,7 +937,7 @@ public class BatteryStatsImpl extends BatteryStats { */ void reset(boolean detachIfReset) { mCount.set(0); - mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; + mLoadedCount = mPluggedCount = mUnpluggedCount = 0; if (detachIfReset) { detach(); } @@ -954,15 +947,16 @@ public class BatteryStatsImpl extends BatteryStats { mTimeBase.remove(this); } - void writeSummaryFromParcelLocked(Parcel out) { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public void writeSummaryFromParcelLocked(Parcel out) { int count = mCount.get(); out.writeInt(count); } - void readSummaryFromParcelLocked(Parcel in) { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public void readSummaryFromParcelLocked(Parcel in) { mLoadedCount = in.readInt(); mCount.set(mLoadedCount); - mLastCount = 0; mUnpluggedCount = mPluggedCount = mLoadedCount; } } @@ -998,7 +992,6 @@ public class BatteryStatsImpl extends BatteryStats { @Override public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) { mUnpluggedCounts = copyArray(mPluggedCounts, mUnpluggedCounts); - mCounts = copyArray(mPluggedCounts, mCounts); } @Override @@ -1029,11 +1022,13 @@ public class BatteryStatsImpl extends BatteryStats { if (counts == null) { return; } - if (mCounts == null) { - mCounts = new long[counts.length]; - } - for (int i = 0; i < counts.length; ++i) { - mCounts[i] += counts[i]; + if (mTimeBase.isRunning()) { + if (mCounts == null) { + mCounts = new long[counts.length]; + } + for (int i = 0; i < counts.length; ++i) { + mCounts[i] += counts[i]; + } } } @@ -1104,13 +1099,13 @@ public class BatteryStatsImpl extends BatteryStats { } } - private void fillArray(long[] a, long val) { + private static void fillArray(long[] a, long val) { if (a != null) { Arrays.fill(a, val); } } - private void subtract(@NonNull long[] val, long[] toSubtract) { + private static void subtract(@NonNull long[] val, long[] toSubtract) { if (toSubtract == null) { return; } @@ -1119,7 +1114,7 @@ public class BatteryStatsImpl extends BatteryStats { } } - private long[] copyArray(long[] src, long[] dest) { + private static long[] copyArray(long[] src, long[] dest) { if (src == null) { return null; } else { @@ -1162,7 +1157,6 @@ public class BatteryStatsImpl extends BatteryStats { @Override public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { mUnpluggedCount = mPluggedCount; - mCount = mPluggedCount; } @Override @@ -1189,7 +1183,9 @@ public class BatteryStatsImpl extends BatteryStats { } void addCountLocked(long count) { - mCount += count; + if (mTimeBase.isRunning()) { + mCount += count; + } } /** @@ -4193,7 +4189,10 @@ public class BatteryStatsImpl extends BatteryStats { getUidStatsLocked(uid).noteMobileRadioApWakeupLocked(); } - public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) { + /** + * Updates the radio power state and returns true if an external stats collection should occur. + */ + public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); if (mMobileRadioPowerState != powerState) { @@ -4230,13 +4229,15 @@ public class BatteryStatsImpl extends BatteryStats { mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); } else { mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); - updateMobileRadioStateLocked(realElapsedRealtimeMs, null); mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); + // Tell the caller to collect radio network/power stats. + return true; } } + return false; } - public void notePowerSaveMode(boolean enabled) { + public void notePowerSaveModeLocked(boolean enabled) { if (mPowerSaveModeEnabled != enabled) { int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; @@ -4821,7 +4822,7 @@ public class BatteryStatsImpl extends BatteryStats { } } - private void noteBluetoothScanStartedLocked(int uid) { + private void noteBluetoothScanStartedLocked(int uid, boolean isUnoptimized) { uid = mapUid(uid); final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); @@ -4833,13 +4834,13 @@ public class BatteryStatsImpl extends BatteryStats { mBluetoothScanTimer.startRunningLocked(elapsedRealtime); } mBluetoothScanNesting++; - getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime); + getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized); } - public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws) { + public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { final int N = ws.size(); for (int i = 0; i < N; i++) { - noteBluetoothScanStartedLocked(ws.get(i)); + noteBluetoothScanStartedLocked(ws.get(i), isUnoptimized); } } @@ -5236,28 +5237,26 @@ public class BatteryStatsImpl extends BatteryStats { public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { if (TextUtils.isEmpty(iface)) return; - if (ConnectivityManager.isNetworkTypeMobile(networkType)) { - mMobileIfaces = includeInStringArray(mMobileIfaces, iface); - if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces); - } else { - mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface); - if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces); - } - if (ConnectivityManager.isNetworkTypeWifi(networkType)) { - mWifiIfaces = includeInStringArray(mWifiIfaces, iface); - if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); - } else { - mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); - if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); + + synchronized (mModemNetworkLock) { + if (ConnectivityManager.isNetworkTypeMobile(networkType)) { + mModemIfaces = includeInStringArray(mModemIfaces, iface); + if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); + } else { + mModemIfaces = excludeFromStringArray(mModemIfaces, iface); + if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); + } } - } - public void noteNetworkStatsEnabledLocked() { - // During device boot, qtaguid isn't enabled until after the inital - // loading of battery stats. Now that they're enabled, take our initial - // snapshot for future delta calculation. - updateMobileRadioStateLocked(mClocks.elapsedRealtime(), null); - updateWifiStateLocked(null); + synchronized (mWifiNetworkLock) { + if (ConnectivityManager.isNetworkTypeWifi(networkType)) { + mWifiIfaces = includeInStringArray(mWifiIfaces, iface); + if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); + } else { + mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); + if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); + } + } } @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { @@ -5611,7 +5610,9 @@ public class BatteryStatsImpl extends BatteryStats { /** Total time spent by the uid holding any partial wakelocks. */ DualTimer mAggregatedPartialWakelockTimer; DualTimer mBluetoothScanTimer; + DualTimer mBluetoothUnoptimizedScanTimer; Counter mBluetoothScanResultCounter; + Counter mBluetoothScanResultBgCounter; int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; StopwatchTimer[] mProcessStateTimer; @@ -6096,20 +6097,41 @@ public class BatteryStatsImpl extends BatteryStats { return mBluetoothScanTimer; } - public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs) { + public DualTimer createBluetoothUnoptimizedScanTimerLocked() { + if (mBluetoothUnoptimizedScanTimer == null) { + mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, + BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, + mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); + } + return mBluetoothUnoptimizedScanTimer; + } + + public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); + if (isUnoptimized) { + createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); + } } public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) { if (mBluetoothScanTimer != null) { mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); } + // In the ble code, a scan cannot change types and nested starts are not possible. + // So if an unoptimizedScan is running, it is now being stopped. + if (mBluetoothUnoptimizedScanTimer != null + && mBluetoothUnoptimizedScanTimer.isRunningLocked()) { + mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); + } } public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { if (mBluetoothScanTimer != null) { mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); } + if (mBluetoothUnoptimizedScanTimer != null) { + mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); + } } public Counter createBluetoothScanResultCounterLocked() { @@ -6119,8 +6141,17 @@ public class BatteryStatsImpl extends BatteryStats { return mBluetoothScanResultCounter; } + public Counter createBluetoothScanResultBgCounterLocked() { + if (mBluetoothScanResultBgCounter == null) { + mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); + } + return mBluetoothScanResultBgCounter; + } + public void noteBluetoothScanResultsLocked(int numNewResults) { createBluetoothScanResultCounterLocked().addAtomic(numNewResults); + // Uses background timebase, so the count will only be incremented if uid in background. + createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); } @Override @@ -6277,10 +6308,28 @@ public class BatteryStatsImpl extends BatteryStats { } @Override + public Timer getBluetoothUnoptimizedScanTimer() { + return mBluetoothUnoptimizedScanTimer; + } + + @Override + public Timer getBluetoothUnoptimizedScanBackgroundTimer() { + if (mBluetoothUnoptimizedScanTimer == null) { + return null; + } + return mBluetoothUnoptimizedScanTimer.getSubTimer(); + } + + @Override public Counter getBluetoothScanResultCounter() { return mBluetoothScanResultCounter; } + @Override + public Counter getBluetoothScanResultBgCounter() { + return mBluetoothScanResultBgCounter; + } + void makeProcessState(int i, Parcel in) { if (i < 0 || i >= NUM_PROCESS_STATE) return; @@ -6531,9 +6580,13 @@ public class BatteryStatsImpl extends BatteryStats { active |= !resetTimerIfNotNull(mForegroundActivityTimer, false); active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false); active |= !resetTimerIfNotNull(mBluetoothScanTimer, false); + active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false); if (mBluetoothScanResultCounter != null) { mBluetoothScanResultCounter.reset(false); } + if (mBluetoothScanResultBgCounter != null) { + mBluetoothScanResultBgCounter.reset(false); + } if (mProcessStateTimer != null) { for (int i = 0; i < NUM_PROCESS_STATE; i++) { @@ -6731,10 +6784,18 @@ public class BatteryStatsImpl extends BatteryStats { mBluetoothScanTimer.detach(); mBluetoothScanTimer = null; } + if (mBluetoothUnoptimizedScanTimer != null) { + mBluetoothUnoptimizedScanTimer.detach(); + mBluetoothUnoptimizedScanTimer = null; + } if (mBluetoothScanResultCounter != null) { mBluetoothScanResultCounter.detach(); mBluetoothScanResultCounter = null; } + if (mBluetoothScanResultBgCounter != null) { + mBluetoothScanResultBgCounter.detach(); + mBluetoothScanResultBgCounter = null; + } if (mUserActivityCounters != null) { for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { mUserActivityCounters[i].detach(); @@ -6919,12 +6980,24 @@ public class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } + if (mBluetoothUnoptimizedScanTimer != null) { + out.writeInt(1); + mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); + } else { + out.writeInt(0); + } if (mBluetoothScanResultCounter != null) { out.writeInt(1); mBluetoothScanResultCounter.writeToParcel(out); } else { out.writeInt(0); } + if (mBluetoothScanResultBgCounter != null) { + out.writeInt(1); + mBluetoothScanResultBgCounter.writeToParcel(out); + } else { + out.writeInt(0); + } for (int i = 0; i < NUM_PROCESS_STATE; i++) { if (mProcessStateTimer[i] != null) { out.writeInt(1); @@ -7033,7 +7106,8 @@ public class BatteryStatsImpl extends BatteryStats { for (int j = 0; j < numWakelocks; j++) { String wakelockName = in.readString(); Uid.Wakelock wakelock = new Wakelock(mBsi, this); - wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in); + wakelock.readFromParcelLocked( + timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); mWakelockStats.add(wakelockName, wakelock); } @@ -7168,10 +7242,22 @@ public class BatteryStatsImpl extends BatteryStats { mBluetoothScanTimer = null; } if (in.readInt() != 0) { + mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, + BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, + mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); + } else { + mBluetoothUnoptimizedScanTimer = null; + } + if (in.readInt() != 0) { mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); } else { mBluetoothScanResultCounter = null; } + if (in.readInt() != 0) { + mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); + } else { + mBluetoothScanResultBgCounter = null; + } mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; for (int i = 0; i < NUM_PROCESS_STATE; i++) { if (in.readInt() != 0) { @@ -7298,8 +7384,9 @@ public class BatteryStatsImpl extends BatteryStats { /** * How long (in ms) this uid has been keeping the device partially awake. + * Tracks both the total time and the time while the app was in the background. */ - DurationTimer mTimerPartial; + DualTimer mTimerPartial; /** * How long (in ms) this uid has been keeping the device fully awake. @@ -7344,13 +7431,13 @@ public class BatteryStatsImpl extends BatteryStats { * @param in the Parcel to be read from. * return a new Timer, or null. */ - private DurationTimer readDurationTimerFromParcel(int type, - ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { + private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, + TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { if (in.readInt() == 0) { return null; } - return new DurationTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); + return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); } boolean reset() { @@ -7388,9 +7475,10 @@ public class BatteryStatsImpl extends BatteryStats { return !wlactive; } - void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { - mTimerPartial = readDurationTimerFromParcel(WAKE_TYPE_PARTIAL, - mBsi.mPartialTimers, screenOffTimeBase, in); + void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, + TimeBase screenOffBgTimeBase, Parcel in) { + mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, + mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, mBsi.mFullTimers, timeBase, in); mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, @@ -7416,49 +7504,6 @@ public class BatteryStatsImpl extends BatteryStats { default: throw new IllegalArgumentException("type = " + type); } } - - public StopwatchTimer getStopwatchTimer(int type) { - switch (type) { - case WAKE_TYPE_PARTIAL: { - DurationTimer t = mTimerPartial; - if (t == null) { - t = new DurationTimer(mBsi.mClocks, mUid, WAKE_TYPE_PARTIAL, - mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase); - mTimerPartial = t; - } - return t; - } - case WAKE_TYPE_FULL: { - StopwatchTimer t = mTimerFull; - if (t == null) { - t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_FULL, - mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); - mTimerFull = t; - } - return t; - } - case WAKE_TYPE_WINDOW: { - StopwatchTimer t = mTimerWindow; - if (t == null) { - t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_WINDOW, - mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); - mTimerWindow = t; - } - return t; - } - case WAKE_TYPE_DRAW: { - StopwatchTimer t = mTimerDraw; - if (t == null) { - t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_DRAW, - mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); - mTimerDraw = t; - } - return t; - } - default: - throw new IllegalArgumentException("type=" + type); - } - } } public static class Sensor extends BatteryStats.Uid.Sensor { @@ -8351,16 +8396,16 @@ public class BatteryStatsImpl extends BatteryStats { Wakelock wl = new Wakelock(mBsi, this); mWakelockStats.add(wlName, wl); if (in.readInt() != 0) { - wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); + getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); } if (in.readInt() != 0) { - wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); + getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); } if (in.readInt() != 0) { - wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); + getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); } if (in.readInt() != 0) { - wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); + getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); } } @@ -8416,10 +8461,57 @@ public class BatteryStatsImpl extends BatteryStats { } } + public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { + if (wl == null) { + return null; + } + switch (type) { + case WAKE_TYPE_PARTIAL: { + DualTimer t = wl.mTimerPartial; + if (t == null) { + t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL, + mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, + mOnBatteryScreenOffBackgroundTimeBase); + wl.mTimerPartial = t; + } + return t; + } + case WAKE_TYPE_FULL: { + StopwatchTimer t = wl.mTimerFull; + if (t == null) { + t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL, + mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); + wl.mTimerFull = t; + } + return t; + } + case WAKE_TYPE_WINDOW: { + StopwatchTimer t = wl.mTimerWindow; + if (t == null) { + t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW, + mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); + wl.mTimerWindow = t; + } + return t; + } + case WAKE_TYPE_DRAW: { + StopwatchTimer t = wl.mTimerDraw; + if (t == null) { + t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW, + mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); + wl.mTimerDraw = t; + } + return t; + } + default: + throw new IllegalArgumentException("type=" + type); + } + } + public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { Wakelock wl = mWakelockStats.startObject(name); if (wl != null) { - wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs); + getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); } if (type == WAKE_TYPE_PARTIAL) { createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); @@ -8435,7 +8527,7 @@ public class BatteryStatsImpl extends BatteryStats { public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { Wakelock wl = mWakelockStats.stopObject(name); if (wl != null) { - wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs); + getWakelockTimerLocked(wl, type).stopRunningLocked(elapsedRealtimeMs); } if (type == WAKE_TYPE_PARTIAL) { if (mAggregatedPartialWakelockTimer != null) { @@ -8613,27 +8705,25 @@ public class BatteryStatsImpl extends BatteryStats { mPlatformIdleStateCallback = null; } - public void setPowerProfile(PowerProfile profile) { - synchronized (this) { - mPowerProfile = profile; + public void setPowerProfileLocked(PowerProfile profile) { + mPowerProfile = profile; - // We need to initialize the KernelCpuSpeedReaders to read from - // the first cpu of each core. Once we have the PowerProfile, we have access to this - // information. - final int numClusters = mPowerProfile.getNumCpuClusters(); - mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; - int firstCpuOfCluster = 0; - for (int i = 0; i < numClusters; i++) { - final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); - mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, - numSpeedSteps); - firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); - } + // We need to initialize the KernelCpuSpeedReaders to read from + // the first cpu of each core. Once we have the PowerProfile, we have access to this + // information. + final int numClusters = mPowerProfile.getNumCpuClusters(); + mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; + int firstCpuOfCluster = 0; + for (int i = 0; i < numClusters; i++) { + final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); + mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, + numSpeedSteps); + firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); + } - if (mEstimatedBatteryCapacity == -1) { - // Initialize the estimated battery capacity to a known preset one. - mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); - } + if (mEstimatedBatteryCapacity == -1) { + // Initialize the estimated battery capacity to a known preset one. + mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); } } @@ -8641,7 +8731,7 @@ public class BatteryStatsImpl extends BatteryStats { mCallback = cb; } - public void setRadioScanningTimeout(long timeout) { + public void setRadioScanningTimeoutLocked(long timeout) { if (mPhoneSignalScanningTimer != null) { mPhoneSignalScanningTimer.setTimeout(timeout); } @@ -9333,277 +9423,293 @@ public class BatteryStatsImpl extends BatteryStats { } } - private String[] mMobileIfaces = EmptyArray.STRING; + private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); + private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6); + + private final Object mWifiNetworkLock = new Object(); + + @GuardedBy("mWifiNetworkLock") private String[] mWifiIfaces = EmptyArray.STRING; - private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); + @GuardedBy("mWifiNetworkLock") + private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); - private static final int NETWORK_STATS_LAST = 0; - private static final int NETWORK_STATS_NEXT = 1; - private static final int NETWORK_STATS_DELTA = 2; + private final Object mModemNetworkLock = new Object(); - private NetworkStats[] mMobileNetworkStats; - private NetworkStats[] mWifiNetworkStats; + @GuardedBy("mModemNetworkLock") + private String[] mModemIfaces = EmptyArray.STRING; - /** - * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer - * as a buffer of NetworkStats objects to cycle through when computing deltas. - */ - private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces, - NetworkStats[] networkStatsBuffer) - throws IOException { - if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED, - false)) { - return null; - } + @GuardedBy("mModemNetworkLock") + private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); - final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, - ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]); - networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats, - networkStatsBuffer[NETWORK_STATS_LAST], null, null, - networkStatsBuffer[NETWORK_STATS_DELTA]); - networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST]; - networkStatsBuffer[NETWORK_STATS_LAST] = stats; - return networkStatsBuffer[NETWORK_STATS_DELTA]; + private NetworkStats readNetworkStatsLocked(String[] ifaces) { + try { + if (!ArrayUtils.isEmpty(ifaces)) { + return mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, + NetworkStats.TAG_NONE, mNetworkStatsPool.acquire()); + } + } catch (IOException e) { + Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces)); + } + return null; } /** * Distribute WiFi energy info and network traffic to apps. * @param info The energy information from the WiFi controller. */ - public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) { + public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) { if (DEBUG_ENERGY) { - Slog.d(TAG, "Updating wifi stats"); + Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); } - final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + // Grab a separate lock to acquire the network stats, which may do I/O. NetworkStats delta = null; - try { - if (!ArrayUtils.isEmpty(mWifiIfaces)) { - delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats); + synchronized (mWifiNetworkLock) { + final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces); + if (latestStats != null) { + delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null, + mNetworkStatsPool.acquire()); + mNetworkStatsPool.release(mLastWifiNetworkStats); + mLastWifiNetworkStats = latestStats; } - } catch (IOException e) { - Slog.wtf(TAG, "Failed to get wifi network stats", e); - return; - } - - if (!mOnBatteryInternal) { - return; } - SparseLongArray rxPackets = new SparseLongArray(); - SparseLongArray txPackets = new SparseLongArray(); - long totalTxPackets = 0; - long totalRxPackets = 0; - if (delta != null) { - final int size = delta.size(); - for (int i = 0; i < size; i++) { - final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); - - if (DEBUG_ENERGY) { - Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes - + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets - + " txPackets=" + entry.txPackets); + synchronized (this) { + if (!mOnBatteryInternal) { + if (delta != null) { + mNetworkStatsPool.release(delta); } + return; + } - if (entry.rxBytes == 0 && entry.txBytes == 0) { - // Skip the lookup below since there is no work to do. - continue; - } + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + SparseLongArray rxPackets = new SparseLongArray(); + SparseLongArray txPackets = new SparseLongArray(); + long totalTxPackets = 0; + long totalRxPackets = 0; + if (delta != null) { + NetworkStats.Entry entry = new NetworkStats.Entry(); + final int size = delta.size(); + for (int i = 0; i < size; i++) { + entry = delta.getValues(i, entry); - final Uid u = getUidStatsLocked(mapUid(entry.uid)); - if (entry.rxBytes != 0) { - u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, - entry.rxPackets); - if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers - u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, - entry.rxPackets); + if (DEBUG_ENERGY) { + Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes + + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets + + " txPackets=" + entry.txPackets); } - mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( - entry.rxBytes); - mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( - entry.rxPackets); - - rxPackets.put(u.getUid(), entry.rxPackets); - // Sum the total number of packets so that the Rx Power can - // be evenly distributed amongst the apps. - totalRxPackets += entry.rxPackets; - } - - if (entry.txBytes != 0) { - u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, - entry.txPackets); - if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers - u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, - entry.txPackets); + if (entry.rxBytes == 0 && entry.txBytes == 0) { + // Skip the lookup below since there is no work to do. + continue; } - mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( - entry.txBytes); - mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( - entry.txPackets); - txPackets.put(u.getUid(), entry.txPackets); + final Uid u = getUidStatsLocked(mapUid(entry.uid)); + if (entry.rxBytes != 0) { + u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, + entry.rxPackets); + if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers + u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, + entry.rxPackets); + } + mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( + entry.rxBytes); + mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( + entry.rxPackets); - // Sum the total number of packets so that the Tx Power can - // be evenly distributed amongst the apps. - totalTxPackets += entry.txPackets; - } - } - } + rxPackets.put(u.getUid(), entry.rxPackets); - if (info != null) { - mHasWifiReporting = true; + // Sum the total number of packets so that the Rx Power can + // be evenly distributed amongst the apps. + totalRxPackets += entry.rxPackets; + } - // Measured in mAms - final long txTimeMs = info.getControllerTxTimeMillis(); - final long rxTimeMs = info.getControllerRxTimeMillis(); - final long idleTimeMs = info.getControllerIdleTimeMillis(); - final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; + if (entry.txBytes != 0) { + u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, + entry.txPackets); + if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers + u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, + entry.txPackets); + } + mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( + entry.txBytes); + mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( + entry.txPackets); - long leftOverRxTimeMs = rxTimeMs; - long leftOverTxTimeMs = txTimeMs; + txPackets.put(u.getUid(), entry.txPackets); - if (DEBUG_ENERGY) { - Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); - Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); - Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); - Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); - Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); + // Sum the total number of packets so that the Tx Power can + // be evenly distributed amongst the apps. + totalTxPackets += entry.txPackets; + } + } + mNetworkStatsPool.release(delta); + delta = null; } - long totalWifiLockTimeMs = 0; - long totalScanTimeMs = 0; - - // On the first pass, collect some totals so that we can normalize power - // calculations if we need to. - final int uidStatsSize = mUidStats.size(); - for (int i = 0; i < uidStatsSize; i++) { - final Uid uid = mUidStats.valueAt(i); + if (info != null) { + mHasWifiReporting = true; - // Sum the total scan power for all apps. - totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( - elapsedRealtimeMs * 1000) / 1000; + // Measured in mAms + final long txTimeMs = info.getControllerTxTimeMillis(); + final long rxTimeMs = info.getControllerRxTimeMillis(); + final long idleTimeMs = info.getControllerIdleTimeMillis(); + final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; - // Sum the total time holding wifi lock for all apps. - totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( - elapsedRealtimeMs * 1000) / 1000; - } - - if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { - Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " - + rxTimeMs + " ms). Normalizing scan time."); - } - if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { - Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " - + txTimeMs + " ms). Normalizing scan time."); - } + long leftOverRxTimeMs = rxTimeMs; + long leftOverTxTimeMs = txTimeMs; - // Actually assign and distribute power usage to apps. - for (int i = 0; i < uidStatsSize; i++) { - final Uid uid = mUidStats.valueAt(i); - - long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( - elapsedRealtimeMs * 1000) / 1000; - if (scanTimeSinceMarkMs > 0) { - // Set the new mark so that next time we get new data since this point. - uid.mWifiScanTimer.setMark(elapsedRealtimeMs); + if (DEBUG_ENERGY) { + Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); + Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); + Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); + Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); + Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); + } + + long totalWifiLockTimeMs = 0; + long totalScanTimeMs = 0; + + // On the first pass, collect some totals so that we can normalize power + // calculations if we need to. + final int uidStatsSize = mUidStats.size(); + for (int i = 0; i < uidStatsSize; i++) { + final Uid uid = mUidStats.valueAt(i); + + // Sum the total scan power for all apps. + totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( + elapsedRealtimeMs * 1000) / 1000; + + // Sum the total time holding wifi lock for all apps. + totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( + elapsedRealtimeMs * 1000) / 1000; + } + + if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { + Slog.d(TAG, + " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " + + rxTimeMs + " ms). Normalizing scan time."); + } + if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { + Slog.d(TAG, + " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " + + txTimeMs + " ms). Normalizing scan time."); + } + + // Actually assign and distribute power usage to apps. + for (int i = 0; i < uidStatsSize; i++) { + final Uid uid = mUidStats.valueAt(i); + + long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( + elapsedRealtimeMs * 1000) / 1000; + if (scanTimeSinceMarkMs > 0) { + // Set the new mark so that next time we get new data since this point. + uid.mWifiScanTimer.setMark(elapsedRealtimeMs); + + long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; + long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; + + // Our total scan time is more than the reported Tx/Rx time. + // This is possible because the cost of a scan is approximate. + // Let's normalize the result so that we evenly blame each app + // scanning. + // + // This means that we may have apps that transmitted/received packets not be + // blamed for this, but this is fine as scans are relatively more expensive. + if (totalScanTimeMs > rxTimeMs) { + scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / + totalScanTimeMs; + } + if (totalScanTimeMs > txTimeMs) { + scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / + totalScanTimeMs; + } - long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; - long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; + if (DEBUG_ENERGY) { + Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" + + scanRxTimeSinceMarkMs + " ms Tx:" + + scanTxTimeSinceMarkMs + " ms)"); + } - // Our total scan time is more than the reported Tx/Rx time. - // This is possible because the cost of a scan is approximate. - // Let's normalize the result so that we evenly blame each app - // scanning. - // - // This means that we may have apps that transmitted/received packets not be - // blamed for this, but this is fine as scans are relatively more expensive. - if (totalScanTimeMs > rxTimeMs) { - scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / - totalScanTimeMs; - } - if (totalScanTimeMs > txTimeMs) { - scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / - totalScanTimeMs; + ControllerActivityCounterImpl activityCounter = + uid.getOrCreateWifiControllerActivityLocked(); + activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); + activityCounter.getTxTimeCounters()[0].addCountLocked( + scanTxTimeSinceMarkMs); + leftOverRxTimeMs -= scanRxTimeSinceMarkMs; + leftOverTxTimeMs -= scanTxTimeSinceMarkMs; } - if (DEBUG_ENERGY) { - Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" - + scanRxTimeSinceMarkMs + " ms Tx:" - + scanTxTimeSinceMarkMs + " ms)"); + // Distribute evenly the power consumed while Idle to each app holding a WiFi + // lock. + final long wifiLockTimeSinceMarkMs = + uid.mFullWifiLockTimer.getTimeSinceMarkLocked( + elapsedRealtimeMs * 1000) / 1000; + if (wifiLockTimeSinceMarkMs > 0) { + // Set the new mark so that next time we get new data since this point. + uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); + + final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) + / totalWifiLockTimeMs; + if (DEBUG_ENERGY) { + Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " + + myIdleTimeMs + " ms"); + } + uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() + .addCountLocked(myIdleTimeMs); } - - ControllerActivityCounterImpl activityCounter = - uid.getOrCreateWifiControllerActivityLocked(); - activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); - activityCounter.getTxTimeCounters()[0].addCountLocked(scanTxTimeSinceMarkMs); - leftOverRxTimeMs -= scanRxTimeSinceMarkMs; - leftOverTxTimeMs -= scanTxTimeSinceMarkMs; } - // Distribute evenly the power consumed while Idle to each app holding a WiFi - // lock. - final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked( - elapsedRealtimeMs * 1000) / 1000; - if (wifiLockTimeSinceMarkMs > 0) { - // Set the new mark so that next time we get new data since this point. - uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); + if (DEBUG_ENERGY) { + Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); + Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); + } - final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) - / totalWifiLockTimeMs; + // Distribute the remaining Tx power appropriately between all apps that transmitted + // packets. + for (int i = 0; i < txPackets.size(); i++) { + final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); + final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) + / totalTxPackets; if (DEBUG_ENERGY) { - Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " - + myIdleTimeMs + " ms"); + Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); } - uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() - .addCountLocked(myIdleTimeMs); + uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] + .addCountLocked(myTxTimeMs); } - } - - if (DEBUG_ENERGY) { - Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); - Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); - } - // Distribute the remaining Tx power appropriately between all apps that transmitted - // packets. - for (int i = 0; i < txPackets.size(); i++) { - final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); - final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets; - if (DEBUG_ENERGY) { - Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); + // Distribute the remaining Rx power appropriately between all apps that received + // packets. + for (int i = 0; i < rxPackets.size(); i++) { + final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); + final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) + / totalRxPackets; + if (DEBUG_ENERGY) { + Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); + } + uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() + .addCountLocked(myRxTimeMs); } - uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] - .addCountLocked(myTxTimeMs); - } - // Distribute the remaining Rx power appropriately between all apps that received - // packets. - for (int i = 0; i < rxPackets.size(); i++) { - final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); - final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets; - if (DEBUG_ENERGY) { - Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); - } - uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() - .addCountLocked(myRxTimeMs); - } + // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. - // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. - // Update WiFi controller stats. - mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); - mWifiActivity.getTxTimeCounters()[0].addCountLocked(info.getControllerTxTimeMillis()); - mWifiActivity.getIdleTimeCounter().addCountLocked(info.getControllerIdleTimeMillis()); + // Update WiFi controller stats. + mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); + mWifiActivity.getTxTimeCounters()[0].addCountLocked( + info.getControllerTxTimeMillis()); + mWifiActivity.getIdleTimeCounter().addCountLocked( + info.getControllerIdleTimeMillis()); - // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. - final double opVolt = mPowerProfile.getAveragePower( - PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; - if (opVolt != 0) { - // We store the power drain as mAms. - mWifiActivity.getPowerCounter().addCountLocked( - (long)(info.getControllerEnergyUsed() / opVolt)); + // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. + final double opVolt = mPowerProfile.getAveragePower( + PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; + if (opVolt != 0) { + // We store the power drain as mAms. + mWifiActivity.getPowerCounter().addCountLocked( + (long) (info.getControllerEnergyUsed() / opVolt)); + } } } } @@ -9611,133 +9717,148 @@ public class BatteryStatsImpl extends BatteryStats { /** * Distribute Cell radio energy info and network traffic to apps. */ - public void updateMobileRadioStateLocked(final long elapsedRealtimeMs, - final ModemActivityInfo activityInfo) { + public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) { if (DEBUG_ENERGY) { Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); } + // Grab a separate lock to acquire the network stats, which may do I/O. NetworkStats delta = null; - try { - if (!ArrayUtils.isEmpty(mMobileIfaces)) { - delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats); + synchronized (mModemNetworkLock) { + final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces); + if (latestStats != null) { + delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null, + mNetworkStatsPool.acquire()); + mNetworkStatsPool.release(mLastModemNetworkStats); + mLastModemNetworkStats = latestStats; } - } catch (IOException e) { - Slog.wtf(TAG, "Failed to get mobile network stats", e); - return; - } - - if (!mOnBatteryInternal) { - return; } - long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( - elapsedRealtimeMs * 1000); - mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); - - long totalRxPackets = 0; - long totalTxPackets = 0; - if (delta != null) { - final int size = delta.size(); - for (int i = 0; i < size; i++) { - final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); - if (entry.rxPackets == 0 && entry.txPackets == 0) { - continue; - } - - if (DEBUG_ENERGY) { - Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes - + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets - + " txPackets=" + entry.txPackets); - } - - totalRxPackets += entry.rxPackets; - totalTxPackets += entry.txPackets; - - final Uid u = getUidStatsLocked(mapUid(entry.uid)); - u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, entry.rxPackets); - u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, entry.txPackets); - if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers - u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, - entry.rxBytes, entry.rxPackets); - u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, - entry.txBytes, entry.txPackets); + synchronized (this) { + if (!mOnBatteryInternal) { + if (delta != null) { + mNetworkStatsPool.release(delta); } - - mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( - entry.rxBytes); - mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( - entry.txBytes); - mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( - entry.rxPackets); - mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( - entry.txPackets); + return; } - // Now distribute proportional blame to the apps that did networking. - long totalPackets = totalRxPackets + totalTxPackets; - if (totalPackets > 0) { + final long elapsedRealtimeMs = SystemClock.elapsedRealtime(); + long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( + elapsedRealtimeMs * 1000); + mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); + + long totalRxPackets = 0; + long totalTxPackets = 0; + if (delta != null) { + NetworkStats.Entry entry = new NetworkStats.Entry(); + final int size = delta.size(); for (int i = 0; i < size; i++) { - final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); + entry = delta.getValues(i, entry); if (entry.rxPackets == 0 && entry.txPackets == 0) { continue; } - final Uid u = getUidStatsLocked(mapUid(entry.uid)); + if (DEBUG_ENERGY) { + Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes + + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets + + " txPackets=" + entry.txPackets); + } - // Distribute total radio active time in to this app. - final long appPackets = entry.rxPackets + entry.txPackets; - final long appRadioTime = (radioTime * appPackets) / totalPackets; - u.noteMobileRadioActiveTimeLocked(appRadioTime); + totalRxPackets += entry.rxPackets; + totalTxPackets += entry.txPackets; + + final Uid u = getUidStatsLocked(mapUid(entry.uid)); + u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, + entry.rxPackets); + u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, + entry.txPackets); + if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers + u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, + entry.rxBytes, entry.rxPackets); + u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, + entry.txBytes, entry.txPackets); + } - // Remove this app from the totals, so that we don't lose any time - // due to rounding. - radioTime -= appRadioTime; - totalPackets -= appPackets; + mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( + entry.rxBytes); + mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( + entry.txBytes); + mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( + entry.rxPackets); + mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( + entry.txPackets); + } - if (activityInfo != null) { - ControllerActivityCounterImpl activityCounter = - u.getOrCreateModemControllerActivityLocked(); - if (totalRxPackets > 0 && entry.rxPackets > 0) { - final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis()) - / totalRxPackets; - activityCounter.getRxTimeCounter().addCountLocked(rxMs); + // Now distribute proportional blame to the apps that did networking. + long totalPackets = totalRxPackets + totalTxPackets; + if (totalPackets > 0) { + for (int i = 0; i < size; i++) { + entry = delta.getValues(i, entry); + if (entry.rxPackets == 0 && entry.txPackets == 0) { + continue; } - if (totalTxPackets > 0 && entry.txPackets > 0) { - for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { - long txMs = entry.txPackets * activityInfo.getTxTimeMillis()[lvl]; - txMs /= totalTxPackets; - activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); + final Uid u = getUidStatsLocked(mapUid(entry.uid)); + + // Distribute total radio active time in to this app. + final long appPackets = entry.rxPackets + entry.txPackets; + final long appRadioTime = (radioTime * appPackets) / totalPackets; + u.noteMobileRadioActiveTimeLocked(appRadioTime); + + // Remove this app from the totals, so that we don't lose any time + // due to rounding. + radioTime -= appRadioTime; + totalPackets -= appPackets; + + if (activityInfo != null) { + ControllerActivityCounterImpl activityCounter = + u.getOrCreateModemControllerActivityLocked(); + if (totalRxPackets > 0 && entry.rxPackets > 0) { + final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis()) + / totalRxPackets; + activityCounter.getRxTimeCounter().addCountLocked(rxMs); + } + + if (totalTxPackets > 0 && entry.txPackets > 0) { + for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { + long txMs = + entry.txPackets * activityInfo.getTxTimeMillis()[lvl]; + txMs /= totalTxPackets; + activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); + } } } } } - } - if (radioTime > 0) { - // Whoops, there is some radio time we can't blame on an app! - mMobileRadioActiveUnknownTime.addCountLocked(radioTime); - mMobileRadioActiveUnknownCount.addCountLocked(1); - } - } + if (radioTime > 0) { + // Whoops, there is some radio time we can't blame on an app! + mMobileRadioActiveUnknownTime.addCountLocked(radioTime); + mMobileRadioActiveUnknownCount.addCountLocked(1); + } - if (activityInfo != null) { - mHasModemReporting = true; - mModemActivity.getIdleTimeCounter().addCountLocked(activityInfo.getIdleTimeMillis()); - mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis()); - for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { - mModemActivity.getTxTimeCounters()[lvl] - .addCountLocked(activityInfo.getTxTimeMillis()[lvl]); + mNetworkStatsPool.release(delta); + delta = null; } - // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. - final double opVolt = mPowerProfile.getAveragePower( - PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; - if (opVolt != 0) { - // We store the power drain as mAms. - mModemActivity.getPowerCounter().addCountLocked( - (long) (activityInfo.getEnergyUsed() / opVolt)); + if (activityInfo != null) { + mHasModemReporting = true; + mModemActivity.getIdleTimeCounter().addCountLocked( + activityInfo.getIdleTimeMillis()); + mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis()); + for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { + mModemActivity.getTxTimeCounters()[lvl] + .addCountLocked(activityInfo.getTxTimeMillis()[lvl]); + } + + // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. + final double opVolt = mPowerProfile.getAveragePower( + PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; + if (opVolt != 0) { + // We store the power drain as mAms. + mModemActivity.getPowerCounter().addCountLocked( + (long) (activityInfo.getEnergyUsed() / opVolt)); + } } } } @@ -11380,8 +11501,14 @@ public class BatteryStatsImpl extends BatteryStats { u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); } if (in.readInt() != 0) { + u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); + } + if (in.readInt() != 0) { u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); } + if (in.readInt() != 0) { + u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); + } u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { if (in.readInt() != 0) { @@ -11789,12 +11916,24 @@ public class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } + if (u.mBluetoothUnoptimizedScanTimer != null) { + out.writeInt(1); + u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); + } else { + out.writeInt(0); + } if (u.mBluetoothScanResultCounter != null) { out.writeInt(1); u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); } else { out.writeInt(0); } + if (u.mBluetoothScanResultBgCounter != null) { + out.writeInt(1); + u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); + } else { + out.writeInt(0); + } for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { if (u.mProcessStateTimer[i] != null) { out.writeInt(1); diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 192e3bb7028f..438b1233a286 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -208,8 +208,15 @@ public: void detachAnimators() { // Remove animators from the list and post a delayed message in future to end the animator + // For infinite animators, remove the listener so we no longer hold a global ref to the AVD + // java object, and therefore the AVD objects in both native and Java can be properly + // released. for (auto& anim : mRunningVDAnimators) { detachVectorDrawableAnimator(anim.get()); + anim->clearOneShotListener(); + } + for (auto& anim : mPausedVDAnimators) { + anim->clearOneShotListener(); } mRunningVDAnimators.clear(); mPausedVDAnimators.clear(); @@ -877,7 +884,8 @@ static jobject android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode( sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> rawConsumer; BufferQueue::createBufferQueue(&producer, &rawConsumer); - rawConsumer->setMaxBufferCount(1); + // We only need 1 buffer but some drivers have bugs so workaround it by setting max count to 2 + rawConsumer->setMaxBufferCount(2); sp<BufferItemConsumer> consumer = new BufferItemConsumer(rawConsumer, GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER); consumer->setDefaultBufferSize(width, height); diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index f747d3dfcba3..90ece60d324d 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3223,6 +3223,9 @@ <!-- Alert windows notification strings --> <skip /> + <!-- Name of notification channel group the system post notification to inform the use about apps + that are drawing ui on-top of other apps (alert-windows) [CHAR LIMIT=NONE] --> + <string name="alert_windows_notification_channel_group_name">Display over other apps</string> <!-- Name of notification channel the system post notification to inform the use about apps that are drawing ui on-top of other apps (alert-windows) [CHAR LIMIT=NONE] --> <string name="alert_windows_notification_channel_name"><xliff:g id="name" example="Google Maps">%s</xliff:g> displaying over other apps</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 8d2666e7c648..bfd40bd704e1 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2946,6 +2946,7 @@ <java-symbol type="drawable" name="resolver_icon_placeholder" /> <!-- Alert windows notification --> + <java-symbol type="string" name="alert_windows_notification_channel_group_name" /> <java-symbol type="string" name="alert_windows_notification_channel_name" /> <java-symbol type="string" name="alert_windows_notification_title" /> <java-symbol type="string" name="alert_windows_notification_message" /> diff --git a/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java b/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java index dd07a085b08e..3ddeef072a9e 100644 --- a/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java +++ b/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java @@ -16,16 +16,15 @@ package android.widget.touchmode; -import android.widget.layout.linear.LLEditTextThenButton; -import static android.util.TouchModeFlexibleAsserts.assertInTouchModeAfterTap; import static android.util.TouchModeFlexibleAsserts.assertInTouchModeAfterClick; +import static android.util.TouchModeFlexibleAsserts.assertInTouchModeAfterTap; import android.test.ActivityInstrumentationTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; -import android.view.KeyEvent; import android.widget.Button; import android.widget.EditText; +import android.widget.layout.linear.LLEditTextThenButton; /** * Some views, like edit texts, can keep and gain focus even when in touch mode. @@ -64,7 +63,8 @@ public class TouchModeFocusableTest extends ActivityInstrumentationTestCase<LLEd @LargeTest public void testClickEditTextGivesItFocus() { // go down to button - sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); + getActivity().runOnUiThread(() -> mButton.requestFocus()); + getInstrumentation().waitForIdleSync(); assertTrue("button should have focus", mButton.isFocused()); assertInTouchModeAfterClick(this, mEditText); @@ -77,11 +77,12 @@ public class TouchModeFocusableTest extends ActivityInstrumentationTestCase<LLEd // isn't focusable in touch mode. @LargeTest public void testEnterTouchModeGivesFocusBackToFocusableInTouchMode() { - sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); + getActivity().runOnUiThread(() -> mButton.requestFocus()); + getInstrumentation().waitForIdleSync(); assertTrue("button should have focus", mButton.isFocused()); - + assertInTouchModeAfterClick(this, mButton); assertTrue("should be in touch mode", mButton.isInTouchMode()); assertNull("nothing should have focus", getActivity().getCurrentFocus()); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java index 9aabdbb2c8f0..c539f789ff60 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java @@ -205,9 +205,9 @@ public class BatteryStatsBackgroundStatsTest extends TestCase { // App in foreground bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); - // Start timer + // Start timer (optimized) curr = 1000 * (clocks.realtime = clocks.uptime = 202); - bi.noteBluetoothScanStartedFromSourceLocked(ws); + bi.noteBluetoothScanStartedFromSourceLocked(ws, false); // Move to background curr = 1000 * (clocks.realtime = clocks.uptime = 254); @@ -221,21 +221,44 @@ public class BatteryStatsBackgroundStatsTest extends TestCase { curr = 1000 * (clocks.realtime = clocks.uptime = 409); bi.noteBluetoothScanStoppedFromSourceLocked(ws); + // Start timer (unoptimized) + curr = 1000 * (clocks.realtime = clocks.uptime = 1000); + bi.noteBluetoothScanStartedFromSourceLocked(ws, true); + + // On battery + curr = 1000 * (clocks.realtime = clocks.uptime = 2001); + bi.updateTimeBasesLocked(true, false, curr, curr); // on battery + + // Move to foreground + curr = 1000 * (clocks.realtime = clocks.uptime = 3004); + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); + + // Stop timer + curr = 1000 * (clocks.realtime = clocks.uptime = 4008); + bi.noteBluetoothScanStoppedFromSourceLocked(ws); + // Test - curr = 1000 * (clocks.realtime = clocks.uptime = 657); + curr = 1000 * (clocks.realtime = clocks.uptime = 5000); BatteryStats.Timer timer = bi.getUidStats().get(UID).getBluetoothScanTimer(); BatteryStats.Timer bgTimer = bi.getUidStats().get(UID).getBluetoothScanBackgroundTimer(); + BatteryStats.Timer badTimer = bi.getUidStats().get(UID).getBluetoothUnoptimizedScanTimer(); + BatteryStats.Timer badBgTimer = bi.getUidStats().get(UID) + .getBluetoothUnoptimizedScanBackgroundTimer(); long time = timer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED); int count = timer.getCountLocked(STATS_SINCE_CHARGED); int bgCount = bgTimer.getCountLocked(STATS_SINCE_CHARGED); long actualTime = timer.getTotalDurationMsLocked(clocks.realtime) * 1000; long bgTime = bgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000; - assertEquals((305 - 202) * 1000, time); - assertEquals(1, count); - assertEquals(0, bgCount); - assertEquals((305 - 202) * 1000, actualTime); - assertEquals((305 - 254) * 1000, bgTime); + long badTime = badTimer.getTotalDurationMsLocked(clocks.realtime) * 1000; + long badBgTime = badBgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000; + assertEquals((305 - 202 + 4008 - 2001) * 1000, time); + assertEquals(1, count); // second scan starts off-battery + assertEquals(0, bgCount); // first scan starts in fg, second starts off-battery + assertEquals((305 - 202 + 4008 - 2001) * 1000, actualTime); + assertEquals((305 - 254 + 3004 - 2001) * 1000, bgTime); + assertEquals((4008 - 2001) * 1000, badTime); + assertEquals((3004 - 2001) * 1000, badBgTime); } @SmallTest diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java new file mode 100644 index 000000000000..08f8dd146516 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.android.internal.os; + +import android.os.BatteryStats; +import android.os.Parcel; +import android.support.test.filters.SmallTest; + +import junit.framework.TestCase; + +/** + * Test BatteryStatsImpl.Counter. + */ +public class BatteryStatsCounterTest extends TestCase { + + @SmallTest + public void testCounter() throws Exception { + final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms + final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase(); + timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime()); + + final BatteryStatsImpl.Counter counter = new BatteryStatsImpl.Counter(timeBase); + + // timeBase off (i.e. plugged in) + timeBase.setRunning(false, 1, 1); + counter.stepAtomic(); + counter.stepAtomic(); + counter.stepAtomic(); + counter.stepAtomic(); + counter.stepAtomic(); + assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(0, counter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // timeBase on (i.e. unplugged) + timeBase.setRunning(true, 2, 2); + counter.stepAtomic(); + counter.stepAtomic(); + counter.stepAtomic(); + counter.stepAtomic(); + assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // timeBase off (i.e. plugged in) + timeBase.setRunning(false, 3, 3); + counter.stepAtomic(); + counter.stepAtomic(); + counter.stepAtomic(); + assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // timeBase on (i.e. unplugged) + timeBase.setRunning(true, 4, 4); + counter.stepAtomic(); + counter.stepAtomic(); + assertEquals(6, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(6, counter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(2, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + } + + + @SmallTest + public void testParceling() throws Exception { + final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms + final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase(); + timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime()); + + final BatteryStatsImpl.Counter origCounter = new BatteryStatsImpl.Counter(timeBase); + + // timeBase on (i.e. unplugged) + timeBase.setRunning(true, 1, 1); + origCounter.stepAtomic(); origCounter.stepAtomic(); origCounter.stepAtomic(); // three times + assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // Test summary parcelling (from origCounter) + final Parcel summaryParcel = Parcel.obtain(); + origCounter.writeSummaryFromParcelLocked(summaryParcel); + summaryParcel.setDataPosition(0); + final BatteryStatsImpl.Counter summaryCounter = new BatteryStatsImpl.Counter(timeBase); + summaryCounter.stepAtomic(); // occurs before reading the summary, so must not count later + summaryCounter.readSummaryFromParcelLocked(summaryParcel); + + // timeBase still on (i.e. unplugged) + summaryCounter.stepAtomic(); // once + assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // timeBase off (i.e. plugged in) + timeBase.setRunning(false, 3, 3); + summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice + assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // timeBase on (i.e. unplugged) + timeBase.setRunning(true, 4, 4); + summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice + assertEquals(6, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(3, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(2, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + + // Test full parcelling (from summaryCounter) + final Parcel fullParcel = Parcel.obtain(); + summaryCounter.writeToParcel(fullParcel); + fullParcel.setDataPosition(0); + final BatteryStatsImpl.Counter fullParcelCounter + = new BatteryStatsImpl.Counter(timeBase, fullParcel); + + // timeBase still on (i.e. unplugged) + fullParcelCounter.stepAtomic(); // once + assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // timeBase off (i.e. plugged in) + timeBase.setRunning(false, 5, 5); + fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice + assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + + // timeBase on (i.e. unplugged) + timeBase.setRunning(true, 6, 6); + fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice + assertEquals(9, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); + assertEquals(6, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT)); + assertEquals(2, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); + } +} 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 06ca18d072e7..4e8ab316e1c9 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java @@ -37,12 +37,28 @@ public class BatteryStatsNoteTest extends TestCase{ public void testNoteBluetoothScanResultLocked() throws Exception { MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks()); bi.updateTimeBasesLocked(true, true, 0, 0); + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); bi.noteBluetoothScanResultsFromSourceLocked(WS, 1); bi.noteBluetoothScanResultsFromSourceLocked(WS, 100); assertEquals(101, bi.getUidStats().get(UID).getBluetoothScanResultCounter() .getCountLocked(STATS_SINCE_CHARGED)); + // TODO: remove next line when Counter misreporting values when plugged-in bug is fixed. + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter(); + if (bgCntr != null) { + assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED)); + } + + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + bi.noteBluetoothScanResultsFromSourceLocked(WS, 17); + assertEquals(101 + 17, + bi.getUidStats().get(UID).getBluetoothScanResultCounter() + .getCountLocked(STATS_SINCE_CHARGED)); + assertEquals(17, + bi.getUidStats().get(UID).getBluetoothScanResultBgCounter() + .getCountLocked(STATS_SINCE_CHARGED)); } /** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */ diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java index 3a16fcff38a2..1412d3e7df59 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java @@ -5,17 +5,18 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ + BatteryStatsBackgroundStatsTest.class, + BatteryStatsCounterTest.class, BatteryStatsDualTimerTest.class, BatteryStatsDurationTimerTest.class, + BatteryStatsNoteTest.class, BatteryStatsSamplingTimerTest.class, + BatteryStatsSensorTest.class, BatteryStatsServTest.class, BatteryStatsStopwatchTimerTest.class, BatteryStatsTimeBaseTest.class, BatteryStatsTimerTest.class, BatteryStatsUidTest.class, - BatteryStatsSensorTest.class, - BatteryStatsBackgroundStatsTest.class, - BatteryStatsNoteTest.class, }) public class BatteryStatsTests { } diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 02a9ffa3039c..9c80ab304b80 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -436,8 +436,15 @@ void CanvasContext::draw() { swap.vsyncTime = mRenderThread.timeLord().latestVsync(); if (mNativeSurface.get()) { int durationUs; - mNativeSurface->query(NATIVE_WINDOW_LAST_DEQUEUE_DURATION, &durationUs); - swap.dequeueDuration = us2ns(durationUs); + nsecs_t dequeueStart = mNativeSurface->getLastDequeueStartTime(); + if (dequeueStart < mCurrentFrameInfo->get(FrameInfoIndex::SyncStart)) { + // Ignoring dequeue duration as it happened prior to frame render start + // and thus is not part of the frame. + swap.dequeueDuration = 0; + } else { + mNativeSurface->query(NATIVE_WINDOW_LAST_DEQUEUE_DURATION, &durationUs); + swap.dequeueDuration = us2ns(durationUs); + } mNativeSurface->query(NATIVE_WINDOW_LAST_QUEUE_DURATION, &durationUs); swap.queueDuration = us2ns(durationUs); } else { diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 6cab56c1d466..2de69e7bc1de 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -75,12 +75,12 @@ import java.util.Map; <h4>Compressed Buffers</h4> <p> Input buffers (for decoders) and output buffers (for encoders) contain compressed data according - to the {@linkplain MediaFormat#KEY_MIME format's type}. For video types this is a single + to the {@linkplain MediaFormat#KEY_MIME format's type}. For video types this is normally a single compressed video frame. For audio data this is normally a single access unit (an encoded audio segment typically containing a few milliseconds of audio as dictated by the format type), but this requirement is slightly relaxed in that a buffer may contain multiple encoded access units of audio. In either case, buffers do not start or end on arbitrary byte boundaries, but rather on - frame/access unit boundaries. + frame/access unit boundaries unless they are flagged with {@link #BUFFER_FLAG_PARTIAL_FRAME}. <h4>Raw Audio Buffers</h4> <p> diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java index 5522d362bc09..799f4bf4f866 100644 --- a/media/java/android/media/MediaSync.java +++ b/media/java/android/media/MediaSync.java @@ -35,7 +35,7 @@ import java.util.LinkedList; import java.util.List; /** - * MediaSync class can be used to synchronously playback audio and video streams. + * MediaSync class can be used to synchronously play audio and video streams. * It can be used to play audio-only or video-only stream, too. * * <p>MediaSync is generally used like this: diff --git a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml index 2f0a411448a5..232459338f48 100644 --- a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml +++ b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml @@ -4,31 +4,35 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity" - tools:ignore="MergeRootFrame"> + tools:ignore="MergeRootFrame" > + <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > - <TextView - android:id="@+id/url_bar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textSize="20sp" - android:singleLine="true" /> + <FrameLayout + android:layout_width="match_parent" + android:layout_height="4dp" > - <ProgressBar - android:id="@+id/progress_bar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - style="?android:attr/progressBarStyleHorizontal" /> + <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container --> + <ProgressBar + android:id="@+id/progress_bar" + style="@android:style/Widget.Material.Light.ProgressBar.Horizontal" + android:indeterminate="false" + android:max="100" + android:progress="0" + android:layout_gravity="center" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + </FrameLayout> - <WebView - android:id="@+id/webview" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignParentBottom="false" - android:layout_alignParentRight="false" /> + <WebView + android:id="@+id/webview" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentBottom="false" + android:layout_alignParentRight="false" /> -</LinearLayout> + </LinearLayout> </FrameLayout> diff --git a/packages/CaptivePortalLogin/res/values/styles.xml b/packages/CaptivePortalLogin/res/values/styles.xml index 4a99638aec95..f6c233954b52 100644 --- a/packages/CaptivePortalLogin/res/values/styles.xml +++ b/packages/CaptivePortalLogin/res/values/styles.xml @@ -4,7 +4,7 @@ Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> - <style name="AppBaseTheme" parent="@android:style/Theme.Material.Settings"> + <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to @@ -15,8 +15,5 @@ <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> - <!-- Setting's theme's accent color makes ProgressBar useless, reset back. --> - <item name="android:colorAccent">@*android:color/material_deep_teal_500</item> </style> - </resources> diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index c9fba95bc828..401a7bca525c 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -37,6 +37,7 @@ import android.util.Log; import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; +import android.view.View; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; import android.webkit.WebSettings; @@ -97,8 +98,6 @@ public class CaptivePortalLoginActivity extends Activity { // setContentView initializes the WebView logic which in turn reads the system properties. setContentView(R.layout.activity_captive_portal_login); - getActionBar().setDisplayShowHomeEnabled(false); - // Exit app if Network disappears. final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork); if (networkCapabilities == null) { @@ -117,9 +116,14 @@ public class CaptivePortalLoginActivity extends Activity { } mCm.registerNetworkCallback(builder.build(), mNetworkCallback); - final WebView myWebView = findViewById(R.id.webview); - myWebView.clearCache(true); - WebSettings webSettings = myWebView.getSettings(); + getActionBar().setDisplayShowHomeEnabled(false); + getActionBar().setElevation(0); // remove shadow + getActionBar().setTitle(getHeaderTitle()); + getActionBar().setSubtitle(""); + + final WebView webview = getWebview(); + webview.clearCache(true); + WebSettings webSettings = webview.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); webSettings.setUseWideViewPort(true); @@ -128,11 +132,11 @@ public class CaptivePortalLoginActivity extends Activity { webSettings.setBuiltInZoomControls(true); webSettings.setDisplayZoomControls(false); mWebViewClient = new MyWebViewClient(); - myWebView.setWebViewClient(mWebViewClient); - myWebView.setWebChromeClient(new MyWebChromeClient()); + webview.setWebViewClient(mWebViewClient); + webview.setWebChromeClient(new MyWebChromeClient()); // Start initial page load so WebView finishes loading proxy settings. // Actual load of mUrl is initiated by MyWebViewClient. - myWebView.loadData("", "text/html", null); + webview.loadData("", "text/html", null); } // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties. @@ -251,10 +255,14 @@ public class CaptivePortalLoginActivity extends Activity { if (url == null) { url = mCm.getCaptivePortalServerUrl(); } + return makeURL(url); + } + + private static URL makeURL(String url) { try { return new URL(url); } catch (MalformedURLException e) { - Log.e(TAG, "Invalid captive portal URL " + url); + Log.e(TAG, "Invalid URL " + url); } return null; } @@ -331,15 +339,16 @@ public class CaptivePortalLoginActivity extends Activity { // For internally generated pages, leave URL bar listing prior URL as this is the URL // the page refers to. if (!url.startsWith(INTERNAL_ASSETS)) { - final TextView myUrlBar = findViewById(R.id.url_bar); - myUrlBar.setText(url); + getActionBar().setSubtitle(getHeaderSubtitle(url)); } + getProgressBar().setVisibility(View.VISIBLE); testForCaptivePortal(); } @Override public void onPageFinished(WebView view, String url) { mPagesLoaded++; + getProgressBar().setVisibility(View.INVISIBLE); if (mPagesLoaded == 1) { // Now that WebView has loaded at least one page we know it has read in the proxy // settings. Now prompt the WebView read the Network-specific proxy settings. @@ -412,8 +421,31 @@ public class CaptivePortalLoginActivity extends Activity { private class MyWebChromeClient extends WebChromeClient { @Override public void onProgressChanged(WebView view, int newProgress) { - final ProgressBar myProgressBar = findViewById(R.id.progress_bar); - myProgressBar.setProgress(newProgress); + getProgressBar().setProgress(newProgress); + } + } + + private ProgressBar getProgressBar() { + return findViewById(R.id.progress_bar); + } + + private WebView getWebview() { + return findViewById(R.id.webview); + } + + private String getHeaderTitle() { + return getString(R.string.action_bar_label); + } + + private String getHeaderSubtitle(String urlString) { + URL url = makeURL(urlString); + if (url == null) { + return urlString; + } + final String https = "https"; + if (https.equals(url.getProtocol())) { + return https + "://" + url.getHost(); } + return url.getHost(); } } diff --git a/packages/SettingsLib/res/layout/usage_view.xml b/packages/SettingsLib/res/layout/usage_view.xml index 151d1ee3b899..da66814f49cb 100644 --- a/packages/SettingsLib/res/layout/usage_view.xml +++ b/packages/SettingsLib/res/layout/usage_view.xml @@ -76,7 +76,7 @@ android:id="@+id/bottom_label_space" android:layout_width="@dimen/usage_graph_labels_width" android:layout_height="wrap_content"/> - <LinearLayout + <com.android.settingslib.graph.BottomLabelLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" @@ -86,13 +86,14 @@ layout="@layout/usage_side_label" /> <Space - android:layout_width="0dp" + android:id="@+id/spacer" + android:layout_width="40dp" android:layout_height="wrap_content" android:layout_weight="1" /> <include android:id="@+id/label_end" layout="@layout/usage_side_label" /> - </LinearLayout> + </com.android.settingslib.graph.BottomLabelLayout> </LinearLayout> </LinearLayout> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 4f5281251314..337a8eb2dd39 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Agtergrondproses-limiet"</string> <string name="show_all_anrs" msgid="28462979638729082">"Wys alle ANRe"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Wys Program reageer nie-dialoog vir agtergrond programme"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Wys kennisgewingkanaalwaarskuwings"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Wys waarskuwing op skerm wanneer \'n program \'n kennisgewing sonder \'n geldige kanaal plaas"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Programme verplig ekstern toegelaat"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Maak dat enige program in eksterne berging geskryf kan word, ongeag manifeswaardes"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Verplig verstelbare groottes vir aktiwiteite"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 465e253de9d9..645aa499e5da 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"የዳራ አሂድ ወሰን"</string> <string name="show_all_anrs" msgid="28462979638729082">"ሁሉንም ANRs አሳይ"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"ለዳራ መተግበሪያዎች ምላሽ የማይሰጥ መገናኛ ትግበራ አሳይ"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"የማሳወቂያ ሰርጥ ማስጠንቀቂያዎችን አሳይ"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"አንድ መተግበሪያ የሚሰራ ሰርጥ ሳይኖረው ማሳወቂያ ሲለጥፍ በማያ ገጽ-ላይ ማስጠንቀቂያን ያሳያል"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"በውጫዊ ላይ ሃይል ይፈቀዳል"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"የዝርዝር ሰነዶች እሴቶች ግምት ውስጥ ሳያስገባ ማንኛውም መተግበሪያ ወደ ውጫዊ ማከማቻው ለመጻፍ ብቁ ያደርጋል"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"እንቅስቃሴዎች ዳግመኛ እንዲመጣጠኑ አስገድድ"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index a4ee8fd5568c..897d4734715e 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"حد العمليات بالخلفية"</string> <string name="show_all_anrs" msgid="28462979638729082">"عرض جميع رسائل ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"عرض مربع الحوار \"التطبيق لا يستجيب\" مع تطبيقات الخلفية"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"عرض تحذيرات قناة الإشعار"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"لعرض تحذير على الشاشة عند نشر تطبيق ما لإشعار بدون قناة صالحة"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"فرض السماح للتطبيقات على الخارجي"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"تأهيل أي تطبيق بحيث تتم كتابته على وحدة تخزين خارجية، بغض النظر عن قيم البيان"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"فرض إمكانية تغيير على الأنشطة"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 690e589e229e..4144593f9315 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Fon prosesi limiti"</string> <string name="show_all_anrs" msgid="28462979638729082">"Bütün ANRları göstər"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Arxa tətbiqlər dialoquna cavab verməyən tətbiqi göstər"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Xəbərdarlıqları göstərin"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Bildiriş paylaşıldıqda xəbərdarlıq göstərir"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Tətbiqlərə xaricdən məcburi icazə"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Seçilmiş hər hansı tətbiqi bəyannamə dəyərlərindən aslı olmayaraq xarici yaddaşa yazılabilən edir."</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Ölçü dəyişdirmək üçün məcburi fəaliyyətlər"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index e59dac6e1c52..73f0de0d5eb6 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje pozadinskih procesa"</string> <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Prikaži dijalog Aplikacija ne reaguje za aplikacije u pozadini"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Prikazuj upozorenja zbog kanala za obaveštenja"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Prikazuje upozorenje na ekranu kada aplikacija postavi obaveštenje bez važećeg kanala"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Prinudno dozvoli aplikacije u spoljnoj"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Prinudno omogući promenu veličine aktivnosti"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index b1ec867876c3..2e8aa9f1dcb5 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Ліміт фонавага працэсу"</string> <string name="show_all_anrs" msgid="28462979638729082">"Паказаць усе ANRS"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Паказаць дыялогавае акно \"Праграма не адказвае\" для фонавых прыкладанняў"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Паказваць папярэджанні канала апавяшчэннаў"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Паказвае папярэджанне на экране, калі праграма публікуе апавяшчэнне без сапраўднага канала"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Прымусова дазволіць праграмы на вонкавым сховішчы"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Робіць любую праграму даступнай для запісу на вонкавае сховішча, незалежна ад значэнняў маніфеста"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Зрабіць вокны дзеянняў даступнымі для змены памеру"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index a8039eb0a8bc..4e24cec10e0d 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Лимит за фонови процеси"</string> <string name="show_all_anrs" msgid="28462979638729082">"Всички нереагиращи прил."</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Диалог. прозорец „НП“ за приложения на заден план"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Предупрежд. за канала за известия"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Показва се предупреждение, когато приложение публикува известие без валиден канал"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Външно хран.: Принуд. разрешаване на приложенията"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Прави всички приложения да отговарят на условията да бъдат записвани във външното хранилище независимо от стойностите в манифеста"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Възможност за преоразмеряване на активностите"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 3f0de25ba7f2..6fb79cb4d85c 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"পশ্চাদপট প্রক্রিয়ার সীমা"</string> <string name="show_all_anrs" msgid="28462979638729082">"সব ANR দেখান"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"পশ্চাদপটের অ্যাপ্লিকেশানগুলির জন্য অ্যাপ্লিকেশান কোনো প্রতিক্রিয়া দিচ্ছে না এমন কথোপকথন দেখান"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"বিজ্ঞপ্তির সতর্কতা দেখুন"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"অ্যাপ সঠিক চ্যানেল ছাড়া বিজ্ঞপ্তি দেখালে সতর্ক করে"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"বহিরাগততে বলপূর্বক মঞ্জুরি"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ম্যানিফেস্ট মানগুলি নির্বিশেষে যেকোনো অ্যাপ্লিকেশানকে বাহ্যিক সঞ্চয়স্থানে লেখার উপযুক্ত বানায়"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"আকার পরিবর্তনযোগ্য করার জন্য ক্রিয়াকলাপগুলিকে জোর করুন"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index f91a8a8f559c..be036953c992 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje procesa u pozadini"</string> <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Prik. dijalog Aplikacija ne reagira za apl. u poz."</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Prikaz upozorenja na obavještenju o kanalu"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Prikaz upozorenja ekranu kada aplikacija pošalje obavještenje bez važećeg kanala."</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Nametni aplikacije na vanjskoj pohrani"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Omogućava da svaka aplikacija bude pogodna za upisivanje na vanjsku pohranu, bez obzira na prikazane vrijednosti"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Nametni aktivnostima mijenjanje veličina"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 99c5d37bd2c5..a56d9946ebd7 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Límita processos en segon pla"</string> <string name="show_all_anrs" msgid="28462979638729082">"Tots els errors sense resposta"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Informa que una aplicació en segon pla no respon"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Avisos del canal de notificacions"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Mostra un avís a la pantalla quan una app publica una notificació sense canal vàlid"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Força permís d\'aplicacions a l\'emmagatzem. extern"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Permet que qualsevol aplicació es pugui escriure en un dispositiu d’emmagatzematge extern, independentment dels valors definits"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Força l\'ajust de la mida de les activitats"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 7b3fb86ff72d..36b372022aa9 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Omezení procesů na pozadí"</string> <string name="show_all_anrs" msgid="28462979638729082">"Zobrazit všechny ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Zobrazovat dialog „Aplikace neodpovídá“ pro aplikace na pozadí"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Zobrazovat upozornění ohledně kanálu oznámení"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Když aplikace odešle oznámení bez platného kanálu, na obrazovce se zobrazí upozornění"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Vynutit povolení aplikací na externím úložišti"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Každou aplikaci bude možné zapsat do externího úložiště, bez ohledu na hodnoty manifestu"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Vynutit možnost změny velikosti aktivit"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 6ccf45baf308..a549082b68c3 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Grænse for baggrundsprocesser"</string> <string name="show_all_anrs" msgid="28462979638729082">"Vis alle \"Appen svarer ikke\""</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Vis \"Appen svarer ikke\" for baggrundsapps"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Vis advarsler om underretningskanal"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Viser en advarsel, når en app sender en underretning uden en gyldig kanal"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Gennemtving tilladelse til eksternt lager"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Gør det muligt at overføre enhver app til et eksternt lager uafhængigt af manifestværdier"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Tving aktiviteter til at kunne tilpasses"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index db58ab2886f9..af31792927c7 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Hintergrundprozesslimit"</string> <string name="show_all_anrs" msgid="28462979638729082">"Alle ANRS anzeigen"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Dialogfeld \"App antwortet nicht\" für Hintergrund-Apps anzeigen"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Warnungen für Benachrichtigungskanäle einblenden"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Blendet Warnungen auf dem Display ein, wenn eine App eine Benachrichtigung ohne gültigen Kanal sendet"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Externe Speichernutzung von Apps erlauben"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Ermöglicht es jeder qualifizierten App, Daten auf externen Speicher zu schreiben, unabhängig von den Manifestwerten"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Anpassen der Größe von Aktivitäten erzwingen"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index cde206669b31..43f0f2ce5e81 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Όριο διεργασ. παρασκηνίου"</string> <string name="show_all_anrs" msgid="28462979638729082">"Εμφάνιση όλων των ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Εμφ.του παραθ. \"Η εφαρμ.δεν αποκρ.\" για εφ.παρασκ."</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Εμφάνιση προειδοπ. καναλιού ειδοπ."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Εμφανίζει προειδοποίηση όταν μια εφαρμογή δημοσιεύει ειδοποίηση χωρίς έγκυρο κανάλι"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Να επιτρέπονται υποχρεωτικά εφαρμογές σε εξωτ.συσ."</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Κάνει κάθε εφαρμογή κατάλληλη για εγγραφή σε εξωτερικό αποθηκευτικό χώρο, ανεξάρτητα από τις τιμές του μανιφέστου"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Αναγκαστική δυνατότητα αλλαγής μεγέθους δραστηριοτήτων"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index b25254575d7c..93e1aa8d9e75 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Background process limit"</string> <string name="show_all_anrs" msgid="28462979638729082">"Show all ANRs"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Show App Not Responding dialogue for background apps"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Show notification channel warnings"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Displays on-screen warning when an app posts a notification without a valid channel"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be re-sizable"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index b25254575d7c..93e1aa8d9e75 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Background process limit"</string> <string name="show_all_anrs" msgid="28462979638729082">"Show all ANRs"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Show App Not Responding dialogue for background apps"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Show notification channel warnings"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Displays on-screen warning when an app posts a notification without a valid channel"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be re-sizable"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index b25254575d7c..93e1aa8d9e75 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Background process limit"</string> <string name="show_all_anrs" msgid="28462979638729082">"Show all ANRs"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Show App Not Responding dialogue for background apps"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Show notification channel warnings"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Displays on-screen warning when an app posts a notification without a valid channel"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Force activities to be re-sizable"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 03d8cea9b160..16d34a210c42 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Límite de procesos en segundo plano"</string> <string name="show_all_anrs" msgid="28462979638729082">"Errores sin respuesta"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Mostrar diálogo cuando las aplic. en 2do plano no responden"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Alertas de notificaciones"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"App que publica notificación sin canal válido"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forzar permisos en almacenamiento externo"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Cualquier app puede escribirse en un almacenamiento externo, sin importar los valores del manifiesto"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forzar actividades para que cambien de tamaño"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 00dbf9c86df3..b7e368490cd3 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Límitar procesos en segundo plano"</string> <string name="show_all_anrs" msgid="28462979638729082">"Errores sin respuesta"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Informar de que una aplicación en segundo plano no responde"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Ver advertencias canal notificaciones"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Muestra advertencia en pantalla cuando app publica notificación sin canal válido"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forzar permiso de aplicaciones de forma externa"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Hace que cualquier aplicación se pueda escribir en un dispositivo de almacenamiento externo, independientemente de los valores definidos"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forzar el ajuste de tamaño de las actividades"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 4d0f5f653a18..b1a40a8c5bd2 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Taustaprotsesside piir"</string> <string name="show_all_anrs" msgid="28462979638729082">"Näita kõiki ANR-e"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Kuva taustarakendustele dial. Rakendus ei reageeri"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Kuva märguandekan. hoiat."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Esitab ekraanil hoiatuse, kui rakendus postitab kehtiva kanalita märguande"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Luba rakendused välises salvestusruumis"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Lubab mis tahes rakendusi kirjutada välisesse salvestusruumi manifesti väärtustest olenemata"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Muuda tegevuste suurused muudetavaks"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 6ed2d75af9f5..2b6d9640f36d 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Atzeko planoko prozesuen muga"</string> <string name="show_all_anrs" msgid="28462979638729082">"Erakutsi ANR guztiak"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"\"Erantzunik ez\" mezua atz. planoko aplikazioetarako"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Erakutsi jakinarazpenen kanaleko abisuak"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Bistaratu abisuak aplikazioek baliozko kanalik gabeko jakinarazpenak argitaratzean"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Behartu aplikazioak onartzea kanpoko biltegian"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Aplikazioek kanpoko memorian idatz dezakete, manifestuaren balioak kontuan izan gabe"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Behartu jardueren tamaina doitu ahal izatea"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index bb10b381d508..ff76b6080102 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"محدودیت پردازش در پسزمینه"</string> <string name="show_all_anrs" msgid="28462979638729082">"نمایش تمام ANRها"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"نمایش گفتگوی \"برنامه پاسخ نمیدهد\" برای برنامههای پسزمینه"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"نمایش هشدارهای کانال اعلان"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"هنگامی که برنامهای بدون وجود کانالی معتبر، اعلانی پست میکند، هشدار روی صفحهای نمایش میدهد"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"اجازه اجباری به برنامههای دستگاه ذخیره خارجی"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"بدون توجه به مقادیر مانیفست، هر برنامهای را برای نوشتن در حافظه خارجی واجد شرایط میکند"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"اجبار فعالیتها به قابل تغییر اندازه بودن"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 7dd2e5837bc4..b6759920e34f 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Taustaprosessi"</string> <string name="show_all_anrs" msgid="28462979638729082">"Näytä kaikki ANR:t"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Näytä Sovellus ei vastaa -ikkuna taustasovell."</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Näytä ilmoituskanavan varoitukset"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Näyttää varoituksen, kun sovellus julkaisee ilmoituksen ilman kelvollista kanavaa."</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Salli aina ulkoinen tallennus"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Mahdollistaa sovelluksen tietojen tallentamisen ulkoiseen tallennustilaan luetteloarvoista riippumatta."</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Pakota kaikki toiminnot hyväksymään koon muutos"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index 5641d7c576b1..7488df782144 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limite processus arr.-plan"</string> <string name="show_all_anrs" msgid="28462979638729082">"Afficher tous les messages «L\'application ne répond pas»"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Afficher « L\'application ne répond plus » pour applis en arrière-plan"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Affich. avertiss. canal notification"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Afficher avertiss. à l\'écran quand une app présente une notific. sans canal valide"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forcer l\'autor. d\'applis sur stockage externe"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Rend possible l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forcer les activités à être redimensionnables"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index b0b532f555a8..c6562e2893f4 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limite processus arr.-plan"</string> <string name="show_all_anrs" msgid="28462979638729082">"Afficher tous les messages ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Afficher \"L\'application ne répond plus\" pour applis en arrière-plan"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Voir avertissements liés aux canaux notification"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Affiche avertissement lorsqu\'une application publie notification sans canal valide"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forcer disponibilité stockage externe pour applis"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Rend possible l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste."</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forcer possibilité de redimensionner les activités"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 81a1ca943133..2fc72cbfcf49 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Límite proceso 2º plano"</string> <string name="show_all_anrs" msgid="28462979638729082">"Mostrar todos os ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Informa que aplicación segundo plano non responde"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostrar avisos de notificacións"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Mostra avisos cando unha aplicación publica notificacións sen unha canle válida"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forzar permiso de aplicacións de forma externa"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Permite que calquera aplicación apta se poida escribir nun almacenamento externo, independentemente dos valores expresados"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forzar o axuste do tamaño das actividades"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index e4e1507d79ef..ed1a38235d43 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"પૃષ્ઠભૂમિ પ્રક્રિયા સીમા"</string> <string name="show_all_anrs" msgid="28462979638729082">"બધા ANR બતાવો"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"પૃષ્ઠભૂમિ ઍપ્લિકેશનો માટે ઍપ્લિકેશન પ્રતિસાદ આપતી નથી સંવાદ બતાવો"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"સૂચના ચૅનલની ચેતવણી બતાવો"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ઍપ્લિકેશન માન્ય ચૅનલ વિના સૂચના પોસ્ટ કરે તો સ્ક્રીન પર ચેતવણી દેખાય છે"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"બાહ્ય પર એપ્લિકેશનોને મંજૂરી આપવાની ફરજ પાડો"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"મેનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, કોઈપણ ઍપ્લિકેશનને બાહ્ય સ્ટોરેજ પર લખાવા માટે લાયક બનાવે છે"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"પ્રવૃત્તિઓને ફરીથી કદ યોગ્ય થવા માટે ફરજ પાડો"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 936e7755df8d..a4a75c51d650 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"पृष्ठभूमि प्रक्रिया सीमा"</string> <string name="show_all_anrs" msgid="28462979638729082">"सभी ANR दिखाएं"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"पृष्ठभूमि ऐप्स के लिए ऐप्स प्रतिसाद नहीं दे रहा डॉयलॉग दिखाएं"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"नोटिफ़िकेशन चैनल चेतावनी दिखाएं"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ऐप्लिकेशन मान्य चैनल के बिना नोटिफ़िकेशन पोस्ट करे तो स्क्रीन पर चेतावनी दिखाएं"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"ऐप्स को बाहरी मेमोरी पर बाध्य करें"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"इससे कोई भी ऐप्लिकेशन, मेनिफेस्ट मानों को अनदेखा करके, बाहरी मेमोरी पर लिखने योग्य बन जाता है"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"आकार बदले जाने के लिए गतिविधियों को बाध्य करें"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index be4ac19cd35d..f4a7497cfd02 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Ograničenje pozadinskog procesa"</string> <string name="show_all_anrs" msgid="28462979638729082">"Prikaži sve ANR-ove"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Prikaz dijaloga o pozad. aplik. koja ne odgovara"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Prikaži upozorenja kanala obavijesti"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Prikazuje upozorenje na zaslonu kada aplikacija objavi obavijest bez važećeg kanala"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Prisilno dopusti aplikacije u vanjskoj pohrani"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Aplikacije se mogu zapisivati u vanjsku pohranu neovisno o vrijednostima manifesta"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Nametni mogućnost promjene veličine za aktivnosti"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index b791178bcfc1..f8007824f331 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Háttérfolyamat-korlátozás"</string> <string name="show_all_anrs" msgid="28462979638729082">"Összes ANR mutatása"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Az Alkalmazás nem válaszol ablak megjelenítése"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Értesítő csatorna figyelmeztetései"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Figyelmeztet, ha egy alkalmazás érvényes csatorna nélkül küld értesítést"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Külső tárhely alkalmazásainak engedélyezése"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Lehetővé teszi bármely alkalmazás külső tárhelyre való írását a jegyzékértékektől függetlenül"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Tevékenységek átméretezésének kényszerítése"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index da34cccd2af9..7643240a981a 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Հետնաշերտի գործընթացի սահմանաչափ"</string> <string name="show_all_anrs" msgid="28462979638729082">"Ցույց տալ բոլոր ANR-երը"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Ցուցադրել այն ծրագիրը, որը չի արձագանքում երկխոսությունը հետնաշերտի ծրագրերի համար"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Ցուցադրել ծանուցումների ալիքի զգուշացումները"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Էկրանին ցուցադրվում է զգուշացում, երբ որևէ հավելված փակցնում է ծանուցում առանց վավեր ալիքի"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Միշտ թույլատրել ծրագրեր արտաքին պահեստում"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Թույլ է տալիս ցանկացած հավելված պահել արտաքին սարքում՝ մանիֆեստի արժեքներից անկախ"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Ստիպել, որ ակտիվությունների չափերը լինեն փոփոխելի"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 13407fe79c48..3aea66b8dc66 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Batas proses latar blkg"</string> <string name="show_all_anrs" msgid="28462979638729082">"Tampilkan semua ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Tmplkn dialog Apl Tidak Merespons utk apl ltr blkg"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Menampilkan peringatan channel notifikasi"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Menampilkan peringatan di layar saat aplikasi memposting notifikasi tanpa channel yang valid"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Paksa izinkan aplikasi di eksternal"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Membuat semua aplikasi dapat ditulis ke penyimpanan eksternal, terlepas dari nilai manifes"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Paksa aktivitas agar ukurannya dapat diubah"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 6457e71306a6..9e3eb2203fb2 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Takmörkun á bakgrunnsvinnslum"</string> <string name="show_all_anrs" msgid="28462979638729082">"Öll forrit sem svara ekki"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Sýna „Forrit svarar ekki“ fyrir bakgrunnsforrit"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Sýna viðvaranir tilkynningarásar"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Birtir viðvörun á skjánum þegar forrit birtir tilkynningu án gildrar rásar"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Þvinga fram leyfi forrita í ytri geymslu"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Gerir öll forrit skrifanleg í ytra geymslurými, óháð gildum í upplýsingaskrá"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Þvinga breytanlega stærð virkni"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 518273018044..5681b76bbd2f 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limite processi background"</string> <string name="show_all_anrs" msgid="28462979638729082">"Mostra tutti errori ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Mostra finestra ANR per applicazioni in background"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostra avvisi canale di notifica"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Viene mostrato un avviso sullo schermo quando un\'app pubblica una notifica senza un canale valido"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forza autorizzazione app su memoria esterna"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Consente l\'installazione di qualsiasi app su memoria esterna, indipendentemente dai valori manifest"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Imponi formato modificabile alle attività"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 249fac472996..d0a8d583a509 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -192,11 +192,11 @@ <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string> <string name="wifi_aggressive_handover_summary" msgid="7266329646559808827">"כשאפשרות זו מופעלת, Wi-Fi יתנהג בצורה אגרסיבית יותר בעת העברת חיבור הנתונים לרשת הסלולרית כשאות ה-Wi-Fi חלש."</string> <string name="wifi_allow_scan_with_traffic_summary" msgid="2575101424972686310">"התר/מנע סריקות נדידה של Wi-Fi בהתבסס על נפח תנועת הנתונים הקיימת בממשק"</string> - <string name="select_logd_size_title" msgid="7433137108348553508">"גדלי מאגר של יוצר יומן"</string> + <string name="select_logd_size_title" msgid="7433137108348553508">"גדלי מאגר של יומן רישום"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"בחר גדלים של יוצר יומן לכל מאגר יומן"</string> <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"האם למחוק את אחסון המתעד המתמיד?"</string> <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"כשאנחנו כבר לא מבצעים מעקב באמצעות המתעד המתמיד, אנחנו נדרשים למחוק את נתוני המתעד המקומי במכשיר."</string> - <string name="select_logpersist_title" msgid="7530031344550073166">"אחסון נתוני מתעד מתמיד במכשיר"</string> + <string name="select_logpersist_title" msgid="7530031344550073166">"אחסון מתמיד של נתוני תיעוד במכשיר"</string> <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"בחר מאגר נתונים זמני ליומן לשם אחסון מתמיד במכשיר"</string> <string name="select_usb_configuration_title" msgid="2649938511506971843">"בחר תצורת USB"</string> <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"בחר תצורת USB"</string> @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"מגבלה של תהליכים ברקע"</string> <string name="show_all_anrs" msgid="28462979638729082">"הצג את כל פריטי ה-ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"הצג תיבת דו-שיח של \'אפליקציה לא מגיבה\' עבור אפליקציות שפועלות ברקע"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"אזהרות לגבי ערוץ הודעות"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"הצגת אזהרה כשאפליקציה שולחת הודעה ללא ערוץ חוקי"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"אילוץ הרשאת אפליקציות באחסון חיצוני"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"מאפשר כתיבה של כל אפליקציה באחסון חיצוני, ללא התחשבות בערכי המניפסט"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"אלץ יכולת קביעת גודל של הפעילויות"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 8837e9734d3e..403677fb6d7b 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"バックグラウンドプロセスの上限"</string> <string name="show_all_anrs" msgid="28462979638729082">"すべてのANRを表示"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"バックグラウンドアプリが応答しない場合に通知する"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"通知チャネルの警告を表示"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"アプリから有効なチャネルのない通知が投稿されたときに画面上に警告を表示します"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"外部ストレージへのアプリの書き込みを許可"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"マニフェストの値に関係なく、すべてのアプリを外部ストレージに書き込めるようになります"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"アクティビティをサイズ変更可能にする"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 81416a0ae0b2..30492cee2da9 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"ფონური პროცესების ლიმიტი"</string> <string name="show_all_anrs" msgid="28462979638729082">"ყველა ANR-ის ჩვენება"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"შეტყობინების ჩვენება, როცა ფონური აპლიკაცია არ პასუხობს"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"შეტყობინებათა არხის გაფრთხილებების ჩვენება"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ეკრანზე აჩვენებს გაფრთხილებას, როცა აპი შეტყობინებას სწორი არხის გარეშე განათავსებს"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"აპების დაშვება გარე მეხსიერებაში"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"აპები ჩაიწერება გარე მეხსიერებაზე აღწერის ფაილების მნიშვნელობების მიუხედავად"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"ზომაცვლადი აქტივობების იძულება"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 66b4a0e2cb51..e6243480d273 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Фондық үрдіс шектеуі"</string> <string name="show_all_anrs" msgid="28462979638729082">"Барлық ANR (қолданба жауап бермеді) хабарларын көрсетіңіз"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Фондық қолданбалардың жауап бермегенін көрсету"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Хабарландыру арнасының ескертулерін көрсету"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Қолданба жарамсыз арна арқылы хабарландыру жариялағанда, экрандық ескертуді көрсетеді"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Сыртқыда қолданбаларға мәжбүрлеп рұқсат ету"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Манифест мәндеріне қарамастан кез келген қолданбаны сыртқы жадқа жазуға жарамды етеді"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Әрекеттерді өлшемін өзгертуге болатын етуге мәжбүрлеу"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 1adc4320dc4a..5498ef372b15 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"ដែនកំណត់ដំណើរការក្នុងផ្ទៃខាងក្រោយ"</string> <string name="show_all_anrs" msgid="28462979638729082">"បង្ហាញ ANRs ទាំងអស់"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"បង្ហាញប្រអប់កម្មវិធីមិនឆ្លើយតបសម្រាប់កម្មវិធីផ្ទៃខាងក្រោយ"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"បង្ហាញការព្រមានអំពីបណ្តាញជូនដំណឹង"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"បង្ហាញការព្រមាននៅលើអេក្រង់ នៅពេលកម្មវិធីបង្ហោះការជូនដំណឹងដោយមិនមានបណ្តាញត្រឹមត្រូវ"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"បង្ខំឲ្យអនុញ្ញាតកម្មវិធីលើឧបករណ៍ផ្ទុកខាងក្រៅ"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ធ្វើឲ្យកម្មវិធីទាំងឡាយមានសិទ្ធិសរសេរទៅកាន់ឧបករណ៍ផ្ទុកខាងក្រៅ ដោយមិនគិតពីតម្លៃជាក់លាក់"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"បង្ខំឲ្យសកម្មភាពអាចប្តូរទំហំបាន"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index c545da7d0098..ab2235ab0ce6 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"ಹಿನ್ನೆಲೆ ಪ್ರಕ್ರಿಯೆ ಮಿತಿ"</string> <string name="show_all_anrs" msgid="28462979638729082">"ಎಲ್ಲ ANR ಗಳನ್ನು ತೋರಿಸು"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"ಹಿನ್ನೆಲೆ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ ಎಂಬ ಸಂಭಾಷಣೆ ತೋರಿಸು"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ಅಧಿಸೂಚನೆ ಎಚ್ಚರಿಕೆ ತೋರಿಸಿ"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ಅಮಾನ್ಯ ಚಾನಲ್ ಅಧಿಸೂಚನೆಗಾಗಿ ಪರದೆಯಲ್ಲಿ ಎಚ್ಚರಿಕೆ"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"ಬಾಹ್ಯವಾಗಿ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಒತ್ತಾಯವಾಗಿ ಅನುಮತಿಸಿ"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳು ಯಾವುದೇ ಆಗಿದ್ದರೂ, ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಒತ್ತಾಯ ಮಾಡಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index bbaeed7bf902..3369a264d50c 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"백그라운드 프로세스 수 제한"</string> <string name="show_all_anrs" msgid="28462979638729082">"모든 ANR 보기"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"백그라운드 앱에 대해 앱 응답 없음 대화상자 표시"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"알림 채널 경고 표시"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"앱에서 유효한 채널 없이 알림을 게시하면 화면에 경고가 표시됩니다."</string> <string name="force_allow_on_external" msgid="3215759785081916381">"외부에서 앱 강제 허용"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"매니페스트 값과 관계없이 모든 앱이 외부 저장소에 작성되도록 허용"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"활동의 크기가 조정 가능하도록 설정"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 66f376970b22..9b0a4d82eb81 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Фондогу процесстер чеги"</string> <string name="show_all_anrs" msgid="28462979638729082">"Бардык ANR\'лерди көрсөтүү"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Фондогу колдонмолорго Колдонмо Жооп Бербейт деп көрсөтүү"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Эскертме каналынын эскертүүлөрүн көрсөтүү"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Колдонмодон жарактуу каналсыз эскертме жайгаштырылганда, экрандан эскертүү көрсөтүлөт"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Тышкы сактагычка сактоого уруксат берүү"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Манифест маанилерине карабастан бардык колдонмолорду тышкы сактагычка сактоого уруксат берет"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Аракеттердин өлчөмүн өзгөртүүнү мажбурлоо"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index c909cbb6859e..aacee8bee419 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"ການຈຳກັດໂປຣເຊສໃນພື້ນຫຼັງ"</string> <string name="show_all_anrs" msgid="28462979638729082">"ສະແດງ ANRs ທັງຫມົດ"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"ສະແດງໜ້າຈໍແອັບຯທີ່ບໍ່ຕອບສະໜອງສຳລັບແອັບຯພື້ນຫຼັງ"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ສະແດງຄຳເຕືອນຊ່ອງການແຈ້ງເຕືອນ"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ສະແດງຄຳເຕືອນໃນໜ້າຈໍເມື່ອແອັບໂພສການແຈ້ງເຕືອນໂດຍບໍ່ມີຊ່ອງທີ່ຖືກຕ້ອງ"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"ບັງຄັບອະນຸຍາດແອັບຢູ່ພາຍນອກ"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ເຮັດໃຫ້ທຸກແອັບມີສິດໄດ້ຮັບການຂຽນໃສ່ພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກ, ໂດຍບໍ່ຄຳນຶງເຖິງຄ່າ manifest"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"ບັງຄັງໃຫ້ກິດຈະກຳປ່ຽນຂະໜາດໄດ້"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 274ce9ad374f..97de7d563e1b 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Fono procesų apribojimas"</string> <string name="show_all_anrs" msgid="28462979638729082">"Rodyti visus ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Fon. programose rodyti dialogo langą „Neatsako“"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Rodyti pran. kan. įspėj."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Ekr. rod. įsp., kai progr. pask. pr. be tink. kan."</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Priverstinai leisti programas išorinėje atmintin."</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Nustatoma, kad visas programas būtų galima įrašyti į išorinę saugyklą, nepaisant aprašo verčių"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Priv. nust., kad veiksm. b. g. atl. kelių d. lang."</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index e760d780dd6c..98c81562acf9 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Fona procesu ierobežojums"</string> <string name="show_all_anrs" msgid="28462979638729082">"Rādīt visus ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Rādīt fona lietotņu dialoglodz. Lietotne nereaģē"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Paziņojumu kanāla brīdinājumi"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Brīdinājums ekrānā, kad lietotne publicē paziņojumu, nenorādot derīgu kanālu"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Lietotņu piespiedu atļaušana ārējā krātuvē"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Ļauj jebkuru lietotni ierakstīt ārējā krātuvē neatkarīgi no manifesta vērtības."</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Pielāgot darbības"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 19794519c81d..2bafd1f051d1 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Граница на процес во зад."</string> <string name="show_all_anrs" msgid="28462979638729082">"Прикажи ги сите ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Прикажи „Апл. не реагира“ за. апл. во заднина"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Прикажи ги предупредувањата на каналот за известувањe"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Предупредува кога апликација дава известување без важечки канал"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Принуд. дозволете апликации на надворешна меморија"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Прави секоја апликација да биде подобна за запишување на надворешна меморија, независно од вредностите на манифестот"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Принуди ги активностите да ја менуваат големината"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 06a9dc16d915..24718799e33b 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"പശ്ചാത്തല പ്രോസസ്സ് പരിധി"</string> <string name="show_all_anrs" msgid="28462979638729082">"എല്ലാ ANR-കളും ദൃശ്യമാക്കുക"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"പശ്ചാത്തല അപ്ലിക്കേഷനുകൾക്ക് അപ്ലിക്കേഷൻ പ്രതികരിക്കുന്നില്ല എന്ന ഡയലോഗ് കാണിക്കുക"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ചാനൽ മുന്നറിയിപ്പ് കാണിക്കൂ"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"സാധുതയുള്ള ചാനലില്ലാതെ ഒരു ആപ്പ്, അറിയിപ്പ് പോസ്റ്റുചെയ്യുമ്പോൾ ഓൺ-സ്ക്രീൻ മുന്നറിയിപ്പ് പ്രദർശിപ്പിക്കുന്നു"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"ബാഹ്യമായതിൽ നിർബന്ധിച്ച് അനുവദിക്കുക"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, ബാഹ്യ സ്റ്റോറേജിലേക്ക് എഴുതപ്പെടുന്നതിന് ഏതൊരു ആപ്പിനെയും യോഗ്യമാക്കുന്നു"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"വലിപ്പം മാറ്റാൻ പ്രവർത്തനങ്ങളെ നിർബന്ധിക്കുക"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index f400f5a63d50..769ef5cf382f 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Далд процессын хязгаар"</string> <string name="show_all_anrs" msgid="28462979638729082">"Бүх ANRs харуулах"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Далд апп-уудад Апп Хариу Өгөхгүй байна гэснийг харуулах"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Мэдэгдлийн сувгийн анхааруулгыг харуулах"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Апп хүчинтэй суваггүйгээр мэдэгдэл гаргах үед дэлгэцэд сануулга харуулна"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Аппыг гадаад санах ойд хадгалахыг зөвшөөрөх"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Манифест утгыг нь үл хамааран дурын апп-г гадаад санах ойд бичих боломжтой болгодог"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Үйл ажиллагааны хэмжээг өөрчилж болохуйц болгох"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 10632e050155..0e1499b5709e 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"पार्श्वभूमी प्रक्रिया मर्यादा"</string> <string name="show_all_anrs" msgid="28462979638729082">"सर्व ANR दर्शवा"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"पार्श्वभूमी अॅप्ससाठी अॅप प्रतिसाद देत नाही संवाद दर्शवा"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"सूचना चॅनेल चेतावण्या दाखवा"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"एखादे अॅप वैध चॅनेलशिवाय सूचना पोस्ट करते तेव्हा स्क्रीनवर चेतावणी देते"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"बाह्यवर अॅप्सना अनुमती देण्याची सक्ती करा"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"मॅनिफेस्ट मूल्यांकडे दुर्लक्ष करून, कोणत्याही अॅपला बाह्य संचयनावर लेखन केले जाण्यासाठी पात्र बनविते"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"क्रियाकलापाचा आकार बदलण्यायोग्य होण्याची सक्ती करा"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index cc6a935a3238..66675859f7e5 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Had proses latar belakang"</string> <string name="show_all_anrs" msgid="28462979638729082">"Tunjukkan semua ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Tunjukkan dialog Aplikasi Tidak Memberi Maklum Balas untuk aplikasi latar belakang"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Papar amaran saluran pemberitahuan"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Memaparkan amaran pada skrin apabila apl menyiarkan pemberitahuan tanpa saluran sah"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Benarkan apl secara paksa pada storan luaran"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Menjadikan sebarang apl layak ditulis ke storan luaran, tanpa mengambil kira nilai manifes"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Paksa aktiviti supaya boleh diubah saiz"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 3e718006a103..2572d60a43d7 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"နောက်ခံလုပ်ငန်းစဉ်ကန့်သတ်ခြင်း"</string> <string name="show_all_anrs" msgid="28462979638729082">"ANRsအားလုံးအား ပြသရန်"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"နောက်ခံအပ်ပလီကေးရှင်းအတွက်တုံ့ပြန်မှုမရှိပြရန်"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ချန်နယ်သတိပေးချက်များပြပါ"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ချန်နယ်မရှိဘဲ အကြောင်းကြားလျှင် စကရင်တွင်သတိပေးသည်"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"အပြင်မှာ အတင်း ခွင့်ပြုရန်"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"တိကျစွာ သတ်မှတ်ထားသည့်တန်ဖိုးများရှိသော်လည်း၊ ပြင်ပသိုလှောင်ခန်းများသို့ မည်သည့်အက်ပ်ကိုမဆို ဝင်ရောက်ခွင့်ပြုပါ"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"လုပ်ဆောင်ချက်များ ဆိုက်ညှိရနိုင်ရန် လုပ်ခိုင်းပါ"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 61ce9cb4df64..a59b89ce332e 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Bakgrunnsprosessgrense"</string> <string name="show_all_anrs" msgid="28462979638729082">"Vis alle ANR-er"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Vis Appen svarer ikke-dialog for bakgrunnsapper"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Vis varselskanaladvarsler"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Viser advarsler på skjermen når apper publiserer varsler uten en gyldig kanal"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Tving frem tillatelse for ekstern lagring av apper"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Dette gjør at alle apper kan lagres på eksterne lagringsmedier – uavhengig av manifestverdier"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Tving aktiviteter til å kunne endre størrelse"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index e87cf2ff3e8b..87873ca51c24 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"पृष्ठभूमि प्रक्रिया सीमा"</string> <string name="show_all_anrs" msgid="28462979638729082">"सबै ANRs देखाउनुहोस्"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"पृष्ठभूमि अनुप्रयोगका लागि जवाफ नदिइरहेका अनुप्रयोगहरू देखाउनुहोस्"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"सूचना च्यानलका चेतावनी देखाउनुहोस्"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"अनुप्रयोगले कुनै मान्य च्यानल बिना सूचना पोस्ट गर्दा स्क्रिनमा चेतावनी देखाउँछ"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"बाह्यमा बल प्रयोगको अनुमति प्राप्त अनुप्रयोगहरू"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"म्यानिफेेस्टका मानहरूको ख्याल नगरी कुनै पनि अनुप्रयोगलाई बाह्य भण्डारणमा लेख्न सकिने खाले बनाउँछ"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"गतिविधिहरू रिसाइज गर्नको लागि बाध्य गर्नुहोस्"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index b98ea2bece6e..34487f7a1c6a 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Achtergrondproceslimiet"</string> <string name="show_all_anrs" msgid="28462979638729082">"Alle ANR\'s weergeven"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"\'App reageert niet\' weerg. voor apps op achtergr."</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Kanaalwaarschuwingen voor meldingen weergeven"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Geeft een waarschuwing op het scherm weer wanneer een app een melding post zonder geldig kanaal"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Toestaan van apps op externe opslag afdwingen"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Hiermee komt elke app in aanmerking voor schrijven naar externe opslag, ongeacht de manifestwaarden"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Formaat activiteiten geforceerd aanpasbaar maken"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 08dd09d7606a..d48a92b98314 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"ਪਿਛੋਕੜ ਪ੍ਰਕਿਰਿਆ ਸੀਮਾ"</string> <string name="show_all_anrs" msgid="28462979638729082">"ਸਾਰੇ ANR ਦਿਖਾਓ"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"ਪਿਛੋਕੜ ਐਪਸ ਲਈ ਐਪਸ ਜਵਾਬ ਨਹੀਂ ਦੇ ਰਹੇ ਡਾਇਲੌਗ ਦਿਖਾਓ"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ਸੂਚਨਾ ਚੈਨਲ ਚੇਤਾਵਨੀਆਂ ਦਿਖਾਓ"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ਐਪ ਵੱਲੋਂ ਵੈਧ ਚੈਨਲ ਤੋਂ ਬਿਨਾਂ ਸੂਚਨਾ ਪੋਸਟ ਕਰਨ \'ਤੇ ਸਕ੍ਰੀਨ \'ਤੇ ਚੇਤਾਵਨੀ ਦਿਖਾਉਂਦੀ ਹੈ"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"ਐਪਸ ਨੂੰ ਬਾਹਰਲੇ ਤੇ ਜ਼ਬਰਦਸਤੀ ਆਗਿਆ ਦਿਓ"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ਮੈਨੀਫੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਕਿਸੇ ਵੀ ਐਪ ਨੂੰ ਬਾਹਰੀ ਸਟੋਰੇਜ \'ਤੇ ਲਿਖਣ ਦੇ ਯੋਗ ਬਣਾਉਂਦੀ ਹੈ"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"ਮੁੜ-ਆਕਾਰ ਬਦਲਣ ਲਈ ਸਰਗਰਮੀਆਂ \'ਤੇ ਜ਼ੋਰ ਦਿਓ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index e559c693e38f..823e9c8de3d4 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limit procesów w tle"</string> <string name="show_all_anrs" msgid="28462979638729082">"Pokaż wszystkie ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Pokaż okno Aplikacja Nie Reaguje dla aplikacji w tle"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Pokaż ostrzeżenia kanału powiadomień"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Wyświetla ostrzeżenie, gdy aplikacja publikuje powiadomienie bez prawidłowego kanału"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Wymuś zezwalanie na aplikacje w pamięci zewn."</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Pozwala na zapis aplikacji w pamięci zewnętrznej niezależnie od wartości w pliku manifestu"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Wymuś zmianę rozmiaru okien aktywności"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index cce80ed195c3..c37d2f471e0b 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limite do proc. 2º plano"</string> <string name="show_all_anrs" msgid="28462979638729082">"Mostrar todos os ANRS"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Exibir \"App não responde\" para app em 2º plano"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostrar avisos do canal de notif."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Exibe aviso na tela quando um app posta notificação sem canal válido"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forçar permissão de apps em armazenamento externo"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Qualifica apps para gravação em armazenamento externo, independentemente de valores de manifestos"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forçar atividades a serem redimensionáveis"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 8124c4b294eb..3a803a82b49f 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limite proc. em 2º plano"</string> <string name="show_all_anrs" msgid="28462979638729082">"Mostrar todos os ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Mostrar erro \"Aplic. não Resp.\" p/ aplic. 2º plano"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostrar avisos do canal de notif."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Mostra um aviso no ecrã quando uma aplic. publica uma notific. sem um canal válido"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forçar perm. de aplicações no armazenamento ext."</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Torna qualquer aplicação elegível para ser gravada no armazenamento externo, independentemente dos valores do manifesto"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forçar as atividades a serem redimensionáveis"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index cce80ed195c3..c37d2f471e0b 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limite do proc. 2º plano"</string> <string name="show_all_anrs" msgid="28462979638729082">"Mostrar todos os ANRS"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Exibir \"App não responde\" para app em 2º plano"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Mostrar avisos do canal de notif."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Exibe aviso na tela quando um app posta notificação sem canal válido"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forçar permissão de apps em armazenamento externo"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Qualifica apps para gravação em armazenamento externo, independentemente de valores de manifestos"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forçar atividades a serem redimensionáveis"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 3a174de1bff5..a86153333e17 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limită procese fundal"</string> <string name="show_all_anrs" msgid="28462979638729082">"Afișați toate elem. ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Aplicații din fundal: afișați Aplicația nu răspunde"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Afișați avertismentele de pe canalul de notificări"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Afișează avertisment pe ecran când o aplicație postează o notificare fără canal valid"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Forțați accesul aplicațiilor la stocarea externă"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Face orice aplicație eligibilă să fie scrisă în stocarea externă, indiferent de valorile manifestului"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Forțați redimensionarea activităților"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index cd8d95611182..9eb75aea60c7 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Лимит фоновых процессов"</string> <string name="show_all_anrs" msgid="28462979638729082">"Все ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Уведомлять о том, что приложение не отвечает"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Показывать предупреждения канала передачи оповещения"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Показывать предупреждение о новых уведомлениях приложения вне допустимого канала"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Разрешить сохранение на внешние накопители"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Разрешить сохранение приложений на внешних накопителях (независимо от значений в манифесте)"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Изменение размера в многооконном режиме"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 592c2f9885ba..8774baa69cf8 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"පසුබිම් ක්රියාවලි සීමාව"</string> <string name="show_all_anrs" msgid="28462979638729082">"සියලුම ANR පෙන්වන්න"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"පසුබිම් යෙදුම් වලට යෙදුම ප්රතිචාර නොදක්වයි කවුළුව පෙන්වන්න"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"දැනුම්දීම් නාලිකා අනතුරු ඇඟවීම් පෙන්."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"යෙදුමක් වලංගු නාලිකාවකින් තොරව දැනුම්දීමක් පළ කරන විට තිරය-මත අනතුරු ඇඟවීමක් සංදර්ශනය කරයි."</string> <string name="force_allow_on_external" msgid="3215759785081916381">"බාහිර මත යෙදුම් ඉඩ දීම බල කරන්න"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"මැනිෆෙස්ට් අගයන් නොසලකා, ඕනෑම යෙදුමක් බාහිර ගබඩාවට ලිවීමට සුදුසුකම් ලබා දෙයි"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"ක්රියාකාරකම් ප්රතිප්රමාණ කළ හැකි බවට බල කරන්න"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index d5c40611f132..925e2c8408cd 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limit procesov na pozadí"</string> <string name="show_all_anrs" msgid="28462979638729082">"Zobrazovať všetky ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Zobrazovať dialóg „Aplikácia neodpovedá“ aj pre aplikácie na pozadí"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Zobraziť hlásenia kanála upozornení"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Zobrazuje varovné hlásenie na obrazovke, keď aplikácia zverejní upozornenie bez platného kanála"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Vynútiť povolenie aplikácií na externom úložisku"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Umožňuje zapísať akúkoľvek aplikáciu do externého úložiska bez ohľadu na hodnoty v manifeste"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Vynútiť možnosť zmeny veľkosti aktivít"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 4e0085c12703..6c2c3550230a 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Omejitev postopkov v ozadju"</string> <string name="show_all_anrs" msgid="28462979638729082">"Pokaži okna neodzivanj"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Prikaz pogovornega okna za neodzivanje aplikacije v ozadju"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Pokaži opoz. kan. za obv."</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Na zaslonu se pokaže opozorilo, ko aplikacija objavi obvestilo brez veljavnega kanala"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Vsili omogočanje aplikacij v zunanji shrambi"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsako aplikacijo zapisati v zunanjo shrambo"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Vsili povečanje velikosti za aktivnosti"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index e8340bf00e6d..9c178d7af523 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Kufizimi i proceseve në sfond"</string> <string name="show_all_anrs" msgid="28462979638729082">"Shfaq raportet ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Shfaq raportet ANR (Aplikacioni nuk përgjigjet) për aplikacionet në sfond"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Shfaq paralajmërimet e kanalit të njoftimeve"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Shfaq paralajmërimin në ekran kur një aplikacion poston një njoftim pa një kanal të vlefshëm"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Detyro lejimin në hapësirën e jashtme"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Bën që çdo aplikacion të jetë i përshtatshëm për t\'u shkruar në hapësirën ruajtëse të jashtme, pavarësisht nga vlerat e manifestit"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Detyro madhësinë e ndryshueshme për aktivitetet"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 63ceb736ea17..44fe06f06409 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Ограничење позадинских процеса"</string> <string name="show_all_anrs" msgid="28462979638729082">"Прикажи све ANR-ове"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Прикажи дијалог Апликација не реагује за апликације у позадини"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Приказуј упозорења због канала за обавештења"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Приказује упозорење на екрану када апликација постави обавештење без важећег канала"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Принудно дозволи апликације у спољној"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Омогућава уписивање свих апликација у спољну меморију, без обзира на вредности манифеста"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Принудно омогући промену величине активности"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index 1f2ca2377bed..d8cc76ff2329 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Begränsa bakgrundsprocess"</string> <string name="show_all_anrs" msgid="28462979638729082">"Visa alla som inte svarar"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Visa dialogrutan om att appen inte svarar för bakgrundsappar"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Visa varningar om aviseringskanal"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Visa varningar på skärmen när en app lägger upp en avisering utan en giltig kanal"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Tillåt appar i externt lagringsutrymme"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Allar appar kan skrivas till extern lagring, oavsett manifestvärden"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Framtvinga storleksanpassning för aktiviteter"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 4d75fbccf361..d48cded1b80c 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Kiwango cha mchakato wa mandari nyuma"</string> <string name="show_all_anrs" msgid="28462979638729082">"Onyesha ANR zote"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Onyesha kisanduku kidadisi cha Programu Haiitikii kwa programu za usuli"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Onyesha arifa za maonyo ya kituo"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Huonyesha onyo kwenye skrini programu inapochapisha arifa bila kituo sahihi."</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Lazima uruhusu programu kwenye hifadhi ya nje"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Huruhusu programu yoyote iwekwe kwenye hifadhi ya nje, bila kujali thamani za faili ya maelezo"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Lazimisha shughuli ziweze kubadilishwa ukubwa"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 47f75860a4eb..44b13ec848bb 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"பின்புலச் செயல்முறை வரம்பு"</string> <string name="show_all_anrs" msgid="28462979638729082">"எல்லா ANRகளையும் காட்டு"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"பின்புலப் பயன்பாடுகளுக்குப் பயன்பாடு பதிலளிக்கவில்லை என்ற உரையாடலைக் காட்டு"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"அறிவிப்புச் சேனல் எச்சரிக்கைகளைக் காட்டு"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"பயன்பாடானது சரியான சேனல் இல்லாமல் அறிவிப்பை இடுகையிடும் போது, திரையில் எச்சரிக்கையைக் காட்டும்"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"பயன்பாடுகளை வெளிப்புறச் சேமிப்பிடத்தில் அனுமதி"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"மேனிஃபெஸ்ட் மதிப்புகளைப் பொருட்படுத்தாமல், எல்லா பயன்பாட்டையும் வெளிப்புறச் சேமிப்பிடத்தில் எழுத அனுமதிக்கும்"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"செயல்பாடுகளை அளவுமாறக்கூடியதாக அமை"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 1a7ad4d8ef24..66f31d8ef9d2 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"నేపథ్య ప్రాసెస్ పరిమితి"</string> <string name="show_all_anrs" msgid="28462979638729082">"అన్ని ANRలను చూపు"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"నేపథ్య అనువర్తనాల కోసం అనువర్తనం ప్రతిస్పందించడం లేదు డైలాగ్ను చూపు"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ఛానెల్ హెచ్చరికల నోటిఫికేషన్ను చూపు"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"చెల్లుబాటు అయ్యే ఛానెల్ లేకుండా అనువర్తనం నోటిఫికేషన్ను పోస్ట్ చేస్తున్నప్పుడు స్క్రీన్పై హెచ్చరికను చూపిస్తుంది"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"అనువర్తనాలను బాహ్య నిల్వలో నిర్బంధంగా అనుమతించు"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ఏ అనువర్తనాన్ని అయినా మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా బాహ్య నిల్వలో వ్రాయడానికి అనుమతిస్తుంది"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"కార్యాచరణలను పరిమాణం మార్చగలిగేలా నిర్బంధించు"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index aa0296c6616e..0cc93a958e5a 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -163,7 +163,7 @@ <string name="oem_unlock_enable" msgid="6040763321967327691">"การปลดล็อก OEM"</string> <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"อนุญาตให้ปลดล็อกตัวโหลดการเปิดเครื่อง"</string> <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"อนุญาตการปลดล็อก OEM ไหม"</string> - <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"คำเตือน: คุณลักษณะการปกป้องอุปกรณ์จะไม่ทำงานบนอุปกรณ์นี้ขณะที่การตั้งค่านี้เปิดอยู่"</string> + <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"คำเตือน: ฟีเจอร์การปกป้องอุปกรณ์จะไม่ทำงานบนอุปกรณ์นี้ขณะที่การตั้งค่านี้เปิดอยู่"</string> <string name="mock_location_app" msgid="7966220972812881854">"เลือกแอปจำลองตำแหน่ง"</string> <string name="mock_location_app_not_set" msgid="809543285495344223">"ไม่ได้ตั้งค่าแอปจำลองตำแหน่ง"</string> <string name="mock_location_app_set" msgid="8966420655295102685">"แอปจำลองตำแหน่ง: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -211,7 +211,7 @@ <string name="dev_settings_warning_message" msgid="2298337781139097964">"การตั้งค่านี้มีไว้เพื่อการพัฒนาเท่านั้น จึงอาจทำให้อุปกรณ์และแอปพลิเคชันที่มีอยู่เสียหายหรือทำงานผิดพลาดได้"</string> <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"ยืนยันแอปพลิเคชันผ่าน USB"</string> <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ตรวจสอบแอปพลิเคชันที่ติดตั้งผ่าน ADB/ADT เพื่อตรวจดูพฤติกรรมที่เป็นอันตราย"</string> - <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ปิดใช้คุณลักษณะการควบคุมระดับเสียงของอุปกรณ์อื่นผ่านบลูทูธในกรณีที่มีปัญหาเกี่ยวกับระดับเสียงของอุปกรณ์ระยะไกล เช่น ระดับเสียงที่ดังเกินไปหรือระดับเสียงที่ไม่มีการควบคุม"</string> + <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ปิดใช้ฟีเจอร์การควบคุมระดับเสียงของอุปกรณ์อื่นผ่านบลูทูธในกรณีที่มีปัญหาเกี่ยวกับระดับเสียงของอุปกรณ์ระยะไกล เช่น ระดับเสียงที่ดังเกินไปหรือระดับเสียงที่ไม่มีการควบคุม"</string> <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"ให้เสียงเรียกเข้าในโทรศัพท์เล่นในชุดหูฟังบลูทูธ"</string> <string name="enable_terminal_title" msgid="95572094356054120">"เทอร์มินัลในตัวเครื่อง"</string> <string name="enable_terminal_summary" msgid="67667852659359206">"เปิดใช้งานแอปเทอร์มินัลที่ให้การเข้าถึงเชลล์ในตัวเครื่อง"</string> @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"ขีดจำกัดกระบวนการพื้นหลัง"</string> <string name="show_all_anrs" msgid="28462979638729082">"แสดง ANR ทั้งหมด"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"แสดงหน้าต่างแอปไม่ตอบสนอง สำหรับแอปพื้นหลัง"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"แสดงคำเตือนจากช่องทางการแจ้งเตือน"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"แสดงคำเตือนบนหน้าจอเมื่อแอปโพสต์การแจ้งเตือนโดยไม่มีช่องทางที่ถูกต้อง"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"บังคับให้แอปสามารถใช้ที่เก็บภายนอก"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ทำให้สามารถเขียนแอปใดๆ ก็ตามไปยังพื้นที่เก็บข้อมูลภายนอกได้ โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"บังคับให้กิจกรรมปรับขนาดได้"</string> @@ -310,7 +308,7 @@ <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"แปลง…"</string> <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"เข้ารหัสไฟล์แล้ว"</string> <string name="title_convert_fbe" msgid="1263622876196444453">"การแปลงเป็นการเข้ารหัสตามไฟล์"</string> - <string name="convert_to_fbe_warning" msgid="6139067817148865527">"แปลงพาร์ทิชันข้อมูลเป็นการเข้ารหัสแบบไฟล์\n !!คำเตือน!! การดำเนินการนี้จะลบข้อมูลทั้งหมดของคุณ\n คุณลักษณะนี้เป็นแบบอัลฟา และอาจทำงานไม่เป็นปกติ\n กด \"ลบและแปลง...\" เพื่อดำเนินการต่อ"</string> + <string name="convert_to_fbe_warning" msgid="6139067817148865527">"แปลงพาร์ทิชันข้อมูลเป็นการเข้ารหัสแบบไฟล์\n !!คำเตือน!! การดำเนินการนี้จะลบข้อมูลทั้งหมดของคุณ\n ฟีเจอร์นี้เป็นแบบอัลฟา และอาจทำงานไม่เป็นปกติ\n กด \"ลบและแปลง...\" เพื่อดำเนินการต่อ"</string> <string name="button_convert_fbe" msgid="5152671181309826405">"ลบและแปลง…"</string> <string name="picture_color_mode" msgid="4560755008730283695">"โหมดสีของรูปภาพ"</string> <string name="picture_color_mode_desc" msgid="1141891467675548590">"ใช้ sRGB"</string> @@ -320,7 +318,7 @@ <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"ตาบอดจางสีแดง (สีแดง/เขียว)"</string> <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"ตาบอดจางสีน้ำเงิน (สีน้ำเงิน/เหลือง)"</string> <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"การแก้สี"</string> - <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"คุณลักษณะนี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string> + <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ฟีเจอร์นี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="845431008899029842">"อีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"อีก <xliff:g id="TIME">%1$s</xliff:g> จึงจะชาร์จเต็ม"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 988a88bd08c7..f00440fb5ae1 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Limitasyon ng proseso sa background"</string> <string name="show_all_anrs" msgid="28462979638729082">"Ipakita ang lahat ng ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"App Not Responding dialog para sa background apps"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Ipakita ang mga babala sa notification channel"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Nagpapakita ng babala sa screen kapag nag-post ang app ng notification nang walang wastong channel"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Pwersahang payagan ang mga app sa external"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Ginagawang kwalipikado ang anumang app na mailagay sa external na storage, anuman ang mga value ng manifest"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Sapilitang gawing resizable ang mga aktibidad"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 5eff6c3afd60..80f5dc49dd1b 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Arka plan işlem sınırı"</string> <string name="show_all_anrs" msgid="28462979638729082">"Tüm ANR\'leri göster"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Arka plan uygulamalar için Uygulama Yanıt Vermiyor mesajını göster"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Bildirim kanalı uyarılarını göster"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Bir uygulama geçerli kanal olmadan bildirim yayınladığında ekranda uyarı gösterir"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Harici birimdeki uygulamalara izin vermeye zorla"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Manifest değerlerinden bağımsız olarak uygulamaları harici depolamaya yazmak için uygun hale getirir"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Etkinlikleri yeniden boyutlandırılabilmeye zorla"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 419a8c00c692..96f0c59d7a59 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Обмеження фон. процесів"</string> <string name="show_all_anrs" msgid="28462979638729082">"Показувати всі ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Сповіщати, коли додаток не відповідає"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Показувати застереження про канал"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"З’являється застереження, коли додаток надсилає сповіщення через недійсний канал"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Примусово записувати додатки в зовнішню пам’ять"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Можна записувати додатки в зовнішню пам’ять, незалежно від значень у маніфесті"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Примусово масштабувати активність"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 55f71324d470..aed65fa90489 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"پس منظر پروسیس کی حد"</string> <string name="show_all_anrs" msgid="28462979638729082">"سبھی ANRs کو دکھائیں"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"پس منظر کی ایپس کیلئے ایپ جواب نہیں دے رہی ہے ڈائلاگ دکھائیں"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"چینل کی اطلاعی تنبیہات دکھائیں"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"کسی ایپ کی طرف سے درست چینل کے بغیر اطلاع پوسٹ ہونے پر آن اسکرین تنبیہ ڈسپلے کرتا ہے"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"بیرونی پر ایپس کو زبردستی اجازت دیں"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"manifest اقدار سے قطع نظر، کسی بھی ایپ کو بیرونی اسٹوریج پر لکھے جانے کا اہل بناتا ہے"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"سرگرمیوں کو ری سائز ایبل بنائیں"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 4b53da5f6efc..ae6ba0ff3133 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Fondagi jarayonlarni cheklash"</string> <string name="show_all_anrs" msgid="28462979638729082">"Hamma ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Ilova javob bermayotgani haqida xabar qilish"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Xabarlar kanali ogohlantirishlarini ko‘rsatish"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Yaroqli kanalsiz yuborilgan yangi ilova xabarnomalari haqida ogohlantirishlarni ko‘rsatish"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Tashqi xotira qurilmasidagi ilova dasturlariga majburiy ruxsat berish"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Manifest qiymatidan qat’i nazar istalgan ilovani tashqi xotiraga saqlash imkonini beradi"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Harakatlarni moslashuvchan o‘lchamga keltirish"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index a6a54d0a0609..87ba837d5f85 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Giới hạn quá trình nền"</string> <string name="show_all_anrs" msgid="28462979638729082">"Hiển thị tất cả ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Hiện hộp thoại Ứng dụng ko đáp ứng cho ứng dụng nền"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Hiện cảnh báo kênh th.báo"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Hiện cảnh báo trên m.hình khi ƯD đăng th.báo ko có kênh hợp lệ"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Buộc cho phép các ứng dụng trên bộ nhớ ngoài"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Giúp mọi ứng dụng đủ điều kiện để được ghi vào bộ nhớ ngoài, bất kể giá trị tệp kê khai là gì"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Buộc các hoạt động có thể thay đổi kích thước"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 41c5f60d18da..ae98f2fee476 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"后台进程限制"</string> <string name="show_all_anrs" msgid="28462979638729082">"显示所有“应用无响应”(ANR)"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"为后台应用显示“应用无响应”对话框"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"显示通知渠道警告"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"当应用未经有效渠道发布通知时,在屏幕上显示警告"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"强制允许将应用写入外部存储设备"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"允许将任何应用写入外部存储设备(无论清单值是什么)"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"强制将活动设为可调整大小"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 00748b0322d6..e1ad0c4ce228 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"背景處理程序限制"</string> <string name="show_all_anrs" msgid="28462979638729082">"顯示所有 ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"顯示背景應用程式的「應用程式無回應」對話框"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"顯示通知渠道警告"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效渠道發佈通知時,在螢幕上顯示警告"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"強制允許應用程式寫入到外部儲存空間"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"在任何資訊清單值下,允許將所有符合資格的應用程式寫入到外部儲存完間"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"強制可變更活動尺寸"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 3988edd27e74..9ed1a26f9f1c 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"背景處理程序限制"</string> <string name="show_all_anrs" msgid="28462979638729082">"顯示所有無回應程式"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"為背景應用程式顯示「應用程式無回應」對話方塊"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"顯示通知管道警告"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"當應用程式未經有效管道發佈通知時,在畫面上顯示警告"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"強制允許將應用程式寫入外部儲存空間"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"允許將任何應用程式寫入外部儲存空間 (無論資訊清單值為何)"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"將活動強制設為可調整大小"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 11dfdccdb31e..630a9dad7ed8 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -272,10 +272,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Isilinganiso senqubo yesithombe sanemuva"</string> <string name="show_all_anrs" msgid="28462979638729082">"Bonisa wonke ama-ANR"</string> <string name="show_all_anrs_summary" msgid="641908614413544127">"Boniso idayalogi Yohlelo Lokusebenza Olungasabeli kwizinhlelo zokusebenza zasemuva"</string> - <!-- no translation found for show_notification_channel_warnings (1399948193466922683) --> - <skip /> - <!-- no translation found for show_notification_channel_warnings_summary (5536803251863694895) --> - <skip /> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Bonisa izexwayiso zesiteshi sesaziso"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Ibonisa isexwayiso esikusikrini uma uhlelo lokusebenza luthumela isaziso ngaphandle kwesiteshi esivumelekile"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Phoqelela ukuvumela izinhlelo zokusebenza ngaphandle"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Yenza noma uluphi uhlelo lokusebenza lifaneleke ukuthi libhalwe kusitoreji sangaphandle, ngaphandle kwamavelu we-manifest"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Imisebenzi yamandla izonikezwa usayizi omusha"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java b/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java new file mode 100644 index 000000000000..8161dd4bb934 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.android.settingslib.graph; + +import android.annotation.Nullable; +import android.content.Context; +import android.support.annotation.VisibleForTesting; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.widget.LinearLayout; + +import com.android.settingslib.R; + +/** + * An extension of LinearLayout that automatically switches to vertical + * orientation when it can't fit its child views horizontally. + * + * Main logic in this class comes from {@link android.support.v7.widget.ButtonBarLayout}. + * Compared with {@link android.support.v7.widget.ButtonBarLayout}, this layout won't reverse + * children's order and won't update the minimum height + */ +public class BottomLabelLayout extends LinearLayout { + private static final String TAG = "BottomLabelLayout"; + + public BottomLabelLayout(Context context, + @Nullable AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int widthSize = MeasureSpec.getSize(widthMeasureSpec); + final boolean isStacked = isStacked(); + boolean needsRemeasure = false; + + // If we're not stacked, make sure the measure spec is AT_MOST rather + // than EXACTLY. This ensures that we'll still get TOO_SMALL so that we + // know to stack the buttons. + final int initialWidthMeasureSpec; + if (!isStacked && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { + initialWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST); + + // We'll need to remeasure again to fill excess space. + needsRemeasure = true; + } else { + initialWidthMeasureSpec = widthMeasureSpec; + } + + super.onMeasure(initialWidthMeasureSpec, heightMeasureSpec); + if (!isStacked) { + final int measuredWidth = getMeasuredWidthAndState(); + final int measuredWidthState = measuredWidth & View.MEASURED_STATE_MASK; + + if (measuredWidthState == View.MEASURED_STATE_TOO_SMALL) { + setStacked(true); + // Measure again in the new orientation. + needsRemeasure = true; + } + } + + if (needsRemeasure) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + } + + @VisibleForTesting + void setStacked(boolean stacked) { + setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); + setGravity(stacked ? Gravity.START : Gravity.BOTTOM); + + final View spacer = findViewById(R.id.spacer); + if (spacer != null) { + spacer.setVisibility(stacked ? View.GONE : View.VISIBLE); + } + } + + private boolean isStacked() { + return getOrientation() == LinearLayout.VERTICAL; + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java new file mode 100644 index 000000000000..ec217230af95 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package com.android.settingslib.graph; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.Space; + +import com.android.settingslib.R; +import com.android.settingslib.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class BottomLabelLayoutTest { + private BottomLabelLayout mBottomLabelLayout; + private Context mContext; + private Space mSpace; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mBottomLabelLayout = new BottomLabelLayout(mContext, null); + mBottomLabelLayout.setOrientation(LinearLayout.HORIZONTAL); + + mSpace = new Space(mContext); + mSpace.setId(R.id.spacer); + mBottomLabelLayout.addView(mSpace); + } + + @Test + public void testSetStacked_stackedTrue_layoutVertical() { + mBottomLabelLayout.setStacked(true); + + assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.VERTICAL); + assertThat(mSpace.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void testSetStacked_stackedFalse_layoutHorizontal() { + mBottomLabelLayout.setStacked(false); + + assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.HORIZONTAL); + assertThat(mSpace.getVisibility()).isEqualTo(View.VISIBLE); + } +} diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml index ed415b8efdac..7e664d0c2d5e 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml @@ -25,7 +25,8 @@ android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> - <TextClock android:id="@+id/date_view" + <com.android.systemui.statusbar.policy.DateView + android:id="@+id/date_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/clock_white" diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index db1e8a9c112e..d214d5525655 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -37,6 +37,7 @@ import android.widget.TextView; import com.android.internal.util.ArrayUtils; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.ChargingView; +import com.android.systemui.statusbar.policy.DateView; import java.util.Locale; @@ -48,7 +49,7 @@ public class KeyguardStatusView extends GridLayout { private final AlarmManager mAlarmManager; private TextView mAlarmStatusView; - private TextClock mDateView; + private DateView mDateView; private TextClock mClockView; private TextView mOwnerInfo; private ViewGroup mClockContainer; @@ -118,7 +119,6 @@ public class KeyguardStatusView extends GridLayout { mAlarmStatusView = findViewById(R.id.alarm_status); mDateView = findViewById(R.id.date_view); mClockView = findViewById(R.id.clock_view); - mDateView.setShowCurrentUserTime(true); mClockView.setShowCurrentUserTime(true); mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext)); mOwnerInfo = findViewById(R.id.owner_info); @@ -154,8 +154,7 @@ public class KeyguardStatusView extends GridLayout { } public void refreshTime() { - mDateView.setFormat24Hour(Patterns.dateView); - mDateView.setFormat12Hour(Patterns.dateView); + mDateView.setDatePattern(Patterns.dateViewSkel); mClockView.setFormat12Hour(Patterns.clockView12); mClockView.setFormat24Hour(Patterns.clockView24); @@ -246,7 +245,7 @@ public class KeyguardStatusView extends GridLayout { // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often. // This is an optimization to ensure we only recompute the patterns when the inputs change. private static final class Patterns { - static String dateView; + static String dateViewSkel; static String clockView12; static String clockView24; static String cacheKey; @@ -254,7 +253,7 @@ public class KeyguardStatusView extends GridLayout { static void update(Context context, boolean hasAlarm) { final Locale locale = Locale.getDefault(); final Resources res = context.getResources(); - final String dateViewSkel = res.getString(hasAlarm + dateViewSkel = res.getString(hasAlarm ? R.string.abbrev_wday_month_day_no_year_alarm : R.string.abbrev_wday_month_day_no_year); final String clockView12Skel = res.getString(R.string.clock_12hr_format); @@ -262,8 +261,6 @@ public class KeyguardStatusView extends GridLayout { final String key = locale.toString() + dateViewSkel + clockView12Skel + clockView24Skel; if (key.equals(cacheKey)) return; - dateView = DateFormat.getBestDateTimePattern(locale, dateViewSkel); - clockView12 = DateFormat.getBestDateTimePattern(locale, clockView12Skel); // CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton // format. The following code removes the AM/PM indicator if we didn't want it. diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java index ec5f9e7eb6f5..493d244f5e99 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java @@ -30,13 +30,13 @@ import android.content.res.Resources; import android.net.Uri; import android.os.Build; import android.os.Handler; -import android.os.HandlerThread; import android.os.Looper; import android.os.SystemProperties; import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; +import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; @@ -166,7 +166,9 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } if (!mPluginMap.containsKey(listener)) return; mPluginMap.remove(listener).destroy(); - stopListening(); + if (mPluginMap.size() == 0) { + stopListening(); + } } private void startListening() { @@ -237,7 +239,9 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage mContext.getSystemService(NotificationManager.class).notifyAsUser(pkg, SystemMessage.NOTE_PLUGIN, nb.build(), UserHandle.ALL); } - clearClassLoader(pkg); + if (clearClassLoader(pkg)) { + Toast.makeText(mContext, "Reloading " + pkg, Toast.LENGTH_LONG).show(); + } if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { for (PluginInstanceManager manager : mPluginMap.values()) { manager.onPackageChange(pkg); @@ -259,8 +263,8 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage return classLoader; } - private void clearClassLoader(String pkg) { - mClassLoaders.remove(pkg); + private boolean clearClassLoader(String pkg) { + return mClassLoaders.remove(pkg) != null; } ClassLoader getParentClassLoader() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java index 2180ec824fb6..46619c214f12 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java @@ -138,7 +138,7 @@ public class RecentsViewTouchHandler { } mVisibleDockStates.clear(); - if (ActivityManager.supportsMultiWindow() && !ssp.hasDockedTask() + if (ActivityManager.supportsMultiWindow(mRv.getContext()) && !ssp.hasDockedTask() && mDividerSnapAlgorithm.isSplitScreenFeasible()) { Recents.logDockAttempt(mRv.getContext(), event.task.getTopComponent(), event.task.resizeMode); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java index 2c3e78f8cb84..0c6b6b842655 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java @@ -59,7 +59,7 @@ public class TaskViewAccessibilityDelegate extends View.AccessibilityDelegate { @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); - if (ActivityManager.supportsSplitScreenMultiWindow() + if (ActivityManager.supportsSplitScreenMultiWindow(mTaskView.getContext()) && !Recents.getSystemServices().hasDockedTask()) { TaskStack.DockState[] dockStates = Recents.getConfiguration() .getDockStatesForCurrentOrientation(); diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java index a2c782eb94f8..578a18a09c6c 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java @@ -142,7 +142,9 @@ public class ForcedResizableInfoActivityController { Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class); ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchTaskId(pendingRecord.taskId); - options.setTaskOverlay(true, false /* canResume */); + // Set as task overlay and allow to resume, so that when an app enters split-screen and + // becomes paused, the overlay will still be shown. + options.setTaskOverlay(true, true /* canResume */); intent.putExtra(EXTRA_FORCED_RESIZEABLE_REASON, pendingRecord.reason); mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 5cb3c1f1f7cd..8368143b176d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -165,7 +165,7 @@ public class NotificationShelf extends ActivatableNotificationView implements openedAmount = Math.min(1.0f, openedAmount); mShelfState.openedAmount = openedAmount; mShelfState.clipTopAmount = 0; - mShelfState.alpha = mAmbientState.isPulsing() ? 0 : 1; + mShelfState.alpha = mAmbientState.hasPulsingNotifications() ? 0 : 1; mShelfState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0; mShelfState.shadowAlpha = 1.0f; mShelfState.hideSensitive = false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index ab41485793a1..18cc8721ff95 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -308,7 +308,7 @@ public class SignalClusterView extends LinearLayout implements NetworkController if (state == null) { return; } - if (mQsSignal) { + if (mQsSignal && qsIcon != null) { icon = qsIcon; type = qsType; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index c7fbbf956c68..85475b60902f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -179,6 +179,10 @@ public class StatusBarIconView extends AnimatedImageView { mIconScale = (float)imageBounds / (float)outerBounds; } + public float getIconScaleFullyDark() { + return (float) mStatusBarIconDrawingSizeDark / mStatusBarIconDrawingSize; + } + public float getIconScale() { return mIconScale; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 4bfc16b7b4d6..d047fa929da2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -545,7 +545,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } private boolean onLongPressRecents() { - if (mRecents == null || !ActivityManager.supportsMultiWindow() + if (mRecents == null || !ActivityManager.supportsMultiWindow(getContext()) || !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index 9000eb4655d1..f94bb0cdd4f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -267,6 +267,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex && iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons; boolean noOverflowAfter = i == childCount - 1; + float drawingScale = mDark && view instanceof StatusBarIconView + ? ((StatusBarIconView) view).getIconScaleFullyDark() + : 1f; if (mOpenedAmount != 0.0f) { noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow; } @@ -303,7 +306,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { visualOverflowStart += mVisualOverflowAdaption * (1f - mOpenedAmount); } } - translationX += iconState.iconAppearAmount * view.getWidth(); + translationX += iconState.iconAppearAmount * view.getWidth() * drawingScale; } if (firstOverflowIndex != -1) { int numDots = 1; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 4b1d7d7e4508..b1d82b1198a3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -55,6 +55,7 @@ public abstract class PanelView extends FrameLayout { private long mDownTime; private float mMinExpandHeight; private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger(); + private boolean mPanelUpdateWhenAnimatorEnds; private final void logf(String fmt, Object... args) { Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args)); @@ -507,7 +508,7 @@ public abstract class PanelView extends FrameLayout { @Override public boolean onInterceptTouchEvent(MotionEvent event) { - if (mInstantExpanding || !mNotificationsDragEnabled + if (mInstantExpanding || !mNotificationsDragEnabled || mTouchDisabled || (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) { return false; } @@ -758,14 +759,14 @@ public abstract class PanelView extends FrameLayout { if (clearAllExpandHack && !mCancelled) { setExpandedHeightInternal(getMaxPanelHeight()); } - mHeightAnimator = null; + setAnimator(null); if (!mCancelled) { notifyExpandingFinished(); } notifyBarPanelExpansionChanged(); } }); - mHeightAnimator = animator; + setAnimator(animator); animator.start(); } @@ -802,15 +803,28 @@ public abstract class PanelView extends FrameLayout { protected void requestPanelHeightUpdate() { float currentMaxPanelHeight = getMaxPanelHeight(); - // If the user isn't actively poking us, let's update the height - if ((!mTracking || isTrackingBlocked()) - && mHeightAnimator == null - && !isFullyCollapsed() - && currentMaxPanelHeight != mExpandedHeight - && mPeekAnimator == null - && !mPeekTouching) { - setExpandedHeight(currentMaxPanelHeight); + if (isFullyCollapsed()) { + return; + } + + if (currentMaxPanelHeight == mExpandedHeight) { + return; + } + + if (mPeekAnimator != null || mPeekTouching) { + return; + } + + if (mTracking && !isTrackingBlocked()) { + return; + } + + if (mHeightAnimator != null) { + mPanelUpdateWhenAnimatorEnds = true; + return; } + + setExpandedHeight(currentMaxPanelHeight); } public void setExpandedHeightInternal(float h) { @@ -1062,7 +1076,7 @@ public abstract class PanelView extends FrameLayout { @Override public void onAnimationEnd(Animator animation) { if (mCancelled) { - mHeightAnimator = null; + setAnimator(null); onAnimationFinished.run(); } else { startUnlockHintAnimationPhase2(onAnimationFinished); @@ -1070,7 +1084,7 @@ public abstract class PanelView extends FrameLayout { } }); animator.start(); - mHeightAnimator = animator; + setAnimator(animator); mKeyguardBottomArea.getIndicationArea().animate() .translationY(-mHintDistance) .setDuration(250) @@ -1088,6 +1102,14 @@ public abstract class PanelView extends FrameLayout { .start(); } + private void setAnimator(ValueAnimator animator) { + mHeightAnimator = animator; + if (animator == null && mPanelUpdateWhenAnimatorEnds) { + mPanelUpdateWhenAnimatorEnds = false; + requestPanelHeightUpdate(); + } + } + /** * Phase 2: Bounce down. */ @@ -1098,13 +1120,13 @@ public abstract class PanelView extends FrameLayout { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mHeightAnimator = null; + setAnimator(null); onAnimationFinished.run(); notifyBarPanelExpansionChanged(); } }); animator.start(); - mHeightAnimator = animator; + setAnimator(animator); } private ValueAnimator createHeightAnimator(float targetHeight) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 07ab6876e42b..4e28e90a1402 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1826,23 +1826,20 @@ public class StatusBar extends SystemUI implements DemoMode, // temporarily become children if they were isolated before. continue; } - int vis = ent.notification.getNotification().visibility; int userId = ent.notification.getUserId(); // Display public version of the notification if we need to redact. - boolean deviceSensitive = (isLockscreenPublicMode(mCurrentUserId) - && !userAllowsPrivateNotificationsInPublic(mCurrentUserId)); - boolean userSensitive = deviceSensitive || (isLockscreenPublicMode(userId) - && !userAllowsPrivateNotificationsInPublic(userId)); - boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE; - boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey()); - boolean sensitive = (sensitiveNote && userSensitive) || sensitivePackage; - boolean showingPublic = sensitive && isLockscreenPublicMode(userId); - if (showingPublic) { + boolean devicePublic = isLockscreenPublicMode(mCurrentUserId); + boolean userPublic = devicePublic || isLockscreenPublicMode(userId); + boolean needsRedaction = needsRedaction(ent); + boolean sensitive = userPublic && needsRedaction; + boolean deviceSensitive = devicePublic + && !userAllowsPrivateNotificationsInPublic(mCurrentUserId); + if (sensitive) { updatePublicContentView(ent, ent.notification); } ent.row.setSensitive(sensitive, deviceSensitive); - ent.row.setNeedsRedaction(needsRedaction(ent)); + ent.row.setNeedsRedaction(needsRedaction); if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) { ExpandableNotificationRow summary = mGroupManager.getGroupSummary( ent.row.getStatusBarNotification()); @@ -4321,7 +4318,12 @@ public class StatusBar extends SystemUI implements DemoMode, final int userId = mCurrentProfiles.valueAt(i).id; boolean isProfilePublic = devicePublic; if (!devicePublic && userId != mCurrentUserId) { - if (mStatusBarKeyguardViewManager.isSecure(userId)) { + // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge + // due to a race condition where this code could be called before + // TrustManagerService updates its internal records, resulting in an incorrect + // state being cached in mLockscreenPublicMode. (b/35951989) + if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) + && mStatusBarKeyguardViewManager.isSecure(userId)) { isProfilePublic = mKeyguardManager.isDeviceLocked(userId); } } @@ -4938,7 +4940,6 @@ public class StatusBar extends SystemUI implements DemoMode, where.getLocationInWindow(mTmpInt2); mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2, mTmpInt2[1] + where.getHeight() / 2); - mNotificationPanel.setTouchDisabled(false); mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); mFalsingManager.onScreenOnFromTouch(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index f050be4720b7..236e008d4296 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -277,7 +277,7 @@ public class StatusBarWindowView extends FrameLayout { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (mService.isDozing() && !mService.isPulsing()) { + if (mService.isDozing() && !mStackScrollLayout.hasPulsingNotifications()) { // Capture all touch events in always-on. return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java index dc33633dde53..74a30fa8094f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java @@ -23,6 +23,7 @@ import android.content.IntentFilter; import android.content.res.TypedArray; import android.icu.text.DateFormat; import android.icu.text.DisplayContext; +import android.text.TextUtils; import android.util.AttributeSet; import android.widget.TextView; @@ -115,4 +116,15 @@ public class DateView extends TextView { mLastText = text; } } + + public void setDatePattern(String pattern) { + if (TextUtils.equals(pattern, mDatePattern)) { + return; + } + mDatePattern = pattern; + mDateFormat = null; + if (isAttachedToWindow()) { + updateClock(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java index e409b9c4454f..41ef78121c12 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java @@ -59,7 +59,7 @@ public class AmbientState { private boolean mPanelTracking; private boolean mExpansionChanging; private boolean mPanelFullWidth; - private boolean mPulsing; + private boolean mHasPulsingNotifications; private boolean mUnlockHintRunning; public AmbientState(Context context) { @@ -287,12 +287,12 @@ public class AmbientState { mPanelTracking = panelTracking; } - public boolean isPulsing() { - return mPulsing; + public boolean hasPulsingNotifications() { + return mHasPulsingNotifications; } - public void setPulsing(boolean pulsing) { - mPulsing = pulsing; + public void setHasPulsingNotifications(boolean hasPulsing) { + mHasPulsingNotifications = hasPulsing; } public boolean isPanelTracking() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 431f646163f5..3cc3604e296c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -53,7 +53,6 @@ import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; -import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.OverScroller; @@ -816,7 +815,8 @@ public class NotificationStackScrollLayout extends ViewGroup */ private float getAppearEndPosition() { int appearPosition; - if (mEmptyShadeView.getVisibility() == GONE) { + int notGoneChildCount = getNotGoneChildCount(); + if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) { int minNotificationsForShelf = 1; if (mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) { appearPosition = mHeadsUpManager.getTopHeadsUpPinnedHeight(); @@ -824,7 +824,7 @@ public class NotificationStackScrollLayout extends ViewGroup } else { appearPosition = 0; } - if (getNotGoneChildCount() >= minNotificationsForShelf) { + if (notGoneChildCount >= minNotificationsForShelf) { appearPosition += mShelf.getIntrinsicHeight(); } } else { @@ -1941,7 +1941,7 @@ public class NotificationStackScrollLayout extends ViewGroup int numShownItems = 0; boolean finish = false; int maxDisplayedNotifications = mAmbientState.isDark() - ? (isPulsing() ? 1 : 0) + ? (hasPulsingNotifications() ? 1 : 0) : mMaxDisplayedNotifications; for (int i = 0; i < getChildCount(); i++) { @@ -1950,7 +1950,8 @@ public class NotificationStackScrollLayout extends ViewGroup && !expandableView.hasNoContentHeight()) { boolean limitReached = maxDisplayedNotifications != -1 && numShownItems >= maxDisplayedNotifications; - boolean notificationOnAmbientThatIsNotPulsing = isPulsing() + boolean notificationOnAmbientThatIsNotPulsing = mAmbientState.isDark() + && hasPulsingNotifications() && expandableView instanceof ExpandableNotificationRow && !isPulsing(((ExpandableNotificationRow) expandableView).getEntry()); if (limitReached || notificationOnAmbientThatIsNotPulsing) { @@ -2008,7 +2009,7 @@ public class NotificationStackScrollLayout extends ViewGroup return false; } - private boolean isPulsing() { + public boolean hasPulsingNotifications() { return mPulsing != null; } @@ -2220,14 +2221,15 @@ public class NotificationStackScrollLayout extends ViewGroup ActivatableNotificationView firstView = mFirstVisibleBackgroundChild; int top = 0; if (firstView != null) { - int finalTranslationY = (int) ViewState.getFinalTranslationY(firstView); + // Round Y up to avoid seeing the background during animation + int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView)); if (mAnimateNextBackgroundTop || mTopAnimator == null && mCurrentBounds.top == finalTranslationY || mTopAnimator != null && mEndAnimationRect.top == finalTranslationY) { // we're ending up at the same location as we are now, lets just skip the animation top = finalTranslationY; } else { - top = (int) firstView.getTranslationY(); + top = (int) Math.ceil(firstView.getTranslationY()); } } ActivatableNotificationView lastView = mShelf.hasItemsInStableShelf() @@ -2837,7 +2839,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updateNotificationAnimationStates() { - boolean running = mAnimationsEnabled || isPulsing(); + boolean running = mAnimationsEnabled || hasPulsingNotifications(); mShelf.setAnimationsEnabled(running); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -2848,7 +2850,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updateAnimationState(View child) { - updateAnimationState((mAnimationsEnabled || isPulsing()) + updateAnimationState((mAnimationsEnabled || hasPulsingNotifications()) && (mIsExpanded || isPinnedHeadsUp(child)), child); } @@ -4117,7 +4119,7 @@ public class NotificationStackScrollLayout extends ViewGroup return; } mPulsing = pulsing; - mAmbientState.setPulsing(isPulsing()); + mAmbientState.setHasPulsingNotifications(hasPulsingNotifications()); updateNotificationAnimationStates(); updateContentHeight(); notifyHeightChangeListener(mShelf); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index 12a8783becf2..5c10e7ed4070 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -413,6 +413,7 @@ public class StackScrollAlgorithm { if (i == 0 && row.isAboveShelf()) { // the first hun can't get off screen. clampHunToMaxTranslation(ambientState, row, childState); + childState.hidden = false; } } if (row.isPinned()) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java index 15cebc70e8bc..8905d725de97 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java @@ -14,13 +14,18 @@ package com.android.systemui; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + import android.app.Fragment; +import android.app.Instrumentation; import android.support.test.InstrumentationRegistry; import android.testing.BaseFragmentTest; import com.android.systemui.utils.leaks.LeakCheckedTest; import com.android.systemui.utils.leaks.LeakCheckedTest.SysuiLeakCheck; +import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -33,6 +38,7 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest { protected final TestableDependency mDependency = new TestableDependency(mContext); protected SysuiTestableContext mSysuiContext; + private Instrumentation mRealInstrumentation; public SysuiBaseFragmentTest(Class<? extends Fragment> cls) { super(cls); @@ -44,6 +50,20 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest { SystemUIFactory.createFromConfig(mContext); // TODO: Figure out another way to give reference to a SysuiTestableContext. mSysuiContext = (SysuiTestableContext) mContext; + + mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); + Instrumentation inst = spy(mRealInstrumentation); + when(inst.getContext()).thenThrow(new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); + when(inst.getTargetContext()).thenThrow(new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); + InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments()); + } + + @After + public void SysuiTeardown() { + InstrumentationRegistry.registerInstance(mRealInstrumentation, + InstrumentationRegistry.getArguments()); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java index 9b675295d26a..361a20fb7bdc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java @@ -15,6 +15,10 @@ */ package com.android.systemui; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.Instrumentation; import android.content.Context; import android.os.Handler; import android.os.Looper; @@ -24,6 +28,7 @@ import android.support.test.filters.SmallTest; import android.testing.LeakCheck; import android.util.Log; +import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -42,11 +47,26 @@ public abstract class SysuiTestCase { public SysuiTestableContext mContext = new SysuiTestableContext( InstrumentationRegistry.getContext(), getLeakCheck()); public TestableDependency mDependency = new TestableDependency(mContext); + private Instrumentation mRealInstrumentation; @Before public void SysuiSetup() throws Exception { System.setProperty("dexmaker.share_classloader", "true"); SystemUIFactory.createFromConfig(mContext); + + mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); + Instrumentation inst = spy(mRealInstrumentation); + when(inst.getContext()).thenThrow(new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); + when(inst.getTargetContext()).thenThrow(new RuntimeException( + "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext")); + InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments()); + } + + @After + public void SysuiTeardown() { + InstrumentationRegistry.registerInstance(mRealInstrumentation, + InstrumentationRegistry.getArguments()); } protected LeakCheck getLeakCheck() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SignalClusterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SignalClusterViewTest.java new file mode 100644 index 000000000000..28a5aa39be80 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SignalClusterViewTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.statusbar; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.support.test.filters.SmallTest; +import android.telephony.SubscriptionInfo; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper.RunWithLooper; +import android.view.LayoutInflater; + +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.policy.NetworkController.IconState; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +@SmallTest +public class SignalClusterViewTest extends SysuiTestCase { + + private SignalClusterView mSignalCluster; + + @Before + public void setup() { + mSignalCluster = (SignalClusterView) LayoutInflater.from(mContext) + .inflate(R.layout.signal_cluster_view, null); + } + + @Test + public void testNonDefaultSim() { + SubscriptionInfo first = mock(SubscriptionInfo.class); + SubscriptionInfo second = mock(SubscriptionInfo.class); + when(first.getSubscriptionId()).thenReturn(0); + when(second.getSubscriptionId()).thenReturn(1); + mSignalCluster.setSubs(Arrays.asList(first, second)); + mSignalCluster.setQsSignalCluster(); + mSignalCluster.setMobileDataIndicators(new IconState(true, 0, 0, ""), null, 0, 0, + false, false, "", "", false, 1, false); + } + +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java index 9b7c5970270f..d925364b0e69 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java @@ -41,9 +41,7 @@ public class WakeLockTest extends SysuiTestCase { @Before public void setUp() { - Context context = InstrumentationRegistry.getContext(); - - mInner = WakeLock.createPartialInner(context, WakeLockTest.class.getName()); + mInner = WakeLock.createPartialInner(mContext, WakeLockTest.class.getName()); mWakeLock = WakeLock.wrap(mInner); } diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 7abaf7ff9922..38b796b316de 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -51,6 +51,7 @@ import android.service.autofill.FillEventHistory.Event; import android.service.autofill.FillResponse; import android.service.autofill.IAutoFillService; import android.text.TextUtils; +import android.util.ArraySet; import android.util.LocalLog; import android.util.Slog; import android.util.SparseArray; @@ -465,10 +466,17 @@ final class AutofillManagerServiceImpl { if (sVerbose) Slog.v(TAG, "destroyLocked()"); final int numSessions = mSessions.size(); + final ArraySet<RemoteFillService> remoteFillServices = new ArraySet<>(numSessions); for (int i = 0; i < numSessions; i++) { - mSessions.valueAt(i).destroyLocked(); + final RemoteFillService remoteFillService = mSessions.valueAt(i).destroyLocked(); + if (remoteFillService != null) { + remoteFillServices.add(remoteFillService); + } } mSessions.clear(); + for (int i = 0; i < remoteFillServices.size(); i++) { + remoteFillServices.valueAt(i).destroy(); + } sendStateToClients(true); } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index bad8dcf42aae..980a7d41200f 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -419,7 +419,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState notifyUnavailableToClient(); } synchronized (mLock) { - processResponseLocked(response); + processResponseLocked(response, requestFlags); } final LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST)) @@ -1026,7 +1026,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState case ACTION_START_SESSION: // View is triggering autofill. mCurrentViewId = viewState.id; - viewState.update(value, virtualBounds); + viewState.update(value, virtualBounds, flags); viewState.setState(ViewState.STATE_STARTED_SESSION); requestNewFillResponseLocked(flags); break; @@ -1065,7 +1065,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } // If the ViewState is ready to be displayed, onReady() will be called. - viewState.update(value, virtualBounds); + viewState.update(value, virtualBounds, flags); break; case ACTION_VIEW_EXITED: if (mCurrentViewId == viewState.id) { @@ -1204,10 +1204,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // Replace the old response mResponses.put(newResponse.getRequestId(), newResponse); // Now process the new response - processResponseLocked(newResponse); + processResponseLocked(newResponse, 0); } - private void processResponseLocked(@NonNull FillResponse newResponse) { + private void processResponseLocked(@NonNull FillResponse newResponse, int flags) { // Make sure we are hiding the UI which will be shown // only if handling the current response requires it. hideAllUiIfOwnedByMe(); @@ -1215,7 +1215,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState final int requestId = newResponse.getRequestId(); if (sVerbose) { Slog.v(TAG, "processResponseLocked(): mCurrentViewId=" + mCurrentViewId - + ", reqId=" + requestId + ", resp=" + newResponse); + + ",flags=" + flags + ", reqId=" + requestId + ", resp=" + newResponse); } if (mResponses == null) { @@ -1231,21 +1231,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } - final ArrayList<Dataset> datasets = newResponse.getDatasets(); - - if (datasets != null && datasets.size() == 1) { - // Check if it its a single response for a manual request, in which case it should - // be automatically filled - final FillContext context = getFillContextByRequestIdLocked(requestId); - if (context != null && (context.getStructure().getFlags() & FLAG_MANUAL_REQUEST) != 0) { - Slog.d(TAG, "autofilling manual request directly"); - autoFill(requestId, 0, datasets.get(0)); - return; - } - } // Updates the UI, if necessary. final ViewState currentView = mViewStates.get(mCurrentViewId); - currentView.maybeCallOnFillReady(); + currentView.maybeCallOnFillReady(flags); } /** @@ -1331,20 +1319,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return viewState; } - /** - * Resets the given state from all existing views in the given dataset. - */ - private void resetViewStatesLocked(@NonNull Dataset dataset, int state) { - final ArrayList<AutofillId> ids = dataset.getFieldIds(); - for (int j = 0; j < ids.size(); j++) { - final AutofillId id = ids.get(j); - final ViewState viewState = mViewStates.get(id); - if (viewState != null) { - viewState.resetState(state); - } - } - } - void autoFill(int requestId, int datasetIndex, Dataset dataset) { synchronized (mLock) { if (mDestroyed) { @@ -1452,8 +1426,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } try { - if (sDebug) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset); - // Skip null values as a null values means no change final int entryCount = dataset.getFieldIds().size(); final List<AutofillId> ids = new ArrayList<>(entryCount); @@ -1480,6 +1452,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (waitingDatasetAuth) { hideFillUiIfOwnedByMe(); } + if (sDebug) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset); + mClient.autofill(id, ids, values); setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED, false); } @@ -1496,15 +1470,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } } - void destroyLocked() { + RemoteFillService destroyLocked() { if (mDestroyed) { - return; + return null; } - mRemoteFillService.destroy(); hideAllUiIfOwnedByMe(); mUi.clearCallback(this); mDestroyed = true; mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName); + return mRemoteFillService; } private void hideAllUiIfOwnedByMe() { @@ -1528,8 +1502,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState + id + " destroyed"); return; } - destroyLocked(); + final RemoteFillService remoteFillService = destroyLocked(); mService.removeSessionLocked(id); + if (remoteFillService != null) { + remoteFillService.destroy(); + } } private int getLastResponseIndex() { diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java index 8a52c965345c..cd8f4a59526f 100644 --- a/services/autofill/java/com/android/server/autofill/ViewState.java +++ b/services/autofill/java/com/android/server/autofill/ViewState.java @@ -16,6 +16,7 @@ package com.android.server.autofill; +import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static com.android.server.autofill.Helper.sDebug; import static com.android.server.autofill.Helper.sVerbose; @@ -157,7 +158,7 @@ final class ViewState { // TODO: refactor / rename / document this method (and maybeCallOnFillReady) to make it clear // that it can change the value and update the UI; similarly, should replace code that // directly sets mAutofillValue to use encapsulation. - void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) { + void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds, int flags) { if (autofillValue != null) { mCurrentValue = autofillValue; } @@ -165,7 +166,7 @@ final class ViewState { mVirtualBounds = virtualBounds; } - maybeCallOnFillReady(); + maybeCallOnFillReady(flags); } /** @@ -173,8 +174,8 @@ final class ViewState { * Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the * fill UI is ready to be displayed (i.e. when response and bounds are set). */ - void maybeCallOnFillReady() { - if ((mState & STATE_AUTOFILLED) != 0) { + void maybeCallOnFillReady(int flags) { + if ((mState & STATE_AUTOFILLED) != 0 && (flags & FLAG_MANUAL_REQUEST) == 0) { if (sDebug) Slog.d(TAG, "Ignoring UI for " + id + " on " + getStateAsString()); return; } diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index d315b3d7b70f..d566d3d608b4 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -158,6 +158,7 @@ final class FillUi { final RemoteViews presentation = dataset.getFieldPresentation(index); final View view; try { + if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId); view = presentation.apply(context, null, interceptionHandler); } catch (RuntimeException e) { Slog.e(TAG, "Error inflating remote views", e); @@ -203,6 +204,7 @@ final class FillUi { return; } if (count <= 0) { + if (sDebug) Slog.d(TAG, "No dataset matches filter: " + mFilterText); mCallback.requestHideFillUi(); } else { if (updateContentSize()) { @@ -382,6 +384,7 @@ final class FillUi { * Shows the window. */ public void show(WindowManager.LayoutParams params) { + if (sVerbose) Slog.v(TAG, "show(): showing=" + mShowing + ", params="+ params); try { if (!mShowing) { params.accessibilityTitle = mContentView.getContext() diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 68c92a865f70..f3ecfeb40498 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -13924,9 +13924,9 @@ public class ActivityManagerService extends IActivityManager.Stub final boolean supportsPictureInPicture = mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); - final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(); + final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext); final boolean supportsSplitScreenMultiWindow = - ActivityManager.supportsSplitScreenMultiWindow(); + ActivityManager.supportsSplitScreenMultiWindow(mContext); final boolean supportsMultiDisplay = mContext.getPackageManager() .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS); final String debugApp = Settings.Global.getString(resolver, DEBUG_APP); @@ -20180,6 +20180,11 @@ public class ActivityManagerService extends IActivityManager.Stub mTempConfig.setTo(getGlobalConfiguration()); final int changes = mTempConfig.updateFrom(values); if (changes == 0) { + // Since calling to Activity.setRequestedOrientation leads to freezing the window with + // setting WindowManagerService.mWaitingForConfig to true, it is important that we call + // performDisplayOverrideConfigUpdate in order to send the new display configuration + // (even if there are no actual changes) to unfreeze the window. + performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY); return 0; } @@ -20368,20 +20373,19 @@ public class ActivityManagerService extends IActivityManager.Stub int displayId) { mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); final int changes = mTempConfig.updateFrom(values); - if (changes == 0) { - return 0; - } - - Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig - + " for displayId=" + displayId); - mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); + if (changes != 0) { + Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + + mTempConfig + " for displayId=" + displayId); + mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); - final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; - if (isDensityChange && displayId == DEFAULT_DISPLAY) { - // Reset the unsupported display size dialog. - mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); + final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; + if (isDensityChange && displayId == DEFAULT_DISPLAY) { + // Reset the unsupported display size dialog. + mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); - killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + killAllBackgroundProcessesExcept(N, + ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + } } // Update the configuration with WM first and check if any of the stacks need to be resized diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 6eae9e6f9b05..d7683047143a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2382,7 +2382,7 @@ final class ActivityManagerShellCommand extends ShellCommand { if (res == null) { return -1; } - pw.println(ActivityManager.supportsMultiWindow()); + pw.println(ActivityManager.supportsMultiWindow(mInternal.mContext)); return 0; } @@ -2391,7 +2391,7 @@ final class ActivityManagerShellCommand extends ShellCommand { if (res == null) { return -1; } - pw.println(ActivityManager.supportsSplitScreenMultiWindow()); + pw.println(ActivityManager.supportsSplitScreenMultiWindow(mInternal.mContext)); return 0; } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index e828d38ef249..b55bae91da8d 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -470,7 +470,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } Configuration getDisplayOverrideConfiguration(int displayId) { - final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); if (activityDisplay == null) { throw new IllegalArgumentException("No display found with id: " + displayId); } @@ -479,7 +479,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } void setDisplayOverrideConfiguration(Configuration overrideConfiguration, int displayId) { - final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); if (activityDisplay == null) { throw new IllegalArgumentException("No display found with id: " + displayId); } @@ -507,7 +507,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (displayId == INVALID_DISPLAY) { return false; } - final ActivityDisplay targetDisplay = mActivityDisplays.get(displayId); + final ActivityDisplay targetDisplay = getActivityDisplayOrCreateLocked(displayId); if (targetDisplay == null) { throw new IllegalArgumentException("No display found with id: " + displayId); } @@ -1672,7 +1672,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId + " callingPid=" + callingPid + " callingUid=" + callingUid); - final ActivityDisplay activityDisplay = mActivityDisplays.get(launchDisplayId); + final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(launchDisplayId); if (activityDisplay == null) { Slog.w(TAG, "Launch on display check: display not found"); return false; @@ -2191,7 +2191,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null. */ ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r) { - final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); if (activityDisplay == null) { throw new IllegalArgumentException( "Display with displayId=" + displayId + " not found."); @@ -2242,10 +2242,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) { final int displayId = mTmpOrderedDisplayIds.get(i); - final List<ActivityStack> stacks = mActivityDisplays.get(displayId).mStacks; - if (stacks == null) { - continue; - } + // If a display is registered in WM, it must also be available in AM. + @SuppressWarnings("ConstantConditions") + final List<ActivityStack> stacks = getActivityDisplayOrCreateLocked(displayId).mStacks; for (int j = stacks.size() - 1; j >= 0; --j) { final ActivityStack stack = stacks.get(j); if (stack != currentFocus && stack.isFocusable() @@ -2576,7 +2575,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) { - final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); if (activityDisplay == null) { return null; } @@ -2808,7 +2807,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D * @param onTop Indicates whether container should be place on top or on bottom. */ void moveStackToDisplayLocked(int stackId, int displayId, boolean onTop) { - final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); if (activityDisplay == null) { throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId=" + displayId); @@ -3915,25 +3914,44 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } private void handleDisplayAdded(int displayId) { - boolean newDisplay; synchronized (mService) { - newDisplay = mActivityDisplays.get(displayId) == null; - if (newDisplay) { - ActivityDisplay activityDisplay = new ActivityDisplay(displayId); - if (activityDisplay.mDisplay == null) { - Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); - return; - } - mActivityDisplays.put(displayId, activityDisplay); - calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); - mWindowManager.onDisplayAdded(displayId); - } + getActivityDisplayOrCreateLocked(displayId); } } /** Check if display with specified id is added to the list. */ boolean isDisplayAdded(int displayId) { - return mActivityDisplays.get(displayId) != null; + return getActivityDisplayOrCreateLocked(displayId) != null; + } + + /** + * Get an existing instance of {@link ActivityDisplay} or create new if there is a + * corresponding record in display manager. + */ + private ActivityDisplay getActivityDisplayOrCreateLocked(int displayId) { + ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + if (activityDisplay != null) { + return activityDisplay; + } + if (mDisplayManager == null) { + // The system isn't fully initialized yet. + return null; + } + final Display display = mDisplayManager.getDisplay(displayId); + if (display == null) { + // The display is not registered in DisplayManager. + return null; + } + // The display hasn't been added to ActivityManager yet, create a new record now. + activityDisplay = new ActivityDisplay(displayId); + if (activityDisplay.mDisplay == null) { + Slog.w(TAG, "Display " + displayId + " gone before initialization complete"); + return null; + } + mActivityDisplays.put(displayId, activityDisplay); + calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); + mWindowManager.onDisplayAdded(displayId); + return activityDisplay; } private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) { @@ -3991,6 +4009,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D info.stackId = stack.mStackId; info.userId = stack.mCurrentUser; info.visible = stack.shouldBeVisible(null) == STACK_VISIBLE; + // A stack might be not attached to a display. info.position = display != null ? display.mStacks.indexOf(stack) : 0; @@ -4618,7 +4637,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D @Override public void addToDisplay(int displayId) { synchronized (mService) { - ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); + final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId); if (activityDisplay == null) { return; } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index e15b13527c3e..c20221bfe4aa 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -17,6 +17,8 @@ package com.android.server.am; import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU; +import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO; +import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI; import android.annotation.Nullable; import android.bluetooth.BluetoothActivityEnergyInfo; @@ -231,10 +233,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void publish(Context context) { mContext = context; - mStats.setRadioScanningTimeout(mContext.getResources().getInteger( - com.android.internal.R.integer.config_radioScanningTimeout) - * 1000L); - mStats.setPowerProfile(new PowerProfile(context)); + synchronized (mStats) { + mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger( + com.android.internal.R.integer.config_radioScanningTimeout) + * 1000L); + mStats.setPowerProfileLocked(new PowerProfile(context)); + } ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder()); } @@ -245,9 +249,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void initPowerManagement() { final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class); powerMgr.registerLowPowerModeObserver(this); - mStats.notePowerSaveMode( - powerMgr.getLowPowerState(ServiceType.BATTERY_STATS) - .batterySaverEnabled); + synchronized (mStats) { + mStats.notePowerSaveModeLocked( + powerMgr.getLowPowerState(ServiceType.BATTERY_STATS) + .batterySaverEnabled); + } (new WakeupReasonThread()).start(); } @@ -280,7 +286,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override public void onLowPowerModeChanged(PowerSaveState result) { synchronized (mStats) { - mStats.notePowerSaveMode(result.batterySaverEnabled); + mStats.notePowerSaveModeLocked(result.batterySaverEnabled); } } @@ -606,8 +612,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) { enforceCallingPermission(); + boolean update; synchronized (mStats) { - mStats.noteMobileRadioPowerState(powerState, timestampNs, uid); + update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid); + } + + if (update) { + mHandler.scheduleSync("modem-data", UPDATE_RADIO); } } @@ -759,7 +770,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active" : "inactive"; mHandler.scheduleSync("wifi-data: " + type, - BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI); + UPDATE_WIFI); } mStats.noteWifiRadioPowerState(powerState, tsNanos, uid); } @@ -917,9 +928,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override public void noteNetworkStatsEnabled() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteNetworkStatsEnabledLocked(); - } + mHandler.scheduleSync("network-stats-enabled", UPDATE_RADIO | UPDATE_WIFI); } @Override @@ -945,10 +954,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub } @Override - public void noteBleScanStarted(WorkSource ws) { + public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteBluetoothScanStartedFromSourceLocked(ws); + mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized); } } @@ -985,9 +994,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub return; } - synchronized (mStats) { - mStats.updateWifiStateLocked(info); - } + mStats.updateWifiState(info); } @Override @@ -1012,9 +1019,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub return; } - synchronized (mStats) { - mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime(), info); - } + mStats.updateMobileRadioState(info); } public boolean isOnBattery() { @@ -1489,7 +1494,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub return; } - if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) { + if ((updateFlags & UPDATE_WIFI) != 0) { if (mWifiManager == null) { mWifiManager = IWifiManager.Stub.asInterface( ServiceManager.getService(Context.WIFI_SERVICE)); @@ -1558,14 +1563,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub mStats.updateKernelWakelocksLocked(); mStats.updateKernelMemoryBandwidthLocked(); - if (wifiInfo != null) { - if (wifiInfo.isValid()) { - mStats.updateWifiStateLocked(extractDelta(wifiInfo)); - } else { - Slog.e(TAG, "wifi info is invalid: " + wifiInfo); - } - } - if (bluetoothInfo != null) { if (bluetoothInfo.isValid()) { mStats.updateBluetoothStateLocked(bluetoothInfo); @@ -1573,14 +1570,21 @@ public final class BatteryStatsService extends IBatteryStats.Stub Slog.e(TAG, "bluetooth info is invalid: " + bluetoothInfo); } } + } - if (modemInfo != null) { - if (modemInfo.isValid()) { - mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime(), - modemInfo); - } else { - Slog.e(TAG, "modem info is invalid: " + modemInfo); - } + if (wifiInfo != null) { + if (wifiInfo.isValid()) { + mStats.updateWifiState(extractDelta(wifiInfo)); + } else { + Slog.e(TAG, "wifi info is invalid: " + wifiInfo); + } + } + + if (modemInfo != null) { + if (modemInfo.isValid()) { + mStats.updateMobileRadioState(modemInfo); + } else { + Slog.e(TAG, "modem info is invalid: " + modemInfo); } } } diff --git a/services/core/java/com/android/server/am/ProviderMap.java b/services/core/java/com/android/server/am/ProviderMap.java index a6997f944a4c..32d03daedef3 100644 --- a/services/core/java/com/android/server/am/ProviderMap.java +++ b/services/core/java/com/android/server/am/ProviderMap.java @@ -382,18 +382,29 @@ public final class ProviderMap { } /** - * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if - * there is a thread associated with the provider. + * Before invoking IApplicationThread.dumpProvider(), print meta information to the print + * writer and handle passed flags. */ private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw, final ContentProviderRecord r, String[] args, boolean dumpAll) { + for (String s: args) { + if (!dumpAll && s.contains("--proto")) { + if (r.proc != null && r.proc.thread != null) { + dumpToTransferPipe(null , fd, pw, r, args); + } + return; + } + } String innerPrefix = prefix + " "; synchronized (mAm) { pw.print(prefix); pw.print("PROVIDER "); - pw.print(r); - pw.print(" pid="); - if (r.proc != null) pw.println(r.proc.pid); - else pw.println("(not running)"); + pw.print(r); + pw.print(" pid="); + if (r.proc != null) { + pw.println(r.proc.pid); + } else { + pw.println("(not running)"); + } if (dumpAll) { r.dump(pw, innerPrefix, true); } @@ -401,23 +412,32 @@ public final class ProviderMap { if (r.proc != null && r.proc.thread != null) { pw.println(" Client:"); pw.flush(); + dumpToTransferPipe(" ", fd, pw, r, args); + } + } + + /** + * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider without + * any meta string (e.g., provider info, indentation) written to the file descriptor. + */ + private void dumpToTransferPipe(String prefix, FileDescriptor fd, PrintWriter pw, + final ContentProviderRecord r, String[] args) { + try { + TransferPipe tp = new TransferPipe(); try { - TransferPipe tp = new TransferPipe(); - try { - r.proc.thread.dumpProvider( - tp.getWriteFd(), r.provider.asBinder(), args); - tp.setBufferPrefix(" "); - // Short timeout, since blocking here can - // deadlock with the application. - tp.go(fd, 2000); - } finally { - tp.kill(); - } - } catch (IOException ex) { - pw.println(" Failure while dumping the provider: " + ex); - } catch (RemoteException ex) { - pw.println(" Got a RemoteException while dumping the service"); + r.proc.thread.dumpProvider( + tp.getWriteFd(), r.provider.asBinder(), args); + tp.setBufferPrefix(prefix); + // Short timeout, since blocking here can + // deadlock with the application. + tp.go(fd, 2000); + } finally { + tp.kill(); } + } catch (IOException ex) { + pw.println(" Failure while dumping the provider: " + ex); + } catch (RemoteException ex) { + pw.println(" Got a RemoteException while dumping the service"); } } } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 901092ed3175..4b71cc15abd6 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -18,7 +18,13 @@ package com.android.server.connectivity; import static android.hardware.usb.UsbManager.USB_CONNECTED; import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; +import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; +import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; +import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR; +import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; +import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; +import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static com.android.server.ConnectivityService.SHORT_ARG; @@ -799,48 +805,80 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } private void handleWifiApAction(Intent intent) { - final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED); + final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED); + final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME); + final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED); + synchronized (Tethering.this.mPublicSync) { switch (curState) { case WifiManager.WIFI_AP_STATE_ENABLING: // We can see this state on the way to both enabled and failure states. break; case WifiManager.WIFI_AP_STATE_ENABLED: - // When the AP comes up and we've been requested to tether it, do so. - // Otherwise, assume it's a local-only hotspot request. - final int state = mWifiTetherRequested - ? IControlsTethering.STATE_TETHERED - : IControlsTethering.STATE_LOCAL_ONLY; - tetherMatchingInterfaces(state, ConnectivityManager.TETHERING_WIFI); + enableWifiIpServingLocked(ifname, ipmode); break; case WifiManager.WIFI_AP_STATE_DISABLED: case WifiManager.WIFI_AP_STATE_DISABLING: case WifiManager.WIFI_AP_STATE_FAILED: default: - if (DBG) { - Log.d(TAG, "Canceling WiFi tethering request - AP_STATE=" + - curState); - } - // Tell appropriate interface state machines that they should tear - // themselves down. - for (int i = 0; i < mTetherStates.size(); i++) { - TetherInterfaceStateMachine tism = - mTetherStates.valueAt(i).stateMachine; - if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) { - tism.sendMessage( - TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); - break; // There should be at most one of these. - } - } - // Regardless of whether we requested this transition, the AP has gone - // down. Don't try to tether again unless we're requested to do so. - mWifiTetherRequested = false; - break; + disableWifiIpServingLocked(curState); + break; } } } } + // TODO: Pass in the interface name and, if non-empty, only turn down IP + // serving on that one interface. + private void disableWifiIpServingLocked(int apState) { + if (DBG) Log.d(TAG, "Canceling WiFi tethering request - AP_STATE=" + apState); + + // Tell appropriate interface state machines that they should tear + // themselves down. + for (int i = 0; i < mTetherStates.size(); i++) { + TetherInterfaceStateMachine tism = mTetherStates.valueAt(i).stateMachine; + if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) { + tism.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); + break; // There should be at most one of these. + } + } + // Regardless of whether we requested this transition, the AP has gone + // down. Don't try to tether again unless we're requested to do so. + mWifiTetherRequested = false; + } + + private void enableWifiIpServingLocked(String ifname, int wifiIpMode) { + // Map wifiIpMode values to IControlsTethering serving states, inferring + // from mWifiTetherRequested as a final "best guess". + final int ipServingMode; + switch (wifiIpMode) { + case IFACE_IP_MODE_TETHERED: + ipServingMode = IControlsTethering.STATE_TETHERED; + break; + case IFACE_IP_MODE_LOCAL_ONLY: + ipServingMode = IControlsTethering.STATE_LOCAL_ONLY; + break; + default: + // Resort to legacy "guessing" behaviour. + // + // When the AP comes up and we've been requested to tether it, + // do so. Otherwise, assume it's a local-only hotspot request. + // + // TODO: Once all AP broadcasts are known to include ifname and + // mode information delete this code path and log an error. + ipServingMode = mWifiTetherRequested + ? IControlsTethering.STATE_TETHERED + : IControlsTethering.STATE_LOCAL_ONLY; + break; + } + + if (!TextUtils.isEmpty(ifname)) { + changeInterfaceState(ifname, ipServingMode); + } else { + tetherMatchingInterfaces(ipServingMode, ConnectivityManager.TETHERING_WIFI); + } + } + // TODO: Consider renaming to something more accurate in its description. // This method: // - allows requesting either tethering or local hotspot serving states @@ -873,22 +911,26 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering return; } + changeInterfaceState(chosenIface, requestedState); + } + + private void changeInterfaceState(String ifname, int requestedState) { final int result; switch (requestedState) { case IControlsTethering.STATE_UNAVAILABLE: case IControlsTethering.STATE_AVAILABLE: - result = untether(chosenIface); + result = untether(ifname); break; case IControlsTethering.STATE_TETHERED: case IControlsTethering.STATE_LOCAL_ONLY: - result = tether(chosenIface, requestedState); + result = tether(ifname, requestedState); break; default: Log.wtf(TAG, "Unknown interface state: " + requestedState); return; } if (result != ConnectivityManager.TETHER_ERROR_NO_ERROR) { - Log.e(TAG, "unable start or stop tethering on iface " + chosenIface); + Log.e(TAG, "unable start or stop tethering on iface " + ifname); return; } } @@ -1470,10 +1512,10 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering final String iface = who.interfaceName(); switch (mode) { case IControlsTethering.STATE_TETHERED: - mgr.updateInterfaceIpState(iface, WifiManager.IFACE_IP_MODE_TETHERED); + mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED); break; case IControlsTethering.STATE_LOCAL_ONLY: - mgr.updateInterfaceIpState(iface, WifiManager.IFACE_IP_MODE_LOCAL_ONLY); + mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY); break; default: Log.wtf(TAG, "Unknown active serving mode: " + mode); @@ -1491,7 +1533,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) { if (who.lastError() != ConnectivityManager.TETHER_ERROR_NO_ERROR) { getWifiManager().updateInterfaceIpState( - who.interfaceName(), WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR); + who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR); } } } diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java index d5742657c5e2..b3cf57b3564a 100644 --- a/services/core/java/com/android/server/display/NightDisplayService.java +++ b/services/core/java/com/android/server/display/NightDisplayService.java @@ -285,12 +285,6 @@ public final class NightDisplayService extends SystemService if (mIsActivated == null || mIsActivated != activated) { Slog.i(TAG, activated ? "Turning on night display" : "Turning off night display"); - if (mIsActivated != null) { - Secure.putLongForUser(getContext().getContentResolver(), - Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(), - mCurrentUser); - } - mIsActivated = activated; if (mAutoMode != null) { @@ -430,19 +424,6 @@ public final class NightDisplayService extends SystemService outTemp[10] = blue; } - private Calendar getLastActivatedTime() { - final ContentResolver cr = getContext().getContentResolver(); - final long lastActivatedTimeMillis = Secure.getLongForUser( - cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1, mCurrentUser); - if (lastActivatedTimeMillis < 0) { - return null; - } - - final Calendar lastActivatedTime = Calendar.getInstance(); - lastActivatedTime.setTimeInMillis(lastActivatedTimeMillis); - return lastActivatedTime; - } - private abstract class AutoMode implements NightDisplayController.Callback { public abstract void onStart(); @@ -522,7 +503,7 @@ public final class NightDisplayService extends SystemService mStartTime = mController.getCustomStartTime(); mEndTime = mController.getCustomEndTime(); - mLastActivatedTime = getLastActivatedTime(); + mLastActivatedTime = mController.getLastActivatedTime(); // Force an update to initialize state. updateActivated(); @@ -538,7 +519,7 @@ public final class NightDisplayService extends SystemService @Override public void onActivated(boolean activated) { - mLastActivatedTime = getLastActivatedTime(); + mLastActivatedTime = mController.getLastActivatedTime(); updateNextAlarm(activated, Calendar.getInstance()); } @@ -579,7 +560,7 @@ public final class NightDisplayService extends SystemService } boolean activate = state.isNight(); - final Calendar lastActivatedTime = getLastActivatedTime(); + final Calendar lastActivatedTime = mController.getLastActivatedTime(); if (lastActivatedTime != null) { final Calendar now = Calendar.getInstance(); final Calendar sunrise = state.sunrise(); diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index b8d633fc666f..73a365b0da72 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -221,7 +221,9 @@ abstract public class ManagedServices { restoredSettingName(element), newValue, userid); - updateSettingsAccordingToInstalledServices(element, userid); + if (mConfig.secureSettingName.equals(element)) { + updateSettingsAccordingToInstalledServices(element, userid); + } rebuildRestoredPackages(); } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 3667e161b7af..1f7feb5dcd57 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1051,7 +1051,8 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting void init(Looper looper, IPackageManager packageManager, PackageManager packageManagerClient, LightsManager lightsManager, NotificationListeners notificationListeners, - ICompanionDeviceManager companionManager, SnoozeHelper snoozeHelper) { + ICompanionDeviceManager companionManager, SnoozeHelper snoozeHelper, + NotificationUsageStats usageStats) { Resources resources = getContext().getResources(); mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(), Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, @@ -1074,7 +1075,7 @@ public class NotificationManagerService extends SystemService { } catch (Resources.NotFoundException e) { extractorNames = new String[0]; } - mUsageStats = new NotificationUsageStats(getContext()); + mUsageStats = usageStats; mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper()); mRankingHelper = new RankingHelper(getContext(), getContext().getPackageManager(), @@ -1243,7 +1244,7 @@ public class NotificationManagerService extends SystemService { init(Looper.myLooper(), AppGlobals.getPackageManager(), getContext().getPackageManager(), getLocalService(LightsManager.class), new NotificationListeners(), - null, snoozeHelper); + null, snoozeHelper, new NotificationUsageStats(getContext())); publishBinderService(Context.NOTIFICATION_SERVICE, mService); publishLocalService(NotificationManagerInternal.class, mInternalService); } @@ -3714,7 +3715,7 @@ public class NotificationManagerService extends SystemService { if (!mInCall && hasValidVibrate && !ringerModeSilent) { mVibrateNotificationKey = key; - buzz = playVibration(record, vibration); + buzz = playVibration(record, vibration, hasValidSound); } } } @@ -3788,22 +3789,41 @@ public class NotificationManagerService extends SystemService { return false; } - private boolean playVibration(final NotificationRecord record, long[] vibration) { + private boolean playVibration(final NotificationRecord record, long[] vibration, + boolean delayVibForSound) { // Escalate privileges so we can use the vibrator even if the // notifying app does not have the VIBRATE permission. long identity = Binder.clearCallingIdentity(); try { - final boolean insistent = - (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0; - final VibrationEffect effect = VibrationEffect.createWaveform( - vibration, insistent ? 0 : -1 /*repeatIndex*/); - mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), - effect, record.getAudioAttributes()); + final VibrationEffect effect; + try { + final boolean insistent = + (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0; + effect = VibrationEffect.createWaveform( + vibration, insistent ? 0 : -1 /*repeatIndex*/); + } catch (IllegalArgumentException e) { + Slog.e(TAG, "Error creating vibration waveform with pattern: " + + Arrays.toString(vibration)); + return false; + } + if (delayVibForSound) { + new Thread(() -> { + // delay the vibration by the same amount as the notification sound + final int waitMs = mAudioManager.getFocusRampTimeMs( + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, + record.getAudioAttributes()); + if (DBG) Slog.v(TAG, "Delaying vibration by " + waitMs + "ms"); + try { + Thread.sleep(waitMs); + } catch (InterruptedException e) { } + mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), + effect, record.getAudioAttributes()); + }).start(); + } else { + mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), + effect, record.getAudioAttributes()); + } return true; - } catch (IllegalArgumentException e) { - Slog.e(TAG, "Error creating vibration waveform with pattern: " + - Arrays.toString(vibration)); - return false; } finally{ Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index 803b0dc0ee5e..95e1db7a3a4c 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -45,6 +45,7 @@ import android.util.Log; import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; +import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; @@ -359,8 +360,13 @@ public final class NotificationRecord { } } + String formatRemoteViews(RemoteViews rv) { + if (rv == null) return "null"; + return String.format("%s/0x%08x (%d bytes): %s", + rv.getPackage(), rv.getLayoutId(), rv.estimateMemoryUsage(), rv.toString()); + } + void dump(PrintWriter pw, String prefix, Context baseContext, boolean redact) { - prefix = prefix + " "; final Notification notification = sbn.getNotification(); final Icon icon = notification.getSmallIcon(); String iconStr = String.valueOf(icon); @@ -368,6 +374,7 @@ public final class NotificationRecord { iconStr += " / " + idDebugString(baseContext, icon.getResPackage(), icon.getResId()); } pw.println(prefix + this); + prefix = prefix + " "; pw.println(prefix + "uid=" + sbn.getUid() + " userId=" + sbn.getUserId()); pw.println(prefix + "icon=" + iconStr); pw.println(prefix + "pri=" + notification.priority); @@ -391,8 +398,11 @@ public final class NotificationRecord { } else { pw.println("null"); } - pw.println(prefix + "contentView=" + notification.contentView); - pw.println(prefix + String.format("color=0x%08x", notification.color)); + pw.println(prefix + "contentView=" + formatRemoteViews(notification.contentView)); + pw.println(prefix + "bigContentView=" + formatRemoteViews(notification.bigContentView)); + pw.println(prefix + "headsUpContentView=" + + formatRemoteViews(notification.headsUpContentView)); + pw.print(prefix + String.format("color=0x%08x", notification.color)); pw.println(prefix + "timeout=" + TimeUtils.formatForLogging(notification.getTimeoutAfter())); if (notification.actions != null && notification.actions.length > 0) { diff --git a/services/core/java/com/android/server/storage/FileCollector.java b/services/core/java/com/android/server/storage/FileCollector.java index 0c119a72e7f9..96e358402a97 100644 --- a/services/core/java/com/android/server/storage/FileCollector.java +++ b/services/core/java/com/android/server/storage/FileCollector.java @@ -203,7 +203,13 @@ public class FileCollector { return 0; } - final long sharedDataSize = shared.getPath().getTotalSpace(); + // In some cases, the path may be null -- we can't determine the size in this case. + final File sharedPath = shared.getPath(); + if (sharedPath == null) { + return 0; + } + + final long sharedDataSize = sharedPath.getTotalSpace(); long systemSize = sm.getPrimaryStorageSize() - sharedDataSize; // This case is not exceptional -- we just fallback to the shared data volume in this case. diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java index 972623c9478d..7eebe39f4ee4 100644 --- a/services/core/java/com/android/server/wm/AlertWindowNotification.java +++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java @@ -25,6 +25,7 @@ import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION; import android.app.Notification; import android.app.NotificationChannel; +import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; @@ -45,6 +46,7 @@ class AlertWindowNotification { private static final int NOTIFICATION_ID = 0; private static int sNextRequestCode = 0; + private static NotificationChannelGroup sChannelGroup; private final int mRequestCode; private final WindowManagerService mService; private String mNotificationTag; @@ -61,6 +63,12 @@ class AlertWindowNotification { mNotificationTag = CHANNEL_PREFIX + mPackageName; mRequestCode = sNextRequestCode++; mIconUtilities = new IconUtilities(mService.mContext); + if (sChannelGroup == null) { + sChannelGroup = new NotificationChannelGroup(CHANNEL_PREFIX, + mService.mContext.getString( + R.string.alert_windows_notification_channel_group_name)); + mNotificationManager.createNotificationChannelGroup(sChannelGroup); + } } void post() { @@ -142,6 +150,7 @@ class AlertWindowNotification { channel.enableLights(false); channel.enableVibration(false); channel.setBlockableSystem(true); + channel.setGroup(sChannelGroup.getId()); mNotificationManager.createNotificationChannel(channel); } diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index 1a685eb0bd94..66401846c034 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -19,7 +19,6 @@ package com.android.server.wm; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static com.android.server.wm.AppTransition.TRANSIT_UNSET; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; @@ -381,6 +380,7 @@ public class AppWindowContainerController // if made visible again. wtoken.removeDeadWindows(); wtoken.setVisibleBeforeClientHidden(); + mService.mUnknownAppVisibilityController.appRemovedOrHidden(wtoken); } else { if (!mService.mAppTransition.isTransitionSet() && mService.mAppTransition.isReady()) { diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 37ebfd3241bf..525e0ff1e8dd 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -52,7 +52,6 @@ import static com.android.server.wm.WindowManagerService.logWithStack; import android.annotation.NonNull; import android.app.Activity; -import android.app.ActivityManager; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Binder; @@ -526,7 +525,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction); mService.mOpeningApps.remove(this); - mService.mUnknownAppVisibilityController.appRemoved(this); + mService.mUnknownAppVisibilityController.appRemovedOrHidden(this); mService.mTaskSnapshotController.onAppRemoved(this); waitingToShow = false; if (mService.mClosingApps.contains(this)) { diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java index 8f4f09e7ae90..eb751fa9749f 100644 --- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java +++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java @@ -84,9 +84,9 @@ class UnknownAppVisibilityController { return builder.toString(); } - void appRemoved(@NonNull AppWindowToken appWindow) { + void appRemovedOrHidden(@NonNull AppWindowToken appWindow) { if (DEBUG_UNKNOWN_APP_VISIBILITY) { - Slog.d(TAG, "App removed appWindow=" + appWindow); + Slog.d(TAG, "App removed or hidden appWindow=" + appWindow); } mUnknownApps.remove(appWindow); } diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java index c080f344c186..4da9c060fc4d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java +++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java @@ -52,7 +52,7 @@ public class WindowManagerDebugConfig { static final boolean DEBUG_CONFIGURATION = false; static final boolean DEBUG_APP_TRANSITIONS = false; static final boolean DEBUG_STARTING_WINDOW_VERBOSE = false; - static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || true; + static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || false; static final boolean DEBUG_WALLPAPER = false; static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER; static final boolean DEBUG_DRAG = false; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d36952ae0e70..02fdfeeb365d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3824,20 +3824,22 @@ public class WindowManagerService extends IWindowManager.Stub long origId = Binder.clearCallingIdentity(); try { - final boolean rotationChanged; // TODO(multi-display): Update rotation for different displays separately. - final DisplayContent displayContent = getDefaultDisplayContentLocked(); + final boolean rotationChanged; + final int displayId; synchronized (mWindowMap) { + final DisplayContent displayContent = getDefaultDisplayContentLocked(); rotationChanged = displayContent.updateRotationUnchecked( false /* inTransaction */); if (!rotationChanged || forceRelayout) { - getDefaultDisplayContentLocked().setLayoutNeeded(); + displayContent.setLayoutNeeded(); mWindowPlacerLocked.performSurfacePlacement(); } + displayId = displayContent.getDisplayId(); } if (rotationChanged || alwaysSendConfiguration) { - sendNewConfiguration(displayContent.getDisplayId()); + sendNewConfiguration(displayId); } } finally { Binder.restoreCallingIdentity(origId); @@ -6898,9 +6900,11 @@ public class WindowManagerService extends IWindowManager.Stub "registerDockedStackListener()")) { return; } - // TODO(multi-display): The listener is registered on the default display only. - getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener( - listener); + synchronized (mWindowMap) { + // TODO(multi-display): The listener is registered on the default display only. + getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener( + listener); + } } @Override diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index cb1b2e6abc58..4442bb87ec33 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -41,6 +41,7 @@ import android.content.res.Configuration; import android.graphics.GraphicBuffer; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.os.Binder; import android.os.Debug; import android.os.Trace; import android.util.ArraySet; @@ -693,7 +694,8 @@ class WindowSurfacePlacer { SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession, "thumbnail anim", dirty.width(), dirty.height(), PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN, - appToken.windowType, window.mOwnerUid); + appToken.windowType, + window != null ? window.mOwnerUid : Binder.getCallingUid()); surfaceControl.setLayerStack(display.getLayerStack()); if (SHOW_TRANSACTIONS) { Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE"); diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java index 39caa3ce147c..ec0887489fba 100644 --- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -61,6 +61,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -102,6 +103,7 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { private static final long[] FALLBACK_VIBRATION_PATTERN = new long[] {100, 100, 100}; private static final VibrationEffect FALLBACK_VIBRATION = VibrationEffect.createWaveform(FALLBACK_VIBRATION_PATTERN, -1); + private static final int MAX_VIBRATION_DELAY = 1000; @Before public void setUp() { @@ -309,6 +311,11 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { (AudioAttributes) anyObject()); } + private void verifyDelayedVibrateLooped() { + verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), + argThat(mVibrateLoopMatcher), (AudioAttributes) anyObject()); + } + private void verifyStopVibrate() { verify(mVibrator, times(1)).cancel(); } @@ -506,8 +513,8 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { VibrationEffect effect = VibrationEffect.createWaveform(r.getVibration(), -1); - verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(effect), - (AudioAttributes) anyObject()); + verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), + eq(effect), (AudioAttributes) anyObject()); } @Test @@ -521,8 +528,8 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { mService.buzzBeepBlinkLocked(r); - verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(FALLBACK_VIBRATION), - (AudioAttributes) anyObject()); + verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), + eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject()); verify(mRingtonePlayer, never()).playAsync (anyObject(), anyObject(), anyBoolean(), anyObject()); } @@ -539,7 +546,7 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { mService.buzzBeepBlinkLocked(r); - verifyVibrateLooped(); + verifyDelayedVibrateLooped(); } @Test diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java index 9afb2d2b210c..ea8ba1b56392 100644 --- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -91,6 +91,8 @@ public class NotificationManagerServiceTest extends NotificationTestCase { private TestableLooper mTestableLooper; @Mock private RankingHelper mRankingHelper; + @Mock + private NotificationUsageStats mUsageStats; private NotificationChannel mTestNotificationChannel = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT); @Mock @@ -147,7 +149,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase { when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener); mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager, mPackageManagerClient, mockLightsManager, mNotificationListeners, mCompanionMgr, - mSnoozeHelper); + mSnoozeHelper, mUsageStats); // Tests call directly into the Binder. mBinderService = mNotificationManagerService.getBinderService(); @@ -261,40 +263,37 @@ public class NotificationManagerServiceTest extends NotificationTestCase { @Test public void testBlockedNotifications_suspended() throws Exception { - NotificationUsageStats usageStats = mock(NotificationUsageStats.class); when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true); NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH); NotificationRecord r = generateNotificationRecord(channel); - assertTrue(mNotificationManagerService.isBlocked(r, usageStats)); - verify(usageStats, times(1)).registerSuspendedByAdmin(eq(r)); + assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats)); + verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r)); } @Test public void testBlockedNotifications_blockedChannel() throws Exception { - NotificationUsageStats usageStats = mock(NotificationUsageStats.class); when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH); channel.setImportance(NotificationManager.IMPORTANCE_NONE); NotificationRecord r = generateNotificationRecord(channel); - assertTrue(mNotificationManagerService.isBlocked(r, usageStats)); - verify(usageStats, times(1)).registerBlocked(eq(r)); + assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats)); + verify(mUsageStats, times(1)).registerBlocked(eq(r)); } @Test public void testBlockedNotifications_blockedApp() throws Exception { - NotificationUsageStats usageStats = mock(NotificationUsageStats.class); when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH); NotificationRecord r = generateNotificationRecord(channel); r.setUserImportance(NotificationManager.IMPORTANCE_NONE); - assertTrue(mNotificationManagerService.isBlocked(r, usageStats)); - verify(usageStats, times(1)).registerBlocked(eq(r)); + assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats)); + verify(mUsageStats, times(1)).registerBlocked(eq(r)); } @Test diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java index 5a4bb27f765f..4a22a299865c 100644 --- a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java @@ -82,7 +82,7 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase { public void testAppRemoved() throws Exception { final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(mDisplayContent); sWm.mUnknownAppVisibilityController.notifyLaunched(token); - sWm.mUnknownAppVisibilityController.appRemoved(token); + sWm.mUnknownAppVisibilityController.appRemovedOrHidden(token); assertTrue(sWm.mUnknownAppVisibilityController.allResolved()); } } diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index bc5e4d51e0f8..fa7b9b0b96f0 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -1449,6 +1449,11 @@ public class PhoneNumberUtils * @hide */ public static boolean isInternationalNumber(String phoneNumber, String defaultCountryIso) { + // If no phone number is provided, it can't be international. + if (TextUtils.isEmpty(phoneNumber)) { + return false; + } + // If it starts with # or * its not international. if (phoneNumber.startsWith("#") || phoneNumber.startsWith("*")) { return false; diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index 3172c6ec856a..50d7f043dfda 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -16,6 +16,12 @@ package com.android.server.connectivity; +import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; +import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; +import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; +import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; +import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; +import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyBoolean; @@ -201,12 +207,22 @@ public class TetheringTest { private void sendWifiApStateChanged(int state) { final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); - intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, state); + intent.putExtra(EXTRA_WIFI_AP_STATE, state); mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } - private void verifyInterfaceServingModeStarted() throws Exception { - verify(mNMService, times(1)).listInterfaces(); + private void sendWifiApStateChanged(int state, String ifname, int ipmode) { + final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); + intent.putExtra(EXTRA_WIFI_AP_STATE, state); + intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname); + intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode); + mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); + } + + private void verifyInterfaceServingModeStarted(boolean ifnameKnown) throws Exception { + if (!ifnameKnown) { + verify(mNMService, times(1)).listInterfaces(); + } verify(mNMService, times(1)).getInterfaceConfig(mTestIfname); verify(mNMService, times(1)) .setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class)); @@ -222,18 +238,21 @@ public class TetheringTest { mIntents.remove(bcast); } - @Test - public void workingLocalOnlyHotspot() throws Exception { + public void workingLocalOnlyHotspot(boolean enrichedApBroadcast) throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); // Emulate externally-visible WifiManager effects, causing the // per-interface state machine to start up, and telling us that // hotspot mode is to be started. mTethering.interfaceStatusChanged(mTestIfname, true); - sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED); + if (enrichedApBroadcast) { + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY); + } else { + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); + } mLooper.dispatchAll(); - verifyInterfaceServingModeStarted(); + verifyInterfaceServingModeStarted(enrichedApBroadcast); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); @@ -274,7 +293,16 @@ public class TetheringTest { } @Test - public void workingWifiTethering() throws Exception { + public void workingLocalOnlyHotspotLegacyApBroadcast() throws Exception { + workingLocalOnlyHotspot(false); + } + + @Test + public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception { + workingLocalOnlyHotspot(true); + } + + public void workingWifiTethering(boolean enrichedApBroadcast) throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); @@ -290,10 +318,14 @@ public class TetheringTest { // per-interface state machine to start up, and telling us that // tethering mode is to be started. mTethering.interfaceStatusChanged(mTestIfname, true); - sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED); + if (enrichedApBroadcast) { + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED); + } else { + sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); + } mLooper.dispatchAll(); - verifyInterfaceServingModeStarted(); + verifyInterfaceServingModeStarted(enrichedApBroadcast); verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER); verify(mNMService, times(1)).setIpForwardingEnabled(true); verify(mNMService, times(1)).startTethering(any(String[].class)); @@ -355,6 +387,16 @@ public class TetheringTest { } @Test + public void workingWifiTetheringLegacyApBroadcast() throws Exception { + workingWifiTethering(false); + } + + @Test + public void workingWifiTetheringEnrichedApBroadcast() throws Exception { + workingWifiTethering(true); + } + + @Test public void failureEnablingIpForwarding() throws Exception { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true); diff --git a/tests/testables/src/android/testing/ViewUtils.java b/tests/testables/src/android/testing/ViewUtils.java index 5a651aacc74f..fca44aed0447 100644 --- a/tests/testables/src/android/testing/ViewUtils.java +++ b/tests/testables/src/android/testing/ViewUtils.java @@ -31,12 +31,10 @@ public class ViewUtils { LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, LayoutParams.TYPE_APPLICATION_OVERLAY, 0, PixelFormat.TRANSLUCENT); - InstrumentationRegistry.getContext() - .getSystemService(WindowManager.class).addView(view, lp); + view.getContext().getSystemService(WindowManager.class).addView(view, lp); } public static void detachView(View view) { - InstrumentationRegistry.getContext() - .getSystemService(WindowManager.class).removeViewImmediate(view); + view.getContext().getSystemService(WindowManager.class).removeViewImmediate(view); } } diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index bf189492b082..b2f1f62647e6 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -160,7 +160,7 @@ cc_library_host_shared { cc_test_host { name: "aapt2_tests", srcs: ["**/*_test.cpp"], - static_libs: ["libaapt2"], + static_libs: ["libaapt2", "libgmock"], defaults: ["aapt_defaults"], } diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 57ae2700127c..32e0fd52acfa 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -415,6 +415,10 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, if (resource_type == "item") { can_be_bag = false; + // The default format for <item> is any. If a format attribute is present, that one will + // override the default. + resource_format = android::ResTable_map::TYPE_ANY; + // Items have their type encoded in the type attribute. if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) { resource_type = maybe_type.value().to_string(); @@ -481,8 +485,8 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, out_resource->name.type = item_iter->second.type; out_resource->name.entry = maybe_name.value().to_string(); - // Only use the implicit format for this type if it wasn't overridden. - if (!resource_format) { + // Only use the implied format of the type when there is no explicit format. + if (resource_format == 0u) { resource_format = item_iter->second.format; } diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index e3abde6bef29..e60ef66a21db 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -25,7 +25,9 @@ #include "test/Test.h" #include "xml/XmlPullParser.h" -using android::StringPiece; +using ::android::StringPiece; +using ::testing::Eq; +using ::testing::NotNull; namespace aapt { @@ -791,15 +793,25 @@ TEST_F(ResourceParserTest, AddResourcesElementShouldAddEntryWithUndefinedSymbol) } TEST_F(ResourceParserTest, ParseItemElementWithFormat) { - std::string input = - R"EOF(<item name="foo" type="integer" format="float">0.3</item>)EOF"; + std::string input = R"(<item name="foo" type="integer" format="float">0.3</item>)"; ASSERT_TRUE(TestParse(input)); - BinaryPrimitive* val = - test::GetValue<BinaryPrimitive>(&table_, "integer/foo"); - ASSERT_NE(nullptr, val); + BinaryPrimitive* val = test::GetValue<BinaryPrimitive>(&table_, "integer/foo"); + ASSERT_THAT(val, NotNull()); + EXPECT_THAT(val->value.dataType, Eq(android::Res_value::TYPE_FLOAT)); + + input = R"(<item name="bar" type="integer" format="fraction">100</item>)"; + ASSERT_FALSE(TestParse(input)); +} + +// An <item> without a format specifier accepts all types of values. +TEST_F(ResourceParserTest, ParseItemElementWithoutFormat) { + std::string input = R"(<item name="foo" type="integer">100%p</item>)"; + ASSERT_TRUE(TestParse(input)); - EXPECT_EQ(uint32_t(android::Res_value::TYPE_FLOAT), val->value.dataType); + BinaryPrimitive* val = test::GetValue<BinaryPrimitive>(&table_, "integer/foo"); + ASSERT_THAT(val, NotNull()); + EXPECT_THAT(val->value.dataType, Eq(android::Res_value::TYPE_FRACTION)); } TEST_F(ResourceParserTest, ParseConfigVaryingItem) { diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp index 1bb7d9beee45..818c8cec30f9 100644 --- a/tools/aapt2/ResourceUtils.cpp +++ b/tools/aapt2/ResourceUtils.cpp @@ -496,19 +496,17 @@ Maybe<int> ParseSdkVersion(const StringPiece& str) { std::unique_ptr<BinaryPrimitive> TryParseBool(const StringPiece& str) { if (Maybe<bool> maybe_result = ParseBool(str)) { - android::Res_value value = {}; - value.dataType = android::Res_value::TYPE_INT_BOOLEAN; - - if (maybe_result.value()) { - value.data = 0xffffffffu; - } else { - value.data = 0; - } - return util::make_unique<BinaryPrimitive>(value); + const uint32_t data = maybe_result.value() ? 0xffffffffu : 0u; + return util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_BOOLEAN, data); } return {}; } +std::unique_ptr<BinaryPrimitive> MakeBool(bool val) { + return util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_BOOLEAN, + val ? 0xffffffffu : 0u); +} + std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str) { std::u16string str16 = util::Utf8ToUtf16(str); android::Res_value value; diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h index 48922b72fefa..da0fc8ee314a 100644 --- a/tools/aapt2/ResourceUtils.h +++ b/tools/aapt2/ResourceUtils.h @@ -147,6 +147,9 @@ std::unique_ptr<BinaryPrimitive> TryParseColor(const android::StringPiece& str); */ std::unique_ptr<BinaryPrimitive> TryParseBool(const android::StringPiece& str); +// Returns a boolean BinaryPrimitive. +std::unique_ptr<BinaryPrimitive> MakeBool(bool val); + /* * Returns a BinaryPrimitve object representing an integer if the string was * parsed as one. diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp index 34bd2b4361ca..abfdec48df67 100644 --- a/tools/aapt2/ResourceValues.cpp +++ b/tools/aapt2/ResourceValues.cpp @@ -29,6 +29,11 @@ namespace aapt { +std::ostream& operator<<(std::ostream& out, const Value& value) { + value.Print(&out); + return out; +} + template <typename Derived> void BaseValue<Derived>::Accept(RawValueVisitor* visitor) { visitor->Visit(static_cast<Derived*>(this)); @@ -346,6 +351,15 @@ Attribute::Attribute(bool w, uint32_t t) weak_ = w; } +std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) { + if (s.symbol.name) { + out << s.symbol.name.value().entry; + } else { + out << "???"; + } + return out << "=" << s.value; +} + template <typename T> constexpr T* add_pointer(T& val) { return &val; @@ -361,31 +375,27 @@ bool Attribute::Equals(const Value* value) const { return false; } - if (type_mask != other->type_mask || min_int != other->min_int || - max_int != other->max_int) { + if (type_mask != other->type_mask || min_int != other->min_int || max_int != other->max_int) { return false; } std::vector<const Symbol*> sorted_a; std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a), add_pointer<const Symbol>); - std::sort(sorted_a.begin(), sorted_a.end(), - [](const Symbol* a, const Symbol* b) -> bool { - return a->symbol.name < b->symbol.name; - }); + std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool { + return a->symbol.name < b->symbol.name; + }); std::vector<const Symbol*> sorted_b; - std::transform(other->symbols.begin(), other->symbols.end(), - std::back_inserter(sorted_b), add_pointer<const Symbol>); - std::sort(sorted_b.begin(), sorted_b.end(), - [](const Symbol* a, const Symbol* b) -> bool { - return a->symbol.name < b->symbol.name; - }); + std::transform(other->symbols.begin(), other->symbols.end(), std::back_inserter(sorted_b), + add_pointer<const Symbol>); + std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool { + return a->symbol.name < b->symbol.name; + }); return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(), [](const Symbol* a, const Symbol* b) -> bool { - return a->symbol.Equals(&b->symbol) && - a->value == b->value; + return a->symbol.Equals(&b->symbol) && a->value == b->value; }); } @@ -588,14 +598,50 @@ bool Attribute::Matches(const Item* item, DiagMessage* out_msg) const { return true; } +std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) { + if (entry.key.name) { + out << entry.key.name.value(); + } else if (entry.key.id) { + out << entry.key.id.value(); + } else { + out << "???"; + } + out << " = " << entry.value; + return out; +} + +template <typename T> +std::vector<T*> ToPointerVec(std::vector<T>& src) { + std::vector<T*> dst; + dst.reserve(src.size()); + for (T& in : src) { + dst.push_back(&in); + } + return dst; +} + +template <typename T> +std::vector<const T*> ToPointerVec(const std::vector<T>& src) { + std::vector<const T*> dst; + dst.reserve(src.size()); + for (const T& in : src) { + dst.push_back(&in); + } + return dst; +} + +static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) { + return a->key.name < b->key.name; +} + bool Style::Equals(const Value* value) const { const Style* other = ValueCast<Style>(value); if (!other) { return false; } + if (bool(parent) != bool(other->parent) || - (parent && other->parent && - !parent.value().Equals(&other->parent.value()))) { + (parent && other->parent && !parent.value().Equals(&other->parent.value()))) { return false; } @@ -603,26 +649,15 @@ bool Style::Equals(const Value* value) const { return false; } - std::vector<const Entry*> sorted_a; - std::transform(entries.begin(), entries.end(), std::back_inserter(sorted_a), - add_pointer<const Entry>); - std::sort(sorted_a.begin(), sorted_a.end(), - [](const Entry* a, const Entry* b) -> bool { - return a->key.name < b->key.name; - }); + std::vector<const Entry*> sorted_a = ToPointerVec(entries); + std::sort(sorted_a.begin(), sorted_a.end(), KeyNameComparator); - std::vector<const Entry*> sorted_b; - std::transform(other->entries.begin(), other->entries.end(), - std::back_inserter(sorted_b), add_pointer<const Entry>); - std::sort(sorted_b.begin(), sorted_b.end(), - [](const Entry* a, const Entry* b) -> bool { - return a->key.name < b->key.name; - }); + std::vector<const Entry*> sorted_b = ToPointerVec(other->entries); + std::sort(sorted_b.begin(), sorted_b.end(), KeyNameComparator); return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(), [](const Entry* a, const Entry* b) -> bool { - return a->key.Equals(&b->key) && - a->value->Equals(b->value.get()); + return a->key.Equals(&b->key) && a->value->Equals(b->value.get()); }); } @@ -633,8 +668,7 @@ Style* Style::Clone(StringPool* new_pool) const { style->comment_ = comment_; style->source_ = source_; for (auto& entry : entries) { - style->entries.push_back( - Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))}); + style->entries.push_back(Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))}); } return style; } @@ -642,26 +676,73 @@ Style* Style::Clone(StringPool* new_pool) const { void Style::Print(std::ostream* out) const { *out << "(style) "; if (parent && parent.value().name) { - if (parent.value().private_reference) { + const Reference& parent_ref = parent.value(); + if (parent_ref.private_reference) { *out << "*"; } - *out << parent.value().name.value(); + *out << parent_ref.name.value(); } *out << " [" << util::Joiner(entries, ", ") << "]"; } -static ::std::ostream& operator<<(::std::ostream& out, - const Style::Entry& value) { - if (value.key.name) { - out << value.key.name.value(); - } else if (value.key.id) { - out << value.key.id.value(); - } else { - out << "???"; +Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) { + Style::Entry cloned_entry{entry.key}; + if (entry.value != nullptr) { + cloned_entry.value.reset(entry.value->Clone(pool)); } - out << " = "; - value.value->Print(&out); - return out; + return cloned_entry; +} + +void Style::MergeWith(Style* other, StringPool* pool) { + if (other->parent) { + parent = other->parent; + } + + // We can't assume that the entries are sorted alphabetically since they're supposed to be + // sorted by Resource Id. Not all Resource Ids may be set though, so we can't sort and merge + // them keying off that. + // + // Instead, sort the entries of each Style by their name in a separate structure. Then merge + // those. + + std::vector<Entry*> this_sorted = ToPointerVec(entries); + std::sort(this_sorted.begin(), this_sorted.end(), KeyNameComparator); + + std::vector<Entry*> other_sorted = ToPointerVec(other->entries); + std::sort(other_sorted.begin(), other_sorted.end(), KeyNameComparator); + + auto this_iter = this_sorted.begin(); + const auto this_end = this_sorted.end(); + + auto other_iter = other_sorted.begin(); + const auto other_end = other_sorted.end(); + + std::vector<Entry> merged_entries; + while (this_iter != this_end) { + if (other_iter != other_end) { + if ((*this_iter)->key.name < (*other_iter)->key.name) { + merged_entries.push_back(std::move(**this_iter)); + ++this_iter; + } else { + // The other overrides. + merged_entries.push_back(CloneEntry(**other_iter, pool)); + if ((*this_iter)->key.name == (*other_iter)->key.name) { + ++this_iter; + } + ++other_iter; + } + } else { + merged_entries.push_back(std::move(**this_iter)); + ++this_iter; + } + } + + while (other_iter != other_end) { + merged_entries.push_back(CloneEntry(**other_iter, pool)); + ++other_iter; + } + + entries = std::move(merged_entries); } bool Array::Equals(const Value* value) const { @@ -758,11 +839,6 @@ void Plural::Print(std::ostream* out) const { } } -static ::std::ostream& operator<<(::std::ostream& out, - const std::unique_ptr<Item>& item) { - return out << *item; -} - bool Styleable::Equals(const Value* value) const { const Styleable* other = ValueCast<Styleable>(value); if (!other) { @@ -810,8 +886,7 @@ struct NameOnlyComparator { void Styleable::MergeWith(Styleable* other) { // Compare only names, because some References may already have their IDs - // assigned - // (framework IDs that don't change). + // assigned (framework IDs that don't change). std::set<Reference, NameOnlyComparator> references; references.insert(entries.begin(), entries.end()); references.insert(other->entries.begin(), other->entries.end()); diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h index 06f949f9555c..ac5795fb9774 100644 --- a/tools/aapt2/ResourceValues.h +++ b/tools/aapt2/ResourceValues.h @@ -40,7 +40,8 @@ struct RawValueVisitor; // type specific operations is to check the Value's type() and // cast it to the appropriate subclass. This isn't super clean, // but it is the simplest strategy. -struct Value { +class Value { + public: virtual ~Value() = default; // Whether this value is weak and can be overridden without warning or error. Default is false. @@ -82,6 +83,8 @@ struct Value { // Human readable printout of this value. virtual void Print(std::ostream* out) const = 0; + friend std::ostream& operator<<(std::ostream& out, const Value& value); + protected: Source source_; std::string comment_; @@ -245,6 +248,8 @@ struct Attribute : public BaseValue<Attribute> { struct Symbol { Reference symbol; uint32_t value; + + friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol); }; uint32_t type_mask; @@ -266,6 +271,8 @@ struct Style : public BaseValue<Style> { struct Entry { Reference key; std::unique_ptr<Item> value; + + friend std::ostream& operator<<(std::ostream& out, const Entry& entry); }; Maybe<Reference> parent; @@ -278,6 +285,10 @@ struct Style : public BaseValue<Style> { bool Equals(const Value* value) const override; Style* Clone(StringPool* new_pool) const override; void Print(std::ostream* out) const override; + + // Merges `style` into this Style. All identical attributes of `style` take precedence, including + // the parent, if there is one. + void MergeWith(Style* style, StringPool* pool); }; struct Array : public BaseValue<Array> { @@ -307,20 +318,15 @@ struct Styleable : public BaseValue<Styleable> { void MergeWith(Styleable* styleable); }; -// Stream operator for printing Value objects. -inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) { - value.Print(&out); - return out; -} - -inline ::std::ostream& operator<<(::std::ostream& out, - const Attribute::Symbol& s) { - if (s.symbol.name) { - out << s.symbol.name.value().entry; +template <typename T> +typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<( + std::ostream& out, const std::unique_ptr<T>& value) { + if (value == nullptr) { + out << "NULL"; } else { - out << "???"; + value->Print(&out); } - return out << "=" << s.value; + return out; } } // namespace aapt diff --git a/tools/aapt2/ResourceValues_test.cpp b/tools/aapt2/ResourceValues_test.cpp index 692258003471..e154d93b6f85 100644 --- a/tools/aapt2/ResourceValues_test.cpp +++ b/tools/aapt2/ResourceValues_test.cpp @@ -148,4 +148,36 @@ TEST(ResourceValuesTest, StyleClone) { EXPECT_TRUE(a->Equals(b.get())); } +TEST(ResourceValuesTest, StyleMerges) { + StringPool pool_a; + StringPool pool_b; + + std::unique_ptr<Style> a = + test::StyleBuilder() + .SetParent("android:style/Parent") + .AddItem("android:attr/a", util::make_unique<String>(pool_a.MakeRef("FooA"))) + .AddItem("android:attr/b", util::make_unique<String>(pool_a.MakeRef("FooB"))) + .Build(); + + std::unique_ptr<Style> b = + test::StyleBuilder() + .SetParent("android:style/OverlayParent") + .AddItem("android:attr/c", util::make_unique<String>(pool_b.MakeRef("OverlayFooC"))) + .AddItem("android:attr/a", util::make_unique<String>(pool_b.MakeRef("OverlayFooA"))) + .Build(); + + a->MergeWith(b.get(), &pool_a); + + StringPool pool; + std::unique_ptr<Style> expected = + test::StyleBuilder() + .SetParent("android:style/OverlayParent") + .AddItem("android:attr/a", util::make_unique<String>(pool.MakeRef("OverlayFooA"))) + .AddItem("android:attr/b", util::make_unique<String>(pool.MakeRef("FooB"))) + .AddItem("android:attr/c", util::make_unique<String>(pool.MakeRef("OverlayFooC"))) + .Build(); + + EXPECT_TRUE(a->Equals(expected.get())); +} + } // namespace aapt diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index dd4b2ba9ff16..740a401f9b57 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -440,7 +440,8 @@ static bool IsTransitionElement(const std::string& name) { } static bool IsVectorElement(const std::string& name) { - return name == "vector" || name == "animated-vector"; + return name == "vector" || name == "animated-vector" || name == "pathInterpolator" || + name == "objectAnimator"; } template <typename T> diff --git a/tools/aapt2/integration-tests/AppOne/res/values/test.xml b/tools/aapt2/integration-tests/AppOne/res/values/test.xml index 91f8bfd0dd14..5104f8212d8b 100644 --- a/tools/aapt2/integration-tests/AppOne/res/values/test.xml +++ b/tools/aapt2/integration-tests/AppOne/res/values/test.xml @@ -30,6 +30,8 @@ <flag name="weak" value="4" /> </attr> + <item name="value_that_allows_any_format" type="integer">-100%p</item> + <!-- Override the Widget styleable declared in StaticLibOne. This should merge the two when built in overlay mode. --> <declare-styleable name="Widget"> diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp index cce750acc2d6..10e837c725e5 100644 --- a/tools/aapt2/link/TableMerger.cpp +++ b/tools/aapt2/link/TableMerger.cpp @@ -179,32 +179,39 @@ static bool MergeEntry(IAaptContext* context, const Source& src, return true; } -/** - * Modified CollisionResolver which will merge Styleables. Used with overlays. - * - * Styleables are not actual resources, but they are treated as such during the - * compilation phase. Styleables don't simply overlay each other, their - * definitions merge - * and accumulate. If both values are Styleables, we just merge them into the - * existing value. - */ -static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing, - Value* incoming) { +// Modified CollisionResolver which will merge Styleables and Styles. Used with overlays. +// +// Styleables are not actual resources, but they are treated as such during the +// compilation phase. +// +// Styleables and Styles don't simply overlay each other, their definitions merge +// and accumulate. If both values are Styleables/Styles, we just merge them into the +// existing value. +static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing, Value* incoming, + StringPool* pool) { if (Styleable* existing_styleable = ValueCast<Styleable>(existing)) { if (Styleable* incoming_styleable = ValueCast<Styleable>(incoming)) { // Styleables get merged. existing_styleable->MergeWith(incoming_styleable); return ResourceTable::CollisionResult::kKeepOriginal; } + } else if (Style* existing_style = ValueCast<Style>(existing)) { + if (Style* incoming_style = ValueCast<Style>(incoming)) { + // Styles get merged. + existing_style->MergeWith(incoming_style, pool); + return ResourceTable::CollisionResult::kKeepOriginal; + } } // Delegate to the default handler. return ResourceTable::ResolveValueCollision(existing, incoming); } -static ResourceTable::CollisionResult MergeConfigValue( - IAaptContext* context, const ResourceNameRef& res_name, const bool overlay, - ResourceConfigValue* dst_config_value, - ResourceConfigValue* src_config_value) { +static ResourceTable::CollisionResult MergeConfigValue(IAaptContext* context, + const ResourceNameRef& res_name, + const bool overlay, + ResourceConfigValue* dst_config_value, + ResourceConfigValue* src_config_value, + StringPool* pool) { using CollisionResult = ResourceTable::CollisionResult; Value* dst_value = dst_config_value->value.get(); @@ -212,10 +219,9 @@ static ResourceTable::CollisionResult MergeConfigValue( CollisionResult collision_result; if (overlay) { - collision_result = ResolveMergeCollision(dst_value, src_value); + collision_result = ResolveMergeCollision(dst_value, src_value, pool); } else { - collision_result = - ResourceTable::ResolveValueCollision(dst_value, src_value); + collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value); } if (collision_result == CollisionResult::kConflict) { @@ -224,10 +230,9 @@ static ResourceTable::CollisionResult MergeConfigValue( } // Error! - context->GetDiagnostics()->Error( - DiagMessage(src_value->GetSource()) - << "resource '" << res_name << "' has a conflicting value for " - << "configuration (" << src_config_value->config << ")"); + context->GetDiagnostics()->Error(DiagMessage(src_value->GetSource()) + << "resource '" << res_name << "' has a conflicting value for " + << "configuration (" << src_config_value->config << ")"); context->GetDiagnostics()->Note(DiagMessage(dst_value->GetSource()) << "originally defined here"); return CollisionResult::kConflict; @@ -287,7 +292,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table, if (dst_config_value) { CollisionResult collision_result = MergeConfigValue(context_, res_name, overlay, dst_config_value, - src_config_value.get()); + src_config_value.get(), &master_table_->string_pool); if (collision_result == CollisionResult::kConflict) { error = true; continue; @@ -295,25 +300,22 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table, continue; } } else { - dst_config_value = dst_entry->FindOrCreateValue( - src_config_value->config, src_config_value->product); + dst_config_value = + dst_entry->FindOrCreateValue(src_config_value->config, src_config_value->product); } // Continue if we're taking the new resource. - if (FileReference* f = - ValueCast<FileReference>(src_config_value->value.get())) { + if (FileReference* f = ValueCast<FileReference>(src_config_value->value.get())) { std::unique_ptr<FileReference> new_file_ref; if (mangle_package) { new_file_ref = CloneAndMangleFile(src_package->name, *f); } else { - new_file_ref = std::unique_ptr<FileReference>( - f->Clone(&master_table_->string_pool)); + new_file_ref = std::unique_ptr<FileReference>(f->Clone(&master_table_->string_pool)); } if (callback) { - if (!callback(res_name, src_config_value->config, - new_file_ref.get(), f)) { + if (!callback(res_name, src_config_value->config, new_file_ref.get(), f)) { error = true; continue; } @@ -337,18 +339,15 @@ std::unique_ptr<FileReference> TableMerger::CloneAndMangleFile( std::string mangled_entry = NameMangler::MangleEntry(package, entry.to_string()); std::string newPath = prefix.to_string() + mangled_entry + suffix.to_string(); std::unique_ptr<FileReference> new_file_ref = - util::make_unique<FileReference>( - master_table_->string_pool.MakeRef(newPath)); + util::make_unique<FileReference>(master_table_->string_pool.MakeRef(newPath)); new_file_ref->SetComment(file_ref.GetComment()); new_file_ref->SetSource(file_ref.GetSource()); return new_file_ref; } - return std::unique_ptr<FileReference>( - file_ref.Clone(&master_table_->string_pool)); + return std::unique_ptr<FileReference>(file_ref.Clone(&master_table_->string_pool)); } -bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file, - bool overlay) { +bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file, bool overlay) { ResourceTable table; std::string path = ResourceUtils::BuildResourceFileName(file_desc); std::unique_ptr<FileReference> file_ref = diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp index 147d857e1447..45b01a494164 100644 --- a/tools/aapt2/link/TableMerger_test.cpp +++ b/tools/aapt2/link/TableMerger_test.cpp @@ -20,6 +20,14 @@ #include "io/FileSystem.h" #include "test/Test.h" +using ::aapt::test::ValueEq; +using ::testing::Contains; +using ::testing::NotNull; +using ::testing::UnorderedElementsAreArray; +using ::testing::Pointee; +using ::testing::Field; +using ::testing::Eq; + namespace aapt { struct TableMergerTest : public ::testing::Test { @@ -62,26 +70,20 @@ TEST_F(TableMergerTest, SimpleMerge) { io::FileCollection collection; ASSERT_TRUE(merger.Merge({}, table_a.get())); - ASSERT_TRUE( - merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection)); + ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection)); EXPECT_TRUE(merger.merged_packages().count("com.app.b") != 0); // Entries from com.app.a should not be mangled. - AAPT_EXPECT_TRUE( - final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo"))); - AAPT_EXPECT_TRUE( - final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar"))); - AAPT_EXPECT_TRUE(final_table.FindResource( - test::ParseNameOrDie("com.app.a:styleable/view"))); + EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo"))); + EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar"))); + EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:styleable/view"))); // The unmangled name should not be present. - AAPT_EXPECT_FALSE( - final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo"))); + EXPECT_FALSE(final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo"))); // Look for the mangled name. - AAPT_EXPECT_TRUE(final_table.FindResource( - test::ParseNameOrDie("com.app.a:id/com.app.b$foo"))); + EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/com.app.b$foo"))); } TEST_F(TableMergerTest, MergeFile) { @@ -100,7 +102,7 @@ TEST_F(TableMergerTest, MergeFile) { FileReference* file = test::GetValueForConfig<FileReference>( &final_table, "com.app.a:layout/main", test::ParseConfigOrDie("hdpi-v4")); - ASSERT_NE(nullptr, file); + ASSERT_THAT(file, NotNull()); EXPECT_EQ(std::string("res/layout-hdpi-v4/main.xml"), *file->path); } @@ -137,17 +139,14 @@ TEST_F(TableMergerTest, MergeFileReferences) { collection.InsertFile("res/xml/file.xml"); ASSERT_TRUE(merger.Merge({}, table_a.get())); - ASSERT_TRUE( - merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection)); + ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection)); - FileReference* f = - test::GetValue<FileReference>(&final_table, "com.app.a:xml/file"); - ASSERT_NE(f, nullptr); + FileReference* f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/file"); + ASSERT_THAT(f, NotNull()); EXPECT_EQ(std::string("res/xml/file.xml"), *f->path); - f = test::GetValue<FileReference>(&final_table, - "com.app.a:xml/com.app.b$file"); - ASSERT_NE(f, nullptr); + f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/com.app.b$file"); + ASSERT_THAT(f, NotNull()); EXPECT_EQ(std::string("res/xml/com.app.b$file.xml"), *f->path); } @@ -171,10 +170,9 @@ TEST_F(TableMergerTest, OverrideResourceWithOverlay) { ASSERT_TRUE(merger.Merge({}, base.get())); ASSERT_TRUE(merger.MergeOverlay({}, overlay.get())); - BinaryPrimitive* foo = - test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo"); - ASSERT_NE(nullptr, foo); - EXPECT_EQ(0x0u, foo->value.data); + BinaryPrimitive* foo = test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo"); + ASSERT_THAT(foo, + Pointee(Field(&BinaryPrimitive::value, Field(&android::Res_value::data, Eq(0u))))); } TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) { @@ -301,7 +299,7 @@ TEST_F(TableMergerTest, FailToMergeNewResourceWithoutAutoAddOverlay) { ASSERT_FALSE(merger.MergeOverlay({}, table_b.get())); } -TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) { +TEST_F(TableMergerTest, OverlaidStyleablesAndStylesShouldBeMerged) { std::unique_ptr<ResourceTable> table_a = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) @@ -310,15 +308,27 @@ TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) { .AddItem("com.app.a:attr/bar") .AddItem("com.app.a:attr/foo", ResourceId(0x01010000)) .Build()) + .AddValue("com.app.a:style/Theme", + test::StyleBuilder() + .SetParent("com.app.a:style/Parent") + .AddItem("com.app.a:attr/bar", util::make_unique<Id>()) + .AddItem("com.app.a:attr/foo", ResourceUtils::MakeBool(false)) + .Build()) .Build(); std::unique_ptr<ResourceTable> table_b = test::ResourceTableBuilder() .SetPackageId("com.app.a", 0x7f) - .AddValue("com.app.a:styleable/Foo", - test::StyleableBuilder() - .AddItem("com.app.a:attr/bat") - .AddItem("com.app.a:attr/foo") + .AddValue("com.app.a:styleable/Foo", test::StyleableBuilder() + .AddItem("com.app.a:attr/bat") + .AddItem("com.app.a:attr/foo") + .Build()) + .AddValue("com.app.a:style/Theme", + test::StyleBuilder() + .SetParent("com.app.a:style/OverlayParent") + .AddItem("com.app.a:attr/bat", util::make_unique<Id>()) + .AddItem("com.app.a:attr/foo", ResourceId(0x01010000), + ResourceUtils::MakeBool(true)) .Build()) .Build(); @@ -330,18 +340,29 @@ TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) { ASSERT_TRUE(merger.Merge({}, table_a.get())); ASSERT_TRUE(merger.MergeOverlay({}, table_b.get())); - Styleable* styleable = - test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo"); - ASSERT_NE(nullptr, styleable); + Styleable* styleable = test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo"); + ASSERT_THAT(styleable, NotNull()); std::vector<Reference> expected_refs = { Reference(test::ParseNameOrDie("com.app.a:attr/bar")), Reference(test::ParseNameOrDie("com.app.a:attr/bat")), - Reference(test::ParseNameOrDie("com.app.a:attr/foo"), - ResourceId(0x01010000)), + Reference(test::ParseNameOrDie("com.app.a:attr/foo"), ResourceId(0x01010000)), }; + EXPECT_THAT(styleable->entries, UnorderedElementsAreArray(expected_refs)); + + Style* style = test::GetValue<Style>(&final_table, "com.app.a:style/Theme"); + ASSERT_THAT(style, NotNull()); + + std::vector<Reference> extracted_refs; + for (const auto& entry : style->entries) { + extracted_refs.push_back(entry.key); + } + EXPECT_THAT(extracted_refs, UnorderedElementsAreArray(expected_refs)); - EXPECT_EQ(expected_refs, styleable->entries); + const auto expected = ResourceUtils::MakeBool(true); + EXPECT_THAT(style->entries, Contains(Field(&Style::Entry::value, Pointee(ValueEq(*expected))))); + EXPECT_THAT(style->parent, + Eq(make_value(Reference(test::ParseNameOrDie("com.app.a:style/OverlayParent"))))); } } // namespace aapt diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h index 248921f3afea..a937de8869a6 100644 --- a/tools/aapt2/test/Common.h +++ b/tools/aapt2/test/Common.h @@ -22,12 +22,14 @@ #include "android-base/logging.h" #include "android-base/macros.h" #include "androidfw/StringPiece.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "ConfigDescription.h" #include "Debug.h" #include "ResourceTable.h" #include "ResourceUtils.h" +#include "ResourceValues.h" #include "ValueVisitor.h" #include "io/File.h" #include "process/IResourceTableConsumer.h" @@ -51,13 +53,11 @@ struct DummyDiagnosticsImpl : public IDiagnostics { return; case Level::Warn: - std::cerr << actual_msg.source << ": warn: " << actual_msg.message - << "." << std::endl; + std::cerr << actual_msg.source << ": warn: " << actual_msg.message << "." << std::endl; break; case Level::Error: - std::cerr << actual_msg.source << ": error: " << actual_msg.message - << "." << std::endl; + std::cerr << actual_msg.source << ": error: " << actual_msg.message << "." << std::endl; break; } } @@ -84,11 +84,9 @@ template <typename T> T* GetValueForConfigAndProduct(ResourceTable* table, const android::StringPiece& res_name, const ConfigDescription& config, const android::StringPiece& product) { - Maybe<ResourceTable::SearchResult> result = - table->FindResource(ParseNameOrDie(res_name)); + Maybe<ResourceTable::SearchResult> result = table->FindResource(ParseNameOrDie(res_name)); if (result) { - ResourceConfigValue* config_value = - result.value().entry->FindValue(config, product); + ResourceConfigValue* config_value = result.value().entry->FindValue(config, product); if (config_value) { return ValueCast<T>(config_value->value.get()); } @@ -111,9 +109,13 @@ class TestFile : public io::IFile { public: explicit TestFile(const android::StringPiece& path) : source_(path) {} - std::unique_ptr<io::IData> OpenAsData() override { return {}; } + std::unique_ptr<io::IData> OpenAsData() override { + return {}; + } - const Source& GetSource() const override { return source_; } + const Source& GetSource() const override { + return source_; + } private: DISALLOW_COPY_AND_ASSIGN(TestFile); @@ -122,6 +124,47 @@ class TestFile : public io::IFile { }; } // namespace test + +// Workaround gtest bug (https://github.com/google/googletest/issues/443) +// that does not select base class operator<< for derived class T. +template <typename T> +typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<( + std::ostream& out, const T& value) { + value.Print(&out); + return out; +} + +template std::ostream& operator<<<Item>(std::ostream&, const Item&); +template std::ostream& operator<<<Reference>(std::ostream&, const Reference&); +template std::ostream& operator<<<Id>(std::ostream&, const Id&); +template std::ostream& operator<<<RawString>(std::ostream&, const RawString&); +template std::ostream& operator<<<String>(std::ostream&, const String&); +template std::ostream& operator<<<StyledString>(std::ostream&, const StyledString&); +template std::ostream& operator<<<FileReference>(std::ostream&, const FileReference&); +template std::ostream& operator<<<BinaryPrimitive>(std::ostream&, const BinaryPrimitive&); +template std::ostream& operator<<<Attribute>(std::ostream&, const Attribute&); +template std::ostream& operator<<<Style>(std::ostream&, const Style&); +template std::ostream& operator<<<Array>(std::ostream&, const Array&); +template std::ostream& operator<<<Plural>(std::ostream&, const Plural&); + +// Add a print method to Maybe. +template <typename T> +void PrintTo(const Maybe<T>& value, std::ostream* out) { + if (value) { + *out << ::testing::PrintToString(value.value()); + } else { + *out << "Nothing"; + } +} + +namespace test { + +MATCHER_P(ValueEq, a, + std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) { + return arg.Equals(&a); +} + +} // namespace test } // namespace aapt #endif /* AAPT_TEST_COMMON_H */ diff --git a/tools/aapt2/test/Test.h b/tools/aapt2/test/Test.h index ec07432fa51e..a24c01cd4137 100644 --- a/tools/aapt2/test/Test.h +++ b/tools/aapt2/test/Test.h @@ -17,6 +17,7 @@ #ifndef AAPT_TEST_TEST_H #define AAPT_TEST_TEST_H +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "test/Builders.h" diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 164b7b059183..58df4ee227f2 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1080,11 +1080,9 @@ public class WifiManager { * Name). In the case when there is an existing configuration with the same * FQDN, the new configuration will replace the existing configuration. * - * An {@link IllegalArgumentException} will be thrown on failure. - * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled - * on the device. - * * @param config The Passpoint configuration to be added + * @throws IllegalArgumentException if configuration is invalid + * @throws UnsupportedOperationException if Passpoint is not enabled on the device. */ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { try { @@ -1099,11 +1097,9 @@ public class WifiManager { /** * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name). * - * An {@link IllegalArgumentException} will be thrown on failure. - * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled - * on the device. - * * @param fqdn The FQDN of the Passpoint configuration to be removed + * @throws IllegalArgumentException if no configuration is associated with the given FQDN. + * @throws UnsupportedOperationException if Passpoint is not enabled on the device. */ public void removePasspointConfiguration(String fqdn) { try { @@ -1120,10 +1116,8 @@ public class WifiManager { * * An empty list will be returned when no configurations are installed. * - * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled - * on the device. - * * @return A list of {@link PasspointConfiguration} + * @throws UnsupportedOperationException if Passpoint is not enabled on the device. */ public List<PasspointConfiguration> getPasspointConfigurations() { try { @@ -1139,12 +1133,10 @@ public class WifiManager { * {@link #EXTRA_ICON} will indicate the result of the request. * A missing intent extra {@link #EXTRA_ICON} will indicate a failure. * - * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled - * on the device. - * * @param bssid The BSSID of the AP * @param fileName Name of the icon file (remote file) to query from the AP * + * @throws UnsupportedOperationException if Passpoint is not enabled on the device. * @hide */ public void queryPasspointIcon(long bssid, String fileName) { diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index f892bb0a3884..71d4173a389c 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -62,16 +62,36 @@ public final class PasspointConfiguration implements Parcelable { * Configurations under HomeSp subtree. */ private HomeSp mHomeSp = null; + /** + * Set the Home SP (Service Provider) information. + * + * @param homeSp The Home SP information to set to + */ public void setHomeSp(HomeSp homeSp) { mHomeSp = homeSp; } + /** + * Get the Home SP (Service Provider) information. + * + * @return Home SP information + */ public HomeSp getHomeSp() { return mHomeSp; } /** * Configurations under Credential subtree. */ private Credential mCredential = null; + /** + * Set the credential information. + * + * @param credential The credential information to set to + */ public void setCredential(Credential credential) { mCredential = credential; } + /** + * Get the credential information. + * + * @return credential information + */ public Credential getCredential() { return mCredential; } diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index d712feb7c6d2..e8fcbfd6731e 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -97,9 +97,19 @@ public final class Credential implements Parcelable { * comparing the realm specified in that hotspot's ANQP element. */ private String mRealm = null; + /** + * Set the realm associated with this credential. + * + * @param realm The realm to set to + */ public void setRealm(String realm) { mRealm = realm; } + /** + * Get the realm associated with this credential. + * + * @return the realm associated with this credential + */ public String getRealm() { return mRealm; } @@ -162,9 +172,19 @@ public final class Credential implements Parcelable { * Username of the credential. */ private String mUsername = null; + /** + * Set the username associated with this user credential. + * + * @param username The username to set to + */ public void setUsername(String username) { mUsername = username; } + /** + * Get the username associated with this user credential. + * + * @return the username associated with this user credential + */ public String getUsername() { return mUsername; } @@ -173,9 +193,19 @@ public final class Credential implements Parcelable { * Base64-encoded password. */ private String mPassword = null; + /** + * Set the Base64-encoded password associated with this user credential. + * + * @param password The password to set to + */ public void setPassword(String password) { mPassword = password; } + /** + * Get the Base64-encoded password associated with this user credential. + * + * @return the Base64-encoded password associated with this user credential + */ public String getPassword() { return mPassword; } @@ -233,14 +263,30 @@ public final class Credential implements Parcelable { /** * EAP (Extensible Authentication Protocol) method type. - * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4 - * for valid values. + * Refer to + * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4"> + * EAP Numbers</a> for valid values. * Using Integer.MIN_VALUE to indicate unset value. */ private int mEapType = Integer.MIN_VALUE; + /** + * Set the EAP (Extensible Authentication Protocol) method type associated with this + * user credential. + * Refer to + * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4"> + * EAP Numbers</a> for valid values. + * + * @param eapType The EAP method type associated with this user credential + */ public void setEapType(int eapType) { mEapType = eapType; } + /** + * Get the EAP (Extensible Authentication Protocol) method type associated with this + * user credential. + * + * @return EAP method type + */ public int getEapType() { return mEapType; } @@ -249,9 +295,19 @@ public final class Credential implements Parcelable { * Non-EAP inner authentication method. */ private String mNonEapInnerMethod = null; + /** + * Set the inner non-EAP method associated with this user credential. + * + * @param nonEapInnerMethod The non-EAP inner method to set to + */ public void setNonEapInnerMethod(String nonEapInnerMethod) { mNonEapInnerMethod = nonEapInnerMethod; } + /** + * Get the inner non-EAP method associated with this user credential. + * + * @return Non-EAP inner method associated with this user credential + */ public String getNonEapInnerMethod() { return mNonEapInnerMethod; } @@ -394,9 +450,19 @@ public final class Credential implements Parcelable { }; } private UserCredential mUserCredential = null; + /** + * Set the user credential information. + * + * @param userCredential The user credential to set to + */ public void setUserCredential(UserCredential userCredential) { mUserCredential = userCredential; } + /** + * Get the user credential information. + * + * @return user credential information + */ public UserCredential getUserCredential() { return mUserCredential; } @@ -421,9 +487,19 @@ public final class Credential implements Parcelable { * Certificate type. */ private String mCertType = null; + /** + * Set the certificate type associated with this certificate credential. + * + * @param certType The certificate type to set to + */ public void setCertType(String certType) { mCertType = certType; } + /** + * Get the certificate type associated with this certificate credential. + * + * @return certificate type + */ public String getCertType() { return mCertType; } @@ -432,9 +508,19 @@ public final class Credential implements Parcelable { * The SHA-256 fingerprint of the certificate. */ private byte[] mCertSha256Fingerprint = null; + /** + * Set the certificate SHA-256 fingerprint associated with this certificate credential. + * + * @param certSha256Fingerprint The certificate fingerprint to set to + */ public void setCertSha256Fingerprint(byte[] certSha256Fingerprint) { mCertSha256Fingerprint = certSha256Fingerprint; } + /** + * Get the certificate SHA-256 fingerprint associated with this certificate credential. + * + * @return certificate SHA-256 fingerprint + */ public byte[] getCertSha256Fingerprint() { return mCertSha256Fingerprint; } @@ -530,9 +616,19 @@ public final class Credential implements Parcelable { }; } private CertificateCredential mCertCredential = null; + /** + * Set the certificate credential information. + * + * @param certCredential The certificate credential to set to + */ public void setCertCredential(CertificateCredential certCredential) { mCertCredential = certCredential; } + /** + * Get the certificate credential information. + * + * @return certificate credential information + */ public CertificateCredential getCertCredential() { return mCertCredential; } @@ -553,9 +649,21 @@ public final class Credential implements Parcelable { * cellular networks */ private String mImsi = null; + /** + * Set the IMSI (International Mobile Subscriber Identity) associated with this SIM + * credential. + * + * @param imsi The IMSI to set to + */ public void setImsi(String imsi) { mImsi = imsi; } + /** + * Get the IMSI (International Mobile Subscriber Identity) associated with this SIM + * credential. + * + * @return IMSI associated with this SIM credential + */ public String getImsi() { return mImsi; } @@ -567,9 +675,21 @@ public final class Credential implements Parcelable { * Using Integer.MIN_VALUE to indicate unset value. */ private int mEapType = Integer.MIN_VALUE; + /** + * Set the EAP (Extensible Authentication Protocol) method type associated with this + * SIM credential. + * + * @param eapType The EAP method type to set to + */ public void setEapType(int eapType) { mEapType = eapType; } + /** + * Get the EAP (Extensible Authentication Protocol) method type associated with this + * SIM credential. + * + * @return EAP method type associated with this SIM credential + */ public int getEapType() { return mEapType; } @@ -704,9 +824,19 @@ public final class Credential implements Parcelable { } } private SimCredential mSimCredential = null; + /** + * Set the SIM credential information. + * + * @param simCredential The SIM credential to set to + */ public void setSimCredential(SimCredential simCredential) { mSimCredential = simCredential; } + /** + * Get the SIM credential information. + * + * @return SIM credential information + */ public SimCredential getSimCredential() { return mSimCredential; } @@ -715,9 +845,19 @@ public final class Credential implements Parcelable { * CA (Certificate Authority) X509 certificate. */ private X509Certificate mCaCertificate = null; + /** + * Set the CA (Certification Authority) certificate associated with this credential. + * + * @param caCertificate The CA certificate to set to + */ public void setCaCertificate(X509Certificate caCertificate) { mCaCertificate = caCertificate; } + /** + * Get the CA (Certification Authority) certificate associated with this credential. + * + * @return CA certificate associated with this credential + */ public X509Certificate getCaCertificate() { return mCaCertificate; } @@ -726,9 +866,19 @@ public final class Credential implements Parcelable { * Client side X509 certificate chain. */ private X509Certificate[] mClientCertificateChain = null; + /** + * Set the client certificate chain associated with this credential. + * + * @param certificateChain The client certificate chain to set to + */ public void setClientCertificateChain(X509Certificate[] certificateChain) { mClientCertificateChain = certificateChain; } + /** + * Get the client certificate chain associated with this credential. + * + * @return client certificate chain associated with this credential + */ public X509Certificate[] getClientCertificateChain() { return mClientCertificateChain; } @@ -737,9 +887,19 @@ public final class Credential implements Parcelable { * Client side private key. */ private PrivateKey mClientPrivateKey = null; + /** + * Set the client private key associated with this credential. + * + * @param clientPrivateKey the client private key to set to + */ public void setClientPrivateKey(PrivateKey clientPrivateKey) { mClientPrivateKey = clientPrivateKey; } + /** + * Get the client private key associated with this credential. + * + * @return client private key associated with this credential. + */ public PrivateKey getClientPrivateKey() { return mClientPrivateKey; } diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java index 2247860d23a5..d829ea81ed56 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java @@ -52,9 +52,19 @@ public final class HomeSp implements Parcelable { * FQDN (Fully Qualified Domain Name) of this home service provider. */ private String mFqdn = null; + /** + * Set the FQDN (Fully Qualified Domain Name) associated with this home service provider. + * + * @param fqdn The FQDN to set to + */ public void setFqdn(String fqdn) { mFqdn = fqdn; } + /** + * Get the FQDN (Fully Qualified Domain Name) associated with this home service provider. + * + * @return the FQDN associated with this home service provider + */ public String getFqdn() { return mFqdn; } @@ -63,9 +73,19 @@ public final class HomeSp implements Parcelable { * Friendly name of this home service provider. */ private String mFriendlyName = null; + /** + * Set the friendly name associated with this home service provider. + * + * @param friendlyName The friendly name to set to + */ public void setFriendlyName(String friendlyName) { mFriendlyName = friendlyName; } + /** + * Get the friendly name associated with this home service provider. + * + * @return the friendly name associated with this home service provider + */ public String getFriendlyName() { return mFriendlyName; } @@ -184,9 +204,21 @@ public final class HomeSp implements Parcelable { * which this provider is a member. */ private long[] mRoamingConsortiumOis = null; + /** + * Set the Organization Identifiers (OIs) identifying a roaming consortium of which this + * provider is a member. + * + * @param roamingConsortiumOis Array of roaming consortium OIs + */ public void setRoamingConsortiumOis(long[] roamingConsortiumOis) { mRoamingConsortiumOis = roamingConsortiumOis; } + /** + * Get the Organization Identifiers (OIs) identifying a roaming consortium of which this + * provider is a member. + * + * @return array of roaming consortium OIs + */ public long[] getRoamingConsortiumOis() { return mRoamingConsortiumOis; } |