diff options
132 files changed, 2905 insertions, 931 deletions
diff --git a/api/current.txt b/api/current.txt index b2966729ffaa..1eb37b3a45c4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -241,10 +241,10 @@ package android { field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb - field public static final int activityHeight = 16844019; // 0x10104f3 + field public static final int activityHeight = 16844021; // 0x10104f5 field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8 field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9 - field public static final int activityWidth = 16844018; // 0x10104f2 + field public static final int activityWidth = 16844020; // 0x10104f4 field public static final int addPrintersActivity = 16843750; // 0x10103e6 field public static final int addStatesFromChildren = 16842992; // 0x10100f0 field public static final int adjustViewBounds = 16843038; // 0x101011e @@ -786,6 +786,7 @@ package android { field public static final int listChoiceIndicatorSingle = 16843289; // 0x1010219 field public static final int listDivider = 16843284; // 0x1010214 field public static final int listDividerAlertDialog = 16843525; // 0x1010305 + field public static final int listMenuViewStyle = 16844018; // 0x10104f2 field public static final int listPopupWindowStyle = 16843519; // 0x10102ff field public static final int listPreferredItemHeight = 16842829; // 0x101004d field public static final int listPreferredItemHeightLarge = 16843654; // 0x1010386 @@ -1148,6 +1149,7 @@ package android { field public static final int strokeLineJoin = 16843788; // 0x101040c field public static final int strokeMiterLimit = 16843789; // 0x101040d field public static final int strokeWidth = 16843783; // 0x1010407 + field public static final int subMenuArrow = 16844019; // 0x10104f3 field public static final int submitBackground = 16843912; // 0x1010488 field public static final int subtitle = 16843473; // 0x10102d1 field public static final int subtitleTextAppearance = 16843823; // 0x101042f @@ -11588,6 +11590,7 @@ package android.graphics { method public void getTextBounds(java.lang.String, int, int, android.graphics.Rect); method public void getTextBounds(char[], int, int, android.graphics.Rect); method public java.util.Locale getTextLocale(); + method public android.util.LocaleList getTextLocales(); method public void getTextPath(char[], int, int, float, float, android.graphics.Path); method public void getTextPath(java.lang.String, int, int, float, float, android.graphics.Path); method public float getTextScaleX(); @@ -11643,6 +11646,7 @@ package android.graphics { method public void setSubpixelText(boolean); method public void setTextAlign(android.graphics.Paint.Align); method public void setTextLocale(java.util.Locale); + method public void setTextLocales(android.util.LocaleList); method public void setTextScaleX(float); method public void setTextSize(float); method public void setTextSkewX(float); @@ -34207,6 +34211,7 @@ package android.util { ctor public LocaleList(java.util.Locale[]); method public static android.util.LocaleList forLanguageTags(java.lang.String); method public java.util.Locale get(int); + method public static android.util.LocaleList getDefault(); method public static android.util.LocaleList getEmptyLocaleList(); method public java.util.Locale getPrimary(); method public boolean isEmpty(); @@ -41719,6 +41724,7 @@ package android.widget { method public java.lang.CharSequence getText(); method public final android.content.res.ColorStateList getTextColors(); method public java.util.Locale getTextLocale(); + method public android.util.LocaleList getTextLocales(); method public float getTextScaleX(); method public float getTextSize(); method public int getTotalPaddingBottom(); @@ -41831,6 +41837,7 @@ package android.widget { method public final void setTextKeepState(java.lang.CharSequence); method public final void setTextKeepState(java.lang.CharSequence, android.widget.TextView.BufferType); method public void setTextLocale(java.util.Locale); + method public void setTextLocales(android.util.LocaleList); method public void setTextScaleX(float); method public void setTextSize(float); method public void setTextSize(int, float); diff --git a/api/system-current.txt b/api/system-current.txt index 7cc66cf1ab3f..f913e6c99b2c 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -333,10 +333,10 @@ package android { field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb - field public static final int activityHeight = 16844019; // 0x10104f3 + field public static final int activityHeight = 16844021; // 0x10104f5 field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8 field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9 - field public static final int activityWidth = 16844018; // 0x10104f2 + field public static final int activityWidth = 16844020; // 0x10104f4 field public static final int addPrintersActivity = 16843750; // 0x10103e6 field public static final int addStatesFromChildren = 16842992; // 0x10100f0 field public static final int adjustViewBounds = 16843038; // 0x101011e @@ -878,6 +878,7 @@ package android { field public static final int listChoiceIndicatorSingle = 16843289; // 0x1010219 field public static final int listDivider = 16843284; // 0x1010214 field public static final int listDividerAlertDialog = 16843525; // 0x1010305 + field public static final int listMenuViewStyle = 16844018; // 0x10104f2 field public static final int listPopupWindowStyle = 16843519; // 0x10102ff field public static final int listPreferredItemHeight = 16842829; // 0x101004d field public static final int listPreferredItemHeightLarge = 16843654; // 0x1010386 @@ -1244,6 +1245,7 @@ package android { field public static final int strokeLineJoin = 16843788; // 0x101040c field public static final int strokeMiterLimit = 16843789; // 0x101040d field public static final int strokeWidth = 16843783; // 0x1010407 + field public static final int subMenuArrow = 16844019; // 0x10104f3 field public static final int submitBackground = 16843912; // 0x1010488 field public static final int subtitle = 16843473; // 0x10102d1 field public static final int subtitleTextAppearance = 16843823; // 0x101042f @@ -11925,6 +11927,7 @@ package android.graphics { method public void getTextBounds(java.lang.String, int, int, android.graphics.Rect); method public void getTextBounds(char[], int, int, android.graphics.Rect); method public java.util.Locale getTextLocale(); + method public android.util.LocaleList getTextLocales(); method public void getTextPath(char[], int, int, float, float, android.graphics.Path); method public void getTextPath(java.lang.String, int, int, float, float, android.graphics.Path); method public float getTextScaleX(); @@ -11980,6 +11983,7 @@ package android.graphics { method public void setSubpixelText(boolean); method public void setTextAlign(android.graphics.Paint.Align); method public void setTextLocale(java.util.Locale); + method public void setTextLocales(android.util.LocaleList); method public void setTextScaleX(float); method public void setTextSize(float); method public void setTextSkewX(float); @@ -36501,6 +36505,7 @@ package android.util { ctor public LocaleList(java.util.Locale[]); method public static android.util.LocaleList forLanguageTags(java.lang.String); method public java.util.Locale get(int); + method public static android.util.LocaleList getDefault(); method public static android.util.LocaleList getEmptyLocaleList(); method public java.util.Locale getPrimary(); method public boolean isEmpty(); @@ -44327,6 +44332,7 @@ package android.widget { method public java.lang.CharSequence getText(); method public final android.content.res.ColorStateList getTextColors(); method public java.util.Locale getTextLocale(); + method public android.util.LocaleList getTextLocales(); method public float getTextScaleX(); method public float getTextSize(); method public int getTotalPaddingBottom(); @@ -44439,6 +44445,7 @@ package android.widget { method public final void setTextKeepState(java.lang.CharSequence); method public final void setTextKeepState(java.lang.CharSequence, android.widget.TextView.BufferType); method public void setTextLocale(java.util.Locale); + method public void setTextLocales(android.util.LocaleList); method public void setTextScaleX(float); method public void setTextSize(float); method public void setTextSize(int, float); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 412e3cde902c..e15ba742b8b6 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4718,7 +4718,13 @@ public final class ActivityThread { mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); - ApplicationInfo instrApp = new ApplicationInfo(); + // The app context's info was created against this thread, but + // the class loader may have already been loaded and cached with + // outdated paths. Clear it so we can load it again using the + // instrumentation paths. + data.info.clearClassLoader(); + + final ApplicationInfo instrApp = new ApplicationInfo(); instrApp.packageName = ii.packageName; instrApp.sourceDir = ii.sourceDir; instrApp.publicSourceDir = ii.publicSourceDir; @@ -4731,6 +4737,7 @@ public final class ActivityThread { ContextImpl instrContext = ContextImpl.createAppContext(this, pi); try { + java.lang.ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index c2bf28a931c8..3b1c60b1501f 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -255,6 +255,13 @@ public final class LoadedApk { return ai.sharedLibraryFiles; } + /** @hide */ + public void clearClassLoader() { + synchronized (this) { + mClassLoader = null; + } + } + public ClassLoader getClassLoader() { synchronized (this) { if (mClassLoader != null) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index e3414d916337..7ffac0a6dc39 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -213,7 +213,8 @@ public class DevicePolicyManager { * @see DeviceAdminReceiver * @deprecated Use {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}. This extra is still - * supported. + * supported, but only if there is only one device admin receiver in the package that requires + * the permission {@link android.Manifest.permission#BIND_DEVICE_ADMIN}. */ @Deprecated public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java index 4da88ee9da9c..7529c5294541 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -77,6 +77,8 @@ public final class Trace { public static final long TRACE_TAG_POWER = 1L << 17; /** @hide */ public static final long TRACE_TAG_PACKAGE_MANAGER = 1L << 18; + /** @hide */ + public static final long TRACE_TAG_SYSTEM_SERVER = 1L << 19; private static final long TRACE_TAG_NOT_READY = 1L << 63; private static final int MAX_SECTION_NAME_LEN = 127; diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java index afae9aceda17..379651ef86f8 100644 --- a/core/java/android/util/LocaleList.java +++ b/core/java/android/util/LocaleList.java @@ -16,7 +16,11 @@ package android.util; +import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.Size; + +import com.android.internal.annotations.GuardedBy; import java.util.HashSet; import java.util.Locale; @@ -164,4 +168,22 @@ public final class LocaleList { return new LocaleList(localeArray); } } + + private final static Object sLock = new Object(); + + @GuardedBy("sLock") + private static LocaleList sDefaultLocaleList; + + // TODO: fix this to return the default system locale list once we have that + @NonNull @Size(min=1) + public static LocaleList getDefault() { + Locale defaultLocale = Locale.getDefault(); + synchronized (sLock) { + if (sDefaultLocaleList == null || sDefaultLocaleList.size() != 1 + || !defaultLocale.equals(sDefaultLocaleList.getPrimary())) { + sDefaultLocaleList = new LocaleList(defaultLocale); + } + } + return sDefaultLocaleList; + } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 665069c6a1ae..5976f0987931 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6687,14 +6687,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Gets the {@link View} description. It briefly describes the view and is - * primarily used for accessibility support. Set this property to enable - * better accessibility support for your application. This is especially - * true for views that do not have textual representation (For example, - * ImageButton). - * - * @return The content description. + * Returns the {@link View}'s content description. + * <p> + * <strong>Note:</strong> Do not override this method, as it will have no + * effect on the content description presented to accessibility services. + * You must call {@link #setContentDescription(CharSequence)} to modify the + * content description. * + * @return the content description + * @see #setContentDescription(CharSequence) * @attr ref android.R.styleable#View_contentDescription */ @ViewDebug.ExportedProperty(category = "accessibility") @@ -6703,14 +6704,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Sets the {@link View} description. It briefly describes the view and is - * primarily used for accessibility support. Set this property to enable - * better accessibility support for your application. This is especially - * true for views that do not have textual representation (For example, - * ImageButton). + * Sets the {@link View}'s content description. + * <p> + * A content description briefly describes the view and is primarily used + * for accessibility support to determine how a view should be presented to + * the user. In the case of a view with no textual representation, such as + * {@link ImageButton}, a useful content description explains what the view + * does. For example, an image button with a phone icon that is used to + * place a call may use "Call" as its content description. An image of a + * floppy disk that is used to save a file may use "Save". * * @param contentDescription The content description. - * + * @see #getContentDescription() * @attr ref android.R.styleable#View_contentDescription */ @RemotableViewMethod diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java index a5696eefa1db..64c41039bea5 100644 --- a/core/java/android/widget/ActionMenuPresenter.java +++ b/core/java/android/widget/ActionMenuPresenter.java @@ -37,7 +37,6 @@ import android.view.View.MeasureSpec; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityNodeInfo; -import android.widget.ListPopupWindow.ForwardingListener; import com.android.internal.view.ActionBarPolicy; import com.android.internal.view.menu.ActionMenuItemView; import com.android.internal.view.menu.BaseMenuPresenter; @@ -45,6 +44,7 @@ import com.android.internal.view.menu.MenuBuilder; import com.android.internal.view.menu.MenuItemImpl; import com.android.internal.view.menu.MenuPopupHelper; import com.android.internal.view.menu.MenuView; +import com.android.internal.view.menu.ShowableListMenu; import com.android.internal.view.menu.SubMenuBuilder; import java.util.ArrayList; @@ -828,7 +828,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter setOnTouchListener(new ForwardingListener(this) { @Override - public ListPopupWindow getPopup() { + public ShowableListMenu getPopup() { if (mOverflowPopup == null) { return null; } @@ -1003,7 +1003,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback { @Override - public ListPopupWindow getPopup() { + public ShowableListMenu getPopup() { return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null; } } diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java index f34ad71ea76a..f5c46db94f4f 100644 --- a/core/java/android/widget/ActivityChooserView.java +++ b/core/java/android/widget/ActivityChooserView.java @@ -17,6 +17,7 @@ package android.widget; import com.android.internal.R; +import com.android.internal.view.menu.ShowableListMenu; import android.annotation.StringRes; import android.content.Context; @@ -37,7 +38,6 @@ import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ActivityChooserModel.ActivityChooserModelClient; -import android.widget.ListPopupWindow.ForwardingListener; /** * This class is a view for choosing an activity for handling a given {@link Intent}. @@ -263,7 +263,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod }); expandButton.setOnTouchListener(new ForwardingListener(expandButton) { @Override - public ListPopupWindow getPopup() { + public ShowableListMenu getPopup() { return getListPopupWindow(); } diff --git a/core/java/android/widget/DropDownListView.java b/core/java/android/widget/DropDownListView.java new file mode 100644 index 000000000000..553651308e9c --- /dev/null +++ b/core/java/android/widget/DropDownListView.java @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.widget; + + +import com.android.internal.widget.AutoScrollHelper.AbsListViewAutoScroller; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.IntProperty; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.accessibility.AccessibilityManager; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.widget.TextView; +import android.widget.ListView; + + +/** + * Wrapper class for a ListView. This wrapper can hijack the focus to + * make sure the list uses the appropriate drawables and states when + * displayed on screen within a drop down. The focus is never actually + * passed to the drop down in this mode; the list only looks focused. + * + * @hide + */ +public class DropDownListView extends ListView { + /** Duration in milliseconds of the drag-to-open click animation. */ + private static final long CLICK_ANIM_DURATION = 150; + + /** Target alpha value for drag-to-open click animation. */ + private static final int CLICK_ANIM_ALPHA = 0x80; + + /** Wrapper around Drawable's <code>alpha</code> property. */ + private static final IntProperty<Drawable> DRAWABLE_ALPHA = + new IntProperty<Drawable>("alpha") { + @Override + public void setValue(Drawable object, int value) { + object.setAlpha(value); + } + + @Override + public Integer get(Drawable object) { + return object.getAlpha(); + } + }; + + /* + * WARNING: This is a workaround for a touch mode issue. + * + * Touch mode is propagated lazily to windows. This causes problems in + * the following scenario: + * - Type something in the AutoCompleteTextView and get some results + * - Move down with the d-pad to select an item in the list + * - Move up with the d-pad until the selection disappears + * - Type more text in the AutoCompleteTextView *using the soft keyboard* + * and get new results; you are now in touch mode + * - The selection comes back on the first item in the list, even though + * the list is supposed to be in touch mode + * + * Using the soft keyboard triggers the touch mode change but that change + * is propagated to our window only after the first list layout, therefore + * after the list attempts to resurrect the selection. + * + * The trick to work around this issue is to pretend the list is in touch + * mode when we know that the selection should not appear, that is when + * we know the user moved the selection away from the list. + * + * This boolean is set to true whenever we explicitly hide the list's + * selection and reset to false whenever we know the user moved the + * selection back to the list. + * + * When this boolean is true, isInTouchMode() returns true, otherwise it + * returns super.isInTouchMode(). + */ + private boolean mListSelectionHidden; + + /** + * True if this wrapper should fake focus. + */ + private boolean mHijackFocus; + + /** Whether to force drawing of the pressed state selector. */ + private boolean mDrawsInPressedState; + + /** Current drag-to-open click animation, if any. */ + private Animator mClickAnimation; + + /** Helper for drag-to-open auto scrolling. */ + private AbsListViewAutoScroller mScrollHelper; + + /** + * Creates a new list view wrapper. + * + * @param context this view's context + */ + public DropDownListView(Context context, boolean hijackFocus) { + this(context, hijackFocus, com.android.internal.R.attr.dropDownListViewStyle); + } + + /** + * Creates a new list view wrapper. + * + * @param context this view's context + */ + public DropDownListView(Context context, boolean hijackFocus, int defStyleAttr) { + super(context, null, defStyleAttr); + mHijackFocus = hijackFocus; + // TODO: Add an API to control this + setCacheColorHint(0); // Transparent, since the background drawable could be anything. + } + + /** + * Handles forwarded events. + * + * @param activePointerId id of the pointer that activated forwarding + * @return whether the event was handled + */ + public boolean onForwardedEvent(MotionEvent event, int activePointerId) { + boolean handledEvent = true; + boolean clearPressedItem = false; + + final int actionMasked = event.getActionMasked(); + switch (actionMasked) { + case MotionEvent.ACTION_CANCEL: + handledEvent = false; + break; + case MotionEvent.ACTION_UP: + handledEvent = false; + // $FALL-THROUGH$ + case MotionEvent.ACTION_MOVE: + final int activeIndex = event.findPointerIndex(activePointerId); + if (activeIndex < 0) { + handledEvent = false; + break; + } + + final int x = (int) event.getX(activeIndex); + final int y = (int) event.getY(activeIndex); + final int position = pointToPosition(x, y); + if (position == INVALID_POSITION) { + clearPressedItem = true; + break; + } + + final View child = getChildAt(position - getFirstVisiblePosition()); + setPressedItem(child, position, x, y); + handledEvent = true; + + if (actionMasked == MotionEvent.ACTION_UP) { + clickPressedItem(child, position); + } + break; + } + + // Failure to handle the event cancels forwarding. + if (!handledEvent || clearPressedItem) { + clearPressedItem(); + } + + // Manage automatic scrolling. + if (handledEvent) { + if (mScrollHelper == null) { + mScrollHelper = new AbsListViewAutoScroller(this); + } + mScrollHelper.setEnabled(true); + mScrollHelper.onTouch(this, event); + } else if (mScrollHelper != null) { + mScrollHelper.setEnabled(false); + } + + return handledEvent; + } + + /** + * Sets whether the list selection is hidden, as part of a workaround for a touch mode issue + * (see the declaration for mListSelectionHidden). + * @param listSelectionHidden + */ + public void setListSelectionHidden(boolean listSelectionHidden) { + this.mListSelectionHidden = listSelectionHidden; + } + + /** + * Starts an alpha animation on the selector. When the animation ends, + * the list performs a click on the item. + */ + private void clickPressedItem(final View child, final int position) { + final long id = getItemIdAtPosition(position); + final Animator anim = ObjectAnimator.ofInt( + mSelector, DRAWABLE_ALPHA, 0xFF, CLICK_ANIM_ALPHA, 0xFF); + anim.setDuration(CLICK_ANIM_DURATION); + anim.setInterpolator(new AccelerateDecelerateInterpolator()); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + performItemClick(child, position, id); + } + }); + anim.start(); + + if (mClickAnimation != null) { + mClickAnimation.cancel(); + } + mClickAnimation = anim; + } + + private void clearPressedItem() { + mDrawsInPressedState = false; + setPressed(false); + updateSelectorState(); + + final View motionView = getChildAt(mMotionPosition - mFirstPosition); + if (motionView != null) { + motionView.setPressed(false); + } + + if (mClickAnimation != null) { + mClickAnimation.cancel(); + mClickAnimation = null; + } + } + + private void setPressedItem(View child, int position, float x, float y) { + mDrawsInPressedState = true; + + // Ordering is essential. First, update the container's pressed state. + drawableHotspotChanged(x, y); + if (!isPressed()) { + setPressed(true); + } + + // Next, run layout if we need to stabilize child positions. + if (mDataChanged) { + layoutChildren(); + } + + // Manage the pressed view based on motion position. This allows us to + // play nicely with actual touch and scroll events. + final View motionView = getChildAt(mMotionPosition - mFirstPosition); + if (motionView != null && motionView != child && motionView.isPressed()) { + motionView.setPressed(false); + } + mMotionPosition = position; + + // Offset for child coordinates. + final float childX = x - child.getLeft(); + final float childY = y - child.getTop(); + child.drawableHotspotChanged(childX, childY); + if (!child.isPressed()) { + child.setPressed(true); + } + + // Ensure that keyboard focus starts from the last touched position. + setSelectedPositionInt(position); + positionSelectorLikeTouch(position, child, x, y); + + // Refresh the drawable state to reflect the new pressed state, + // which will also update the selector state. + refreshDrawableState(); + + if (mClickAnimation != null) { + mClickAnimation.cancel(); + mClickAnimation = null; + } + } + + @Override + boolean touchModeDrawsInPressedState() { + return mDrawsInPressedState || super.touchModeDrawsInPressedState(); + } + + /** + * Avoids jarring scrolling effect by ensuring that list elements + * made of a text view fit on a single line. + * + * @param position the item index in the list to get a view for + * @return the view for the specified item + */ + @Override + View obtainView(int position, boolean[] isScrap) { + View view = super.obtainView(position, isScrap); + + if (view instanceof TextView) { + ((TextView) view).setHorizontallyScrolling(true); + } + + return view; + } + + @Override + public boolean isInTouchMode() { + // WARNING: Please read the comment where mListSelectionHidden is declared + return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); + } + + /** + * Returns the focus state in the drop down. + * + * @return true always if hijacking focus + */ + @Override + public boolean hasWindowFocus() { + return mHijackFocus || super.hasWindowFocus(); + } + + /** + * Returns the focus state in the drop down. + * + * @return true always if hijacking focus + */ + @Override + public boolean isFocused() { + return mHijackFocus || super.isFocused(); + } + + /** + * Returns the focus state in the drop down. + * + * @return true always if hijacking focus + */ + @Override + public boolean hasFocus() { + return mHijackFocus || super.hasFocus(); + } +}
\ No newline at end of file diff --git a/core/java/android/widget/ForwardingListener.java b/core/java/android/widget/ForwardingListener.java new file mode 100644 index 000000000000..fd7140f779fe --- /dev/null +++ b/core/java/android/widget/ForwardingListener.java @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.widget; + +import android.os.SystemClock; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewParent; + +import com.android.internal.view.menu.ShowableListMenu; + +/** + * Abstract class that forwards touch events to a {@link ListPopupWindow}. + * + * @hide + */ +public abstract class ForwardingListener + implements View.OnTouchListener, View.OnAttachStateChangeListener { + + /** Scaled touch slop, used for detecting movement outside bounds. */ + private final float mScaledTouchSlop; + + /** Timeout before disallowing intercept on the source's parent. */ + private final int mTapTimeout; + + /** Timeout before accepting a long-press to start forwarding. */ + private final int mLongPressTimeout; + + /** Source view from which events are forwarded. */ + private final View mSrc; + + /** Runnable used to prevent conflicts with scrolling parents. */ + private Runnable mDisallowIntercept; + + /** Runnable used to trigger forwarding on long-press. */ + private Runnable mTriggerLongPress; + + /** Whether this listener is currently forwarding touch events. */ + private boolean mForwarding; + + /** + * Whether forwarding was initiated by a long-press. If so, we won't + * force the window to dismiss when the touch stream ends. + */ + private boolean mWasLongPress; + + /** The id of the first pointer down in the current event stream. */ + private int mActivePointerId; + + public ForwardingListener(View src) { + mSrc = src; + mScaledTouchSlop = ViewConfiguration.get(src.getContext()).getScaledTouchSlop(); + mTapTimeout = ViewConfiguration.getTapTimeout(); + + // Use a medium-press timeout. Halfway between tap and long-press. + mLongPressTimeout = (mTapTimeout + ViewConfiguration.getLongPressTimeout()) / 2; + + src.addOnAttachStateChangeListener(this); + } + + /** + * Returns the popup to which this listener is forwarding events. + * <p> + * Override this to return the correct popup. If the popup is displayed + * asynchronously, you may also need to override + * {@link #onForwardingStopped} to prevent premature cancellation of + * forwarding. + * + * @return the popup to which this listener is forwarding events + */ + public abstract ShowableListMenu getPopup(); + + @Override + public boolean onTouch(View v, MotionEvent event) { + final boolean wasForwarding = mForwarding; + final boolean forwarding; + if (wasForwarding) { + forwarding = onTouchForwarded(event) || !onForwardingStopped(); + } else { + forwarding = onTouchObserved(event) && onForwardingStarted(); + + if (forwarding) { + // Make sure we cancel any ongoing source event stream. + final long now = SystemClock.uptimeMillis(); + final MotionEvent e = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, + 0.0f, 0.0f, 0); + mSrc.onTouchEvent(e); + e.recycle(); + } + } + + mForwarding = forwarding; + return forwarding || wasForwarding; + } + + @Override + public void onViewAttachedToWindow(View v) { + } + + @Override + public void onViewDetachedFromWindow(View v) { + mForwarding = false; + mActivePointerId = MotionEvent.INVALID_POINTER_ID; + + if (mDisallowIntercept != null) { + mSrc.removeCallbacks(mDisallowIntercept); + } + } + + /** + * Called when forwarding would like to start. + * <p> + * By default, this will show the popup returned by {@link #getPopup()}. + * It may be overridden to perform another action, like clicking the + * source view or preparing the popup before showing it. + * + * @return true to start forwarding, false otherwise + */ + protected boolean onForwardingStarted() { + final ShowableListMenu popup = getPopup(); + if (popup != null && !popup.isShowing()) { + popup.show(); + } + return true; + } + + /** + * Called when forwarding would like to stop. + * <p> + * By default, this will dismiss the popup returned by + * {@link #getPopup()}. It may be overridden to perform some other + * action. + * + * @return true to stop forwarding, false otherwise + */ + protected boolean onForwardingStopped() { + final ShowableListMenu popup = getPopup(); + if (popup != null && popup.isShowing()) { + popup.dismiss(); + } + return true; + } + + /** + * Observes motion events and determines when to start forwarding. + * + * @param srcEvent motion event in source view coordinates + * @return true to start forwarding motion events, false otherwise + */ + private boolean onTouchObserved(MotionEvent srcEvent) { + final View src = mSrc; + if (!src.isEnabled()) { + return false; + } + + final int actionMasked = srcEvent.getActionMasked(); + switch (actionMasked) { + case MotionEvent.ACTION_DOWN: + mActivePointerId = srcEvent.getPointerId(0); + mWasLongPress = false; + + if (mDisallowIntercept == null) { + mDisallowIntercept = new DisallowIntercept(); + } + src.postDelayed(mDisallowIntercept, mTapTimeout); + + if (mTriggerLongPress == null) { + mTriggerLongPress = new TriggerLongPress(); + } + src.postDelayed(mTriggerLongPress, mLongPressTimeout); + break; + case MotionEvent.ACTION_MOVE: + final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId); + if (activePointerIndex >= 0) { + final float x = srcEvent.getX(activePointerIndex); + final float y = srcEvent.getY(activePointerIndex); + + // Has the pointer moved outside of the view? + if (!src.pointInView(x, y, mScaledTouchSlop)) { + clearCallbacks(); + + // Don't let the parent intercept our events. + src.getParent().requestDisallowInterceptTouchEvent(true); + return true; + } + } + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + clearCallbacks(); + break; + } + + return false; + } + + private void clearCallbacks() { + if (mTriggerLongPress != null) { + mSrc.removeCallbacks(mTriggerLongPress); + } + + if (mDisallowIntercept != null) { + mSrc.removeCallbacks(mDisallowIntercept); + } + } + + private void onLongPress() { + clearCallbacks(); + + final View src = mSrc; + if (!src.isEnabled() || src.isLongClickable()) { + // Ignore long-press if the view is disabled or has its own + // handler. + return; + } + + if (!onForwardingStarted()) { + return; + } + + // Don't let the parent intercept our events. + src.getParent().requestDisallowInterceptTouchEvent(true); + + // Make sure we cancel any ongoing source event stream. + final long now = SystemClock.uptimeMillis(); + final MotionEvent e = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0); + src.onTouchEvent(e); + e.recycle(); + + mForwarding = true; + mWasLongPress = true; + } + + /** + * Handles forwarded motion events and determines when to stop + * forwarding. + * + * @param srcEvent motion event in source view coordinates + * @return true to continue forwarding motion events, false to cancel + */ + private boolean onTouchForwarded(MotionEvent srcEvent) { + final View src = mSrc; + final ShowableListMenu popup = getPopup(); + if (popup == null || !popup.isShowing()) { + return false; + } + + final DropDownListView dst = (DropDownListView) popup.getListView(); + if (dst == null || !dst.isShown()) { + return false; + } + + // Convert event to destination-local coordinates. + final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); + src.toGlobalMotionEvent(dstEvent); + dst.toLocalMotionEvent(dstEvent); + + // Forward converted event to destination view, then recycle it. + final boolean handled = dst.onForwardedEvent(dstEvent, mActivePointerId); + dstEvent.recycle(); + + // Always cancel forwarding when the touch stream ends. + final int action = srcEvent.getActionMasked(); + final boolean keepForwarding = action != MotionEvent.ACTION_UP + && action != MotionEvent.ACTION_CANCEL; + + return handled && keepForwarding; + } + + private class DisallowIntercept implements Runnable { + @Override + public void run() { + final ViewParent parent = mSrc.getParent(); + parent.requestDisallowInterceptTouchEvent(true); + } + } + + private class TriggerLongPress implements Runnable { + @Override + public void run() { + onLongPress(); + } + } +}
\ No newline at end of file diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index a02efcff4197..3d07d87dfe70 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -25,7 +25,6 @@ import android.database.DataSetObserver; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Handler; -import android.os.SystemClock; import android.text.TextUtils; import android.util.AttributeSet; import android.util.IntProperty; @@ -36,13 +35,13 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnTouchListener; -import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.WindowManager; import android.view.animation.AccelerateDecelerateInterpolator; import com.android.internal.R; +import com.android.internal.view.menu.ShowableListMenu; import com.android.internal.widget.AutoScrollHelper.AbsListViewAutoScroller; import java.util.Locale; @@ -58,7 +57,7 @@ import java.util.Locale; * @see android.widget.AutoCompleteTextView * @see android.widget.Spinner */ -public class ListPopupWindow { +public class ListPopupWindow implements ShowableListMenu { private static final String TAG = "ListPopupWindow"; private static final boolean DEBUG = false; @@ -580,6 +579,7 @@ public class ListPopupWindow { * Show the popup list. If the list is already showing, this method * will recalculate the popup's size and position. */ + @Override public void show() { int height = buildDropDown(); @@ -671,6 +671,7 @@ public class ListPopupWindow { /** * Dismiss the popup window. */ + @Override public void dismiss() { mPopup.dismiss(); removePromptView(); @@ -732,7 +733,7 @@ public class ListPopupWindow { public void setSelection(int position) { DropDownListView list = mDropDownList; if (isShowing() && list != null) { - list.mListSelectionHidden = false; + list.setListSelectionHidden(false); list.setSelection(position); if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) { list.setItemChecked(position, true); @@ -748,7 +749,7 @@ public class ListPopupWindow { final DropDownListView list = mDropDownList; if (list != null) { // WARNING: Please read the comment where mListSelectionHidden is declared - list.mListSelectionHidden = true; + list.setListSelectionHidden(true); list.hideSelector(); list.requestLayout(); } @@ -757,6 +758,7 @@ public class ListPopupWindow { /** * @return {@code true} if the popup is currently showing, {@code false} otherwise. */ + @Override public boolean isShowing() { return mPopup.isShowing(); } @@ -842,6 +844,7 @@ public class ListPopupWindow { * @return The {@link ListView} displayed within the popup window. * Only valid when {@link #isShowing()} == {@code true}. */ + @Override public ListView getListView() { return mDropDownList; } @@ -911,7 +914,7 @@ public class ListPopupWindow { } else { // WARNING: Please read the comment where mListSelectionHidden // is declared - mDropDownList.mListSelectionHidden = false; + mDropDownList.setListSelectionHidden(false); } consumed = mDropDownList.onKeyDown(keyCode, event); @@ -1037,7 +1040,7 @@ public class ListPopupWindow { public OnTouchListener createDragToOpenListener(View src) { return new ForwardingListener(src) { @Override - public ListPopupWindow getPopup() { + public ShowableListMenu getPopup() { return ListPopupWindow.this; } }; @@ -1088,7 +1091,7 @@ public class ListPopupWindow { DropDownListView dropDownList = mDropDownList; if (dropDownList != null) { - dropDownList.mListSelectionHidden = false; + dropDownList.setListSelectionHidden(false); } } } @@ -1219,568 +1222,6 @@ public class ListPopupWindow { return listContent + otherHeights; } - /** - * Abstract class that forwards touch events to a {@link ListPopupWindow}. - * - * @hide - */ - public static abstract class ForwardingListener - implements View.OnTouchListener, View.OnAttachStateChangeListener { - /** Scaled touch slop, used for detecting movement outside bounds. */ - private final float mScaledTouchSlop; - - /** Timeout before disallowing intercept on the source's parent. */ - private final int mTapTimeout; - - /** Timeout before accepting a long-press to start forwarding. */ - private final int mLongPressTimeout; - - /** Source view from which events are forwarded. */ - private final View mSrc; - - /** Runnable used to prevent conflicts with scrolling parents. */ - private Runnable mDisallowIntercept; - - /** Runnable used to trigger forwarding on long-press. */ - private Runnable mTriggerLongPress; - - /** Whether this listener is currently forwarding touch events. */ - private boolean mForwarding; - - /** - * Whether forwarding was initiated by a long-press. If so, we won't - * force the window to dismiss when the touch stream ends. - */ - private boolean mWasLongPress; - - /** The id of the first pointer down in the current event stream. */ - private int mActivePointerId; - - public ForwardingListener(View src) { - mSrc = src; - mScaledTouchSlop = ViewConfiguration.get(src.getContext()).getScaledTouchSlop(); - mTapTimeout = ViewConfiguration.getTapTimeout(); - - // Use a medium-press timeout. Halfway between tap and long-press. - mLongPressTimeout = (mTapTimeout + ViewConfiguration.getLongPressTimeout()) / 2; - - src.addOnAttachStateChangeListener(this); - } - - /** - * Returns the popup to which this listener is forwarding events. - * <p> - * Override this to return the correct popup. If the popup is displayed - * asynchronously, you may also need to override - * {@link #onForwardingStopped} to prevent premature cancelation of - * forwarding. - * - * @return the popup to which this listener is forwarding events - */ - public abstract ListPopupWindow getPopup(); - - @Override - public boolean onTouch(View v, MotionEvent event) { - final boolean wasForwarding = mForwarding; - final boolean forwarding; - if (wasForwarding) { - forwarding = onTouchForwarded(event) || !onForwardingStopped(); - } else { - forwarding = onTouchObserved(event) && onForwardingStarted(); - - if (forwarding) { - // Make sure we cancel any ongoing source event stream. - final long now = SystemClock.uptimeMillis(); - final MotionEvent e = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, - 0.0f, 0.0f, 0); - mSrc.onTouchEvent(e); - e.recycle(); - } - } - - mForwarding = forwarding; - return forwarding || wasForwarding; - } - - @Override - public void onViewAttachedToWindow(View v) { - } - - @Override - public void onViewDetachedFromWindow(View v) { - mForwarding = false; - mActivePointerId = MotionEvent.INVALID_POINTER_ID; - - if (mDisallowIntercept != null) { - mSrc.removeCallbacks(mDisallowIntercept); - } - } - - /** - * Called when forwarding would like to start. - * <p> - * By default, this will show the popup returned by {@link #getPopup()}. - * It may be overridden to perform another action, like clicking the - * source view or preparing the popup before showing it. - * - * @return true to start forwarding, false otherwise - */ - protected boolean onForwardingStarted() { - final ListPopupWindow popup = getPopup(); - if (popup != null && !popup.isShowing()) { - popup.show(); - } - return true; - } - - /** - * Called when forwarding would like to stop. - * <p> - * By default, this will dismiss the popup returned by - * {@link #getPopup()}. It may be overridden to perform some other - * action. - * - * @return true to stop forwarding, false otherwise - */ - protected boolean onForwardingStopped() { - final ListPopupWindow popup = getPopup(); - if (popup != null && popup.isShowing()) { - popup.dismiss(); - } - return true; - } - - /** - * Observes motion events and determines when to start forwarding. - * - * @param srcEvent motion event in source view coordinates - * @return true to start forwarding motion events, false otherwise - */ - private boolean onTouchObserved(MotionEvent srcEvent) { - final View src = mSrc; - if (!src.isEnabled()) { - return false; - } - - final int actionMasked = srcEvent.getActionMasked(); - switch (actionMasked) { - case MotionEvent.ACTION_DOWN: - mActivePointerId = srcEvent.getPointerId(0); - mWasLongPress = false; - - if (mDisallowIntercept == null) { - mDisallowIntercept = new DisallowIntercept(); - } - src.postDelayed(mDisallowIntercept, mTapTimeout); - - if (mTriggerLongPress == null) { - mTriggerLongPress = new TriggerLongPress(); - } - src.postDelayed(mTriggerLongPress, mLongPressTimeout); - break; - case MotionEvent.ACTION_MOVE: - final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId); - if (activePointerIndex >= 0) { - final float x = srcEvent.getX(activePointerIndex); - final float y = srcEvent.getY(activePointerIndex); - - // Has the pointer has moved outside of the view? - if (!src.pointInView(x, y, mScaledTouchSlop)) { - clearCallbacks(); - - // Don't let the parent intercept our events. - src.getParent().requestDisallowInterceptTouchEvent(true); - return true; - } - } - break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - clearCallbacks(); - break; - } - - return false; - } - - private void clearCallbacks() { - if (mTriggerLongPress != null) { - mSrc.removeCallbacks(mTriggerLongPress); - } - - if (mDisallowIntercept != null) { - mSrc.removeCallbacks(mDisallowIntercept); - } - } - - private void onLongPress() { - clearCallbacks(); - - final View src = mSrc; - if (!src.isEnabled() || src.isLongClickable()) { - // Ignore long-press if the view is disabled or has its own - // handler. - return; - } - - if (!onForwardingStarted()) { - return; - } - - // Don't let the parent intercept our events. - src.getParent().requestDisallowInterceptTouchEvent(true); - - // Make sure we cancel any ongoing source event stream. - final long now = SystemClock.uptimeMillis(); - final MotionEvent e = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0); - src.onTouchEvent(e); - e.recycle(); - - mForwarding = true; - mWasLongPress = true; - } - - /** - * Handled forwarded motion events and determines when to stop - * forwarding. - * - * @param srcEvent motion event in source view coordinates - * @return true to continue forwarding motion events, false to cancel - */ - private boolean onTouchForwarded(MotionEvent srcEvent) { - final View src = mSrc; - final ListPopupWindow popup = getPopup(); - if (popup == null || !popup.isShowing()) { - return false; - } - - final DropDownListView dst = popup.mDropDownList; - if (dst == null || !dst.isShown()) { - return false; - } - - // Convert event to destination-local coordinates. - final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); - src.toGlobalMotionEvent(dstEvent); - dst.toLocalMotionEvent(dstEvent); - - // Forward converted event to destination view, then recycle it. - final boolean handled = dst.onForwardedEvent(dstEvent, mActivePointerId); - dstEvent.recycle(); - - // Always cancel forwarding when the touch stream ends. - final int action = srcEvent.getActionMasked(); - final boolean keepForwarding = action != MotionEvent.ACTION_UP - && action != MotionEvent.ACTION_CANCEL; - - return handled && keepForwarding; - } - - private class DisallowIntercept implements Runnable { - @Override - public void run() { - final ViewParent parent = mSrc.getParent(); - parent.requestDisallowInterceptTouchEvent(true); - } - } - - private class TriggerLongPress implements Runnable { - @Override - public void run() { - onLongPress(); - } - } - } - - /** - * <p>Wrapper class for a ListView. This wrapper can hijack the focus to - * make sure the list uses the appropriate drawables and states when - * displayed on screen within a drop down. The focus is never actually - * passed to the drop down in this mode; the list only looks focused.</p> - */ - static class DropDownListView extends ListView { - /** Duration in milliseconds of the drag-to-open click animation. */ - private static final long CLICK_ANIM_DURATION = 150; - - /** Target alpha value for drag-to-open click animation. */ - private static final int CLICK_ANIM_ALPHA = 0x80; - - /** Wrapper around Drawable's <code>alpha</code> property. */ - private static final IntProperty<Drawable> DRAWABLE_ALPHA = - new IntProperty<Drawable>("alpha") { - @Override - public void setValue(Drawable object, int value) { - object.setAlpha(value); - } - - @Override - public Integer get(Drawable object) { - return object.getAlpha(); - } - }; - - /* - * WARNING: This is a workaround for a touch mode issue. - * - * Touch mode is propagated lazily to windows. This causes problems in - * the following scenario: - * - Type something in the AutoCompleteTextView and get some results - * - Move down with the d-pad to select an item in the list - * - Move up with the d-pad until the selection disappears - * - Type more text in the AutoCompleteTextView *using the soft keyboard* - * and get new results; you are now in touch mode - * - The selection comes back on the first item in the list, even though - * the list is supposed to be in touch mode - * - * Using the soft keyboard triggers the touch mode change but that change - * is propagated to our window only after the first list layout, therefore - * after the list attempts to resurrect the selection. - * - * The trick to work around this issue is to pretend the list is in touch - * mode when we know that the selection should not appear, that is when - * we know the user moved the selection away from the list. - * - * This boolean is set to true whenever we explicitly hide the list's - * selection and reset to false whenever we know the user moved the - * selection back to the list. - * - * When this boolean is true, isInTouchMode() returns true, otherwise it - * returns super.isInTouchMode(). - */ - private boolean mListSelectionHidden; - - /** - * True if this wrapper should fake focus. - */ - private boolean mHijackFocus; - - /** Whether to force drawing of the pressed state selector. */ - private boolean mDrawsInPressedState; - - /** Current drag-to-open click animation, if any. */ - private Animator mClickAnimation; - - /** Helper for drag-to-open auto scrolling. */ - private AbsListViewAutoScroller mScrollHelper; - - /** - * <p>Creates a new list view wrapper.</p> - * - * @param context this view's context - */ - public DropDownListView(Context context, boolean hijackFocus) { - super(context, null, com.android.internal.R.attr.dropDownListViewStyle); - mHijackFocus = hijackFocus; - // TODO: Add an API to control this - setCacheColorHint(0); // Transparent, since the background drawable could be anything. - } - - /** - * Handles forwarded events. - * - * @param activePointerId id of the pointer that activated forwarding - * @return whether the event was handled - */ - public boolean onForwardedEvent(MotionEvent event, int activePointerId) { - boolean handledEvent = true; - boolean clearPressedItem = false; - - final int actionMasked = event.getActionMasked(); - switch (actionMasked) { - case MotionEvent.ACTION_CANCEL: - handledEvent = false; - break; - case MotionEvent.ACTION_UP: - handledEvent = false; - // $FALL-THROUGH$ - case MotionEvent.ACTION_MOVE: - final int activeIndex = event.findPointerIndex(activePointerId); - if (activeIndex < 0) { - handledEvent = false; - break; - } - - final int x = (int) event.getX(activeIndex); - final int y = (int) event.getY(activeIndex); - final int position = pointToPosition(x, y); - if (position == INVALID_POSITION) { - clearPressedItem = true; - break; - } - - final View child = getChildAt(position - getFirstVisiblePosition()); - setPressedItem(child, position, x, y); - handledEvent = true; - - if (actionMasked == MotionEvent.ACTION_UP) { - clickPressedItem(child, position); - } - break; - } - - // Failure to handle the event cancels forwarding. - if (!handledEvent || clearPressedItem) { - clearPressedItem(); - } - - // Manage automatic scrolling. - if (handledEvent) { - if (mScrollHelper == null) { - mScrollHelper = new AbsListViewAutoScroller(this); - } - mScrollHelper.setEnabled(true); - mScrollHelper.onTouch(this, event); - } else if (mScrollHelper != null) { - mScrollHelper.setEnabled(false); - } - - return handledEvent; - } - - /** - * Starts an alpha animation on the selector. When the animation ends, - * the list performs a click on the item. - */ - private void clickPressedItem(final View child, final int position) { - final long id = getItemIdAtPosition(position); - final Animator anim = ObjectAnimator.ofInt( - mSelector, DRAWABLE_ALPHA, 0xFF, CLICK_ANIM_ALPHA, 0xFF); - anim.setDuration(CLICK_ANIM_DURATION); - anim.setInterpolator(new AccelerateDecelerateInterpolator()); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - performItemClick(child, position, id); - } - }); - anim.start(); - - if (mClickAnimation != null) { - mClickAnimation.cancel(); - } - mClickAnimation = anim; - } - - private void clearPressedItem() { - mDrawsInPressedState = false; - setPressed(false); - updateSelectorState(); - - final View motionView = getChildAt(mMotionPosition - mFirstPosition); - if (motionView != null) { - motionView.setPressed(false); - } - - if (mClickAnimation != null) { - mClickAnimation.cancel(); - mClickAnimation = null; - } - } - - private void setPressedItem(View child, int position, float x, float y) { - mDrawsInPressedState = true; - - // Ordering is essential. First, update the container's pressed state. - drawableHotspotChanged(x, y); - if (!isPressed()) { - setPressed(true); - } - - // Next, run layout if we need to stabilize child positions. - if (mDataChanged) { - layoutChildren(); - } - - // Manage the pressed view based on motion position. This allows us to - // play nicely with actual touch and scroll events. - final View motionView = getChildAt(mMotionPosition - mFirstPosition); - if (motionView != null && motionView != child && motionView.isPressed()) { - motionView.setPressed(false); - } - mMotionPosition = position; - - // Offset for child coordinates. - final float childX = x - child.getLeft(); - final float childY = y - child.getTop(); - child.drawableHotspotChanged(childX, childY); - if (!child.isPressed()) { - child.setPressed(true); - } - - // Ensure that keyboard focus starts from the last touched position. - setSelectedPositionInt(position); - positionSelectorLikeTouch(position, child, x, y); - - // Refresh the drawable state to reflect the new pressed state, - // which will also update the selector state. - refreshDrawableState(); - - if (mClickAnimation != null) { - mClickAnimation.cancel(); - mClickAnimation = null; - } - } - - @Override - boolean touchModeDrawsInPressedState() { - return mDrawsInPressedState || super.touchModeDrawsInPressedState(); - } - - /** - * <p>Avoids jarring scrolling effect by ensuring that list elements - * made of a text view fit on a single line.</p> - * - * @param position the item index in the list to get a view for - * @return the view for the specified item - */ - @Override - View obtainView(int position, boolean[] isScrap) { - View view = super.obtainView(position, isScrap); - - if (view instanceof TextView) { - ((TextView) view).setHorizontallyScrolling(true); - } - - return view; - } - - @Override - public boolean isInTouchMode() { - // WARNING: Please read the comment where mListSelectionHidden is declared - return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); - } - - /** - * <p>Returns the focus state in the drop down.</p> - * - * @return true always if hijacking focus - */ - @Override - public boolean hasWindowFocus() { - return mHijackFocus || super.hasWindowFocus(); - } - - /** - * <p>Returns the focus state in the drop down.</p> - * - * @return true always if hijacking focus - */ - @Override - public boolean isFocused() { - return mHijackFocus || super.isFocused(); - } - - /** - * <p>Returns the focus state in the drop down.</p> - * - * @return true always if hijacking focus - */ - @Override - public boolean hasFocus() { - return mHijackFocus || super.hasFocus(); - } - } - private class PopupDataSetObserver extends DataSetObserver { @Override public void onChanged() { diff --git a/core/java/android/widget/MenuPopupWindow.java b/core/java/android/widget/MenuPopupWindow.java index 8d42c739b627..9e47e8513d49 100644 --- a/core/java/android/widget/MenuPopupWindow.java +++ b/core/java/android/widget/MenuPopupWindow.java @@ -36,11 +36,11 @@ public class MenuPopupWindow extends ListPopupWindow { } @Override - ListPopupWindow.DropDownListView createDropDownListView(Context context, boolean hijackFocus) { + DropDownListView createDropDownListView(Context context, boolean hijackFocus) { return new MenuDropDownListView(context, hijackFocus); } - static class MenuDropDownListView extends ListPopupWindow.DropDownListView { + static class MenuDropDownListView extends DropDownListView { private boolean mHoveredOnDisabledItem = false; private AccessibilityManager mAccessibilityManager; diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java index 1507dfb29285..3b2d60d1e1a4 100644 --- a/core/java/android/widget/PopupMenu.java +++ b/core/java/android/widget/PopupMenu.java @@ -20,6 +20,7 @@ import com.android.internal.R; import com.android.internal.view.menu.MenuBuilder; import com.android.internal.view.menu.MenuPopupHelper; import com.android.internal.view.menu.MenuPresenter; +import com.android.internal.view.menu.ShowableListMenu; import com.android.internal.view.menu.SubMenuBuilder; import android.annotation.MenuRes; @@ -30,7 +31,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnTouchListener; -import android.widget.ListPopupWindow.ForwardingListener; /** * A PopupMenu displays a {@link Menu} in a modal popup window anchored to a {@link View}. @@ -170,7 +170,7 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { } @Override - public ListPopupWindow getPopup() { + public ShowableListMenu getPopup() { // This will be null until show() is called. return mPopup.getPopup(); } diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index f3cf61c7a1eb..c79e18449e39 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -17,6 +17,7 @@ package android.widget; import com.android.internal.R; +import com.android.internal.view.menu.ShowableListMenu; import android.annotation.DrawableRes; import android.annotation.Nullable; @@ -44,7 +45,6 @@ import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityNodeInfo; -import android.widget.ListPopupWindow.ForwardingListener; import android.widget.PopupWindow.OnDismissListener; /** @@ -278,7 +278,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { mPopup = popup; mForwardingListener = new ForwardingListener(this) { @Override - public ListPopupWindow getPopup() { + public ShowableListMenu getPopup() { return popup; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 7a6437724e2f..61402abcece7 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -21,6 +21,7 @@ import android.annotation.ColorInt; import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.Size; import android.annotation.StringRes; import android.annotation.StyleRes; import android.annotation.XmlRes; @@ -103,6 +104,7 @@ import android.text.style.URLSpan; import android.text.style.UpdateAppearance; import android.text.util.Linkify; import android.util.AttributeSet; +import android.util.LocaleList; import android.util.Log; import android.util.TypedValue; import android.view.AccessibilityIterators.TextSegmentIterator; @@ -553,7 +555,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private final TextPaint mTextPaint; private boolean mUserSetTextScaleX; private Layout mLayout; - private boolean mLocaleChanged = false; + private boolean mLocalesChanged = false; @ViewDebug.ExportedProperty(category = "text") private int mGravity = Gravity.TOP | Gravity.START; @@ -2817,32 +2819,58 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Get the default {@link Locale} of the text in this TextView. - * @return the default {@link Locale} of the text in this TextView. + * Get the default primary {@link Locale} of the text in this TextView. This will always be + * the first member of {@link #getTextLocales()}. + * @return the default primary {@link Locale} of the text in this TextView. */ + @NonNull public Locale getTextLocale() { return mTextPaint.getTextLocale(); } /** - * Set the default {@link Locale} of the text in this TextView to the given value. This value - * is used to choose appropriate typefaces for ambiguous characters. Typically used for CJK - * locales to disambiguate Hanzi/Kanji/Hanja characters. + * Get the default {@link LocaleList} of the text in this TextView. + * @return the default {@link LocaleList} of the text in this TextView. + */ + @NonNull @Size(min=1) + public LocaleList getTextLocales() { + return mTextPaint.getTextLocales(); + } + + /** + * Set the default {@link LocaleList} of the text in this TextView to a one-member list + * containing just the given value. * * @param locale the {@link Locale} for drawing text, must not be null. * - * @see Paint#setTextLocale + * @see #setTextLocales */ - public void setTextLocale(Locale locale) { - mLocaleChanged = true; + public void setTextLocale(@NonNull Locale locale) { + mLocalesChanged = true; mTextPaint.setTextLocale(locale); } + /** + * Set the default {@link LocaleList} of the text in this TextView to the given value. + * + * This value is used to choose appropriate typefaces for ambiguous characters (typically used + * for CJK locales to disambiguate Hanzi/Kanji/Hanja characters). It also affects + * other aspects of text display, including line breaking. + * + * @param locales the {@link LocaleList} for drawing text, must not be null or empty. + * + * @see Paint#setTextLocales + */ + public void setTextLocales(@NonNull @Size(min=1) LocaleList locales) { + mLocalesChanged = true; + mTextPaint.setTextLocales(locales); + } + @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - if (!mLocaleChanged) { - mTextPaint.setTextLocale(Locale.getDefault()); + if (!mLocalesChanged) { + mTextPaint.setTextLocales(LocaleList.getDefault()); } } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 9ca937c167fe..959d249c3ecd 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -179,8 +179,18 @@ public class ZygoteInit { static void preload() { Log.d(TAG, "begin preload"); - preloadClasses(); - preloadResources(); + try { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses"); + preloadClasses(); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } + try { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources"); + preloadResources(); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } preloadOpenGL(); preloadSharedLibraries(); preloadTextResources(); @@ -266,6 +276,7 @@ public class ZygoteInit { } try { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line); if (false) { Log.v(TAG, "Preloading " + line + "..."); } @@ -289,6 +300,8 @@ public class ZygoteInit { throw (RuntimeException) t; } throw new RuntimeException(t); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); } } @@ -302,7 +315,9 @@ public class ZygoteInit { runtime.setTargetHeapUtilization(defaultUtilization); // Fill in dex caches with classes, fields, and methods brought in by preloading. + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches"); runtime.preloadDexCaches(); + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); // Bring back root. We'll need it later if we're in the zygote. if (droppedPriviliges) { @@ -564,41 +579,56 @@ public class ZygoteInit { public static void main(String argv[]) { try { - RuntimeInit.enableDdms(); - // Start profiling the zygote initialization. - SamplingProfilerIntegration.start(); - boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; - for (int i = 1; i < argv.length; i++) { - if ("start-system-server".equals(argv[i])) { - startSystemServer = true; - } else if (argv[i].startsWith(ABI_LIST_ARG)) { - abiList = argv[i].substring(ABI_LIST_ARG.length()); - } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { - socketName = argv[i].substring(SOCKET_NAME_ARG.length()); - } else { - throw new RuntimeException("Unknown command line argument: " + argv[i]); + try { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit"); + RuntimeInit.enableDdms(); + // Start profiling the zygote initialization. + SamplingProfilerIntegration.start(); + + for (int i = 1; i < argv.length; i++) { + if ("start-system-server".equals(argv[i])) { + startSystemServer = true; + } else if (argv[i].startsWith(ABI_LIST_ARG)) { + abiList = argv[i].substring(ABI_LIST_ARG.length()); + } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { + socketName = argv[i].substring(SOCKET_NAME_ARG.length()); + } else { + throw new RuntimeException("Unknown command line argument: " + argv[i]); + } } - } - if (abiList == null) { - throw new RuntimeException("No ABI list supplied."); - } + if (abiList == null) { + throw new RuntimeException("No ABI list supplied."); + } - registerZygoteSocket(socketName); - EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, - SystemClock.uptimeMillis()); - preload(); - EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, - SystemClock.uptimeMillis()); + registerZygoteSocket(socketName); + try { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload"); + EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, + SystemClock.uptimeMillis()); + preload(); + EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, + SystemClock.uptimeMillis()); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } - // Finish profiling the zygote initialization. - SamplingProfilerIntegration.writeZygoteSnapshot(); + // Finish profiling the zygote initialization. + SamplingProfilerIntegration.writeZygoteSnapshot(); - // Do an initial gc to clean up after startup - gcAndFinalize(); + // Do an initial gc to clean up after startup + try { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC"); + gcAndFinalize(); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } // Disable tracing so that forked processes do not inherit stale tracing tags from // Zygote. diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java index 8db363dadfa9..ce5bc908814c 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java @@ -29,10 +29,10 @@ import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.widget.ActionMenuView; +import android.widget.ForwardingListener; import android.widget.ListPopupWindow; import android.widget.TextView; import android.widget.Toast; -import android.widget.ListPopupWindow.ForwardingListener; /** * @hide @@ -320,7 +320,7 @@ public class ActionMenuItemView extends TextView } @Override - public ListPopupWindow getPopup() { + public ShowableListMenu getPopup() { if (mPopupCallback != null) { return mPopupCallback.getPopup(); } @@ -331,7 +331,7 @@ public class ActionMenuItemView extends TextView protected boolean onForwardingStarted() { // Call the invoker, then check if the expected popup is showing. if (mItemInvoker != null && mItemInvoker.invokeItem(mItemData)) { - final ListPopupWindow popup = getPopup(); + final ShowableListMenu popup = getPopup(); return popup != null && popup.isShowing(); } return false; @@ -339,7 +339,7 @@ public class ActionMenuItemView extends TextView @Override protected boolean onForwardingStopped() { - final ListPopupWindow popup = getPopup(); + final ShowableListMenu popup = getPopup(); if (popup != null) { popup.dismiss(); return true; @@ -349,6 +349,6 @@ public class ActionMenuItemView extends TextView } public static abstract class PopupCallback { - public abstract ListPopupWindow getPopup(); + public abstract ShowableListMenu getPopup(); } } diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java index 29ac3f349d0a..25263932bb75 100644 --- a/core/java/com/android/internal/view/menu/ListMenuItemView.java +++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java @@ -43,11 +43,13 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView private TextView mTitleView; private CheckBox mCheckBox; private TextView mShortcutView; + private ImageView mSubMenuArrowView; private Drawable mBackground; private int mTextAppearance; private Context mTextAppearanceContext; private boolean mPreserveIconSpacing; + private Drawable mSubMenuArrow; private int mMenuType; @@ -68,6 +70,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView mPreserveIconSpacing = a.getBoolean( com.android.internal.R.styleable.MenuView_preserveIconSpacing, false); mTextAppearanceContext = context; + mSubMenuArrow = a.getDrawable(com.android.internal.R.styleable.MenuView_subMenuArrow); a.recycle(); } @@ -77,7 +80,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView } public ListMenuItemView(Context context, AttributeSet attrs) { - this(context, attrs, 0); + this(context, attrs, com.android.internal.R.attr.listMenuViewStyle); } @Override @@ -93,6 +96,10 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView } mShortcutView = (TextView) findViewById(com.android.internal.R.id.shortcut); + mSubMenuArrowView = (ImageView) findViewById(com.android.internal.R.id.submenuarrow); + if (mSubMenuArrowView != null) { + mSubMenuArrowView.setImageDrawable(mSubMenuArrow); + } } public void initialize(MenuItemImpl itemData, int menuType) { @@ -106,6 +113,7 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut()); setIcon(itemData.getIcon()); setEnabled(itemData.isEnabled()); + setSubMenuArrowVisible(itemData.hasSubMenu()); } public void setForceShowIcon(boolean forceShow) { @@ -186,6 +194,12 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView compoundButton.setChecked(checked); } + private void setSubMenuArrowVisible(boolean hasSubmenu) { + if (mSubMenuArrowView != null) { + mSubMenuArrowView.setVisibility(hasSubmenu ? View.VISIBLE : View.GONE); + } + } + public void setShortcut(boolean showShortcut, char shortcutKey) { final int newVisibility = (showShortcut && mItemData.shouldShowShortcut()) ? VISIBLE : GONE; diff --git a/core/java/com/android/internal/view/menu/MenuAdapter.java b/core/java/com/android/internal/view/menu/MenuAdapter.java new file mode 100644 index 000000000000..1e03b1f8b971 --- /dev/null +++ b/core/java/com/android/internal/view/menu/MenuAdapter.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 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.view.menu; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; + +import java.util.ArrayList; + +public class MenuAdapter extends BaseAdapter { + static final int ITEM_LAYOUT = com.android.internal.R.layout.popup_menu_item_layout; + + MenuBuilder mAdapterMenu; + + private int mExpandedIndex = -1; + + private boolean mForceShowIcon; + private final boolean mOverflowOnly; + private final LayoutInflater mInflater; + + public MenuAdapter(MenuBuilder menu, LayoutInflater inflater, boolean overflowOnly) { + mOverflowOnly = overflowOnly; + mInflater = inflater; + mAdapterMenu = menu; + findExpandedIndex(); + } + + public void setForceShowIcon(boolean forceShow) { + mForceShowIcon = forceShow; + } + + public int getCount() { + ArrayList<MenuItemImpl> items = mOverflowOnly ? + mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); + if (mExpandedIndex < 0) { + return items.size(); + } + return items.size() - 1; + } + + public MenuBuilder getAdapterMenu() { + return mAdapterMenu; + } + + public MenuItemImpl getItem(int position) { + ArrayList<MenuItemImpl> items = mOverflowOnly ? + mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); + if (mExpandedIndex >= 0 && position >= mExpandedIndex) { + position++; + } + return items.get(position); + } + + public long getItemId(int position) { + // Since a menu item's ID is optional, we'll use the position as an + // ID for the item in the AdapterView + return position; + } + + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = mInflater.inflate(ITEM_LAYOUT, parent, false); + } + + MenuView.ItemView itemView = (MenuView.ItemView) convertView; + if (mForceShowIcon) { + ((ListMenuItemView) convertView).setForceShowIcon(true); + } + itemView.initialize(getItem(position), 0); + return convertView; + } + + void findExpandedIndex() { + final MenuItemImpl expandedItem = mAdapterMenu.getExpandedItem(); + if (expandedItem != null) { + final ArrayList<MenuItemImpl> items = mAdapterMenu.getNonActionItems(); + final int count = items.size(); + for (int i = 0; i < count; i++) { + final MenuItemImpl item = items.get(i); + if (item == expandedItem) { + mExpandedIndex = i; + return; + } + } + } + mExpandedIndex = -1; + } + + @Override + public void notifyDataSetChanged() { + findExpandedIndex(); + super.notifyDataSetChanged(); + } +}
\ No newline at end of file diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java index 13654a695fcf..e6bc6c3ae044 100644 --- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java +++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java @@ -89,7 +89,7 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On mContext = context; mInflater = LayoutInflater.from(context); mMenu = menu; - mAdapter = new MenuAdapter(mMenu); + mAdapter = new MenuAdapter(mMenu, mInflater, overflowOnly); mOverflowOnly = overflowOnly; mPopupStyleAttr = popupStyleAttr; mPopupStyleRes = popupStyleRes; @@ -358,73 +358,4 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On @Override public void onRestoreInstanceState(Parcelable state) { } - - private class MenuAdapter extends BaseAdapter { - private MenuBuilder mAdapterMenu; - private int mExpandedIndex = -1; - - public MenuAdapter(MenuBuilder menu) { - mAdapterMenu = menu; - findExpandedIndex(); - } - - public int getCount() { - ArrayList<MenuItemImpl> items = mOverflowOnly ? - mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); - if (mExpandedIndex < 0) { - return items.size(); - } - return items.size() - 1; - } - - public MenuItemImpl getItem(int position) { - ArrayList<MenuItemImpl> items = mOverflowOnly ? - mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); - if (mExpandedIndex >= 0 && position >= mExpandedIndex) { - position++; - } - return items.get(position); - } - - public long getItemId(int position) { - // Since a menu item's ID is optional, we'll use the position as an - // ID for the item in the AdapterView - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null) { - convertView = mInflater.inflate(ITEM_LAYOUT, parent, false); - } - - MenuView.ItemView itemView = (MenuView.ItemView) convertView; - if (mForceShowIcon) { - ((ListMenuItemView) convertView).setForceShowIcon(true); - } - itemView.initialize(getItem(position), 0); - return convertView; - } - - void findExpandedIndex() { - final MenuItemImpl expandedItem = mMenu.getExpandedItem(); - if (expandedItem != null) { - final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems(); - final int count = items.size(); - for (int i = 0; i < count; i++) { - final MenuItemImpl item = items.get(i); - if (item == expandedItem) { - mExpandedIndex = i; - return; - } - } - } - mExpandedIndex = -1; - } - - @Override - public void notifyDataSetChanged() { - findExpandedIndex(); - super.notifyDataSetChanged(); - } - } } diff --git a/core/java/com/android/internal/view/menu/ShowableListMenu.java b/core/java/com/android/internal/view/menu/ShowableListMenu.java new file mode 100644 index 000000000000..ca158fdb690e --- /dev/null +++ b/core/java/com/android/internal/view/menu/ShowableListMenu.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 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.view.menu; + +import android.widget.ListView; + +/** + * A list menu which can be shown and hidden and which is internally represented by a ListView. + */ +public interface ShowableListMenu { + public void show(); + + public void dismiss(); + + public boolean isShowing(); + + /** + * @return The internal ListView for the visible menu. + */ + public ListView getListView(); +} diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index f7a2f9fb53f5..e4bc80013b9c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#define ATRACE_TAG ATRACE_TAG_DALVIK #define LOG_TAG "AndroidRuntime" //#define LOG_NDEBUG 0 @@ -23,6 +24,7 @@ #include <binder/IServiceManager.h> #include <utils/Log.h> #include <utils/misc.h> +#include <utils/Trace.h> #include <binder/Parcel.h> #include <utils/threads.h> #include <cutils/properties.h> @@ -1437,6 +1439,7 @@ static const RegJNIRec gRegJNI[] = { */ /*static*/ int AndroidRuntime::startReg(JNIEnv* env) { + ATRACE_NAME("RegisterAndroidNatives"); /* * This hook causes all future threads created in this process to be * attached to the JavaVM. (This needs to go away in favor of JNI diff --git a/core/res/res/drawable/ic_arrow_drop_right_black_24dp.xml b/core/res/res/drawable/ic_arrow_drop_right_black_24dp.xml new file mode 100644 index 000000000000..2dd0540f8bb5 --- /dev/null +++ b/core/res/res/drawable/ic_arrow_drop_right_black_24dp.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="25.0dp" + android:viewportHeight="25.0" + android:viewportWidth="24.0" + android:width="25.0dp" + android:tint="?attr/colorControlNormal" + android:autoMirrored="true"> + + <group + android:name="arrow" + android:rotation="90.0" + android:pivotX="12.0" + android:pivotY="13.0" + android:translateY="1.0"> + <path android:fillColor="#000000" android:pathData="M7,14 L12,9 L17,14 L7,14 Z" /> + <path android:pathData="M0,0 L24,0 L24,24 L0,24 L0,0 Z" /> + </group> +</vector>
\ No newline at end of file diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml index 0bc636f0c4af..8b8c93afffbd 100644 --- a/core/res/res/layout/popup_menu_item_layout.xml +++ b/core/res/res/layout/popup_menu_item_layout.xml @@ -57,6 +57,15 @@ </RelativeLayout> + <ImageView + android:id="@+id/submenuarrow" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_marginStart="8dp" + android:scaleType="center" + android:visibility="gone" /> + <!-- Checkbox, and/or radio button will be inserted here. --> </com.android.internal.view.menu.ListMenuItemView> diff --git a/core/res/res/values-ca-watch/strings.xml b/core/res/res/values-ca-watch/strings.xml index b01ca630166e..231450fec3c2 100644 --- a/core/res/res/values-ca-watch/strings.xml +++ b/core/res/res/values-ca-watch/strings.xml @@ -31,7 +31,7 @@ <string name="permgrouplab_camerawear" msgid="4543951283103407017">"fer fotos i enregistrar vídeos"</string> <string name="permgrouplab_phonewear" msgid="134365036753766126">"fer i gestionar trucades telefòniques"</string> <string name="permgrouplab_sensorswear" msgid="1429324744329327663">"accedir a les dades del sensor sobre els signes vitals"</string> - <string name="permlab_statusBarServicewear" msgid="2469402818964691034">"ser la barra d\'estat"</string> + <string name="permlab_statusBarServicewear" msgid="2469402818964691034">"aparèixer a la barra d\'estat"</string> <string name="permlab_bodySensorswear" msgid="7857941041202791873">"accedir als sensors corporals (com ara monitors de freqüència cardíaca)"</string> <string name="permlab_accessFineLocationwear" msgid="5584423486924377563">"accedir a la ubicació precisa (basada en el GPS i la xarxa)"</string> <string name="permlab_accessCoarseLocationwear" msgid="5880746016230166090">"accedir a la ubicació aproximada (basada en la xarxa)"</string> @@ -40,7 +40,7 @@ <string name="permlab_manageProfileAndDeviceOwnerswear" msgid="7313340516937821847">"gestionar els propietaris del perfil i del dispositiu"</string> <string name="permlab_changeWimaxStatewear" msgid="3828470843939853744">"canviar l\'estat de WiMAX"</string> <string name="permlab_handoverStatuswear" msgid="4835786819716499249">"rebre l\'estat de la transferència d\'Android Beam"</string> - <string name="permlab_route_media_outputwear" msgid="8737024341474587192">"indicar la ruta de sortida del contingut multimèdia"</string> + <string name="permlab_route_media_outputwear" msgid="8737024341474587192">"indicar la sortida del fitxer multimèdia"</string> <string name="permlab_readInstallSessionswear" msgid="9059478058685861989">"llegir les sessions d\'instal·lació"</string> - <string name="permlab_requestInstallPackageswear" msgid="4982025836783539503">"sol·licitar els paquets d\'instal·lació"</string> + <string name="permlab_requestInstallPackageswear" msgid="4982025836783539503">"sol·licitar la instal·lació de paquets"</string> </resources> diff --git a/core/res/res/values-el-watch/strings.xml b/core/res/res/values-el-watch/strings.xml index 8081013177ff..83d9c3dae2e2 100644 --- a/core/res/res/values-el-watch/strings.xml +++ b/core/res/res/values-el-watch/strings.xml @@ -42,5 +42,5 @@ <string name="permlab_handoverStatuswear" msgid="4835786819716499249">"λήψη κατάστασης μεταφοράς Android Beam"</string> <string name="permlab_route_media_outputwear" msgid="8737024341474587192">"δρομολόγηση εξόδου μέσων"</string> <string name="permlab_readInstallSessionswear" msgid="9059478058685861989">"ανάγνωση περιόδων σύνδεσης εγκατάστασης"</string> - <string name="permlab_requestInstallPackageswear" msgid="4982025836783539503">"αίτημα εγκατάστασης πακέτων."</string> + <string name="permlab_requestInstallPackageswear" msgid="4982025836783539503">"αίτημα εγκατάστασης πακέτων"</string> </resources> diff --git a/core/res/res/values-eu-rES-watch/strings.xml b/core/res/res/values-eu-rES-watch/strings.xml index 011105e4faa5..0fca702c9e34 100644 --- a/core/res/res/values-eu-rES-watch/strings.xml +++ b/core/res/res/values-eu-rES-watch/strings.xml @@ -26,7 +26,7 @@ <string name="permgrouplab_locationwear" msgid="6275317222482780209">"Atzitu erlojuaren kokapena"</string> <string name="permgrouplab_calendarwear" msgid="441900844045065081">"Atzitu egutegia"</string> <string name="permgrouplab_smswear" msgid="6849506550342974220">"Bidali eta ikusi SMS mezuak"</string> - <string name="permgrouplab_storagewear" msgid="1003807594193602313">"Atzitu erlojuko argazkiak, multimedia-elementuak eta fitxategiak"</string> + <string name="permgrouplab_storagewear" msgid="1003807594193602313">"Atzitu erlojuko argazkiak, multimedia-edukia eta fitxategiak"</string> <string name="permgrouplab_microphonewear" msgid="1047561180980891136">"Grabatu audioa"</string> <string name="permgrouplab_camerawear" msgid="4543951283103407017">"Atera argazkiak eta grabatu bideoak"</string> <string name="permgrouplab_phonewear" msgid="134365036753766126">"Egin eta kudeatu telefono-deiak"</string> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index 43264a7586f2..2bdc9c83532d 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -1149,7 +1149,7 @@ <string name="sync_really_delete" msgid="2572600103122596243">"ഇനങ്ങൾ ഇല്ലാതാക്കുക"</string> <string name="sync_undo_deletes" msgid="2941317360600338602">"ഇല്ലാതാക്കിയവ പഴയപടിയാക്കുക"</string> <string name="sync_do_nothing" msgid="3743764740430821845">"ഇപ്പോൾ ഒന്നും ചെയ്യേണ്ടതില്ല"</string> - <string name="choose_account_label" msgid="5655203089746423927">"ഒരു അക്കൗണ്ട് തിരഞ്ഞെടുക്കുക"</string> + <string name="choose_account_label" msgid="5655203089746423927">"അക്കൗണ്ട് തിരഞ്ഞെടുക്കൂ"</string> <string name="add_account_label" msgid="2935267344849993553">"ഒരു അക്കൗണ്ട് ചേർക്കുക"</string> <string name="add_account_button_label" msgid="3611982894853435874">"അക്കൗണ്ട് ചേർക്കുക"</string> <string name="number_picker_increment_button" msgid="2412072272832284313">"വർദ്ധിപ്പിക്കുക"</string> diff --git a/core/res/res/values-ne-rNP-watch/strings.xml b/core/res/res/values-ne-rNP-watch/strings.xml index a38de9997437..1b4ffc9fd23f 100644 --- a/core/res/res/values-ne-rNP-watch/strings.xml +++ b/core/res/res/values-ne-rNP-watch/strings.xml @@ -26,7 +26,7 @@ <string name="permgrouplab_locationwear" msgid="6275317222482780209">"यो घडीको स्थान पहुँच गर्नुहोस्"</string> <string name="permgrouplab_calendarwear" msgid="441900844045065081">"आफ्नो पात्रोमा पहुँच गर्नुहोस्"</string> <string name="permgrouplab_smswear" msgid="6849506550342974220">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string> - <string name="permgrouplab_storagewear" msgid="1003807594193602313">"आफ्नो समयमा फोटो, मिडिया, र फाइलहरू हेर्नुहोस्"</string> + <string name="permgrouplab_storagewear" msgid="1003807594193602313">"आफ्नो समयमा तस्बिर, मिडिया, र फाइलहरू हेर्नुहोस्"</string> <string name="permgrouplab_microphonewear" msgid="1047561180980891136">"अडियो रेकर्ड गर्नुहोस्"</string> <string name="permgrouplab_camerawear" msgid="4543951283103407017">"तस्बिरहरू खिच्नुहोस् र भिडियो रेकर्ड गर्नुहोस्"</string> <string name="permgrouplab_phonewear" msgid="134365036753766126">"फोन कलहरू गर्नुहोस् र व्यवस्थापन गर्नुहोस्"</string> diff --git a/core/res/res/values-ta-rIN-watch/strings.xml b/core/res/res/values-ta-rIN-watch/strings.xml index 63e072fb0e25..629ca273b937 100644 --- a/core/res/res/values-ta-rIN-watch/strings.xml +++ b/core/res/res/values-ta-rIN-watch/strings.xml @@ -29,7 +29,7 @@ <string name="permgrouplab_storagewear" msgid="1003807594193602313">"உங்கள் வாட்சில் உள்ள படங்கள், மீடியா மற்றும் கோப்புகளை அணுகும்"</string> <string name="permgrouplab_microphonewear" msgid="1047561180980891136">"ஆடியோவைப் பதிவுசெய்யும்"</string> <string name="permgrouplab_camerawear" msgid="4543951283103407017">"படங்களை எடுக்கும், வீடியோவைப் பதிவுசெய்யும்"</string> - <string name="permgrouplab_phonewear" msgid="134365036753766126">"மொபைல் அழைப்புகளைச் செய்யும், பெறும்"</string> + <string name="permgrouplab_phonewear" msgid="134365036753766126">"மொபைல் அழைப்புகளைச் செய்யும், நிர்வகிக்கும்"</string> <string name="permgrouplab_sensorswear" msgid="1429324744329327663">"உங்கள் உடலியக்கக் குறிகள் பற்றிய உணர்வித் தரவை அணுகும்"</string> <string name="permlab_statusBarServicewear" msgid="2469402818964691034">"நிலைப் பட்டியில் இருக்கும்"</string> <string name="permlab_bodySensorswear" msgid="7857941041202791873">"உடல் உணர்விகளை (இதயத் துடிப்பு மானிட்டர்கள் போன்றவை) அணுகும்"</string> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index aa469496e6c6..e6e20f163406 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -429,7 +429,7 @@ <string name="fingerprint_error_no_space" msgid="1055819001126053318">"فنگر پرنٹ اسٹور نہیں کیا جا سکتا ہے۔ براہ کرم ایک موجودہ فنگر پرنٹ ہٹائیں۔"</string> <string name="fingerprint_error_timeout" msgid="3927186043737732875">"فنگر پرنٹ کی میعاد ختم ہوگئی۔ دوبارہ کوشش کریں۔"</string> <string name="fingerprint_error_canceled" msgid="4402024612660774395">"فنگر پرنٹ کی کارروائی منسوخ ہوگئی۔"</string> - <string name="fingerprint_error_lockout" msgid="5536934748136933450">"کافی زیادہ کوششیں کی گئیں۔ بعد میں دوباہ کوشش کریں۔"</string> + <string name="fingerprint_error_lockout" msgid="5536934748136933450">"کافی زیادہ کوششیں کی گئیں۔ بعد میں دوبارہ کوشش کریں۔"</string> <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"دوبارہ کوشش کریں۔"</string> <string name="fingerprint_name_template" msgid="5870957565512716938">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 61af6c5d1892..59d1a7c62e2a 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -639,6 +639,8 @@ i <attr name="imageButtonStyle" format="reference" /> <!-- The style resource to use for an ImageButton that is an image well. --> <attr name="imageWellStyle" format="reference" /> + <!-- Default menu-style ListView style. --> + <attr name="listMenuViewStyle" format="reference" /> <!-- Default ListView style. --> <attr name="listViewStyle" format="reference" /> <!-- ListView with white background. --> @@ -3784,6 +3786,8 @@ i <attr name="itemIconDisabledAlpha" format="float" /> <!-- Whether space should be reserved in layout when an icon is missing. --> <attr name="preserveIconSpacing" format="boolean" /> + <!-- Drawable for the arrow icon indicating a particular item is a submenu. --> + <attr name="subMenuArrow" format="reference" /> </declare-styleable> <declare-styleable name="IconMenuView"> <!-- Defines the height of each row. --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index d2089cdad73b..c89b31bd7e65 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2660,6 +2660,9 @@ =============================================================== --> <eat-comment /> + <public type="attr" name="listMenuViewStyle" /> + <public type="attr" name="subMenuArrow" /> + <public type="style" name="Theme.Material.DayNight" /> <public type="style" name="Theme.Material.DayNight.DarkActionBar" /> <public type="style" name="Theme.Material.DayNight.Dialog" /> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index 2369c9be158d..5dc14e301704 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -685,6 +685,10 @@ please see styles_device_defaults.xml. <style name="Widget.Material.ListView.White"/> + <style name="Widget.Material.ListMenuView"> + <item name="subMenuArrow">@drawable/ic_arrow_drop_right_black_24dp</item> + </style> + <style name="Widget.Material.PopupWindow" parent="Widget.PopupWindow"/> <style name="Widget.Material.PopupWindow.ActionMode"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e04c7438a224..98c9f77523b1 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -158,6 +158,7 @@ <java-symbol type="id" name="shortcut" /> <java-symbol type="id" name="skip_button" /> <java-symbol type="id" name="split_action_bar" /> + <java-symbol type="id" name="submenuarrow" /> <java-symbol type="id" name="submit_area" /> <java-symbol type="id" name="switch_new" /> <java-symbol type="id" name="switch_old" /> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index e406ae06d96c..30101909f0b4 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -238,6 +238,7 @@ please see themes_device_defaults.xml. <item name="gridViewStyle">@style/Widget.Material.GridView</item> <item name="imageButtonStyle">@style/Widget.Material.ImageButton</item> <item name="imageWellStyle">@style/Widget.Material.ImageWell</item> + <item name="listMenuViewStyle">@style/Widget.Material.ListMenuView</item> <item name="listViewStyle">@style/Widget.Material.ListView</item> <item name="listViewWhiteStyle">@style/Widget.Material.ListView.White</item> <item name="popupWindowStyle">@style/Widget.Material.PopupWindow</item> @@ -594,6 +595,7 @@ please see themes_device_defaults.xml. <item name="gridViewStyle">@style/Widget.Material.Light.GridView</item> <item name="imageButtonStyle">@style/Widget.Material.Light.ImageButton</item> <item name="imageWellStyle">@style/Widget.Material.Light.ImageWell</item> + <item name="listMenuViewStyle">@style/Widget.Material.ListMenuView</item> <item name="listViewStyle">@style/Widget.Material.Light.ListView</item> <item name="listViewWhiteStyle">@style/Widget.Material.Light.ListView.White</item> <item name="popupWindowStyle">@style/Widget.Material.Light.PopupWindow</item> diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index c5d68bd230c1..ce35b871b8db 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -17,10 +17,13 @@ package android.graphics; import android.annotation.ColorInt; +import android.annotation.NonNull; +import android.annotation.Size; import android.text.GraphicsOperations; import android.text.SpannableString; import android.text.SpannedString; import android.text.TextUtils; +import android.util.LocaleList; import java.util.Locale; @@ -50,7 +53,7 @@ public class Paint { private float mCompatScaling; private float mInvCompatScaling; - private Locale mLocale; + private LocaleList mLocales; private String mFontFeatureSettings; /** @@ -434,7 +437,7 @@ public class Paint { // setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV // ? HINTING_OFF : HINTING_ON); mCompatScaling = mInvCompatScaling = 1; - setTextLocale(Locale.getDefault()); + setTextLocales(LocaleList.getDefault()); } /** @@ -474,7 +477,7 @@ public class Paint { mInvCompatScaling = 1; mBidiFlags = BIDI_DEFAULT_LTR; - setTextLocale(Locale.getDefault()); + setTextLocales(LocaleList.getDefault()); setElegantTextHeight(false); mFontFeatureSettings = null; } @@ -512,7 +515,7 @@ public class Paint { mInvCompatScaling = paint.mInvCompatScaling; mBidiFlags = paint.mBidiFlags; - mLocale = paint.mLocale; + mLocales = paint.mLocales; mFontFeatureSettings = paint.mFontFeatureSettings; } @@ -1174,47 +1177,80 @@ public class Paint { } /** - * Get the text Locale. + * Get the text's primary Locale. Note that this is not all of the locale-related information + * Paint has. Use {@link #getTextLocales()} to get the complete list. * - * @return the paint's Locale used for drawing text, never null. + * @return the paint's primary Locale used for drawing text, never null. */ + @NonNull public Locale getTextLocale() { - return mLocale; + return mLocales.getPrimary(); } /** - * Set the text locale. + * Get the text locale list. * - * The text locale affects how the text is drawn for some languages. + * @return the paint's LocaleList used for drawing text, never null or empty. + */ + @NonNull @Size(min=1) + public LocaleList getTextLocales() { + return mLocales; + } + + /** + * Set the text locale list to a one-member list consisting of just the locale. + * + * See {@link #setTextLocales(LocaleList)} for how the locale list affects + * the way the text is drawn for some languages. + * + * @param locale the paint's locale value for drawing text, must not be null. + */ + public void setTextLocale(@NonNull Locale locale) { + if (locale == null) { + throw new IllegalArgumentException("locale cannot be null"); + } + if (mLocales != null && mLocales.size() == 1 && locale.equals(mLocales.getPrimary())) { + return; + } + mLocales = new LocaleList(locale); + native_setTextLocale(mNativePaint, locale.toString()); + } + + /** + * Set the text locale list. * - * For example, if the locale is {@link Locale#CHINESE} or {@link Locale#CHINA}, + * The text locale list affects how the text is drawn for some languages. + * + * For example, if the locale list contains {@link Locale#CHINESE} or {@link Locale#CHINA}, * then the text renderer will prefer to draw text using a Chinese font. Likewise, - * if the locale is {@link Locale#JAPANESE} or {@link Locale#JAPAN}, then the text - * renderer will prefer to draw text using a Japanese font. + * if the locale list contains {@link Locale#JAPANESE} or {@link Locale#JAPAN}, then the text + * renderer will prefer to draw text using a Japanese font. If the locale list contains both, + * the order those locales appear in the list is considered for deciding the font. * * This distinction is important because Chinese and Japanese text both use many * of the same Unicode code points but their appearance is subtly different for * each language. * - * By default, the text locale is initialized to the system locale (as returned - * by {@link Locale#getDefault}). This assumes that the text to be rendered will - * most likely be in the user's preferred language. + * By default, the text locale list is initialized to a one-member list just containing the + * system locale (as returned by {@link LocaleList#getDefault()}). This assumes that the text to + * be rendered will most likely be in the user's preferred language. * - * If the actual language of the text is known, then it can be provided to the - * text renderer using this method. The text renderer may attempt to guess the + * If the actual language or languages of the text is/are known, then they can be provided to + * the text renderer using this method. The text renderer may attempt to guess the * language script based on the contents of the text to be drawn independent of - * the text locale here. Specifying the text locale just helps it do a better - * job in certain ambiguous cases + * the text locale here. Specifying the text locales just helps it do a better + * job in certain ambiguous cases. * - * @param locale the paint's locale value for drawing text, must not be null. + * @param locales the paint's locale list for drawing text, must not be null or empty. */ - public void setTextLocale(Locale locale) { - if (locale == null) { - throw new IllegalArgumentException("locale cannot be null"); + public void setTextLocales(@NonNull @Size(min=1) LocaleList locales) { + if (locales == null || locales.isEmpty()) { + throw new IllegalArgumentException("locales cannot be null or empty"); } - if (locale.equals(mLocale)) return; - mLocale = locale; - native_setTextLocale(mNativePaint, locale.toString()); + if (locales.equals(mLocales)) return; + mLocales = locales; + // TODO: Pass the whole LocaleList to native code + native_setTextLocale(mNativePaint, locales.getPrimary().toString()); } /** diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/CursorHelper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/CursorHelper.java index 48d5dcfeb5f5..b5694b73a239 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/CursorHelper.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/CursorHelper.java @@ -17,6 +17,7 @@ package com.android.mtp; import android.database.MatrixCursor; +import android.mtp.MtpConstants; import android.mtp.MtpObjectInfo; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; @@ -72,11 +73,11 @@ final class CursorHelper { static String formatTypeToMimeType(int format) { // TODO: Add complete list of mime types. switch (format) { - case 0x3001: + case MtpConstants.FORMAT_ASSOCIATION: return DocumentsContract.Document.MIME_TYPE_DIR; - case 0x3009: + case MtpConstants.FORMAT_MP3: return "audio/mp3"; - case 0x3801: + case MtpConstants.FORMAT_EXIF_JPEG: return "image/jpeg"; default: return "application/octet-stream"; @@ -87,13 +88,13 @@ final class CursorHelper { // TODO: Add complete list of mime types. switch (mimeType.toLowerCase()) { case Document.MIME_TYPE_DIR: - return 0x3001; + return MtpConstants.FORMAT_ASSOCIATION; case "audio/mp3": - return 0x3009; + return MtpConstants.FORMAT_MP3; case "image/jpeg": - return 0x3801; + return MtpConstants.FORMAT_EXIF_JPEG; default: - return 0x3000; // Undefined object. + return MtpConstants.FORMAT_UNDEFINED; } } } diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java index cbb72d14f52e..9b316be48a15 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java @@ -209,7 +209,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { public void testQueryDocument() throws IOException { mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder() .setObjectHandle(2) - .setFormat(0x3801) + .setFormat(MtpConstants.FORMAT_EXIF_JPEG) .setName("image.jpg") .setDateModified(1422716400000L) .setCompressedSize(1024 * 1024 * 5) @@ -234,7 +234,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { public void testQueryDocument_directory() throws IOException { mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder() .setObjectHandle(2) - .setFormat(0x3001 /* directory format */) + .setFormat(MtpConstants.FORMAT_ASSOCIATION) .setName("directory") .setDateModified(1422716400000L) .build()); @@ -281,7 +281,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { mMtpManager.setObjectInfo(0, new MtpObjectInfo.Builder() .setObjectHandle(1) - .setFormat(0x3801 /* JPEG */) + .setFormat(MtpConstants.FORMAT_EXIF_JPEG) .setName("image.jpg") .setCompressedSize(1024 * 1024 * 5) .setThumbCompressedSize(5 * 1024) diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 9294a16ca6b5..1473f24bae42 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Program is nie op jou toestel geïnstalleer nie"</string> <string name="clock_seconds" msgid="7689554147579179507">"Wys horlosiesekondes"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Wys horlosiesekondes op die statusbalk. Sal batterylewe dalk beïnvloed."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Herrangskik Kitsinstellings"</string> + <string name="show_brightness" msgid="6613930842805942519">"Wys helderheid in Kitsinstellings"</string> + <string name="qs_paging" msgid="7020133150248666132">"Gebruik verdeling in Kitsinstellings"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimenteel"</string> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 13f768d87953..7ab6af9cb72d 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"መተግበሪያ በእርስዎ መሣሪያ ላይ አልተጫነም"</string> <string name="clock_seconds" msgid="7689554147579179507">"የሰዓት ሰከንዶችን አሳይ"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"የሰዓት ሰከንዶችን በሁኔታ አሞሌ ውስጥ አሳይ። በባትሪ ዕድሜ ላይ ተጽዕኖ ሊኖርው ይችል ይሆናል።"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ፈጣን ቅንብሮችን ዳግም ያደራጁ"</string> + <string name="show_brightness" msgid="6613930842805942519">"በፈጣን ቅንብሮች ውስጥ ብሩህነትን አሳይ"</string> + <string name="qs_paging" msgid="7020133150248666132">"በፈጣን ቅንብሮች ውስጥ ምልክት መጥሪያን ይጠቀሙ"</string> + <string name="experimental" msgid="6198182315536726162">"የሙከራ"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 6889a4352983..bd026501dc45 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -439,4 +439,8 @@ <string name="activity_not_found" msgid="348423244327799974">"التطبيق غير مثبّت على جهازك"</string> <string name="clock_seconds" msgid="7689554147579179507">"عرض ثواني الساعة"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"عرض ثواني الساعة في شريط الحالة. قد يؤثر ذلك في عمر البطارية."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"إعادة ترتيب الإعدادات السريعة"</string> + <string name="show_brightness" msgid="6613930842805942519">"عرض السطوع في الإعدادات السريعة"</string> + <string name="qs_paging" msgid="7020133150248666132">"استخدام ترقيم الصفحات في الإعدادات السريعة"</string> + <string name="experimental" msgid="6198182315536726162">"إعدادات تجريبية"</string> </resources> diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml index 51513bd5ebf8..a0d7d2b21c7c 100644 --- a/packages/SystemUI/res/values-az-rAZ/strings.xml +++ b/packages/SystemUI/res/values-az-rAZ/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Tətbiq cihazınızda quraşdırılmayıb"</string> <string name="clock_seconds" msgid="7689554147579179507">"Saatın saniyəsini göstərin"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Saatın saniyəsini status panelində göstərin. Batareyaya təsir edə bilər."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Sürətli Ayarları yenidən tənzimləyin"</string> + <string name="show_brightness" msgid="6613930842805942519">"Sürətli ayarlarda parlaqlılığı göstərin"</string> + <string name="qs_paging" msgid="7020133150248666132">"Sürətli Ayarlarda səhifə nömrələməsindən istifadə edin"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimental"</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 014d802204ec..a14d0fc70c07 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Приложението не е инсталирано на устройството ви"</string> <string name="clock_seconds" msgid="7689554147579179507">"Показване на секундите на часовника"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Показване на секундите на часовника в лентата на състоянието. Може да се отрази на живота на батерията."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Пренареждане на бързите настройки"</string> + <string name="show_brightness" msgid="6613930842805942519">"Показване на яркостта от бързите настройки"</string> + <string name="qs_paging" msgid="7020133150248666132">"Използване на разделянето на страници от бързите настройки"</string> + <string name="experimental" msgid="6198182315536726162">"Експериментални"</string> </resources> diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml index 08600193fc1c..e819d54e0901 100644 --- a/packages/SystemUI/res/values-bn-rBD/strings.xml +++ b/packages/SystemUI/res/values-bn-rBD/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"আপনার ডিভাইসে অ্যাপ্লিকেশান ইনস্টল করা নেই"</string> <string name="clock_seconds" msgid="7689554147579179507">"ঘড়ির সেকেন্ড দেখায়"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"স্থিতি দন্ডে ঘড়ির সেকেন্ড দেখায়৷ ব্যাটারি লাইফকে প্রভাবিত করতে পারে৷"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"দ্রুত সেটিংসে পুনরায় সাজান"</string> + <string name="show_brightness" msgid="6613930842805942519">"দ্রুত সেটিংসে উজ্জ্বলতা দেখান"</string> + <string name="qs_paging" msgid="7020133150248666132">"দ্রুত সেটিংসে পেজিং ব্যবহার করুন"</string> + <string name="experimental" msgid="6198182315536726162">"পরীক্ষামূলক"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 9c32052992cd..7def415f9bdb 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"L\'aplicació no està instal·lada al dispositiu"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostra els segons del rellotge"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra els segons del rellotge a la barra d\'estat. Això pot afectar la durada de la bateria."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Torna a ordenar la Configuració ràpida"</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostra la brillantor a la Configuració ràpida"</string> + <string name="qs_paging" msgid="7020133150248666132">"Utilitza la paginació a la Configuració ràpida"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 4d96a011a094..a73947fdfb05 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -439,4 +439,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikace není v zařízení nainstalována."</string> <string name="clock_seconds" msgid="7689554147579179507">"Zobrazit sekundovou ručičku"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Na stavovém řádku se bude zobrazovat sekundová ručička. Může být ovlivněna výdrž baterie."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Změnit uspořádání Rychlého nastavení"</string> + <string name="show_brightness" msgid="6613930842805942519">"Zobrazit jas v Rychlém nastavení"</string> + <string name="qs_paging" msgid="7020133150248666132">"Použít v Rychlém nastavení stránkování"</string> + <string name="experimental" msgid="6198182315536726162">"Experimentální"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 7f005a383d3b..6f491874e6a8 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Applikationen er ikke installeret på din enhed."</string> <string name="clock_seconds" msgid="7689554147579179507">"Vis sekunder"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Vis sekunder i statuslinjen. Dette kan påvirke batteriets levetid."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Omarranger Hurtige indstillinger"</string> + <string name="show_brightness" msgid="6613930842805942519">"Vis lysstyrke i Hurtige indstillinger"</string> + <string name="qs_paging" msgid="7020133150248666132">"Brug sidelayout i Hurtige indstillinger"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimentel"</string> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 36f3c985672e..a659077bd821 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Die App ist nicht auf Ihrem Gerät installiert."</string> <string name="clock_seconds" msgid="7689554147579179507">"Uhrsekunden anzeigen"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Uhrsekunden in der Statusleiste anzeigen. Kann sich auf die Akkulaufzeit auswirken."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Schnelleinstellungen neu anordnen"</string> + <string name="show_brightness" msgid="6613930842805942519">"Helligkeit in den Schnelleinstellungen anzeigen"</string> + <string name="qs_paging" msgid="7020133150248666132">"Seitenlayout in den Schnelleinstellungen verwenden"</string> + <string name="experimental" msgid="6198182315536726162">"Experimentell"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 8e73b21d5d9c..bcfc4589a6b8 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Η εφαρμογή δεν έχει εγκατασταθεί στη συσκευή σας"</string> <string name="clock_seconds" msgid="7689554147579179507">"Εμφάνιση δευτερολέπτων ρολογιού"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Εμφάνιση δευτερολέπτων ρολογιού στη γραμμή κατάστασης. Ενδέχεται να επηρεάσει τη διάρκεια ζωής της μπαταρίας."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Αναδιάταξη Γρήγορων ρυθμίσεων"</string> + <string name="show_brightness" msgid="6613930842805942519">"Εμφάνιση φωτεινότητας στις Γρήγορες ρυθμίσεις"</string> + <string name="qs_paging" msgid="7020133150248666132">"Χρήση τηλεειδοποίησης στις Γρήγορες ρυθμίσεις"</string> + <string name="experimental" msgid="6198182315536726162">"Σε πειραματικό στάδιο"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 0b499557f8fd..fb781d4d91ea 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string> <string name="clock_seconds" msgid="7689554147579179507">"Show clock seconds"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Rearrange Quick Settings"</string> + <string name="show_brightness" msgid="6613930842805942519">"Show brightness in Quick Settings"</string> + <string name="qs_paging" msgid="7020133150248666132">"Use paging in Quick Settings"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 0b499557f8fd..fb781d4d91ea 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string> <string name="clock_seconds" msgid="7689554147579179507">"Show clock seconds"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Rearrange Quick Settings"</string> + <string name="show_brightness" msgid="6613930842805942519">"Show brightness in Quick Settings"</string> + <string name="qs_paging" msgid="7020133150248666132">"Use paging in Quick Settings"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 0b499557f8fd..fb781d4d91ea 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Application is not installed on your device"</string> <string name="clock_seconds" msgid="7689554147579179507">"Show clock seconds"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Show clock seconds in the status bar. May impact battery life."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Rearrange Quick Settings"</string> + <string name="show_brightness" msgid="6613930842805942519">"Show brightness in Quick Settings"</string> + <string name="qs_paging" msgid="7020133150248666132">"Use paging in Quick Settings"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index c4dca9c491dc..10834a23baa7 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"La aplicación no está instalada en el dispositivo"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostrar los segundos del reloj"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Muestra los segundos del reloj en la barra de estado. Puede afectar la duración de la batería."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar la Configuración rápida"</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostrar el brillo en la Configuración rápida"</string> + <string name="qs_paging" msgid="7020133150248666132">"Usar la paginación en la Configuración rápida"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index e316a944793c..37c81f4936c0 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"La aplicación no está instalada en tu dispositivo"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostrar los segundos del reloj"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Muestra los segundos del reloj en la barra de estado. Puede afectar a la duración de la batería."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar Ajustes rápidos"</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostrar brillo en Ajustes rápidos"</string> + <string name="qs_paging" msgid="7020133150248666132">"Utilizar paginación en Ajustes rápidos"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index a151bce0f475..f4218a3a6eb3 100644 --- a/packages/SystemUI/res/values-et-rEE/strings.xml +++ b/packages/SystemUI/res/values-et-rEE/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Rakendust pole teie seadmesse installitud"</string> <string name="clock_seconds" msgid="7689554147579179507">"Kella sekundite kuvamine"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Olekuribal kella sekundite kuvamine. See võib mõjutada aku kasutusaega."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Korralda kiirseaded ümber"</string> + <string name="show_brightness" msgid="6613930842805942519">"Kuva kiirseadetes heledus"</string> + <string name="qs_paging" msgid="7020133150248666132">"Kasuta kiirseadetes lehe paigutust"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimentaalne"</string> </resources> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index 37cdee70163d..fbf0eb42e73c 100644 --- a/packages/SystemUI/res/values-eu-rES/strings.xml +++ b/packages/SystemUI/res/values-eu-rES/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikazioa ez dago gailuan instalatuta"</string> <string name="clock_seconds" msgid="7689554147579179507">"Erakutsi erlojuko segundoak"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Erakutsi erlojuko segundoak egoera-barran. Baliteke bateria gehiago erabiltzea."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Berrantolatu ezarpen bizkorrak"</string> + <string name="show_brightness" msgid="6613930842805942519">"Erakutsi ezarpen bizkorren distira"</string> + <string name="qs_paging" msgid="7020133150248666132">"Erabili ezarpen bizkorretako orriak pasatzeko diseinu berria"</string> + <string name="experimental" msgid="6198182315536726162">"Esperimentala"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 80d09185003d..fa01c47df918 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"برنامه در دستگاه شما نصب نیست"</string> <string name="clock_seconds" msgid="7689554147579179507">"نمایش ثانیههای ساعت"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"ثانیههای ساعت را در نوار وضعیت نشان میدهد. ممکن است بر ماندگاری باتری تأثیر بگذارد."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ترتیب مجدد در تنظیمات سریع"</string> + <string name="show_brightness" msgid="6613930842805942519">"نمایش روشنایی در تنظیمات سریع"</string> + <string name="qs_paging" msgid="7020133150248666132">"استفاده از صفحهبندی در تنظیمات سریع"</string> + <string name="experimental" msgid="6198182315536726162">"آزمایشی"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index b86247acf597..6c4a0299069b 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Sovellusta ei ole asennettu laitteellesi."</string> <string name="clock_seconds" msgid="7689554147579179507">"Näytä sekunnit kellossa"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Näytä sekunnit tilapalkin kellossa. Tämä voi vaikuttaa akun kestoon."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Järjestä pika-asetukset uudelleen"</string> + <string name="show_brightness" msgid="6613930842805942519">"Näytä kirkkaus pika-asetuksissa"</string> + <string name="qs_paging" msgid="7020133150248666132">"Käytä sivutusta pika-asetuksissa"</string> + <string name="experimental" msgid="6198182315536726162">"Kokeellinen"</string> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index f99447cde722..07a2fc349f5e 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"L\'application n\'est pas installée sur votre appareil"</string> <string name="clock_seconds" msgid="7689554147579179507">"Afficher les secondes sur l\'horloge"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Afficher les secondes sur l\'horloge dans la barre d\'état. Cela peut réduire l\'autonomie de la pile."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Réorganiser les paramètres rapides"</string> + <string name="show_brightness" msgid="6613930842805942519">"Afficher la luminosité dans les paramètres rapides"</string> + <string name="qs_paging" msgid="7020133150248666132">"Utiliser la pagination dans les paramètres rapides"</string> + <string name="experimental" msgid="6198182315536726162">"Fonctions expérimentales"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index aada1eb83f7a..0aa45ae8a393 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"L\'application n\'est pas installée sur votre appareil."</string> <string name="clock_seconds" msgid="7689554147579179507">"Afficher les secondes sur l\'horloge"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Afficher les secondes dans la barre d\'état. Cela risque de réduire l\'autonomie de la batterie."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Réorganiser la fenêtre de configuration rapide"</string> + <string name="show_brightness" msgid="6613930842805942519">"Afficher la luminosité dans fenêtre de configuration rapide"</string> + <string name="qs_paging" msgid="7020133150248666132">"Utiliser mise en page dans fenêtre de configuration rapide"</string> + <string name="experimental" msgid="6198182315536726162">"Paramètres expérimentaux"</string> </resources> diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml index 951809fe1d8c..ec64f229ea4e 100644 --- a/packages/SystemUI/res/values-gl-rES/strings.xml +++ b/packages/SystemUI/res/values-gl-rES/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"A aplicación non está instalada no teu dispositivo"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do reloxo"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra os segundos do reloxo na barra de estado. Pode influír na duración da batería."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar Configuración rápida"</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostrar brillo en Configuración rápida"</string> + <string name="qs_paging" msgid="7020133150248666132">"Utilizar paxinación en Configuración rápida"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml index 02e4e5209892..e873c95f14f7 100644 --- a/packages/SystemUI/res/values-gu-rIN/strings.xml +++ b/packages/SystemUI/res/values-gu-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"તમારા ઉપકરણ પર એપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી"</string> <string name="clock_seconds" msgid="7689554147579179507">"ઘડિયાળ સેકન્ડ બતાવો"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"ઘડિયાળ સેકન્ડ સ્થિતિ બારમાં બતાવો. બૅટરીની આવરદા પર અસર કરી શકે છે."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ઝડપી સેટિંગ્સને ફરીથી ગોઠવો"</string> + <string name="show_brightness" msgid="6613930842805942519">"ઝડપી સેટિંગ્સમાં તેજ બતાવો"</string> + <string name="qs_paging" msgid="7020133150248666132">"ઝડપી સેટિંગ્સમાં પૃષ્ઠાંકનનો ઉપયોગ કરો"</string> + <string name="experimental" msgid="6198182315536726162">"પ્રાયોગિક"</string> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 3ed090c90111..83ac46eaf42d 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"ऐप्लिकेशन आपके डिवाइस पर इंस्टॉल नहीं है"</string> <string name="clock_seconds" msgid="7689554147579179507">"घड़ी के सेकंड दिखाएं"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"स्थिति बार में घड़ी के सेकंड दिखाएं. इससे बैटरी के जीवनकाल पर प्रभाव पड़ सकता है."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"त्वरित सेटिंग को पुन: व्यवस्थित करें"</string> + <string name="show_brightness" msgid="6613930842805942519">"त्वरित सेटिंग में स्क्रीन की रोशनी दिखाएं"</string> + <string name="qs_paging" msgid="7020133150248666132">"त्वरित सेटिंग में पेजिंग का उपयोग करें"</string> + <string name="experimental" msgid="6198182315536726162">"प्रयोगात्मक"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 9698abac2dc5..b5d993117334 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -436,4 +436,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikacija nije instalirana na vašem uređaju"</string> <string name="clock_seconds" msgid="7689554147579179507">"Prikaži sekunde na satu"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikazuju se sekunde na satu na traci statusa. Može utjecati na trajanje baterije."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Promijeni raspored Brzih postavki"</string> + <string name="show_brightness" msgid="6613930842805942519">"Prikaži svjetlinu u Brzim postavkama"</string> + <string name="qs_paging" msgid="7020133150248666132">"Upotrijebi redni broj stranice u Brzim postavkama"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimentalno"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 37cb0a81610f..79390a69990e 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Az alkalmazás nincs telepítve eszközén."</string> <string name="clock_seconds" msgid="7689554147579179507">"Másodpercek megjelenítése az órán"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Másodpercek megjelenítése az állapotsor óráján. Ez hatással lehet az akkumulátor üzemidejére."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Gyorsbeállítások átrendezése"</string> + <string name="show_brightness" msgid="6613930842805942519">"Fényerő megjelenítése a gyorsbeállításokban"</string> + <string name="qs_paging" msgid="7020133150248666132">"Oldalelrendezés használata a gyorsbeállításokban"</string> + <string name="experimental" msgid="6198182315536726162">"Kísérleti"</string> </resources> diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml index e31cf497199a..9f48b2618e3e 100644 --- a/packages/SystemUI/res/values-hy-rAM/strings.xml +++ b/packages/SystemUI/res/values-hy-rAM/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Հավելվածը տեղադրված չէ սարքի վրա"</string> <string name="clock_seconds" msgid="7689554147579179507">"Ցույց տալ ժամացույցի վայրկյանները"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Ցույց տալ ժամացույցի վայրկյանները կարգավիճակի տողում: Կարող է ազդել մարտկոցի աշխատանքի ժամանակի վրա:"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Վերադասավորել Արագ կարգավորումները"</string> + <string name="show_brightness" msgid="6613930842805942519">"Ցույց տալ պայծառությունն Արագ կարգավորումներում"</string> + <string name="qs_paging" msgid="7020133150248666132">"Օգտագործել էջերի դասավորությունը Արագ կարգավորումներում"</string> + <string name="experimental" msgid="6198182315536726162">"Փորձնական"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index ad8141bb2b34..600241151aab 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikasi tidak dipasang di perangkat"</string> <string name="clock_seconds" msgid="7689554147579179507">"Tampilkan detik jam"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Tampilkan detik jam di bilah status. Dapat memengaruhi masa pakai baterai."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Atur Ulang Setelan Cepat"</string> + <string name="show_brightness" msgid="6613930842805942519">"Tampilkan kecerahan di Setelan Cepat"</string> + <string name="qs_paging" msgid="7020133150248666132">"Gunakan pembagian laman di Setelan Cepat"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimental"</string> </resources> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index 02caf17e496c..e8e053090fda 100644 --- a/packages/SystemUI/res/values-is-rIS/strings.xml +++ b/packages/SystemUI/res/values-is-rIS/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Forritið er ekki uppsett í tækinu."</string> <string name="clock_seconds" msgid="7689554147579179507">"Sýna sekúndur á klukku"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Sýna sekúndur á klukku í stöðustikunni. Getur haft áhrif á endingu rafhlöðu."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Endurraða flýtistillingum"</string> + <string name="show_brightness" msgid="6613930842805942519">"Sýna birtustig í flýtistillingum"</string> + <string name="qs_paging" msgid="7020133150248666132">"Nota síðuskoðun í flýtistillingum"</string> + <string name="experimental" msgid="6198182315536726162">"Tilraunastillingar"</string> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index ab5d8beab1f9..8ee5f078a806 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Applicazione non installata sul dispositivo"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostra i secondi nell\'orologio"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra i secondi nell\'orologio nella barra di stato. Ciò potrebbe ridurre la durata della carica della batteria."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Riorganizza Impostazioni rapide"</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostra luminosità in Impostazioni rapide"</string> + <string name="qs_paging" msgid="7020133150248666132">"Utilizza nuovo layout in Impostazioni rapide"</string> + <string name="experimental" msgid="6198182315536726162">"Sperimentali"</string> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 9dad8aaf464f..e38501d5afb3 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -437,4 +437,12 @@ <string name="activity_not_found" msgid="348423244327799974">"האפליקציה אינה מותקנת במכשיר"</string> <string name="clock_seconds" msgid="7689554147579179507">"הצג שניות בשעון"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"הצג שניות בשעון בשורת הסטטוס. פעולה זו עשויה להשפיע על אורך חיי הסוללה."</string> + <!-- no translation found for qs_rearrange (8060918697551068765) --> + <skip /> + <!-- no translation found for show_brightness (6613930842805942519) --> + <skip /> + <!-- no translation found for qs_paging (7020133150248666132) --> + <skip /> + <!-- no translation found for experimental (6198182315536726162) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 9cb2fc856263..a73f4c1d9fc6 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"アプリが端末にインストールされていません"</string> <string name="clock_seconds" msgid="7689554147579179507">"時計の秒を表示"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"ステータスバーに時計の秒を表示します。電池使用量に影響する可能性があります。"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"クイック設定を並べ替え"</string> + <string name="show_brightness" msgid="6613930842805942519">"クイック設定に明るさ調整バーを表示する"</string> + <string name="qs_paging" msgid="7020133150248666132">"クイック設定でページ設定を使用する"</string> + <string name="experimental" msgid="6198182315536726162">"試験運用版"</string> </resources> diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml index a9728b25a6bd..f1035a8d8fc5 100644 --- a/packages/SystemUI/res/values-ka-rGE/strings.xml +++ b/packages/SystemUI/res/values-ka-rGE/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"აპლიკაცია თქვენს მოწყობილობაზე დაყენებული არ არის"</string> <string name="clock_seconds" msgid="7689554147579179507">"საათის წამების ჩვენება"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"საათის წამების ჩვენება სტატუსის ზოლში. შეიძლება გავლენა იქონიოს ბატარეაზე."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"სწრაფი პარამეტრების გადაწყობა"</string> + <string name="show_brightness" msgid="6613930842805942519">"სიკაშკაშის ჩვენება სწრაფ პარამეტრებში"</string> + <string name="qs_paging" msgid="7020133150248666132">"გამოიყენეთ გვერდების დანომვრა სწრაფ პარამეტრებში"</string> + <string name="experimental" msgid="6198182315536726162">"ექსპერიმენტული"</string> </resources> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml index 1d61372522aa..8b82e5fce6c9 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Қолданба құрылғыда орнатылмаған"</string> <string name="clock_seconds" msgid="7689554147579179507">"Сағат секундтарын көрсету"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Күйін көрсету жолағында сағат секундтарын көрсету. Батареяның қызмет көрсету мерзіміне әсер етуі мүмкін."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Жылдам параметрлерді қайта реттеу"</string> + <string name="show_brightness" msgid="6613930842805942519">"Жылдам параметрлерде жарықтықты көрсету"</string> + <string name="qs_paging" msgid="7020133150248666132">"Жылдам параметрлерде беттерді нөмірлеуді пайдалану"</string> + <string name="experimental" msgid="6198182315536726162">"Эксперименттік"</string> </resources> diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml index c233f83e2af7..b8db00f9067c 100644 --- a/packages/SystemUI/res/values-km-rKH/strings.xml +++ b/packages/SystemUI/res/values-km-rKH/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"កម្មវិធីមិនបានដំឡើងនៅលើឧបករណ៍របស់អ្នកទេ"</string> <string name="clock_seconds" msgid="7689554147579179507">"បង្ហាញវិនាទី"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"បង្ហាញវិនាទីនៅលើរបារស្ថានភាពអាចនឹងប៉ះពាល់ដល់ថាមពលថ្ម។"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"រៀបចំការកំណត់រហ័សឡើងវិញ"</string> + <string name="show_brightness" msgid="6613930842805942519">"បង្ហាញកម្រិតពន្លឺនៅក្នុងការកំណត់រហ័ស"</string> + <string name="qs_paging" msgid="7020133150248666132">"ប្រើការចុះទំព័រនៅក្នុងការកំណត់រហ័ស"</string> + <string name="experimental" msgid="6198182315536726162">"ពិសោធន៍"</string> </resources> diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml index d486e56a7266..316c04fe12a2 100644 --- a/packages/SystemUI/res/values-kn-rIN/strings.xml +++ b/packages/SystemUI/res/values-kn-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ"</string> <string name="clock_seconds" msgid="7689554147579179507">"ಗಡಿಯಾರದ ಸೆಕೆಂಡುಗಳನ್ನು ತೋರಿಸು"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಲ್ಲಿ ಗಡಿಯಾರ ಸೆಕೆಂಡುಗಳನ್ನು ತೋರಿಸು. ಇದಕ್ಕೆ ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯು ಪರಿಣಾಮಬೀರಬಹುದು."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮರುಹೊಂದಿಸಿ"</string> + <string name="show_brightness" msgid="6613930842805942519">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಪ್ರಖರತೆಯನ್ನು ತೋರಿಸಿ"</string> + <string name="qs_paging" msgid="7020133150248666132">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಪುಟಗಳನ್ನು ಬಳಸಿ"</string> + <string name="experimental" msgid="6198182315536726162">"ಪ್ರಾಯೋಗಿಕ"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 35057544cf8a..d7f1543a87d0 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"기기에 애플리케이션이 설치되어 있지 않습니다."</string> <string name="clock_seconds" msgid="7689554147579179507">"시계 초 단위 표시"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"상태 표시줄에 시계 초 단위를 표시합니다. 배터리 수명에 영향을 줄 수도 있습니다."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"빠른 설정 재정렬"</string> + <string name="show_brightness" msgid="6613930842805942519">"빠른 설정에서 밝기 표시"</string> + <string name="qs_paging" msgid="7020133150248666132">"빠른 설정에서 페이지 레이아웃 사용"</string> + <string name="experimental" msgid="6198182315536726162">"베타"</string> </resources> diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml index 968a65a76e5e..efe699b5519c 100644 --- a/packages/SystemUI/res/values-ky-rKG/strings.xml +++ b/packages/SystemUI/res/values-ky-rKG/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Колдонмо сиздин түзмөгүңүздө орнотулган эмес"</string> <string name="clock_seconds" msgid="7689554147579179507">"Сааттын секунддары көрсөтүлсүн"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Абал тилкесинен сааттын секунддары көрсөтүлсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Ыкчам жөндөөлөрдү кайра коюу"</string> + <string name="show_brightness" msgid="6613930842805942519">"Ыкчам жөндөөлөрдөн жарыктыгын көрсөтүү"</string> + <string name="qs_paging" msgid="7020133150248666132">"Ыкчам жөндөөлөрдөн баракты номерлөөнү колдонуу"</string> + <string name="experimental" msgid="6198182315536726162">"Сынамык"</string> </resources> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index f34c70eefbd4..50b4522caabf 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"ແອັບພລິເຄຊັນບໍ່ຖືກຕິດຕັ້ງຢູ່ໃນອຸປະກອນຂອງທ່ານ"</string> <string name="clock_seconds" msgid="7689554147579179507">"ສະແດງວິນາທີໂມງ"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"ສະແດງວິນາທີໂມງຢູ່ໃນແຖບສະຖານະ. ອາດຈະມີຜົນກະທົບຕໍ່ອາຍຸແບັດເຕີຣີ."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ຈັດວາງການຕັ້ງຄ່າດ່ວນຄືນໃໝ່"</string> + <string name="show_brightness" msgid="6613930842805942519">"ສະແດງຄວາມແຈ້ງຢູ່ໃນການຕັ້ງຄ່າດ່ວນ"</string> + <string name="qs_paging" msgid="7020133150248666132">"ໃຊ້ການໃສ່ໜ້າຢູ່ໃນການຕັ້ງຄ່າດ່ວນ"</string> + <string name="experimental" msgid="6198182315536726162">"ຍັງຢູ່ໃນການທົດລອງ"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index cf70d6bd5a31..90827785d109 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Programa neįdiegta įrenginyje"</string> <string name="clock_seconds" msgid="7689554147579179507">"Rodyti laikrodžio sekundes"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Rodyti laikrodžio sekundes būsenos juostoje. Tai gali paveikti akumuliatoriaus naudojimo laiką."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Pertvarkyti sparčiuosius nustatymus"</string> + <string name="show_brightness" msgid="6613930842805942519">"Rodyti skaistį sparčiuosiuose nustatymuose"</string> + <string name="qs_paging" msgid="7020133150248666132">"Naudoti puslapių kaitą sparčiuosiuose nustatymuose"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimentinė versija"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 5e2db80b9927..5fb4bb0c2f86 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -436,4 +436,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Lietojumprogramma nav instalēta jūsu ierīcē."</string> <string name="clock_seconds" msgid="7689554147579179507">"Rādīt pulksteņa sekundes"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Statusa joslā rādīt pulksteņa sekundes. Var ietekmēt akumulatora darbības laiku."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Pārkārtot ātros iestatījumus"</string> + <string name="show_brightness" msgid="6613930842805942519">"Rādīt spilgtumu ātrajos iestatījumos"</string> + <string name="qs_paging" msgid="7020133150248666132">"Izmantot lapošanu ātrajos iestatījumos"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimentāli"</string> </resources> diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml index fe781b6b3219..8571b3f441f1 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Апликацијата не е инсталирана на уредот"</string> <string name="clock_seconds" msgid="7689554147579179507">"Прикажи ги секундите на часовникот"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Прикажи ги секундите на часовникот на статусната лента. Може да влијае на траењето на батеријата."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Преуредете ги Брзи поставки"</string> + <string name="show_brightness" msgid="6613930842805942519">"Прикажете ја осветленоста во Брзи поставки"</string> + <string name="qs_paging" msgid="7020133150248666132">"Користете прелистување страници во Брзи поставки"</string> + <string name="experimental" msgid="6198182315536726162">"Експериментално"</string> </resources> diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml index 6e6fc55e0214..4b11962a91c4 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"നിങ്ങളുടെ ഉപകരണത്തിൽ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാൾ ചെയ്തിട്ടില്ല"</string> <string name="clock_seconds" msgid="7689554147579179507">"ക്ലോക്ക് സെക്കൻഡ് കാണിക്കുക"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"സ്റ്റാറ്റസ് ബാറിൽ ക്ലോക്ക് സെക്കൻഡ് കാണിക്കുന്നത് ബാറ്ററിയുടെ ലൈഫിനെ ബാധിക്കാം."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ദ്രുത ക്രമീകരണം പുനഃസജ്ജീകരിക്കുക"</string> + <string name="show_brightness" msgid="6613930842805942519">"ദ്രുത ക്രമീകരണത്തിൽ തെളിച്ചം കാണിക്കുക"</string> + <string name="qs_paging" msgid="7020133150248666132">"ദ്രുത്ര ക്രമീകരണത്തിൽ പേജിംഗ് ഉപയോഗിക്കുക"</string> + <string name="experimental" msgid="6198182315536726162">"പരീക്ഷണാത്മകം!"</string> </resources> diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml index 65250bbbec60..d1dbd6dbf2d4 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings.xml @@ -433,4 +433,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Апп-ыг таны төхөөрөмжид суулгаагүй байна"</string> <string name="clock_seconds" msgid="7689554147579179507">"Цагийн секундыг харуулах"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Статус талбарт цагийн секундыг харуулах. Энэ нь тэжээлийн цэнэгт нөлөөлж болно."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Түргэн тохиргоог дахин засварлах"</string> + <string name="show_brightness" msgid="6613930842805942519">"Түргэн тохиргоонд гэрэлтүүлэг харах"</string> + <string name="qs_paging" msgid="7020133150248666132">"Хуудаслалтыг түргэн тохиргоонд ашиглаарай"</string> + <string name="experimental" msgid="6198182315536726162">"Туршилтын"</string> </resources> diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml index 0f71b4bc446b..fe50f909bd1a 100644 --- a/packages/SystemUI/res/values-mr-rIN/strings.xml +++ b/packages/SystemUI/res/values-mr-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"अनुप्रयोग आपल्या डिव्हाइसवर स्थापित केलेला नाही"</string> <string name="clock_seconds" msgid="7689554147579179507">"घड्याळ सेकंद दर्शवा"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"स्टेटस बारमध्ये घड्याळ सेकंद दर्शवा. कदाचित बॅटरी आयुष्य प्रभावित होऊ शकते."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"दृत सेटिंग्जची पुनर्रचना करा"</string> + <string name="show_brightness" msgid="6613930842805942519">"दृत सेटिंग्जमध्ये चमक दर्शवा"</string> + <string name="qs_paging" msgid="7020133150248666132">"द्रुत सेटिंग्जमध्ये लिखाण वापरा"</string> + <string name="experimental" msgid="6198182315536726162">"प्रायोगिक"</string> </resources> diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml index 596275c6e058..01f7edfd6066 100644 --- a/packages/SystemUI/res/values-ms-rMY/strings.xml +++ b/packages/SystemUI/res/values-ms-rMY/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikasi tidak dipasang pada peranti anda"</string> <string name="clock_seconds" msgid="7689554147579179507">"Tunjukkan saat jam"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Tunjukkan saat jam dalam bar status. Mungkin menjejaskan hayat bateri."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Susun Semula Tetapan Pantas"</string> + <string name="show_brightness" msgid="6613930842805942519">"Tunjukkan kecerahan dalam Tetapan Pantas"</string> + <string name="qs_paging" msgid="7020133150248666132">"Gunakan penghalaman dalam Tetapan Pantas"</string> + <string name="experimental" msgid="6198182315536726162">"Percubaan"</string> </resources> diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml index 3147d0cc73f3..d0eaccfaf550 100644 --- a/packages/SystemUI/res/values-my-rMM/strings.xml +++ b/packages/SystemUI/res/values-my-rMM/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"အပလီကေးရှင်းကို သင်၏ ကိရိယာထဲသို့ တပ်ဆင်မပေးရသေးပါ။"</string> <string name="clock_seconds" msgid="7689554147579179507">"နာရီ စက္ကန့်များကို ပြရန်"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"အခြေအနေပြနေရာမှာ နာရီ စက္ကန့်များကို ပြပါ။ ဘက်ထရီ သက်တမ်းကို အကျိုးသက်ရောက်နိုင်တယ်။"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"အမြန် ဆက်တင်များကို ပြန်စီစဉ်ရန်"</string> + <string name="show_brightness" msgid="6613930842805942519">"အမြန် ဆက်တင်များထဲက တောက်ပမှုကို ပြရန်"</string> + <string name="qs_paging" msgid="7020133150248666132">"အမြန် ဆက်တင်များထဲတွင် စာမျက်နှာ ပုံစံချမှုကို အသုံးပြုပါ"</string> + <string name="experimental" msgid="6198182315536726162">"စမ်းသပ်ရေး"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index f1bfbe1d8a98..e582039142db 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Appen er ikke installert på enheten din"</string> <string name="clock_seconds" msgid="7689554147579179507">"Vis sekunder på klokken"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Vis sekunder i statusfeltet på klokken. Det kan påvirke batteritiden."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Omorganiser hurtiginnstillingene"</string> + <string name="show_brightness" msgid="6613930842805942519">"Vis lysstyrke i hurtiginnstillingene"</string> + <string name="qs_paging" msgid="7020133150248666132">"Bruk sidetall i hurtiginnstillingene"</string> + <string name="experimental" msgid="6198182315536726162">"På forsøksstadiet"</string> </resources> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 461a15f83173..c3dc703e72ad 100644 --- a/packages/SystemUI/res/values-ne-rNP/strings.xml +++ b/packages/SystemUI/res/values-ne-rNP/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"तपाईँको यन्त्रमा अनुप्रयोग स्थापना भएको छैन"</string> <string name="clock_seconds" msgid="7689554147579179507">"घडीमा सेकेन्ड देखाउनुहोस्"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"वस्तुस्थिति पट्टीको घडीमा सेकेन्ड देखाउनुहोस्। ब्याट्री आयु प्रभावित हुन सक्छ।"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"द्रुत सेटिङहरू पुनः व्यवस्थित गर्नुहोस्"</string> + <string name="show_brightness" msgid="6613930842805942519">"द्रुत सेटिङहरूमा उज्यालो देखाउनुहोस्"</string> + <string name="qs_paging" msgid="7020133150248666132">"द्रुत सेटिङहरूमा पेजिंग प्रयोग गर्नुहोस्"</string> + <string name="experimental" msgid="6198182315536726162">"प्रयोगात्मक"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index b74f91da327b..13f02d59fae0 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Deze app is niet geïnstalleerd op uw apparaat"</string> <string name="clock_seconds" msgid="7689554147579179507">"Klokseconden weergeven"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Klokseconden op de statusbalk weergeven. Kan van invloed zijn op de accuduur."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Snelle instellingen opnieuw indelen"</string> + <string name="show_brightness" msgid="6613930842805942519">"Helderheid weergeven in Snelle instellingen"</string> + <string name="qs_paging" msgid="7020133150248666132">"Paginering gebruiken in Snelle instellingen"</string> + <string name="experimental" msgid="6198182315536726162">"Experimenteel"</string> </resources> diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml index 06746ccf08b2..ef3d2f3585bd 100644 --- a/packages/SystemUI/res/values-pa-rIN/strings.xml +++ b/packages/SystemUI/res/values-pa-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"ਐਪਲੀਕੇਸ਼ਨ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਤੇ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ"</string> <string name="clock_seconds" msgid="7689554147579179507">"ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"ਸਥਿਤੀ ਬਾਰ ਵਿੱਚ ਘੜੀ ਸਕਿੰਟ ਦਿਖਾਓ। ਬੈਟਰੀ ਸਮਰੱਥਾ ਤੇ ਅਸਰ ਪੈ ਸਕਦਾ ਹੈ।"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਦੁਬਾਰਾ ਕ੍ਰਮ ਦਿਓ"</string> + <string name="show_brightness" msgid="6613930842805942519">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਮਕ ਦਿਖਾਓ"</string> + <string name="qs_paging" msgid="7020133150248666132">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਪੇਜਿੰਗ ਵਰਤੋ"</string> + <string name="experimental" msgid="6198182315536726162">"ਪ੍ਰਯੋਗਾਤਮਿਕ"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 66100c19045e..8c2c5c430213 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikacja nie jest zainstalowana na urządzeniu"</string> <string name="clock_seconds" msgid="7689554147579179507">"Pokaż sekundy na zegarku"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Pokaż sekundy na zegarku na pasku stanu. Może mieć wpływ na czas pracy baterii."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Uporządkuj Szybkie ustawienia"</string> + <string name="show_brightness" msgid="6613930842805942519">"Pokaż jasność w Szybkich ustawieniach"</string> + <string name="qs_paging" msgid="7020133150248666132">"Użyj stronicowania w Szybkich ustawieniach"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperymentalne"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 53cea01a3ce5..3803b812013d 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"O app não está instalado no seu dispositivo"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do relógio"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de status. Pode afetar a duração da bateria."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar \"Configurações rápidas\""</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostrar brilho nas \"Configurações rápidas\""</string> + <string name="qs_paging" msgid="7020133150248666132">"Usar paginação nas \"Configurações rápidas\""</string> + <string name="experimental" msgid="6198182315536726162">"Experimentais"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 50064137ac98..be42e8a72d53 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"A aplicação não está instalada no dispositivo"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do relógio"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de estado. Pode afetar a autonomia da bateria."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar Definições rápidas"</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostrar luminosidade nas Definições rápidas"</string> + <string name="qs_paging" msgid="7020133150248666132">"Utilizar paginação nas Definições rápidas"</string> + <string name="experimental" msgid="6198182315536726162">"Experimental"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 53cea01a3ce5..3803b812013d 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"O app não está instalado no seu dispositivo"</string> <string name="clock_seconds" msgid="7689554147579179507">"Mostrar segundos do relógio"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostrar segundos do relógio na barra de status. Pode afetar a duração da bateria."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Reorganizar \"Configurações rápidas\""</string> + <string name="show_brightness" msgid="6613930842805942519">"Mostrar brilho nas \"Configurações rápidas\""</string> + <string name="qs_paging" msgid="7020133150248666132">"Usar paginação nas \"Configurações rápidas\""</string> + <string name="experimental" msgid="6198182315536726162">"Experimentais"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index d97e16b820aa..bb8f2c3fe6b5 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -436,4 +436,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplicația nu este instalată pe dispozitiv"</string> <string name="clock_seconds" msgid="7689554147579179507">"Afișează secundele pe ceas"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Afișează secundele pe ceas în bara de stare. Poate afecta autonomia bateriei."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Rearanjați Setările rapide"</string> + <string name="show_brightness" msgid="6613930842805942519">"Afișați luminozitatea în Setările rapide"</string> + <string name="qs_paging" msgid="7020133150248666132">"Folosiți paginarea în Setările rapide"</string> + <string name="experimental" msgid="6198182315536726162">"Experimentale"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index d67ad389b4c2..9609f40bdff8 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -269,7 +269,7 @@ <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Нет сети"</string> <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi выкл."</string> <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Не удалось найти доступные сети Wi-Fi"</string> - <string name="quick_settings_cast_title" msgid="7709016546426454729">"Wi-Fi-монитор"</string> + <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляция"</string> <string name="quick_settings_casting" msgid="6601710681033353316">"Передача изображения"</string> <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Безымянное устройство"</string> <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Готово к передаче"</string> @@ -439,4 +439,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Приложение не установлено на вашем устройстве"</string> <string name="clock_seconds" msgid="7689554147579179507">"Показывать секунды"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Показывать в строке состояния время с точностью до секунды (заряд батареи может расходоваться быстрее)."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Изменить порядок Быстрых настроек"</string> + <string name="show_brightness" msgid="6613930842805942519">"Добавить яркость в Быстрые настройки"</string> + <string name="qs_paging" msgid="7020133150248666132">"Разбить Быстрые настройки на страницы"</string> + <string name="experimental" msgid="6198182315536726162">"Экспериментальная функция"</string> </resources> diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml index 06cb62644399..9e7883422230 100644 --- a/packages/SystemUI/res/values-si-rLK/strings.xml +++ b/packages/SystemUI/res/values-si-rLK/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"යෙදුම ඔබේ උපාංගය මත ස්ථාපනය කර නැත"</string> <string name="clock_seconds" msgid="7689554147579179507">"ඔරලෝසු තත්පර පෙන්වන්න"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"තත්ත්ව තීරුවෙහි ඔරලෝසු තත්පර පෙන්වන්න. බැටරි ආයු කාලයට බලපෑමට හැකිය."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"ඉක්මන් සැකසීම් යළි පිළිවෙළට සකසන්න"</string> + <string name="show_brightness" msgid="6613930842805942519">"ඉක්මන් සැකසීම්වල දීප්තිය පෙන්වන්න"</string> + <string name="qs_paging" msgid="7020133150248666132">"ඉක්මන් සැකසීම්වල පිටු පිරිසැලසුම් භාවිත කරන්න"</string> + <string name="experimental" msgid="6198182315536726162">"පරීක්ෂණාත්මක"</string> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 037074bab323..e3f0fb32c964 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -439,4 +439,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikácia nie je nainštalovaná na zariadení"</string> <string name="clock_seconds" msgid="7689554147579179507">"Zobraziť sekundy"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Zobrazí sekundy v stavovom riadku. Môže to ovplyvňovať výdrž batérie."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Zmeniť usporiadanie Rýchlych nastavení"</string> + <string name="show_brightness" msgid="6613930842805942519">"Zobraziť jas v Rýchlych nastaveniach"</string> + <string name="qs_paging" msgid="7020133150248666132">"Použite stránkovanie v Rýchlych nastaveniach"</string> + <string name="experimental" msgid="6198182315536726162">"Experimentálne"</string> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 31fe5d88027f..4dffcfa2bcd1 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikacija ni nameščena v napravi"</string> <string name="clock_seconds" msgid="7689554147579179507">"Prikaz sekund pri uri"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikaže sekunde pri uri v vrstici stanja. To lahko vpliva na čas delovanja pri akumulatorskem napajanju."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Preuredi hitre nastavitve"</string> + <string name="show_brightness" msgid="6613930842805942519">"Prikaz svetlosti v hitrih nastavitvah"</string> + <string name="qs_paging" msgid="7020133150248666132">"Uporaba postavitve strani v hitrih nastavitvah"</string> + <string name="experimental" msgid="6198182315536726162">"Poskusno"</string> </resources> diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml index ffb8bea66147..20c342638aaa 100644 --- a/packages/SystemUI/res/values-sq-rAL/strings.xml +++ b/packages/SystemUI/res/values-sq-rAL/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Aplikacioni nuk është instaluar në pajisjen tënde."</string> <string name="clock_seconds" msgid="7689554147579179507">"Trego sekondat e orës"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Trego sekondat e orës në shiritin e statusit. Mund të ndikojë te jeta e baterisë."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Risistemo Cilësimet e shpejta"</string> + <string name="show_brightness" msgid="6613930842805942519">"Shfaq ndriçimin te Cilësimet e shpejta"</string> + <string name="qs_paging" msgid="7020133150248666132">"Përdor faqosjen te Cilësimet e shpejta"</string> + <string name="experimental" msgid="6198182315536726162">"Eksperimentale"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index bae0284761c9..1dcde3a1b0bb 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -436,4 +436,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Апликација није инсталирана на уређају"</string> <string name="clock_seconds" msgid="7689554147579179507">"Приказуј секунде на сату"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Секунде на сату се приказују на статусној траци. То може да утиче на трајање батерије."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Преуреди Брза подешавања"</string> + <string name="show_brightness" msgid="6613930842805942519">"Прикажи осветљеност у Брзим подешавањима"</string> + <string name="qs_paging" msgid="7020133150248666132">"Користи листање страница у Брзим подешавањима"</string> + <string name="experimental" msgid="6198182315536726162">"Експериментално"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 6588f10a0135..0abeb1eb4d85 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Appen är inte installerad på enheten"</string> <string name="clock_seconds" msgid="7689554147579179507">"Visa klocksekunder"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Visa klocksekunder i statusfältet. Detta kan påverka batteritiden."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Ordna snabbinställningarna"</string> + <string name="show_brightness" msgid="6613930842805942519">"Visa ljusstyrka i snabbinställningarna"</string> + <string name="qs_paging" msgid="7020133150248666132">"Använd sidindelning i snabbinställningarna"</string> + <string name="experimental" msgid="6198182315536726162">"Experimentella"</string> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 623f12cac3d4..d000004c530a 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Programu haijasakinishwa kwenye kifaa chako"</string> <string name="clock_seconds" msgid="7689554147579179507">"Onyesha sekunde za saa"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Onyesha sekunde za saa katika sehemu ya arifa. Inaweza kuathiri muda wa matumizi ya betri."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Panga Upya Mipangilio ya Haraka"</string> + <string name="show_brightness" msgid="6613930842805942519">"Onyesha unga\'avu katika Mipangilio ya Haraka"</string> + <string name="qs_paging" msgid="7020133150248666132">"Tumia nambari za ukurasa katika Mipangilio ya Haraka"</string> + <string name="experimental" msgid="6198182315536726162">"Ya majaribio"</string> </resources> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index c6cb337e7d4d..7b1ded375bac 100644 --- a/packages/SystemUI/res/values-ta-rIN/strings.xml +++ b/packages/SystemUI/res/values-ta-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"சாதனத்தில் பயன்பாடு நிறுவப்படவில்லை"</string> <string name="clock_seconds" msgid="7689554147579179507">"கடிகார வினாடிகளைக் காட்டு"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"நிலைப் பட்டியில் கடிகார வினாடிகளைக் காட்டும். பேட்டரியின் ஆயுளைக் குறைக்கலாம்."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"விரைவு அமைப்புகளை மறுவரிசைப்படுத்து"</string> + <string name="show_brightness" msgid="6613930842805942519">"விரைவு அமைப்புகளில் ஒளிர்வுப் பட்டியைக் காட்டு"</string> + <string name="qs_paging" msgid="7020133150248666132">"விரைவு அமைப்புகளில் புதிய பக்கத் தளவமைப்பைப் பயன்படுத்து"</string> + <string name="experimental" msgid="6198182315536726162">"சோதனை முயற்சி"</string> </resources> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index c0717c1fd90c..06762bd7ef4e 100644 --- a/packages/SystemUI/res/values-te-rIN/strings.xml +++ b/packages/SystemUI/res/values-te-rIN/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"అనువర్తనం మీ పరికరంలో ఇన్స్టాల్ చేయలేదు"</string> <string name="clock_seconds" msgid="7689554147579179507">"గడియారం సెకన్లు చూపు"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"స్థితి పట్టీలో గడియారం సెకన్లు చూపుతుంది. బ్యాటరీ శక్తి ప్రభావితం చేయవచ్చు."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"శీఘ్ర సెట్టింగ్ల ఏర్పాటు క్రమం మార్చు"</string> + <string name="show_brightness" msgid="6613930842805942519">"శీఘ్ర సెట్టింగ్ల్లో ప్రకాశం చూపు"</string> + <string name="qs_paging" msgid="7020133150248666132">"శీఘ్ర సెట్టింగ్ల్లో పేజింగ్ను ఉపయోగించు"</string> + <string name="experimental" msgid="6198182315536726162">"ప్రయోగాత్మకం"</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index e16fdd2cccae..52c7af7f2f27 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"ยังไม่ได้ติดตั้งแอปพลิเคชันบนอุปกรณ์ของคุณ"</string> <string name="clock_seconds" msgid="7689554147579179507">"แสดงวินาทีของนาฬิกา"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"แสดงวินาทีของนาฬิกาในแถบสถานะ อาจส่งผลต่ออายุแบตเตอรี"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"จัดเรียงการตั้งค่าด่วนใหม่"</string> + <string name="show_brightness" msgid="6613930842805942519">"แสดงความสว่างในการตั้งค่าด่วน"</string> + <string name="qs_paging" msgid="7020133150248666132">"ใช้การแบ่งหน้าในการตั้งค่าด่วน"</string> + <string name="experimental" msgid="6198182315536726162">"ทดสอบ"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index d970084ca02f..66056d10dc64 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Hindi naka-install ang application sa iyong device"</string> <string name="clock_seconds" msgid="7689554147579179507">"Ipakita ang mga segundo ng orasan"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Ipakita ang mga segundo ng orasan sa status bar. Maaaring makaapekto sa tagal ng baterya."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Ayusing Muli ang Mga Mabilisang Setting"</string> + <string name="show_brightness" msgid="6613930842805942519">"Ipakita ang liwanag sa Mga Mabilisang Setting"</string> + <string name="qs_paging" msgid="7020133150248666132">"Gamitin ang paging sa Mga Mabilisang Setting"</string> + <string name="experimental" msgid="6198182315536726162">"Pang-eksperimento"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index b22b4fbc7eb8..fdad0d554a54 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Uygulama, cihazınızda yüklü değil"</string> <string name="clock_seconds" msgid="7689554147579179507">"Saatin saniyelerini göster"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Durum çubuğunda saatin saniyelerini gösterir. Pil ömrünü etkileyebilir."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Hızlı Ayarlar\'ı Yeniden Düzenle"</string> + <string name="show_brightness" msgid="6613930842805942519">"Hızlı Ayarlar\'da parlaklığı göster"</string> + <string name="qs_paging" msgid="7020133150248666132">"Hızlı Ayarlar\'da sayfa ayırmayı kullan"</string> + <string name="experimental" msgid="6198182315536726162">"Deneysel"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 898611d38c87..9dde80178d2d 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Додаток не встановлено на вашому пристрої"</string> <string name="clock_seconds" msgid="7689554147579179507">"Показувати секунди на годиннику"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Показувати секунди на годиннику в рядку стану. Акумулятор може розряджатися швидше."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Упорядкувати швидкі налаштування"</string> + <string name="show_brightness" msgid="6613930842805942519">"Показувати панель яскравості у швидких налаштуваннях"</string> + <string name="qs_paging" msgid="7020133150248666132">"Показувати швидкі налаштування у вигляді сторінок"</string> + <string name="experimental" msgid="6198182315536726162">"Експериментальні налаштування"</string> </resources> diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml index d5683e1daecc..a4ef16acae62 100644 --- a/packages/SystemUI/res/values-ur-rPK/strings.xml +++ b/packages/SystemUI/res/values-ur-rPK/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"ایپلیکیشن آپ کے آلہ پر انسٹال نہیں ہے"</string> <string name="clock_seconds" msgid="7689554147579179507">"گھڑی کے سیکنڈز دکھائیں"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"گھڑی کے سیکنڈز اسٹیٹس بار میں دکھائیں۔ اس کا بیٹری کی زندگی پر اثر پڑ سکتا ہے۔"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"فوری ترتیبات کو دوبارہ ترتیب دیں"</string> + <string name="show_brightness" msgid="6613930842805942519">"فوری ترتیبات میں چمکیلا پن دکھائیں"</string> + <string name="qs_paging" msgid="7020133150248666132">"فوری ترتیبات میں پیجنگ استعمال کریں"</string> + <string name="experimental" msgid="6198182315536726162">"تجرباتی"</string> </resources> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml index e31af6b44342..118c4b8a6968 100644 --- a/packages/SystemUI/res/values-uz-rUZ/strings.xml +++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Ilova qurilmangizga o‘rnatilmagan"</string> <string name="clock_seconds" msgid="7689554147579179507">"Soat soniyalari ko‘rsatilsin"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Holat panelida soat soniyalari ko‘rsatilsin. Bu batareya resursiga ta’sir qilishi mumkin."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Tezkor sozlamalarni qayta tartiblash"</string> + <string name="show_brightness" msgid="6613930842805942519">"Tezkor sozlamalarda yorqinlikni ko‘rsatish"</string> + <string name="qs_paging" msgid="7020133150248666132">"Tezkor sozlamalarda peyjingdan foydalanish"</string> + <string name="experimental" msgid="6198182315536726162">"Tajribaviy"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 030bbbe7ec70..460d57ae4410 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Ứng dụng chưa được cài đặt trên thiết bị của bạn"</string> <string name="clock_seconds" msgid="7689554147579179507">"Hiển thị giây đồng hồ"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Hiển thị giây đồng hồ trong thanh trạng thái. Có thể ảnh hưởng đến thời lượng pin."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Sắp xếp lại Cài đặt nhanh"</string> + <string name="show_brightness" msgid="6613930842805942519">"Hiển thị độ sáng trong Cài đặt nhanh"</string> + <string name="qs_paging" msgid="7020133150248666132">"Sử dụng đánh số trang trong Cài đặt nhanh"</string> + <string name="experimental" msgid="6198182315536726162">"Thử nghiệm"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index b046415bac2c..05644e70be6e 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -437,4 +437,12 @@ <string name="activity_not_found" msgid="348423244327799974">"您的设备中未安装此应用"</string> <string name="clock_seconds" msgid="7689554147579179507">"显示时钟的秒数"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"在状态栏中显示时钟的秒数。这可能会影响电池的续航时间。"</string> + <!-- no translation found for qs_rearrange (8060918697551068765) --> + <skip /> + <!-- no translation found for show_brightness (6613930842805942519) --> + <skip /> + <!-- no translation found for qs_paging (7020133150248666132) --> + <skip /> + <!-- no translation found for experimental (6198182315536726162) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index d568dba45d2d..f7cac90e1522 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"尚未在裝置安裝應用程式"</string> <string name="clock_seconds" msgid="7689554147579179507">"顯示時鐘秒數"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"在狀態列中顯示時鐘秒數,但可能會影響電池壽命。"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"重新排列快速設定"</string> + <string name="show_brightness" msgid="6613930842805942519">"在快速設定顯示亮度"</string> + <string name="qs_paging" msgid="7020133150248666132">"在快速設定使用分頁"</string> + <string name="experimental" msgid="6198182315536726162">"實驗版"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 702ad53449e4..369172f36836 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -437,4 +437,8 @@ <string name="activity_not_found" msgid="348423244327799974">"您的裝置未安裝這個應用程式"</string> <string name="clock_seconds" msgid="7689554147579179507">"顯示時鐘秒數"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"在狀態列中顯示時鐘秒數。這可能會影響電池續航力。"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"重新排列快速設定"</string> + <string name="show_brightness" msgid="6613930842805942519">"在快速設定中顯示亮度"</string> + <string name="qs_paging" msgid="7020133150248666132">"在快速設定中使用分頁功能"</string> + <string name="experimental" msgid="6198182315536726162">"實驗性"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 8774036f4749..2a14a9f2b6d4 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -435,4 +435,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Uhlelo lokusebenza alufakiwe kudivayisi yakho"</string> <string name="clock_seconds" msgid="7689554147579179507">"Bonisa amasekhondi wewashi"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Bonisa amasekhondi wewashi kubha yesimo. Ingathinta impilo yebhethri."</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Hlela kabusha izilungiselelo ezisheshayo"</string> + <string name="show_brightness" msgid="6613930842805942519">"Bonisa ukukhanya kuzilungiselelo ezisheshayo"</string> + <string name="qs_paging" msgid="7020133150248666132">"Sebenzisa i-paging kuzilungiselelo ezisheshayo"</string> + <string name="experimental" msgid="6198182315536726162">"Okokulinga"</string> </resources> diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java index fda6479e2d56..92e6814c42d1 100644 --- a/services/core/java/com/android/server/SystemServiceManager.java +++ b/services/core/java/com/android/server/SystemServiceManager.java @@ -17,6 +17,7 @@ package com.android.server; import android.content.Context; +import android.os.Trace; import android.util.Slog; import java.lang.reflect.Constructor; @@ -75,43 +76,48 @@ public class SystemServiceManager { */ @SuppressWarnings("unchecked") public <T extends SystemService> T startService(Class<T> serviceClass) { - final String name = serviceClass.getName(); - Slog.i(TAG, "Starting " + name); - - // Create the service. - if (!SystemService.class.isAssignableFrom(serviceClass)) { - throw new RuntimeException("Failed to create " + name - + ": service must extend " + SystemService.class.getName()); - } - final T service; try { - Constructor<T> constructor = serviceClass.getConstructor(Context.class); - service = constructor.newInstance(mContext); - } catch (InstantiationException ex) { - throw new RuntimeException("Failed to create service " + name - + ": service could not be instantiated", ex); - } catch (IllegalAccessException ex) { - throw new RuntimeException("Failed to create service " + name - + ": service must have a public constructor with a Context argument", ex); - } catch (NoSuchMethodException ex) { - throw new RuntimeException("Failed to create service " + name - + ": service must have a public constructor with a Context argument", ex); - } catch (InvocationTargetException ex) { - throw new RuntimeException("Failed to create service " + name - + ": service constructor threw an exception", ex); - } + final String name = serviceClass.getName(); + Slog.i(TAG, "Starting " + name); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name); + + // Create the service. + if (!SystemService.class.isAssignableFrom(serviceClass)) { + throw new RuntimeException("Failed to create " + name + + ": service must extend " + SystemService.class.getName()); + } + final T service; + try { + Constructor<T> constructor = serviceClass.getConstructor(Context.class); + service = constructor.newInstance(mContext); + } catch (InstantiationException ex) { + throw new RuntimeException("Failed to create service " + name + + ": service could not be instantiated", ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException("Failed to create service " + name + + ": service must have a public constructor with a Context argument", ex); + } catch (NoSuchMethodException ex) { + throw new RuntimeException("Failed to create service " + name + + ": service must have a public constructor with a Context argument", ex); + } catch (InvocationTargetException ex) { + throw new RuntimeException("Failed to create service " + name + + ": service constructor threw an exception", ex); + } - // Register it. - mServices.add(service); + // Register it. + mServices.add(service); - // Start it. - try { - service.onStart(); - } catch (RuntimeException ex) { - throw new RuntimeException("Failed to start service " + name - + ": onStart threw an exception", ex); + // Start it. + try { + service.onStart(); + } catch (RuntimeException ex) { + throw new RuntimeException("Failed to start service " + name + + ": onStart threw an exception", ex); + } + return service; + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } - return service; } /** @@ -127,18 +133,22 @@ public class SystemServiceManager { mCurrentPhase = phase; Slog.i(TAG, "Starting phase " + mCurrentPhase); - - final int serviceLen = mServices.size(); - for (int i = 0; i < serviceLen; i++) { - final SystemService service = mServices.get(i); - try { - service.onBootPhase(mCurrentPhase); - } catch (Exception ex) { - throw new RuntimeException("Failed to boot service " - + service.getClass().getName() - + ": onBootPhase threw an exception during phase " - + mCurrentPhase, ex); + try { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase); + final int serviceLen = mServices.size(); + for (int i = 0; i < serviceLen; i++) { + final SystemService service = mServices.get(i); + try { + service.onBootPhase(mCurrentPhase); + } catch (Exception ex) { + throw new RuntimeException("Failed to boot service " + + service.getClass().getName() + + ": onBootPhase threw an exception during phase " + + mCurrentPhase, ex); + } } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c0ffb56bca98..09ac7d913c9e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -215,6 +215,7 @@ import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.Trace; import android.os.UpdateLock; import android.os.UserHandle; import android.os.UserManager; @@ -1885,7 +1886,9 @@ public final class ActivityManagerService extends ActivityManagerNative } case FINISH_BOOTING_MSG: { if (msg.arg1 != 0) { + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); finishBooting(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } if (msg.arg2 != 0) { enableScreenAfterBoot(); @@ -6450,7 +6453,9 @@ public final class ActivityManagerService extends ActivityManagerNative mBootAnimationComplete = true; } if (callFinishBooting) { + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); finishBooting(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } @@ -6465,7 +6470,9 @@ public final class ActivityManagerService extends ActivityManagerNative } if (booting) { + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); finishBooting(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } if (enableScreen) { diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java index 5c60a610e392..239c471d2859 100644 --- a/services/core/java/com/android/server/location/GpsLocationProvider.java +++ b/services/core/java/com/android/server/location/GpsLocationProvider.java @@ -434,8 +434,11 @@ public class GpsLocationProvider implements LocationProviderInterface { private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action); + if (action == null) { + return; + } + if (action.equals(ALARM_WAKEUP)) { startNavigating(false); } else if (action.equals(ALARM_TIMEOUT)) { @@ -490,21 +493,27 @@ public class GpsLocationProvider implements LocationProviderInterface { private void checkSmsSuplInit(Intent intent) { SmsMessage[] messages = Intents.getMessagesFromIntent(intent); - if (messages == null) { Log.e(TAG, "Message does not exist in the intent."); return; } - for (int i=0; i <messages.length; i++) { - byte[] supl_init = messages[i].getUserData(); - native_agps_ni_message(supl_init,supl_init.length); + for (SmsMessage message : messages) { + if (message != null && message.mWrappedSmsMessage != null) { + byte[] suplInit = message.getUserData(); + if (suplInit != null) { + native_agps_ni_message(suplInit, suplInit.length); + } + } } } private void checkWapSuplInit(Intent intent) { - byte[] supl_init = (byte[]) intent.getExtra("data"); - native_agps_ni_message(supl_init,supl_init.length); + byte[] suplInit = intent.getByteArrayExtra("data"); + if (suplInit == null) { + return; + } + native_agps_ni_message(suplInit,suplInit.length); } private void updateLowPowerMode() { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 21dd647b6785..aafaf8373cf8 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -38,6 +38,7 @@ import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.Trace; import android.os.UserHandle; import android.os.storage.IMountService; import android.util.DisplayMetrics; @@ -175,97 +176,103 @@ public final class SystemServer { } private void run() { - // If a device's clock is before 1970 (before 0), a lot of - // APIs crash dealing with negative numbers, notably - // java.io.File#setLastModified, so instead we fake it and - // hope that time from cell towers or NTP fixes it shortly. - if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { - Slog.w(TAG, "System clock is before 1970; setting to 1970."); - SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); - } + try { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices"); + // If a device's clock is before 1970 (before 0), a lot of + // APIs crash dealing with negative numbers, notably + // java.io.File#setLastModified, so instead we fake it and + // hope that time from cell towers or NTP fixes it shortly. + if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { + Slog.w(TAG, "System clock is before 1970; setting to 1970."); + SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); + } - // If the system has "persist.sys.language" and friends set, replace them with - // "persist.sys.locale". Note that the default locale at this point is calculated - // using the "-Duser.locale" command line flag. That flag is usually populated by - // AndroidRuntime using the same set of system properties, but only the system_server - // and system apps are allowed to set them. - // - // NOTE: Most changes made here will need an equivalent change to - // core/jni/AndroidRuntime.cpp - if (!SystemProperties.get("persist.sys.language").isEmpty()) { - final String languageTag = Locale.getDefault().toLanguageTag(); - - SystemProperties.set("persist.sys.locale", languageTag); - SystemProperties.set("persist.sys.language", ""); - SystemProperties.set("persist.sys.country", ""); - SystemProperties.set("persist.sys.localevar", ""); - } + // If the system has "persist.sys.language" and friends set, replace them with + // "persist.sys.locale". Note that the default locale at this point is calculated + // using the "-Duser.locale" command line flag. That flag is usually populated by + // AndroidRuntime using the same set of system properties, but only the system_server + // and system apps are allowed to set them. + // + // NOTE: Most changes made here will need an equivalent change to + // core/jni/AndroidRuntime.cpp + if (!SystemProperties.get("persist.sys.language").isEmpty()) { + final String languageTag = Locale.getDefault().toLanguageTag(); + + SystemProperties.set("persist.sys.locale", languageTag); + SystemProperties.set("persist.sys.language", ""); + SystemProperties.set("persist.sys.country", ""); + SystemProperties.set("persist.sys.localevar", ""); + } - // Here we go! - Slog.i(TAG, "Entered the Android system server!"); - EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); - - // In case the runtime switched since last boot (such as when - // the old runtime was removed in an OTA), set the system - // property so that it is in sync. We can't do this in - // libnativehelper's JniInvocation::Init code where we already - // had to fallback to a different runtime because it is - // running as root and we need to be the system user to set - // the property. http://b/11463182 - SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); - - // Enable the sampling profiler. - if (SamplingProfilerIntegration.isEnabled()) { - SamplingProfilerIntegration.start(); - mProfilerSnapshotTimer = new Timer(); - mProfilerSnapshotTimer.schedule(new TimerTask() { - @Override - public void run() { - SamplingProfilerIntegration.writeSnapshot("system_server", null); - } - }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); - } + // Here we go! + Slog.i(TAG, "Entered the Android system server!"); + EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); + + // In case the runtime switched since last boot (such as when + // the old runtime was removed in an OTA), set the system + // property so that it is in sync. We can't do this in + // libnativehelper's JniInvocation::Init code where we already + // had to fallback to a different runtime because it is + // running as root and we need to be the system user to set + // the property. http://b/11463182 + SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); + + // Enable the sampling profiler. + if (SamplingProfilerIntegration.isEnabled()) { + SamplingProfilerIntegration.start(); + mProfilerSnapshotTimer = new Timer(); + mProfilerSnapshotTimer.schedule(new TimerTask() { + @Override + public void run() { + SamplingProfilerIntegration.writeSnapshot("system_server", null); + } + }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); + } - // Mmmmmm... more memory! - VMRuntime.getRuntime().clearGrowthLimit(); + // Mmmmmm... more memory! + VMRuntime.getRuntime().clearGrowthLimit(); - // The system server has to run all of the time, so it needs to be - // as efficient as possible with its memory usage. - VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); + // The system server has to run all of the time, so it needs to be + // as efficient as possible with its memory usage. + VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); - // Some devices rely on runtime fingerprint generation, so make sure - // we've defined it before booting further. - Build.ensureFingerprintProperty(); + // Some devices rely on runtime fingerprint generation, so make sure + // we've defined it before booting further. + Build.ensureFingerprintProperty(); - // Within the system server, it is an error to access Environment paths without - // explicitly specifying a user. - Environment.setUserRequired(true); + // Within the system server, it is an error to access Environment paths without + // explicitly specifying a user. + Environment.setUserRequired(true); - // Ensure binder calls into the system always run at foreground priority. - BinderInternal.disableBackgroundScheduling(true); + // Ensure binder calls into the system always run at foreground priority. + BinderInternal.disableBackgroundScheduling(true); - // Prepare the main looper thread (this thread). - android.os.Process.setThreadPriority( + // Prepare the main looper thread (this thread). + android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); - android.os.Process.setCanSelfBackground(false); - Looper.prepareMainLooper(); + android.os.Process.setCanSelfBackground(false); + Looper.prepareMainLooper(); - // Initialize native services. - System.loadLibrary("android_servers"); + // Initialize native services. + System.loadLibrary("android_servers"); - // Check whether we failed to shut down last time we tried. - // This call may not return. - performPendingShutdown(); + // Check whether we failed to shut down last time we tried. + // This call may not return. + performPendingShutdown(); - // Initialize the system context. - createSystemContext(); + // Initialize the system context. + createSystemContext(); - // Create the system service manager. - mSystemServiceManager = new SystemServiceManager(mSystemContext); - LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); + // Create the system service manager. + mSystemServiceManager = new SystemServiceManager(mSystemContext); + LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } // Start services. try { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices"); startBootstrapServices(); startCoreServices(); startOtherServices(); @@ -273,6 +280,8 @@ public final class SystemServer { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // For debug builds, log event loop stalls to dropbox for analysis. @@ -340,7 +349,9 @@ public final class SystemServer { // Now that the power manager has been started, let the activity manager // initialize power management features. + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement"); mActivityManagerService.initPowerManagement(); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // Manages LEDs and display backlight so we need it to bring up the display. mSystemServiceManager.startService(LightsService.class); @@ -363,14 +374,16 @@ public final class SystemServer { } // Start the package manager. - Slog.i(TAG, "Package Manager"); + traceBeginAndSlog("StartPackageManagerService"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "User Service"); + traceBeginAndSlog("StartUserManagerService"); ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // Initialize attribute cache used to cache resources from packages. AttributeCache.init(mSystemContext); @@ -442,17 +455,20 @@ public final class SystemServer { Slog.i(TAG, "Reading configuration..."); SystemConfig.getInstance(); - Slog.i(TAG, "Scheduling Policy"); + traceBeginAndSlog("StartSchedulingPolicyService"); ServiceManager.addService("scheduling_policy", new SchedulingPolicyService()); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mSystemServiceManager.startService(TelecomLoaderService.class); - Slog.i(TAG, "Telephony Registry"); + traceBeginAndSlog("StartTelephonyRegistry"); telephonyRegistry = new TelephonyRegistry(context); ServiceManager.addService("telephony.registry", telephonyRegistry); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "Entropy Mixer"); + traceBeginAndSlog("StartEntropyMixer"); entropyMixer = new EntropyMixer(context); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mContentResolver = context.getContentResolver(); @@ -460,47 +476,55 @@ public final class SystemServer { mSystemServiceManager.startService(CameraService.class); // The AccountManager must come before the ContentService + traceBeginAndSlog("StartAccountManagerService"); try { // TODO: seems like this should be disable-able, but req'd by ContentService - Slog.i(TAG, "Account Manager"); accountManager = new AccountManagerService(context); ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager); } catch (Throwable e) { Slog.e(TAG, "Failure starting Account Manager", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "Content Manager"); + traceBeginAndSlog("StartContentService"); contentService = ContentService.main(context, mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "System Content Providers"); + traceBeginAndSlog("InstallSystemProviders"); mActivityManagerService.installSystemProviders(); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "Vibrator Service"); + traceBeginAndSlog("StartVibratorService"); vibrator = new VibratorService(context); ServiceManager.addService("vibrator", vibrator); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "Consumer IR Service"); + traceBeginAndSlog("StartConsumerIrService"); consumerIr = new ConsumerIrService(context); ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mSystemServiceManager.startService(AlarmManagerService.class); alarm = IAlarmManager.Stub.asInterface( ServiceManager.getService(Context.ALARM_SERVICE)); - Slog.i(TAG, "Init Watchdog"); + traceBeginAndSlog("InitWatchdog"); final Watchdog watchdog = Watchdog.getInstance(); watchdog.init(context, mActivityManagerService); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "Input Manager"); + traceBeginAndSlog("StartInputManagerService"); inputManager = new InputManagerService(context); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Slog.i(TAG, "Window Manager"); + traceBeginAndSlog("StartWindowManagerService"); wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mActivityManagerService.setWindowManager(wm); @@ -523,7 +547,6 @@ public final class SystemServer { } else if (disableBluetooth) { Slog.i(TAG, "Bluetooth Service disabled by config"); } else { - Slog.i(TAG, "Bluetooth Service"); mSystemServiceManager.startService(BluetoothService.class); } } catch (RuntimeException e) { @@ -544,21 +567,23 @@ public final class SystemServer { // Bring up services needed for UI. if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) { + traceBeginAndSlog("StartInputMethodManagerService"); try { - Slog.i(TAG, "Input Method Service"); imm = new InputMethodManagerService(context); ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm); } catch (Throwable e) { reportWtf("starting Input Manager Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + traceBeginAndSlog("StartAccessibilityManagerService"); try { - Slog.i(TAG, "Accessibility Manager"); ServiceManager.addService(Context.ACCESSIBILITY_SERVICE, new AccessibilityManagerService(context)); } catch (Throwable e) { reportWtf("starting Accessibility Manager", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } try { @@ -588,11 +613,13 @@ public final class SystemServer { // as appropriate. mSystemServiceManager.startService(UiModeManagerService.class); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PerformBootDexOpt"); try { mPackageManagerService.performBootDexOpt(); } catch (Throwable e) { reportWtf("performing boot dexopt", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); try { ActivityManagerNative.getDefault().showBootMessage( @@ -604,13 +631,14 @@ public final class SystemServer { if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) { if (!disableNonCoreServices) { + traceBeginAndSlog("StartLockSettingsService"); try { - Slog.i(TAG, "LockSettingsService"); lockSettings = new LockSettingsService(context); ServiceManager.addService("lock_settings", lockSettings); } catch (Throwable e) { reportWtf("starting LockSettingsService service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); if (!SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("")) { mSystemServiceManager.startService(PersistentDataBlockService.class); @@ -624,64 +652,70 @@ public final class SystemServer { } if (!disableSystemUI) { + traceBeginAndSlog("StartStatusBarManagerService"); try { - Slog.i(TAG, "Status Bar"); statusBar = new StatusBarManagerService(context, wm); ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar); } catch (Throwable e) { reportWtf("starting StatusBarManagerService", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNonCoreServices) { + traceBeginAndSlog("StartClipboardService"); try { - Slog.i(TAG, "Clipboard Service"); ServiceManager.addService(Context.CLIPBOARD_SERVICE, new ClipboardService(context)); } catch (Throwable e) { reportWtf("starting Clipboard Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNetwork) { + traceBeginAndSlog("StartNetworkManagementService"); try { - Slog.i(TAG, "NetworkManagement Service"); networkManagement = NetworkManagementService.create(context); ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement); } catch (Throwable e) { reportWtf("starting NetworkManagement Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNonCoreServices) { + traceBeginAndSlog("StartTextServicesManagerService"); try { - Slog.i(TAG, "Text Service Manager Service"); tsms = new TextServicesManagerService(context); ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms); } catch (Throwable e) { reportWtf("starting Text Service Manager Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNetwork) { + traceBeginAndSlog("StartNetworkScoreService"); try { - Slog.i(TAG, "Network Score Service"); networkScore = new NetworkScoreService(context); ServiceManager.addService(Context.NETWORK_SCORE_SERVICE, networkScore); } catch (Throwable e) { reportWtf("starting Network Score Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + traceBeginAndSlog("StartNetworkStatsService"); try { - Slog.i(TAG, "NetworkStats Service"); networkStats = new NetworkStatsService(context, networkManagement, alarm); ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats); } catch (Throwable e) { reportWtf("starting NetworkStats Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + traceBeginAndSlog("StartNetworkPolicyManagerService"); try { - Slog.i(TAG, "NetworkPolicy Service"); networkPolicy = new NetworkPolicyManagerService( context, mActivityManagerService, (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE), @@ -690,6 +724,7 @@ public final class SystemServer { } catch (Throwable e) { reportWtf("starting NetworkPolicy Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS); mSystemServiceManager.startService(WIFI_SERVICE_CLASS); @@ -703,8 +738,8 @@ public final class SystemServer { mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS); } + traceBeginAndSlog("StartConnectivityService"); try { - Slog.i(TAG, "Connectivity Service"); connectivity = new ConnectivityService( context, networkManagement, networkStats, networkPolicy); ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity); @@ -713,25 +748,28 @@ public final class SystemServer { } catch (Throwable e) { reportWtf("starting Connectivity Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + traceBeginAndSlog("StartNsdService"); try { - Slog.i(TAG, "Network Service Discovery Service"); serviceDiscovery = NsdService.create(context); ServiceManager.addService( Context.NSD_SERVICE, serviceDiscovery); } catch (Throwable e) { reportWtf("starting Service Discovery Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNonCoreServices) { + traceBeginAndSlog("StartUpdateLockService"); try { - Slog.i(TAG, "UpdateLock Service"); ServiceManager.addService(Context.UPDATE_LOCK_SERVICE, new UpdateLockService(context)); } catch (Throwable e) { reportWtf("starting UpdateLockService", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } /* @@ -740,25 +778,31 @@ public final class SystemServer { * first before continuing. */ if (mountService != null && !mOnlyCore) { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "WaitForAsecScan"); try { mountService.waitForAsecScan(); } catch (RemoteException ignored) { } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeAccountManagerServiceReady"); try { if (accountManager != null) accountManager.systemReady(); } catch (Throwable e) { reportWtf("making Account Manager Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeContentServiceReady"); try { if (contentService != null) contentService.systemReady(); } catch (Throwable e) { reportWtf("making Content Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mSystemServiceManager.startService(NotificationManagerService.class); notification = INotificationManager.Stub.asInterface( @@ -768,66 +812,72 @@ public final class SystemServer { mSystemServiceManager.startService(DeviceStorageMonitorService.class); if (!disableLocation) { + traceBeginAndSlog("StartLocationManagerService"); try { - Slog.i(TAG, "Location Manager"); location = new LocationManagerService(context); ServiceManager.addService(Context.LOCATION_SERVICE, location); } catch (Throwable e) { reportWtf("starting Location Manager", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + traceBeginAndSlog("StartCountryDetectorService"); try { - Slog.i(TAG, "Country Detector"); countryDetector = new CountryDetectorService(context); ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector); } catch (Throwable e) { reportWtf("starting Country Detector", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNonCoreServices) { + traceBeginAndSlog("StartSearchManagerService"); try { - Slog.i(TAG, "Search Service"); ServiceManager.addService(Context.SEARCH_SERVICE, new SearchManagerService(context)); } catch (Throwable e) { reportWtf("starting Search Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } mSystemServiceManager.startService(DropBoxManagerService.class); if (!disableNonCoreServices && context.getResources().getBoolean( R.bool.config_enableWallpaperService)) { + traceBeginAndSlog("StartWallpaperManagerService"); try { - Slog.i(TAG, "Wallpaper Service"); wallpaper = new WallpaperManagerService(context); ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper); } catch (Throwable e) { reportWtf("starting Wallpaper Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } + traceBeginAndSlog("StartAudioService"); try { - Slog.i(TAG, "Audio Service"); audioService = new AudioService(context); ServiceManager.addService(Context.AUDIO_SERVICE, audioService); } catch (Throwable e) { reportWtf("starting Audio Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); if (!disableNonCoreServices) { mSystemServiceManager.startService(DockObserver.class); } + traceBeginAndSlog("StartWiredAccessoryManager"); try { - Slog.i(TAG, "Wired Accessory Manager"); // Listen for wired headset changes inputManager.setWiredAccessoryCallbacks( new WiredAccessoryManager(context, inputManager)); } catch (Throwable e) { reportWtf("starting WiredAccessoryManager", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); if (!disableNonCoreServices) { if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_MIDI)) { @@ -839,17 +889,20 @@ public final class SystemServer { || mPackageManager.hasSystemFeature( PackageManager.FEATURE_USB_ACCESSORY)) { // Manage USB host and device support + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartUsbService"); mSystemServiceManager.startService(USB_SERVICE_CLASS); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } + traceBeginAndSlog("StartSerialService"); try { - Slog.i(TAG, "Serial Service"); // Serial port support serial = new SerialService(context); ServiceManager.addService(Context.SERIAL_SERVICE, serial); } catch (Throwable e) { Slog.e(TAG, "Failure starting SerialService", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } mSystemServiceManager.startService(TwilightService.class); @@ -875,49 +928,54 @@ public final class SystemServer { } } + traceBeginAndSlog("StartDiskStatsService"); try { - Slog.i(TAG, "DiskStats Service"); ServiceManager.addService("diskstats", new DiskStatsService(context)); } catch (Throwable e) { reportWtf("starting DiskStats Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + traceBeginAndSlog("StartSamplingProfilerService"); try { // need to add this service even if SamplingProfilerIntegration.isEnabled() // is false, because it is this service that detects system property change and // turns on SamplingProfilerIntegration. Plus, when sampling profiler doesn't work, // there is little overhead for running this service. - Slog.i(TAG, "SamplingProfiler Service"); ServiceManager.addService("samplingprofiler", new SamplingProfilerService(context)); } catch (Throwable e) { reportWtf("starting SamplingProfiler Service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); if (!disableNetwork && !disableNetworkTime) { + traceBeginAndSlog("StartNetworkTimeUpdateService"); try { - Slog.i(TAG, "NetworkTimeUpdateService"); networkTimeUpdater = new NetworkTimeUpdateService(context); } catch (Throwable e) { reportWtf("starting NetworkTimeUpdate service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } + traceBeginAndSlog("StartCommonTimeManagementService"); try { - Slog.i(TAG, "CommonTimeManagementService"); commonTimeMgmtService = new CommonTimeManagementService(context); ServiceManager.addService("commontime_management", commonTimeMgmtService); } catch (Throwable e) { reportWtf("starting CommonTimeManagementService service", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); if (!disableNetwork) { + traceBeginAndSlog("CertBlacklister"); try { - Slog.i(TAG, "CertBlacklister"); CertBlacklister blacklister = new CertBlacklister(context); } catch (Throwable e) { reportWtf("starting CertBlacklister", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNonCoreServices) { @@ -926,13 +984,14 @@ public final class SystemServer { } if (!disableNonCoreServices && ZygoteInit.PRELOAD_RESOURCES) { + traceBeginAndSlog("StartAssetAtlasService"); try { - Slog.i(TAG, "Assets Atlas Service"); atlas = new AssetAtlasService(context); ServiceManager.addService(AssetAtlasService.ASSET_ATLAS_SERVICE, atlas); } catch (Throwable e) { reportWtf("starting AssetAtlasService", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } if (!disableNonCoreServices) { @@ -957,24 +1016,26 @@ public final class SystemServer { } if (!disableNonCoreServices) { + traceBeginAndSlog("StartMediaRouterService"); try { - Slog.i(TAG, "Media Router Service"); mediaRouter = new MediaRouterService(context); ServiceManager.addService(Context.MEDIA_ROUTER_SERVICE, mediaRouter); } catch (Throwable e) { reportWtf("starting MediaRouterService", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mSystemServiceManager.startService(TrustManagerService.class); mSystemServiceManager.startService(FingerprintService.class); + traceBeginAndSlog("StartBackgroundDexOptService"); try { - Slog.i(TAG, "BackgroundDexOptService"); BackgroundDexOptService.schedule(context, 0); } catch (Throwable e) { reportWtf("starting BackgroundDexOptService", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } @@ -1002,12 +1063,15 @@ public final class SystemServer { // It is now time to start up the app processes... + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeVibratorServiceReady"); try { vibrator.systemReady(); } catch (Throwable e) { reportWtf("making Vibrator Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeLockSettingsServiceReady"); if (lockSettings != null) { try { lockSettings.systemReady(); @@ -1015,17 +1079,20 @@ public final class SystemServer { reportWtf("making Lock Settings Service ready", e); } } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // Needed by DevicePolicyManager for initialization mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeWindowManagerServiceReady"); try { wm.systemReady(); } catch (Throwable e) { reportWtf("making Window Manager Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); if (safeMode) { mActivityManagerService.showSafeModeOverlay(); @@ -1046,25 +1113,32 @@ public final class SystemServer { systemTheme.rebase(); } + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakePowerManagerServiceReady"); try { // TODO: use boot phase mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService()); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } catch (Throwable e) { reportWtf("making Power Manager Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakePackageManagerServiceReady"); try { mPackageManagerService.systemReady(); } catch (Throwable e) { reportWtf("making Package Manager Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeDisplayManagerServiceReady"); try { // TODO: use boot phase and communicate these flags some other way mDisplayManagerService.systemReady(safeMode, mOnlyCore); } catch (Throwable e) { reportWtf("making Display Manager Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); // These are needed to propagate to the runnable below. final NetworkManagementService networkManagementF = networkManagement; @@ -1098,55 +1172,76 @@ public final class SystemServer { Slog.i(TAG, "Making services ready"); mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PhaseActivityManagerReady"); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartObservingNativeCrashes"); try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); Slog.i(TAG, "WebViewFactory preparation"); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "WebViewFactoryPreparation"); WebViewFactory.prepareWebViewInSystemServer(); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI"); try { startSystemUi(context); } catch (Throwable e) { reportWtf("starting System UI", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeMountServiceReady"); try { if (networkScoreF != null) networkScoreF.systemReady(); } catch (Throwable e) { reportWtf("making Network Score Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeNetworkManagementServiceReady"); try { if (networkManagementF != null) networkManagementF.systemReady(); } catch (Throwable e) { reportWtf("making Network Managment Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeNetworkStatsServiceReady"); try { if (networkStatsF != null) networkStatsF.systemReady(); } catch (Throwable e) { reportWtf("making Network Stats Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeNetworkPolicyServiceReady"); try { if (networkPolicyF != null) networkPolicyF.systemReady(); } catch (Throwable e) { reportWtf("making Network Policy Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeConnectivityServiceReady"); try { if (connectivityF != null) connectivityF.systemReady(); } catch (Throwable e) { reportWtf("making Connectivity Service ready", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeAudioServiceReady"); try { if (audioServiceF != null) audioServiceF.systemReady(); } catch (Throwable e) { reportWtf("Notifying AudioService running", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); Watchdog.getInstance().start(); // It is now okay to let the various system services start their // third party code... + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PhaseThirdPartyAppsCanStart"); mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); @@ -1215,6 +1310,7 @@ public final class SystemServer { } catch (Throwable e) { reportWtf("Notifying MmsService running", e); } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } }); } @@ -1226,4 +1322,9 @@ public final class SystemServer { //Slog.d(TAG, "Starting service: " + intent); context.startServiceAsUser(intent, UserHandle.SYSTEM); } + + private static void traceBeginAndSlog(String name) { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, name); + Slog.i(TAG, name); + } } diff --git a/tests/SurfaceComposition/Android.mk b/tests/SurfaceComposition/Android.mk new file mode 100644 index 000000000000..95f69f179c20 --- /dev/null +++ b/tests/SurfaceComposition/Android.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2015 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +# Don't include this package in any target +LOCAL_MODULE_TAGS := tests +# When built, explicitly put it in the data partition. +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) + +LOCAL_DEX_PREOPT := false + +LOCAL_PROGUARD_ENABLED := disabled + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := SurfaceComposition + +LOCAL_SDK_VERSION := current + +include $(BUILD_PACKAGE) diff --git a/tests/SurfaceComposition/AndroidManifest.xml b/tests/SurfaceComposition/AndroidManifest.xml new file mode 100644 index 000000000000..4c0a9b61fd8f --- /dev/null +++ b/tests/SurfaceComposition/AndroidManifest.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2015 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.surfacecomposition"> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <application android:theme="@style/noeffects"> + <uses-library android:name="android.test.runner" /> + <activity android:name="android.surfacecomposition.SurfaceCompositionMeasuringActivity" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <uses-library android:name="android.test.runner" /> + </application> + + <!-- self-instrumenting test package. --> + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="android.surfacecomposition"> + </instrumentation> +</manifest> diff --git a/tests/SurfaceComposition/res/values/themes.xml b/tests/SurfaceComposition/res/values/themes.xml new file mode 100644 index 000000000000..254d707134aa --- /dev/null +++ b/tests/SurfaceComposition/res/values/themes.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + --> +<resources> + <style name="noeffects" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen"> + <item name="android:windowNoTitle">true</item> + <item name="android:windowFullscreen">true</item> + <item name="android:fadingEdge">none</item> + <item name="android:windowContentTransitions">false</item> + <item name="android:windowAnimationStyle">@null</item> + </style> +</resources> diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/CustomLayout.java b/tests/SurfaceComposition/src/android/surfacecomposition/CustomLayout.java new file mode 100644 index 000000000000..d626f10b42cb --- /dev/null +++ b/tests/SurfaceComposition/src/android/surfacecomposition/CustomLayout.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.surfacecomposition; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +public class CustomLayout extends ViewGroup { + public CustomLayout(Context context) { + super(context); + } + + public static class LayoutParams extends ViewGroup.LayoutParams { + private int mLeft, mTop, mRight, mBottom; + + public LayoutParams(int left, int top, int right, int bottom) { + super(0, 0); + mLeft = left; + mTop = top; + mRight = right; + mBottom = bottom; + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + View child = getChildAt(i); + CustomLayout.LayoutParams lp = (CustomLayout.LayoutParams) child.getLayoutParams(); + child.layout(lp.mLeft, lp.mTop, lp.mRight, lp.mBottom); + } + } +} diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/CustomSurfaceView.java b/tests/SurfaceComposition/src/android/surfacecomposition/CustomSurfaceView.java new file mode 100644 index 000000000000..0430662873cf --- /dev/null +++ b/tests/SurfaceComposition/src/android/surfacecomposition/CustomSurfaceView.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.surfacecomposition; + +import java.util.Random; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * This provides functionality to measure Surface update frame rate. The idea is to + * constantly invalidates Surface in a separate thread. Lowest possible way is to + * use SurfaceView which works with Surface. This gives a very small overhead + * and very close to Android internals. Note, that lockCanvas is blocking + * methods and it returns once SurfaceFlinger consumes previous buffer. This + * gives the change to measure real performance of Surface compositor. + */ +public class CustomSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + private final static long DURATION_TO_WARMUP_MS = 50; + private final static long DURATION_TO_MEASURE_ROUGH_MS = 500; + private final static long DURATION_TO_MEASURE_PRECISE_MS = 3000; + private final static Random mRandom = new Random(); + + private final Object mSurfaceLock = new Object(); + private Surface mSurface; + private boolean mDrawNameOnReady = true; + private boolean mSurfaceWasChanged = false; + private String mName; + private Canvas mCanvas; + + class ValidateThread extends Thread { + private double mFPS = 0.0f; + // Used to support early exit and prevent long computation. + private double mBadFPS; + private double mPerfectFPS; + + ValidateThread(double badFPS, double perfectFPS) { + mBadFPS = badFPS; + mPerfectFPS = perfectFPS; + } + + public void run() { + long startTime = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTime < DURATION_TO_WARMUP_MS) { + invalidateSurface(false); + } + + startTime = System.currentTimeMillis(); + long endTime; + int frameCnt = 0; + while (true) { + invalidateSurface(false); + endTime = System.currentTimeMillis(); + ++frameCnt; + mFPS = (double)frameCnt * 1000.0 / (endTime - startTime); + if ((endTime - startTime) >= DURATION_TO_MEASURE_ROUGH_MS) { + // Test if result looks too bad or perfect and stop early. + if (mFPS <= mBadFPS || mFPS >= mPerfectFPS) { + break; + } + } + if ((endTime - startTime) >= DURATION_TO_MEASURE_PRECISE_MS) { + break; + } + } + } + + public double getFPS() { + return mFPS; + } + } + + public CustomSurfaceView(Context context, String name) { + super(context); + mName = name; + getHolder().addCallback(this); + } + + public void setMode(int pixelFormat, boolean drawNameOnReady) { + mDrawNameOnReady = drawNameOnReady; + getHolder().setFormat(pixelFormat); + } + + public void acquireCanvas() { + synchronized (mSurfaceLock) { + if (mCanvas != null) { + throw new RuntimeException("Surface canvas was already acquired."); + } + if (mSurface != null) { + mCanvas = mSurface.lockCanvas(null); + } + } + } + + public void releaseCanvas() { + synchronized (mSurfaceLock) { + if (mCanvas != null) { + if (mSurface == null) { + throw new RuntimeException( + "Surface was destroyed but canvas was not released."); + } + mSurface.unlockCanvasAndPost(mCanvas); + mCanvas = null; + } + } + } + + /** + * Invalidate surface. + */ + private void invalidateSurface(boolean drawSurfaceId) { + synchronized (mSurfaceLock) { + if (mSurface != null) { + Canvas canvas = mSurface.lockCanvas(null); + // Draw surface name for debug purpose only. This does not affect the test + // because it is drawn only during allocation. + if (drawSurfaceId) { + int textSize = canvas.getHeight() / 24; + Paint paint = new Paint(); + paint.setTextSize(textSize); + int textWidth = (int)(paint.measureText(mName) + 0.5f); + int x = mRandom.nextInt(canvas.getWidth() - textWidth); + int y = textSize + mRandom.nextInt(canvas.getHeight() - textSize); + // Create effect of fog to visually control correctness of composition. + paint.setColor(0xFFFF8040); + canvas.drawARGB(32, 255, 255, 255); + canvas.drawText(mName, x, y, paint); + } + mSurface.unlockCanvasAndPost(canvas); + } + } + } + + /** + * Wait until surface is created and ready to use or return immediately if surface + * already exists. + */ + public void waitForSurfaceReady() { + synchronized (mSurfaceLock) { + if (mSurface == null) { + try { + mSurfaceLock.wait(5000); + } catch(InterruptedException e) { + e.printStackTrace(); + } + } + if (mSurface == null) + throw new RuntimeException("Surface is not ready."); + mSurfaceWasChanged = false; + } + } + + /** + * Wait until surface is destroyed or return immediately if surface does not exist. + */ + public void waitForSurfaceDestroyed() { + synchronized (mSurfaceLock) { + if (mSurface != null) { + try { + mSurfaceLock.wait(5000); + } catch(InterruptedException e) { + e.printStackTrace(); + } + } + if (mSurface != null) + throw new RuntimeException("Surface still exists."); + mSurfaceWasChanged = false; + } + } + + /** + * Validate that surface has not been changed since waitForSurfaceReady or + * waitForSurfaceDestroyed. + */ + public void validateSurfaceNotChanged() { + synchronized (mSurfaceLock) { + if (mSurfaceWasChanged) { + throw new RuntimeException("Surface was changed during the test execution."); + } + } + } + + public double measureFPS(double badFPS, double perfectFPS) { + try { + ValidateThread validateThread = new ValidateThread(badFPS, perfectFPS); + validateThread.start(); + validateThread.join(); + return validateThread.getFPS(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + synchronized (mSurfaceLock) { + mSurfaceWasChanged = true; + } + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + // This method is always called at least once, after surfaceCreated. + synchronized (mSurfaceLock) { + mSurface = holder.getSurface(); + // We only need to invalidate the surface for the compositor performance test so that + // it gets included in the composition process. For allocation performance we + // don't need to invalidate surface and this allows us to remove non-necessary + // surface invalidation from the test. + if (mDrawNameOnReady) { + invalidateSurface(true); + } + mSurfaceWasChanged = true; + mSurfaceLock.notify(); + } + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + synchronized (mSurfaceLock) { + mSurface = null; + mSurfaceWasChanged = true; + mSurfaceLock.notify(); + } + } +} diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/MemoryAccessTask.java b/tests/SurfaceComposition/src/android/surfacecomposition/MemoryAccessTask.java new file mode 100644 index 000000000000..c716daee2fa6 --- /dev/null +++ b/tests/SurfaceComposition/src/android/surfacecomposition/MemoryAccessTask.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.surfacecomposition; + +import android.util.Log; + +/** + * This task will simulate CPU activity by consuming memory bandwidth from the system. + * Note: On most system the CPU and GPU will share the same memory. + */ +public class MemoryAccessTask { + private final static String TAG = "MemoryAccessTask"; + private final static int BUFFER_SIZE = 32 * 1024 * 1024; + private final static int BUFFER_STEP = 256; + private boolean mStopRequested; + private WorkThread mThread; + private final Object mLock = new Object(); + + public class WorkThread extends Thread { + public void run() { + byte[] memory = new byte[BUFFER_SIZE]; + while (true) { + synchronized (mLock) { + if (mStopRequested) { + break; + } + } + long result = 0; + for (int index = 0; index < BUFFER_SIZE; index += BUFFER_STEP) { + result += ++memory[index]; + } + Log.v(TAG, "Processing...:" + result); + } + } + } + + public void start() { + if (mThread != null) { + throw new RuntimeException("Work thread is already started"); + } + mStopRequested = false; + mThread = new WorkThread(); + mThread.start(); + } + + public void stop() { + if (mThread != null) { + synchronized (mLock) { + mStopRequested = true; + } + try { + mThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionMeasuringActivity.java b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionMeasuringActivity.java new file mode 100644 index 000000000000..e3e1d34f193e --- /dev/null +++ b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionMeasuringActivity.java @@ -0,0 +1,602 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.surfacecomposition; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +import android.app.ActionBar; +import android.app.Activity; +import android.app.ActivityManager; +import android.app.ActivityManager.MemoryInfo; +import android.content.Context; +import android.graphics.Color; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.Display; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.Spinner; +import android.widget.TextView; + +/** + * This activity is designed to measure peformance scores of Android surfaces. + * It can work in two modes. In first mode functionality of this activity is + * invoked from Cts test (SurfaceCompositionTest). This activity can also be + * used in manual mode as a normal app. Different pixel formats are supported. + * + * measureCompositionScore(pixelFormat) + * This test measures surface compositor performance which shows how many + * surfaces of specific format surface compositor can combine without dropping + * frames. We allow one dropped frame per half second. + * + * measureAllocationScore(pixelFormat) + * This test measures surface allocation/deallocation performance. It shows + * how many surface lifecycles (creation, destruction) can be done per second. + * + * In manual mode, which activated by pressing button 'Compositor speed' or + * 'Allocator speed', all possible pixel format are tested and combined result + * is displayed in text view. Additional system information such as memory + * status, display size and surface format is also displayed and regulary + * updated. + */ +public class SurfaceCompositionMeasuringActivity extends Activity implements OnClickListener { + private final static int MIN_NUMBER_OF_SURFACES = 15; + private final static int MAX_NUMBER_OF_SURFACES = 40; + private final static int WARM_UP_ALLOCATION_CYCLES = 2; + private final static int MEASURE_ALLOCATION_CYCLES = 5; + private final static int TEST_COMPOSITOR = 1; + private final static int TEST_ALLOCATION = 2; + private final static float MIN_REFRESH_RATE_SUPPORTED = 50.0f; + + private final static DecimalFormat DOUBLE_FORMAT = new DecimalFormat("#.00"); + // Possible selection in pixel format selector. + private final static int[] PIXEL_FORMATS = new int[] { + PixelFormat.TRANSLUCENT, + PixelFormat.TRANSPARENT, + PixelFormat.OPAQUE, + PixelFormat.RGBA_8888, + PixelFormat.RGBX_8888, + PixelFormat.RGB_888, + PixelFormat.RGB_565, + }; + + + private List<CustomSurfaceView> mViews = new ArrayList<CustomSurfaceView>(); + private Button mMeasureCompositionButton; + private Button mMeasureAllocationButton; + private Spinner mPixelFormatSelector; + private TextView mResultView; + private TextView mSystemInfoView; + private final Object mLockResumed = new Object(); + private boolean mResumed; + + // Drop one frame per half second. + // TODO(khmel) + // Add a feature flag and set the target FPS dependent on the target system as e.g.: + // 59FPS for MULTI_WINDOW and 54 otherwise (to satisfy the default lax Android requirements). + private double mRefreshRate; + private double mTargetFPS; + + private int mWidth; + private int mHeight; + + class CompositorScore { + double mSurfaces; + double mBitrate; + + @Override + public String toString() { + return DOUBLE_FORMAT.format(mSurfaces) + " surfaces. " + + "Bitrate: " + getReadableMemory((long)mBitrate) + "/s"; + } + } + + /** + * Measure performance score. + * + * @return biggest possible number of visible surfaces which surface + * compositor can handle. + */ + public CompositorScore measureCompositionScore(int pixelFormat) { + waitForActivityResumed(); + //MemoryAccessTask memAccessTask = new MemoryAccessTask(); + //memAccessTask.start(); + // Destroy any active surface. + configureSurfacesAndWait(0, pixelFormat, false); + CompositorScore score = new CompositorScore(); + score.mSurfaces = measureCompositionScore(new Measurement(0, 60.0), + new Measurement(mViews.size() + 1, 0.0f), pixelFormat); + // Assume 32 bits per pixel. + score.mBitrate = score.mSurfaces * mTargetFPS * mWidth * mHeight * 4.0; + //memAccessTask.stop(); + return score; + } + + static class AllocationScore { + double mMedian; + double mMin; + double mMax; + + @Override + public String toString() { + return DOUBLE_FORMAT.format(mMedian) + " (min:" + DOUBLE_FORMAT.format(mMin) + + ", max:" + DOUBLE_FORMAT.format(mMax) + ") surface allocations per second"; + } + } + + public AllocationScore measureAllocationScore(int pixelFormat) { + waitForActivityResumed(); + AllocationScore score = new AllocationScore(); + for (int i = 0; i < MEASURE_ALLOCATION_CYCLES + WARM_UP_ALLOCATION_CYCLES; ++i) { + long time1 = System.currentTimeMillis(); + configureSurfacesAndWait(MIN_NUMBER_OF_SURFACES, pixelFormat, false); + acquireSurfacesCanvas(); + long time2 = System.currentTimeMillis(); + releaseSurfacesCanvas(); + configureSurfacesAndWait(0, pixelFormat, false); + // Give SurfaceFlinger some time to rebuild the layer stack and release the buffers. + try { + Thread.sleep(500); + } catch(InterruptedException e) { + e.printStackTrace(); + } + if (i < WARM_UP_ALLOCATION_CYCLES) { + // This is warm-up cycles, ignore result so far. + continue; + } + double speed = MIN_NUMBER_OF_SURFACES * 1000.0 / (time2 - time1); + score.mMedian += speed / MEASURE_ALLOCATION_CYCLES; + if (i == WARM_UP_ALLOCATION_CYCLES) { + score.mMin = speed; + score.mMax = speed; + } else { + score.mMin = Math.min(score.mMin, speed); + score.mMax = Math.max(score.mMax, speed); + } + } + + return score; + } + + @Override + public void onClick(View view) { + if (view == mMeasureCompositionButton) { + doTest(TEST_COMPOSITOR); + } else if (view == mMeasureAllocationButton) { + doTest(TEST_ALLOCATION); + } + } + + private void doTest(final int test) { + enableControls(false); + final int pixelFormat = PIXEL_FORMATS[mPixelFormatSelector.getSelectedItemPosition()]; + new Thread() { + public void run() { + final StringBuffer sb = new StringBuffer(); + switch (test) { + case TEST_COMPOSITOR: { + sb.append("Compositor score:"); + CompositorScore score = measureCompositionScore(pixelFormat); + sb.append("\n " + getPixelFormatInfo(pixelFormat) + ":" + + score + "."); + } + break; + case TEST_ALLOCATION: { + sb.append("Allocation score:"); + AllocationScore score = measureAllocationScore(pixelFormat); + sb.append("\n " + getPixelFormatInfo(pixelFormat) + ":" + + score + "."); + } + break; + } + runOnUiThreadAndWait(new Runnable() { + public void run() { + mResultView.setText(sb.toString()); + enableControls(true); + updateSystemInfo(pixelFormat); + } + }); + } + }.start(); + } + + /** + * Wait until activity is resumed. + */ + public void waitForActivityResumed() { + synchronized (mLockResumed) { + if (!mResumed) { + try { + mLockResumed.wait(10000); + } catch (InterruptedException e) { + } + } + if (!mResumed) { + throw new RuntimeException("Activity was not resumed"); + } + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + detectRefreshRate(); + + // To layouts in parent. First contains list of Surfaces and second + // controls. Controls stay on top. + RelativeLayout rootLayout = new RelativeLayout(this); + rootLayout.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + + CustomLayout layout = new CustomLayout(this); + layout.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + + Rect rect = new Rect(); + getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); + mWidth = rect.right; + mHeight = rect.bottom; + long maxMemoryPerSurface = roundToNextPowerOf2(mWidth) * roundToNextPowerOf2(mHeight) * 4; + // Use 75% of available memory. + int surfaceCnt = (int)((getMemoryInfo().availMem * 3) / (4 * maxMemoryPerSurface)); + if (surfaceCnt < MIN_NUMBER_OF_SURFACES) { + throw new RuntimeException("Not enough memory to allocate " + + MIN_NUMBER_OF_SURFACES + " surfaces."); + } + if (surfaceCnt > MAX_NUMBER_OF_SURFACES) { + surfaceCnt = MAX_NUMBER_OF_SURFACES; + } + + LinearLayout controlLayout = new LinearLayout(this); + controlLayout.setOrientation(LinearLayout.VERTICAL); + controlLayout.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + + mMeasureCompositionButton = createButton("Compositor speed.", controlLayout); + mMeasureAllocationButton = createButton("Allocation speed", controlLayout); + + String[] pixelFomats = new String[PIXEL_FORMATS.length]; + for (int i = 0; i < pixelFomats.length; ++i) { + pixelFomats[i] = getPixelFormatInfo(PIXEL_FORMATS[i]); + } + mPixelFormatSelector = new Spinner(this); + ArrayAdapter<String> pixelFormatSelectorAdapter = + new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, pixelFomats); + pixelFormatSelectorAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + mPixelFormatSelector.setAdapter(pixelFormatSelectorAdapter); + mPixelFormatSelector.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + controlLayout.addView(mPixelFormatSelector); + + mResultView = new TextView(this); + mResultView.setBackgroundColor(0); + mResultView.setText("Press button to start test."); + mResultView.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + controlLayout.addView(mResultView); + + mSystemInfoView = new TextView(this); + mSystemInfoView.setBackgroundColor(0); + mSystemInfoView.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + controlLayout.addView(mSystemInfoView); + + for (int i = 0; i < surfaceCnt; ++i) { + CustomSurfaceView view = new CustomSurfaceView(this, "Surface:" + i); + // Create all surfaces overlapped in order to prevent SurfaceFlinger + // to filter out surfaces by optimization in case surface is opaque. + // In case surface is transparent it will be drawn anyway. Note that first + // surface covers whole screen and must stand below other surfaces. Z order of + // layers is not predictable and there is only one way to force first + // layer to be below others is to mark it as media and all other layers + // to mark as media overlay. + if (i == 0) { + view.setLayoutParams(new CustomLayout.LayoutParams(0, 0, mWidth, mHeight)); + view.setZOrderMediaOverlay(false); + } else { + // Z order of other layers is not predefined so make offset on x and reverse + // offset on y to make sure that surface is visible in any layout. + int x = i; + int y = (surfaceCnt - i); + view.setLayoutParams(new CustomLayout.LayoutParams(x, y, x + mWidth, y + mHeight)); + view.setZOrderMediaOverlay(true); + } + view.setVisibility(View.INVISIBLE); + layout.addView(view); + mViews.add(view); + } + + rootLayout.addView(layout); + rootLayout.addView(controlLayout); + + setContentView(rootLayout); + } + + private Button createButton(String caption, LinearLayout layout) { + Button button = new Button(this); + button.setText(caption); + button.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + button.setOnClickListener(this); + layout.addView(button); + return button; + } + + private void enableControls(boolean enabled) { + mMeasureCompositionButton.setEnabled(enabled); + mMeasureAllocationButton.setEnabled(enabled); + mPixelFormatSelector.setEnabled(enabled); + } + + @Override + protected void onResume() { + super.onResume(); + + updateSystemInfo(PixelFormat.UNKNOWN); + + synchronized (mLockResumed) { + mResumed = true; + mLockResumed.notifyAll(); + } + } + + @Override + protected void onPause() { + super.onPause(); + + synchronized (mLockResumed) { + mResumed = false; + } + } + + class Measurement { + Measurement(int surfaceCnt, double fps) { + mSurfaceCnt = surfaceCnt; + mFPS = fps; + } + + public final int mSurfaceCnt; + public final double mFPS; + } + + private double measureCompositionScore(Measurement ok, Measurement fail, int pixelFormat) { + if (ok.mSurfaceCnt + 1 == fail.mSurfaceCnt) { + // Interpolate result. + double fraction = (mTargetFPS - fail.mFPS) / (ok.mFPS - fail.mFPS); + return ok.mSurfaceCnt + fraction; + } + + int medianSurfaceCnt = (ok.mSurfaceCnt + fail.mSurfaceCnt) / 2; + Measurement median = new Measurement(medianSurfaceCnt, + measureFPS(medianSurfaceCnt, pixelFormat)); + + if (median.mFPS >= mTargetFPS) { + return measureCompositionScore(median, fail, pixelFormat); + } else { + return measureCompositionScore(ok, median, pixelFormat); + } + } + + private double measureFPS(int surfaceCnt, int pixelFormat) { + configureSurfacesAndWait(surfaceCnt, pixelFormat, true); + // At least one view is visible and it is enough to update only + // one overlapped surface in order to force SurfaceFlinger to send + // all surfaces to compositor. + double fps = mViews.get(0).measureFPS(mRefreshRate * 0.8, mRefreshRate * 0.999); + + // Make sure that surface configuration was not changed. + validateSurfacesNotChanged(); + + return fps; + } + + private void waitForSurfacesConfigured(final int pixelFormat) { + for (int i = 0; i < mViews.size(); ++i) { + CustomSurfaceView view = mViews.get(i); + if (view.getVisibility() == View.VISIBLE) { + view.waitForSurfaceReady(); + } else { + view.waitForSurfaceDestroyed(); + } + } + runOnUiThreadAndWait(new Runnable() { + @Override + public void run() { + updateSystemInfo(pixelFormat); + } + }); + } + + private void validateSurfacesNotChanged() { + for (int i = 0; i < mViews.size(); ++i) { + CustomSurfaceView view = mViews.get(i); + view.validateSurfaceNotChanged(); + } + } + + private void configureSurfaces(int surfaceCnt, int pixelFormat, boolean invalidate) { + for (int i = 0; i < mViews.size(); ++i) { + CustomSurfaceView view = mViews.get(i); + if (i < surfaceCnt) { + view.setMode(pixelFormat, invalidate); + view.setVisibility(View.VISIBLE); + } else { + view.setVisibility(View.INVISIBLE); + } + } + } + + private void configureSurfacesAndWait(final int surfaceCnt, final int pixelFormat, + final boolean invalidate) { + runOnUiThreadAndWait(new Runnable() { + @Override + public void run() { + configureSurfaces(surfaceCnt, pixelFormat, invalidate); + } + }); + waitForSurfacesConfigured(pixelFormat); + } + + private void acquireSurfacesCanvas() { + for (int i = 0; i < mViews.size(); ++i) { + CustomSurfaceView view = mViews.get(i); + view.acquireCanvas(); + } + } + + private void releaseSurfacesCanvas() { + for (int i = 0; i < mViews.size(); ++i) { + CustomSurfaceView view = mViews.get(i); + view.releaseCanvas(); + } + } + + private static String getReadableMemory(long bytes) { + long unit = 1024; + if (bytes < unit) { + return bytes + " B"; + } + int exp = (int) (Math.log(bytes) / Math.log(unit)); + return String.format("%.1f %sB", bytes / Math.pow(unit, exp), + "KMGTPE".charAt(exp-1)); + } + + private MemoryInfo getMemoryInfo() { + ActivityManager activityManager = (ActivityManager) + getSystemService(ACTIVITY_SERVICE); + MemoryInfo memInfo = new MemoryInfo(); + activityManager.getMemoryInfo(memInfo); + return memInfo; + } + + private void updateSystemInfo(int pixelFormat) { + int visibleCnt = 0; + for (int i = 0; i < mViews.size(); ++i) { + if (mViews.get(i).getVisibility() == View.VISIBLE) { + ++visibleCnt; + } + } + + MemoryInfo memInfo = getMemoryInfo(); + String info = "Available " + + getReadableMemory(memInfo.availMem) + " from " + + getReadableMemory(memInfo.totalMem) + ".\nVisible " + + visibleCnt + " from " + mViews.size() + " " + + getPixelFormatInfo(pixelFormat) + " surfaces.\n" + + "View size: " + mWidth + "x" + mHeight + + ". Refresh rate: " + DOUBLE_FORMAT.format(mRefreshRate) + "."; + mSystemInfoView.setText(info); + } + + private void detectRefreshRate() { + WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE); + mRefreshRate = wm.getDefaultDisplay().getRefreshRate(); + if (mRefreshRate < MIN_REFRESH_RATE_SUPPORTED) + throw new RuntimeException("Unsupported display refresh rate: " + mRefreshRate); + mTargetFPS = mRefreshRate - 2.0f; + } + + private int roundToNextPowerOf2(int value) { + --value; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + return value + 1; + } + + public static String getPixelFormatInfo(int pixelFormat) { + switch (pixelFormat) { + case PixelFormat.TRANSLUCENT: + return "TRANSLUCENT"; + case PixelFormat.TRANSPARENT: + return "TRANSPARENT"; + case PixelFormat.OPAQUE: + return "OPAQUE"; + case PixelFormat.RGBA_8888: + return "RGBA_8888"; + case PixelFormat.RGBX_8888: + return "RGBX_8888"; + case PixelFormat.RGB_888: + return "RGB_888"; + case PixelFormat.RGB_565: + return "RGB_565"; + default: + return "PIX.FORMAT:" + pixelFormat; + } + } + + /** + * A helper that executes a task in the UI thread and waits for its completion. + * + * @param task - task to execute. + */ + private void runOnUiThreadAndWait(Runnable task) { + new UIExecutor(task); + } + + class UIExecutor implements Runnable { + private final Object mLock = new Object(); + private Runnable mTask; + private boolean mDone = false; + + UIExecutor(Runnable task) { + mTask = task; + mDone = false; + runOnUiThread(this); + synchronized (mLock) { + while (!mDone) { + try { + mLock.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + public void run() { + mTask.run(); + synchronized (mLock) { + mDone = true; + mLock.notify(); + } + } + } +} diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java new file mode 100644 index 000000000000..6e9e7390c2c1 --- /dev/null +++ b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.surfacecomposition; + +import android.graphics.PixelFormat; +import android.surfacecomposition.SurfaceCompositionMeasuringActivity.AllocationScore; +import android.surfacecomposition.SurfaceCompositionMeasuringActivity.CompositorScore; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +public class SurfaceCompositionTest extends + ActivityInstrumentationTestCase2<SurfaceCompositionMeasuringActivity> { + private final static String TAG = "SurfaceCompositionTest"; + + // Pass threshold for major pixel formats. + private final static int[] TEST_PIXEL_FORMATS = new int[] { + PixelFormat.TRANSLUCENT, + PixelFormat.OPAQUE, + }; + + // Based on Nexus 9 performance which is usually < 9.0. + private final static double[] MIN_ACCEPTED_COMPOSITION_SCORE = new double[] { + 8.0, + 8.0, + }; + + // Based on Nexus 6 performance which is usually < 28.0. + private final static double[] MIN_ACCEPTED_ALLOCATION_SCORE = new double[] { + 20.0, + 20.0, + }; + + public SurfaceCompositionTest() { + super(SurfaceCompositionMeasuringActivity.class); + } + + private void testRestoreContexts() { + } + + @SmallTest + public void testSurfaceCompositionPerformance() { + for (int i = 0; i < TEST_PIXEL_FORMATS.length; ++i) { + int pixelFormat = TEST_PIXEL_FORMATS[i]; + String formatName = SurfaceCompositionMeasuringActivity.getPixelFormatInfo(pixelFormat); + CompositorScore score = getActivity().measureCompositionScore(pixelFormat); + Log.i(TAG, "testSurfaceCompositionPerformance(" + formatName + ") = " + score); + assertTrue("Device does not support surface(" + formatName + ") composition " + + "performance score. " + score.mSurfaces + " < " + + MIN_ACCEPTED_COMPOSITION_SCORE[i] + ".", + score.mSurfaces >= MIN_ACCEPTED_COMPOSITION_SCORE[i]); + } + } + + @SmallTest + public void testSurfaceAllocationPerformance() { + for (int i = 0; i < TEST_PIXEL_FORMATS.length; ++i) { + int pixelFormat = TEST_PIXEL_FORMATS[i]; + String formatName = SurfaceCompositionMeasuringActivity.getPixelFormatInfo(pixelFormat); + AllocationScore score = getActivity().measureAllocationScore(pixelFormat); + Log.i(TAG, "testSurfaceAllocationPerformance(" + formatName + ") = " + score); + assertTrue("Device does not support surface(" + formatName + ") allocation " + + "performance score. " + score.mMedian + " < " + + MIN_ACCEPTED_ALLOCATION_SCORE[i] + ".", + score.mMedian >= MIN_ACCEPTED_ALLOCATION_SCORE[i]); + } + } +} diff --git a/tools/aidl/Android.mk b/tools/aidl/Android.mk index 354563ae48bc..542f272d8af7 100644 --- a/tools/aidl/Android.mk +++ b/tools/aidl/Android.mk @@ -64,7 +64,8 @@ LOCAL_STATIC_LIBRARIES := \ libgmock_host \ libgtest_host \ -LOCAL_LDLIBS := -lrt +LOCAL_LDLIBS_linux := -lrt + include $(BUILD_HOST_NATIVE_TEST) endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK |