Merge "Add tests for text layout cache"
diff --git a/api/current.txt b/api/current.txt
index b296672..1eb37b3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -241,10 +241,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 7cc66cf..f913e6c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -333,10 +333,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 412e3cd..e15ba74 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4718,7 +4718,13 @@
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 @@
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 c2bf28a..3b1c60b 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -255,6 +255,13 @@
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 e3414d9..7ffac0a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -213,7 +213,8 @@
* @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 4da88ee..7529c52 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -77,6 +77,8 @@
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 afae9ac..379651e 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 @@
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 665069c..5976f09 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6687,14 +6687,15 @@
}
/**
- * 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).
+ * 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.
- *
+ * @return the content description
+ * @see #setContentDescription(CharSequence)
* @attr ref android.R.styleable#View_contentDescription
*/
@ViewDebug.ExportedProperty(category = "accessibility")
@@ -6703,14 +6704,18 @@
}
/**
- * 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 a5696ee..64c4103 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -37,7 +37,6 @@
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.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 @@
setOnTouchListener(new ForwardingListener(this) {
@Override
- public ListPopupWindow getPopup() {
+ public ShowableListMenu getPopup() {
if (mOverflowPopup == null) {
return null;
}
@@ -1003,7 +1003,7 @@
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 f34ad71..f5c46db 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.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 @@
});
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 0000000..5536513
--- /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 0000000..fd7140f
--- /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 a02efcf..3d07d87 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -25,7 +25,6 @@
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.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 @@
* @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 @@
* 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 @@
/**
* Dismiss the popup window.
*/
+ @Override
public void dismiss() {
mPopup.dismiss();
removePromptView();
@@ -732,7 +733,7 @@
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 @@
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 @@
/**
* @return {@code true} if the popup is currently showing, {@code false} otherwise.
*/
+ @Override
public boolean isShowing() {
return mPopup.isShowing();
}
@@ -842,6 +844,7 @@
* @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 @@
} 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 OnTouchListener createDragToOpenListener(View src) {
return new ForwardingListener(src) {
@Override
- public ListPopupWindow getPopup() {
+ public ShowableListMenu getPopup() {
return ListPopupWindow.this;
}
};
@@ -1088,7 +1091,7 @@
DropDownListView dropDownList = mDropDownList;
if (dropDownList != null) {
- dropDownList.mListSelectionHidden = false;
+ dropDownList.setListSelectionHidden(false);
}
}
}
@@ -1219,568 +1222,6 @@
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 8d42c73..9e47e85 100644
--- a/core/java/android/widget/MenuPopupWindow.java
+++ b/core/java/android/widget/MenuPopupWindow.java
@@ -36,11 +36,11 @@
}
@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 1507dfb..3b2d60d 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -20,6 +20,7 @@
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.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 @@
}
@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 f3cf61c..c79e184 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.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 @@
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 7a64377..61402ab 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -21,6 +21,7 @@
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.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 @@
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 @@
}
/**
- * 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 9ca937c..959d249 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -179,8 +179,18 @@
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 @@
}
try {
+ Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line);
if (false) {
Log.v(TAG, "Preloading " + line + "...");
}
@@ -289,6 +300,8 @@
throw (RuntimeException) t;
}
throw new RuntimeException(t);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
}
}
@@ -302,7 +315,9 @@
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,42 +579,57 @@
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.");
+ }
+
+ 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();
+
+ // 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);
}
- 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());
-
- // Finish profiling the zygote initialization.
- SamplingProfilerIntegration.writeZygoteSnapshot();
-
- // Do an initial gc to clean up after startup
- gcAndFinalize();
-
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index 8db363d..ce5bc90 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.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 @@
}
@Override
- public ListPopupWindow getPopup() {
+ public ShowableListMenu getPopup() {
if (mPopupCallback != null) {
return mPopupCallback.getPopup();
}
@@ -331,7 +331,7 @@
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 @@
@Override
protected boolean onForwardingStopped() {
- final ListPopupWindow popup = getPopup();
+ final ShowableListMenu popup = getPopup();
if (popup != null) {
popup.dismiss();
return true;
@@ -349,6 +349,6 @@
}
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 29ac3f3..2526393 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 @@
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 @@
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 ListMenuItemView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, com.android.internal.R.attr.listMenuViewStyle);
}
@Override
@@ -93,6 +96,10 @@
}
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 @@
setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut());
setIcon(itemData.getIcon());
setEnabled(itemData.isEnabled());
+ setSubMenuArrowVisible(itemData.hasSubMenu());
}
public void setForceShowIcon(boolean forceShow) {
@@ -186,6 +194,12 @@
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 0000000..1e03b1f
--- /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 13654a6..e6bc6c3 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 @@
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 @@
@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 0000000..ca158fd
--- /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 f7a2f9f..e4bc800 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*/ 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 0000000..2dd0540
--- /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 0bc636f..8b8c93a 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 b01ca63..231450f 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 8081013..83d9c3d 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 011105e..0fca702 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 43264a7..2bdc9c8 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 a38de99..1b4ffc9 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 63e072f..629ca27 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 aa46949..e6e20f1 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 61af6c5..59d1a7c 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -639,6 +639,8 @@
<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 @@
<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 d2089cd..c89b31b 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 2369c9b..5dc14e3 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -685,6 +685,10 @@
<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 e04c743..98c9f77 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 e406ae0..3010190 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -238,6 +238,7 @@
<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 @@
<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 c5d68bd..ce35b87 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 @@
private float mCompatScaling;
private float mInvCompatScaling;
- private Locale mLocale;
+ private LocaleList mLocales;
private String mFontFeatureSettings;
/**
@@ -434,7 +437,7 @@
// setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
// ? HINTING_OFF : HINTING_ON);
mCompatScaling = mInvCompatScaling = 1;
- setTextLocale(Locale.getDefault());
+ setTextLocales(LocaleList.getDefault());
}
/**
@@ -474,7 +477,7 @@
mInvCompatScaling = 1;
mBidiFlags = BIDI_DEFAULT_LTR;
- setTextLocale(Locale.getDefault());
+ setTextLocales(LocaleList.getDefault());
setElegantTextHeight(false);
mFontFeatureSettings = null;
}
@@ -512,7 +515,7 @@
mInvCompatScaling = paint.mInvCompatScaling;
mBidiFlags = paint.mBidiFlags;
- mLocale = paint.mLocale;
+ mLocales = paint.mLocales;
mFontFeatureSettings = paint.mFontFeatureSettings;
}
@@ -1174,47 +1177,80 @@
}
/**
- * 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.
*
- * For example, if the locale is {@link Locale#CHINESE} or {@link Locale#CHINA},
+ * 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.
+ *
+ * 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 48d5dcf..b5694b7 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 @@
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 @@
// 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 cbb72d1..9b316be 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 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 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 @@
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 9294a16..1473f24 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 13f768d..7ab6af9 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 6889a43..bd02650 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 51513bd..a0d7d2b 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 014d802..a14d0fc 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 0860019..e819d54 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 9c32052..7def415f 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 4d96a01..a73947f 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 7f005a3..6f49187 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 36f3c98..a659077 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 8e73b21..bcfc458 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 0b49955..fb781d4 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 0b49955..fb781d4 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 0b49955..fb781d4 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 c4dca9c..10834a2 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 e316a94..37c81f4 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 a151bce..f4218a3 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 37cdee7..fbf0eb42 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 80d0918..fa01c47 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 b86247a..6c4a029 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 f99447c..07a2fc3 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 aada1eb..0aa45ae 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 951809f..ec64f22 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 02e4e52..e873c95 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 3ed090c..83ac46e 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 9698aba..b5d9931 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 37cb0a8..79390a6 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 e31cf49..9f48b26 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 ad8141b..60024115 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 02caf17..e8e0530 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 ab5d8beab..8ee5f07 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 9dad8aa..e38501d 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 9cb2fc8..a73f4c1 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 a9728b2..f1035a8 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 1d61372..8b82e5f 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 c233f83..b8db00f 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 d486e56..316c04f 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 3505754..d7f1543 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 968a65a..efe699b 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 f34c70e..50b4522 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 cf70d6b..9082778 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 5e2db80..5fb4bb0 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 fe781b6..8571b3f 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 6e6fc55..4b11962 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 65250bb..d1dbd6d 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 0f71b4b..fe50f90 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 596275c..01f7edf 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 3147d0c..d0eaccf 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 f1bfbe1..e582039 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 461a15f..c3dc703 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 b74f91d..13f02d5 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 06746cc..ef3d2f3 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 66100c1..8c2c5c4 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 53cea01..3803b81 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 5006413..be42e8a 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 53cea01..3803b81 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 d97e16b..bb8f2c3 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 d67ad38..9609f40 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 06cb626..9e78834 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 037074b..e3f0fb3 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 31fe5d8..4dffcfa 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 ffb8bea..20c3426 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 bae0284..1dcde3a 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 6588f10..0abeb1e 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 623f12c..d000004 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 c6cb337..7b1ded3 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 c0717c1..06762bd 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 e16fdd2..52c7af7 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 d970084..66056d1 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 b22b4fb..fdad0d5 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 898611d..9dde801 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 d5683e1..a4ef16a 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 e31af6b..118c4b8 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 030bbbe..460d57a 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 b046415..05644e7 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 d568dba..f7cac90 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 702ad53..369172f3 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 8774036..2a14a9f 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 fda6479..92e6814 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 @@
*/
@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);
- // Register it.
- mServices.add(service);
+ // 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);
+ }
- // Start it.
- try {
- service.onStart();
- } catch (RuntimeException ex) {
- throw new RuntimeException("Failed to start service " + name
- + ": onStart threw an exception", ex);
+ // 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);
+ }
+ return service;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
- return service;
}
/**
@@ -127,18 +133,22 @@
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 c0ffb56..09ac7d9 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.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 @@
}
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 @@
mBootAnimationComplete = true;
}
if (callFinishBooting) {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
finishBooting();
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
@@ -6465,7 +6470,9 @@
}
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 5c60a61..239c471 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 @@
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 @@
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 21dd647b..aafaf83 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -38,6 +38,7 @@
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 @@
}
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();
+ // 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", "");
- }
+ 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());
+ // 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());
+ // 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);
- }
+ // 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 @@
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 @@
// 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 @@
}
// 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 @@
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 @@
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 @@
} 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 @@
// 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 @@
// 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 @@
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 @@
}
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 @@
} 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 @@
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 @@
} 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 @@
* 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 @@
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 @@
|| 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 @@
}
}
+ 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 @@
}
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 @@
}
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 @@
// 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 @@
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 @@
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 @@
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 @@
} catch (Throwable e) {
reportWtf("Notifying MmsService running", e);
}
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
});
}
@@ -1226,4 +1322,9 @@
//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 0000000..95f69f1
--- /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 0000000..4c0a9b6
--- /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 0000000..254d707
--- /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 0000000..d626f10
--- /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 0000000..0430662
--- /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 0000000..c716dae
--- /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 0000000..e3e1d34
--- /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 0000000..6e9e739
--- /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 354563a..542f272 100644
--- a/tools/aidl/Android.mk
+++ b/tools/aidl/Android.mk
@@ -64,7 +64,8 @@
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