Merge "Import translations. DO NOT MERGE"
diff --git a/api/current.txt b/api/current.txt
index 1055c24..ef6aed7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3175,6 +3175,7 @@
method public void finishActivity(int);
method public void finishActivityFromChild(android.app.Activity, int);
method public void finishAffinity();
+ method public void finishAndRemoveTask();
method public void finishFromChild(android.app.Activity);
method public void finishWithTransition();
method public android.app.ActionBar getActionBar();
@@ -16813,11 +16814,24 @@
package android.nfc.cardemulation {
+ public final class AidGroup implements android.os.Parcelable {
+ ctor public AidGroup(java.util.ArrayList<java.lang.String>, java.lang.String);
+ method public int describeContents();
+ method public java.util.ArrayList<java.lang.String> getAids();
+ method public java.lang.String getCategory();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int MAX_NUM_AIDS = 256; // 0x100
+ }
+
public final class CardEmulation {
+ method public android.nfc.cardemulation.AidGroup getAidGroupForService(android.content.ComponentName, java.lang.String);
method public static synchronized android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
method public int getSelectionModeForCategory(java.lang.String);
method public boolean isDefaultServiceForAid(android.content.ComponentName, java.lang.String);
method public boolean isDefaultServiceForCategory(android.content.ComponentName, java.lang.String);
+ method public boolean registerAidGroupForService(android.content.ComponentName, android.nfc.cardemulation.AidGroup);
+ method public boolean removeAidGroupForService(android.content.ComponentName, java.lang.String);
field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
field public static final java.lang.String CATEGORY_OTHER = "other";
field public static final java.lang.String CATEGORY_PAYMENT = "payment";
@@ -19256,11 +19270,12 @@
field public static final int L = 10000; // 0x2710
}
- public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
+ public final class Bundle extends android.os.CommonBundle {
ctor public Bundle();
ctor public Bundle(java.lang.ClassLoader);
ctor public Bundle(int);
ctor public Bundle(android.os.Bundle);
+ ctor public Bundle(android.os.PersistableBundle);
method public void clear();
method public java.lang.Object clone();
method public boolean containsKey(java.lang.String);
@@ -19298,6 +19313,7 @@
method public T getParcelable(java.lang.String);
method public android.os.Parcelable[] getParcelableArray(java.lang.String);
method public java.util.ArrayList<T> getParcelableArrayList(java.lang.String);
+ method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
method public java.io.Serializable getSerializable(java.lang.String);
method public short getShort(java.lang.String);
method public short getShort(java.lang.String, short);
@@ -19311,6 +19327,7 @@
method public boolean isEmpty();
method public java.util.Set<java.lang.String> keySet();
method public void putAll(android.os.Bundle);
+ method public void putAll(android.os.PersistableBundle);
method public void putBinder(java.lang.String, android.os.IBinder);
method public void putBoolean(java.lang.String, boolean);
method public void putBooleanArray(java.lang.String, boolean[]);
@@ -19334,6 +19351,7 @@
method public void putParcelable(java.lang.String, android.os.Parcelable);
method public void putParcelableArray(java.lang.String, android.os.Parcelable[]);
method public void putParcelableArrayList(java.lang.String, java.util.ArrayList<? extends android.os.Parcelable>);
+ method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
method public void putSerializable(java.lang.String, java.io.Serializable);
method public void putShort(java.lang.String, short);
method public void putShortArray(java.lang.String, short[]);
@@ -19362,6 +19380,9 @@
method public abstract void onCancel();
}
+ abstract class CommonBundle implements java.lang.Cloneable android.os.Parcelable {
+ }
+
public class ConditionVariable {
ctor public ConditionVariable();
ctor public ConditionVariable(boolean);
@@ -19788,6 +19809,8 @@
method public final void readMap(java.util.Map, java.lang.ClassLoader);
method public final T readParcelable(java.lang.ClassLoader);
method public final android.os.Parcelable[] readParcelableArray(java.lang.ClassLoader);
+ method public final android.os.PersistableBundle readPersistableBundle();
+ method public final android.os.PersistableBundle readPersistableBundle(java.lang.ClassLoader);
method public final java.io.Serializable readSerializable();
method public final android.util.SparseArray readSparseArray(java.lang.ClassLoader);
method public final android.util.SparseBooleanArray readSparseBooleanArray();
@@ -19828,6 +19851,7 @@
method public final void writeNoException();
method public final void writeParcelable(android.os.Parcelable, int);
method public final void writeParcelableArray(T[], int);
+ method public final void writePersistableBundle(android.os.PersistableBundle);
method public final void writeSerializable(java.io.Serializable);
method public final void writeSparseArray(android.util.SparseArray<java.lang.Object>);
method public final void writeSparseBooleanArray(android.util.SparseBooleanArray);
@@ -19938,6 +19962,51 @@
field public static final int PATTERN_SIMPLE_GLOB = 2; // 0x2
}
+ public final class PersistableBundle extends android.os.CommonBundle {
+ ctor public PersistableBundle();
+ ctor public PersistableBundle(java.lang.ClassLoader);
+ ctor public PersistableBundle(int);
+ ctor public PersistableBundle(android.os.PersistableBundle);
+ method public void clear();
+ method public java.lang.Object clone();
+ method public boolean containsKey(java.lang.String);
+ method public int describeContents();
+ method public java.lang.Object get(java.lang.String);
+ method public java.lang.ClassLoader getClassLoader();
+ method public double getDouble(java.lang.String);
+ method public double getDouble(java.lang.String, double);
+ method public double[] getDoubleArray(java.lang.String);
+ method public int getInt(java.lang.String);
+ method public int getInt(java.lang.String, int);
+ method public int[] getIntArray(java.lang.String);
+ method public long getLong(java.lang.String);
+ method public long getLong(java.lang.String, long);
+ method public long[] getLongArray(java.lang.String);
+ method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
+ method public java.lang.String getString(java.lang.String);
+ method public java.lang.String getString(java.lang.String, java.lang.String);
+ method public java.lang.String[] getStringArray(java.lang.String);
+ method public boolean isEmpty();
+ method public java.util.Set<java.lang.String> keySet();
+ method public void putAll(android.os.PersistableBundle);
+ method public void putDouble(java.lang.String, double);
+ method public void putDoubleArray(java.lang.String, double[]);
+ method public void putInt(java.lang.String, int);
+ method public void putIntArray(java.lang.String, int[]);
+ method public void putLong(java.lang.String, long);
+ method public void putLongArray(java.lang.String, long[]);
+ method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
+ method public void putString(java.lang.String, java.lang.String);
+ method public void putStringArray(java.lang.String, java.lang.String[]);
+ method public void readFromParcel(android.os.Parcel);
+ method public void remove(java.lang.String);
+ method public void setClassLoader(java.lang.ClassLoader);
+ method public int size();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final android.os.PersistableBundle EMPTY;
+ }
+
public final class PowerManager {
method public void goToSleep(long);
method public boolean isInteractive();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a5a06e3..599a608 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4314,11 +4314,10 @@
}
/**
- * Call this when your activity is done and should be closed. The
- * ActivityResult is propagated back to whoever launched you via
- * onActivityResult().
+ * Finishes the current activity and specifies whether to remove the task associated with this
+ * activity.
*/
- public void finish() {
+ private void finish(boolean finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
@@ -4332,7 +4331,7 @@
resultData.prepareToLeaveProcess();
}
if (ActivityManagerNative.getDefault()
- .finishActivity(mToken, resultCode, resultData)) {
+ .finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
@@ -4344,6 +4343,15 @@
}
/**
+ * Call this when your activity is done and should be closed. The
+ * ActivityResult is propagated back to whoever launched you via
+ * onActivityResult().
+ */
+ public void finish() {
+ finish(false);
+ }
+
+ /**
* Finish this activity as well as all activities immediately below it
* in the current task that have the same affinity. This is typically
* used when an application can be launched on to another task (such as
@@ -4442,6 +4450,14 @@
}
/**
+ * Call this when your activity is done and should be closed and the task should be completely
+ * removed as a part of finishing the Activity.
+ */
+ public void finishAndRemoveTask() {
+ finish(true);
+ }
+
+ /**
* Called when an activity you launched exits, giving you the requestCode
* you started it with, the resultCode it returned, and any additional
* data from it. The <var>resultCode</var> will be
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 44c74d8..10831f2 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -263,7 +263,8 @@
if (data.readInt() != 0) {
resultData = Intent.CREATOR.createFromParcel(data);
}
- boolean res = finishActivity(token, resultCode, resultData);
+ boolean finishTask = (data.readInt() != 0);
+ boolean res = finishActivity(token, resultCode, resultData, finishTask);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
return true;
@@ -2342,7 +2343,7 @@
data.recycle();
return result != 0;
}
- public boolean finishActivity(IBinder token, int resultCode, Intent resultData)
+ public boolean finishActivity(IBinder token, int resultCode, Intent resultData, boolean finishTask)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -2355,6 +2356,7 @@
} else {
data.writeInt(0);
}
+ data.writeInt(finishTask ? 1 : 0);
mRemote.transact(FINISH_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
boolean res = reply.readInt() != 0;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 965f815..88eae7f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2363,7 +2363,7 @@
// manager to stop us.
try {
ActivityManagerNative.getDefault()
- .finishActivity(r.token, Activity.RESULT_CANCELED, null);
+ .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
// Ignore
}
@@ -2984,7 +2984,7 @@
// just end this activity.
try {
ActivityManagerNative.getDefault()
- .finishActivity(token, Activity.RESULT_CANCELED, null);
+ .finishActivity(token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
}
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index bfbd339..52003f1 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -79,7 +79,7 @@
int flagsMask, int flagsValues, Bundle options) throws RemoteException;
public boolean startNextMatchingActivity(IBinder callingActivity,
Intent intent, Bundle options) throws RemoteException;
- public boolean finishActivity(IBinder token, int code, Intent data)
+ public boolean finishActivity(IBinder token, int code, Intent data, boolean finishTask)
throws RemoteException;
public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
public boolean finishActivityAffinity(IBinder token) throws RemoteException;
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index a6a04d1..5cf61a8 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -41,8 +41,6 @@
@Deprecated
public static final int DISABLE_NOTIFICATION_TICKER
= View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
- public static final int DISABLE_PRIVATE_NOTIFICATIONS
- = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
diff --git a/core/java/android/nfc/INfcCardEmulation.aidl b/core/java/android/nfc/INfcCardEmulation.aidl
index b8a5ba7..ae9796b 100644
--- a/core/java/android/nfc/INfcCardEmulation.aidl
+++ b/core/java/android/nfc/INfcCardEmulation.aidl
@@ -17,6 +17,7 @@
package android.nfc;
import android.content.ComponentName;
+import android.nfc.cardemulation.AidGroup;
import android.nfc.cardemulation.ApduServiceInfo;
import android.os.RemoteCallback;
@@ -29,5 +30,8 @@
boolean isDefaultServiceForAid(int userHandle, in ComponentName service, String aid);
boolean setDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
boolean setDefaultForNextTap(int userHandle, in ComponentName service);
+ boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup);
+ AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category);
+ boolean removeAidGroupForService(int userHandle, in ComponentName service, String category);
List<ApduServiceInfo> getServices(int userHandle, in String category);
}
diff --git a/core/java/android/nfc/cardemulation/AidGroup.aidl b/core/java/android/nfc/cardemulation/AidGroup.aidl
new file mode 100644
index 0000000..56d6fa5
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/AidGroup.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 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.nfc.cardemulation;
+
+parcelable AidGroup;
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
new file mode 100644
index 0000000..2820f40
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -0,0 +1,165 @@
+package android.nfc.cardemulation;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * The AidGroup class represents a group of ISO/IEC 7816-4
+ * Application Identifiers (AIDs) for a specific application
+ * category, along with a description resource describing
+ * the group.
+ */
+public final class AidGroup implements Parcelable {
+ /**
+ * The maximum number of AIDs that can be present in any one group.
+ */
+ public static final int MAX_NUM_AIDS = 256;
+
+ static final String TAG = "AidGroup";
+
+ final ArrayList<String> aids;
+ final String category;
+ final String description;
+
+ /**
+ * Creates a new AidGroup object.
+ *
+ * @param aids The list of AIDs present in the group
+ * @param category The category of this group
+ */
+ public AidGroup(ArrayList<String> aids, String category) {
+ if (aids == null || aids.size() == 0) {
+ throw new IllegalArgumentException("No AIDS in AID group.");
+ }
+ if (aids.size() > MAX_NUM_AIDS) {
+ throw new IllegalArgumentException("Too many AIDs in AID group.");
+ }
+ if (!isValidCategory(category)) {
+ throw new IllegalArgumentException("Category specified is not valid.");
+ }
+ this.aids = aids;
+ this.category = category;
+ this.description = null;
+ }
+
+ AidGroup(String category, String description) {
+ this.aids = new ArrayList<String>();
+ this.category = category;
+ this.description = description;
+ }
+
+ /**
+ * @return the category of this AID group
+ */
+ public String getCategory() {
+ return category;
+ }
+
+ /**
+ * @return the list of AIDs in this group
+ */
+ public ArrayList<String> getAids() {
+ return aids;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder out = new StringBuilder("Category: " + category +
+ ", AIDs:");
+ for (String aid : aids) {
+ out.append(aid);
+ out.append(", ");
+ }
+ return out.toString();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(category);
+ dest.writeInt(aids.size());
+ if (aids.size() > 0) {
+ dest.writeStringList(aids);
+ }
+ }
+
+ public static final Parcelable.Creator<AidGroup> CREATOR =
+ new Parcelable.Creator<AidGroup>() {
+
+ @Override
+ public AidGroup createFromParcel(Parcel source) {
+ String category = source.readString();
+ int listSize = source.readInt();
+ ArrayList<String> aidList = new ArrayList<String>();
+ if (listSize > 0) {
+ source.readStringList(aidList);
+ }
+ return new AidGroup(aidList, category);
+ }
+
+ @Override
+ public AidGroup[] newArray(int size) {
+ return new AidGroup[size];
+ }
+ };
+
+ /**
+ * @hide
+ * Note: description is not serialized, since it's not localized
+ * and resource identifiers don't make sense to persist.
+ */
+ static public AidGroup createFromXml(XmlPullParser parser) throws XmlPullParserException, IOException {
+ String category = parser.getAttributeValue(null, "category");
+ ArrayList<String> aids = new ArrayList<String>();
+ int eventType = parser.getEventType();
+ int minDepth = parser.getDepth();
+ while (eventType != XmlPullParser.END_DOCUMENT && parser.getDepth() >= minDepth) {
+ if (eventType == XmlPullParser.START_TAG) {
+ String tagName = parser.getName();
+ if (tagName.equals("aid")) {
+ String aid = parser.getAttributeValue(null, "value");
+ if (aid != null) {
+ aids.add(aid);
+ }
+ } else {
+ Log.d(TAG, "Ignorning unexpected tag: " + tagName);
+ }
+ }
+ eventType = parser.next();
+ }
+ if (category != null && aids.size() > 0) {
+ return new AidGroup(aids, category);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public void writeAsXml(XmlSerializer out) throws IOException {
+ out.attribute(null, "category", category);
+ for (String aid : aids) {
+ out.startTag(null, "aid");
+ out.attribute(null, "value", aid);
+ out.endTag(null, "aid");
+ }
+ }
+
+ boolean isValidCategory(String category) {
+ return CardEmulation.CATEGORY_PAYMENT.equals(category) ||
+ CardEmulation.CATEGORY_OTHER.equals(category);
+ }
+}
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index d7ef4bc..94f35ed 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -35,9 +35,12 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.FileDescriptor;
import java.io.IOException;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
/**
* @hide
@@ -56,24 +59,19 @@
final String mDescription;
/**
- * Convenience AID list
- */
- final ArrayList<String> mAids;
-
- /**
* Whether this service represents AIDs running on the host CPU
*/
final boolean mOnHost;
/**
- * All AID groups this service handles
+ * Mapping from category to static AID group
*/
- final ArrayList<AidGroup> mAidGroups;
+ final HashMap<String, AidGroup> mStaticAidGroups;
/**
- * Convenience hashmap
+ * Mapping from category to dynamic AID group
*/
- final HashMap<String, AidGroup> mCategoryToGroup;
+ final HashMap<String, AidGroup> mDynamicAidGroups;
/**
* Whether this service should only be started when the device is unlocked.
@@ -86,26 +84,33 @@
final int mBannerResourceId;
/**
+ * The uid of the package the service belongs to
+ */
+ final int mUid;
+ /**
* @hide
*/
public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
- ArrayList<AidGroup> aidGroups, boolean requiresUnlock, int bannerResource) {
+ ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
+ boolean requiresUnlock, int bannerResource, int uid) {
this.mService = info;
this.mDescription = description;
- this.mAidGroups = aidGroups;
- this.mAids = new ArrayList<String>();
- this.mCategoryToGroup = new HashMap<String, AidGroup>();
+ this.mStaticAidGroups = new HashMap<String, AidGroup>();
+ this.mDynamicAidGroups = new HashMap<String, AidGroup>();
this.mOnHost = onHost;
this.mRequiresDeviceUnlock = requiresUnlock;
- for (AidGroup aidGroup : aidGroups) {
- this.mCategoryToGroup.put(aidGroup.category, aidGroup);
- this.mAids.addAll(aidGroup.aids);
+ for (AidGroup aidGroup : staticAidGroups) {
+ this.mStaticAidGroups.put(aidGroup.category, aidGroup);
+ }
+ for (AidGroup aidGroup : dynamicAidGroups) {
+ this.mDynamicAidGroups.put(aidGroup.category, aidGroup);
}
this.mBannerResourceId = bannerResource;
+ this.mUid = uid;
}
- public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost)
- throws XmlPullParserException, IOException {
+ public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost) throws
+ XmlPullParserException, IOException {
ServiceInfo si = info.serviceInfo;
XmlResourceParser parser = null;
try {
@@ -163,10 +168,10 @@
sa.recycle();
}
- mAidGroups = new ArrayList<AidGroup>();
- mCategoryToGroup = new HashMap<String, AidGroup>();
- mAids = new ArrayList<String>();
+ mStaticAidGroups = new HashMap<String, AidGroup>();
+ mDynamicAidGroups = new HashMap<String, AidGroup>();
mOnHost = onHost;
+
final int depth = parser.getDepth();
AidGroup currentGroup = null;
@@ -179,14 +184,14 @@
final TypedArray groupAttrs = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AidGroup);
// Get category of AID group
- String groupDescription = groupAttrs.getString(
- com.android.internal.R.styleable.AidGroup_description);
String groupCategory = groupAttrs.getString(
com.android.internal.R.styleable.AidGroup_category);
+ String groupDescription = groupAttrs.getString(
+ com.android.internal.R.styleable.AidGroup_description);
if (!CardEmulation.CATEGORY_PAYMENT.equals(groupCategory)) {
groupCategory = CardEmulation.CATEGORY_OTHER;
}
- currentGroup = mCategoryToGroup.get(groupCategory);
+ currentGroup = mStaticAidGroups.get(groupCategory);
if (currentGroup != null) {
if (!CardEmulation.CATEGORY_OTHER.equals(groupCategory)) {
Log.e(TAG, "Not allowing multiple aid-groups in the " +
@@ -200,9 +205,8 @@
} else if (eventType == XmlPullParser.END_TAG && "aid-group".equals(tagName) &&
currentGroup != null) {
if (currentGroup.aids.size() > 0) {
- if (!mCategoryToGroup.containsKey(currentGroup.category)) {
- mAidGroups.add(currentGroup);
- mCategoryToGroup.put(currentGroup.category, currentGroup);
+ if (!mStaticAidGroups.containsKey(currentGroup.category)) {
+ mStaticAidGroups.put(currentGroup.category, currentGroup);
}
} else {
Log.e(TAG, "Not adding <aid-group> with empty or invalid AIDs");
@@ -216,7 +220,6 @@
toUpperCase();
if (isValidAid(aid) && !currentGroup.aids.contains(aid)) {
currentGroup.aids.add(aid);
- mAids.add(aid);
} else {
Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
}
@@ -228,6 +231,8 @@
} finally {
if (parser != null) parser.close();
}
+ // Set uid
+ mUid = si.applicationInfo.uid;
}
public ComponentName getComponent() {
@@ -235,16 +240,58 @@
mService.serviceInfo.name);
}
+ /**
+ * Returns a consolidated list of AIDs from the AID groups
+ * registered by this service. Note that if a service has both
+ * a static (manifest-based) AID group for a category and a dynamic
+ * AID group, only the dynamically registered AIDs will be returned
+ * for that category.
+ * @return List of AIDs registered by the service
+ */
public ArrayList<String> getAids() {
- return mAids;
+ final ArrayList<String> aids = new ArrayList<String>();
+ for (AidGroup group : getAidGroups()) {
+ aids.addAll(group.aids);
+ }
+ return aids;
}
+ /**
+ * Returns the registered AID group for this category.
+ */
+ public AidGroup getDynamicAidGroupForCategory(String category) {
+ return mDynamicAidGroups.get(category);
+ }
+
+ public boolean removeDynamicAidGroupForCategory(String category) {
+ return (mDynamicAidGroups.remove(category) != null);
+ }
+
+ /**
+ * Returns a consolidated list of AID groups
+ * registered by this service. Note that if a service has both
+ * a static (manifest-based) AID group for a category and a dynamic
+ * AID group, only the dynamically registered AID group will be returned
+ * for that category.
+ * @return List of AIDs registered by the service
+ */
public ArrayList<AidGroup> getAidGroups() {
- return mAidGroups;
+ final ArrayList<AidGroup> groups = new ArrayList<AidGroup>();
+ for (Map.Entry<String, AidGroup> entry : mDynamicAidGroups.entrySet()) {
+ groups.add(entry.getValue());
+ }
+ for (Map.Entry<String, AidGroup> entry : mStaticAidGroups.entrySet()) {
+ if (!mDynamicAidGroups.containsKey(entry.getKey())) {
+ // Consolidate AID groups - don't return static ones
+ // if a dynamic group exists for the category.
+ groups.add(entry.getValue());
+ }
+ }
+ return groups;
}
public boolean hasCategory(String category) {
- return mCategoryToGroup.containsKey(category);
+ return (mStaticAidGroups.containsKey(category) || mDynamicAidGroups.containsKey(category));
}
public boolean isOnHost() {
@@ -259,6 +306,14 @@
return mDescription;
}
+ public int getUid() {
+ return mUid;
+ }
+
+ public void setOrReplaceDynamicAidGroup(AidGroup aidGroup) {
+ mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup);
+ }
+
public CharSequence loadLabel(PackageManager pm) {
return mService.loadLabel(pm);
}
@@ -304,8 +359,12 @@
StringBuilder out = new StringBuilder("ApduService: ");
out.append(getComponent());
out.append(", description: " + mDescription);
- out.append(", AID Groups: ");
- for (AidGroup aidGroup : mAidGroups) {
+ out.append(", Static AID Groups: ");
+ for (AidGroup aidGroup : mStaticAidGroups.values()) {
+ out.append(aidGroup.toString());
+ }
+ out.append(", Dynamic AID Groups: ");
+ for (AidGroup aidGroup : mDynamicAidGroups.values()) {
out.append(aidGroup.toString());
}
return out.toString();
@@ -336,12 +395,17 @@
mService.writeToParcel(dest, flags);
dest.writeString(mDescription);
dest.writeInt(mOnHost ? 1 : 0);
- dest.writeInt(mAidGroups.size());
- if (mAidGroups.size() > 0) {
- dest.writeTypedList(mAidGroups);
+ dest.writeInt(mStaticAidGroups.size());
+ if (mStaticAidGroups.size() > 0) {
+ dest.writeTypedList(new ArrayList<AidGroup>(mStaticAidGroups.values()));
+ }
+ dest.writeInt(mDynamicAidGroups.size());
+ if (mDynamicAidGroups.size() > 0) {
+ dest.writeTypedList(new ArrayList<AidGroup>(mDynamicAidGroups.values()));
}
dest.writeInt(mRequiresDeviceUnlock ? 1 : 0);
dest.writeInt(mBannerResourceId);
+ dest.writeInt(mUid);
};
public static final Parcelable.Creator<ApduServiceInfo> CREATOR =
@@ -351,14 +415,21 @@
ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
String description = source.readString();
boolean onHost = (source.readInt() != 0) ? true : false;
- ArrayList<AidGroup> aidGroups = new ArrayList<AidGroup>();
- int numGroups = source.readInt();
- if (numGroups > 0) {
- source.readTypedList(aidGroups, AidGroup.CREATOR);
+ ArrayList<AidGroup> staticAidGroups = new ArrayList<AidGroup>();
+ int numStaticGroups = source.readInt();
+ if (numStaticGroups > 0) {
+ source.readTypedList(staticAidGroups, AidGroup.CREATOR);
+ }
+ ArrayList<AidGroup> dynamicAidGroups = new ArrayList<AidGroup>();
+ int numDynamicGroups = source.readInt();
+ if (numDynamicGroups > 0) {
+ source.readTypedList(dynamicAidGroups, AidGroup.CREATOR);
}
boolean requiresUnlock = (source.readInt() != 0) ? true : false;
int bannerResource = source.readInt();
- return new ApduServiceInfo(info, onHost, description, aidGroups, requiresUnlock, bannerResource);
+ int uid = source.readInt();
+ return new ApduServiceInfo(info, onHost, description, staticAidGroups,
+ dynamicAidGroups, requiresUnlock, bannerResource, uid);
}
@Override
@@ -367,76 +438,22 @@
}
};
- public static class AidGroup implements Parcelable {
- final ArrayList<String> aids;
- final String category;
- final String description;
-
- AidGroup(ArrayList<String> aids, String category, String description) {
- this.aids = aids;
- this.category = category;
- this.description = description;
- }
-
- AidGroup(String category, String description) {
- this.aids = new ArrayList<String>();
- this.category = category;
- this.description = description;
- }
-
- public String getCategory() {
- return category;
- }
-
- public ArrayList<String> getAids() {
- return aids;
- }
-
- @Override
- public String toString() {
- StringBuilder out = new StringBuilder("Category: " + category +
- ", description: " + description + ", AIDs:");
- for (String aid : aids) {
- out.append(aid);
- out.append(", ");
- }
- return out.toString();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(category);
- dest.writeString(description);
- dest.writeInt(aids.size());
- if (aids.size() > 0) {
- dest.writeStringList(aids);
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println(" " + getComponent() +
+ " (Description: " + getDescription() + ")");
+ pw.println(" Static AID groups:");
+ for (AidGroup group : mStaticAidGroups.values()) {
+ pw.println(" Category: " + group.category);
+ for (String aid : group.aids) {
+ pw.println(" AID: " + aid);
}
}
-
- public static final Parcelable.Creator<ApduServiceInfo.AidGroup> CREATOR =
- new Parcelable.Creator<ApduServiceInfo.AidGroup>() {
-
- @Override
- public AidGroup createFromParcel(Parcel source) {
- String category = source.readString();
- String description = source.readString();
- int listSize = source.readInt();
- ArrayList<String> aidList = new ArrayList<String>();
- if (listSize > 0) {
- source.readStringList(aidList);
- }
- return new AidGroup(aidList, category, description);
+ pw.println(" Dynamic AID groups:");
+ for (AidGroup group : mDynamicAidGroups.values()) {
+ pw.println(" Category: " + group.category);
+ for (String aid : group.aids) {
+ pw.println(" AID: " + aid);
}
-
- @Override
- public AidGroup[] newArray(int size) {
- return new AidGroup[size];
- }
- };
+ }
}
}
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 58d9616..41f039c 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -168,6 +168,10 @@
if (manager == null) {
// Get card emu service
INfcCardEmulation service = adapter.getCardEmulationService();
+ if (service == null) {
+ Log.e(TAG, "This device does not implement the INfcCardEmulation interface.");
+ throw new UnsupportedOperationException();
+ }
manager = new CardEmulation(context, service);
sCardEmus.put(context, manager);
}
@@ -271,6 +275,109 @@
}
/**
+ * Registers a group of AIDs for the specified service.
+ *
+ * <p>If an AID group for that category was previously
+ * registered for this service (either statically
+ * through the manifest, or dynamically by using this API),
+ * that AID group will be replaced with this one.
+ *
+ * <p>Note that you can only register AIDs for a service that
+ * is running under the same UID as you are. Typically
+ * this means you need to call this from the same
+ * package as the service itself, though UIDs can also
+ * be shared between packages using shared UIDs.
+ *
+ * @param service The component name of the service
+ * @param aidGroup The group of AIDs to be registered
+ * @return whether the registration was successful.
+ */
+ public boolean registerAidGroupForService(ComponentName service, AidGroup aidGroup) {
+ try {
+ return sService.registerAidGroupForService(UserHandle.myUserId(), service, aidGroup);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.registerAidGroupForService(UserHandle.myUserId(), service,
+ aidGroup);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Retrieves the currently registered AID group for the specified
+ * category for a service.
+ *
+ * <p>Note that this will only return AID groups that were dynamically
+ * registered using {@link #registerAidGroupForService(ComponentName, AidGroup)}
+ * method. It will *not* return AID groups that were statically registered
+ * in the manifest.
+ *
+ * @param service The component name of the service
+ * @param category The category of the AID group to be returned, e.g. {@link #CATEGORY_PAYMENT}
+ * @return The AID group, or null if it couldn't be found
+ */
+ public AidGroup getAidGroupForService(ComponentName service, String category) {
+ try {
+ return sService.getAidGroupForService(UserHandle.myUserId(), service, category);
+ } catch (RemoteException e) {
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ return sService.getAidGroupForService(UserHandle.myUserId(), service, category);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Removes a registered AID group for the specified category for the
+ * service provided.
+ *
+ * <p>Note that this will only remove AID groups that were dynamically
+ * registered using the {@link #registerAidGroupForService(ComponentName, AidGroup)}
+ * method. It will *not* remove AID groups that were statically registered in
+ * the manifest. If a dynamically registered AID group is removed using
+ * this method, and a statically registered AID group for the same category
+ * exists in the manifest, that AID group will become active again.
+ *
+ * @param service The component name of the service
+ * @param category The category of the AID group to be removed, e.g. {@link #CATEGORY_PAYMENT}
+ * @return whether the group was successfully removed.
+ */
+ public boolean removeAidGroupForService(ComponentName service, String category) {
+ try {
+ return sService.removeAidGroupForService(UserHandle.myUserId(), service, category);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.removeAidGroupForService(UserHandle.myUserId(), service, category);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
* @hide
*/
public boolean setDefaultServiceForCategory(ComponentName service, String category) {
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index af57507..c85e418 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -17,7 +17,6 @@
package android.os;
import android.util.ArrayMap;
-import android.util.Log;
import android.util.SparseArray;
import java.io.Serializable;
@@ -29,47 +28,25 @@
* A mapping from String values to various Parcelable types.
*
*/
-public final class Bundle implements Parcelable, Cloneable {
- private static final String TAG = "Bundle";
- static final boolean DEBUG = false;
+public final class Bundle extends CommonBundle {
public static final Bundle EMPTY;
-
- static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
static final Parcel EMPTY_PARCEL;
static {
EMPTY = new Bundle();
EMPTY.mMap = ArrayMap.EMPTY;
- EMPTY_PARCEL = Parcel.obtain();
+ EMPTY_PARCEL = CommonBundle.EMPTY_PARCEL;
}
- // Invariant - exactly one of mMap / mParcelledData will be null
- // (except inside a call to unparcel)
-
- /* package */ ArrayMap<String, Object> mMap = null;
-
- /*
- * If mParcelledData is non-null, then mMap will be null and the
- * data are stored as a Parcel containing a Bundle. When the data
- * are unparcelled, mParcelledData willbe set to null.
- */
- /* package */ Parcel mParcelledData = null;
-
private boolean mHasFds = false;
private boolean mFdsKnown = true;
private boolean mAllowFds = true;
/**
- * The ClassLoader used when unparcelling data from mParcelledData.
- */
- private ClassLoader mClassLoader;
-
- /**
* Constructs a new, empty Bundle.
*/
public Bundle() {
- mMap = new ArrayMap<String, Object>();
- mClassLoader = getClass().getClassLoader();
+ super();
}
/**
@@ -79,11 +56,17 @@
* @param parcelledData a Parcel containing a Bundle
*/
Bundle(Parcel parcelledData) {
- readFromParcel(parcelledData);
+ super(parcelledData);
+
+ mHasFds = mParcelledData.hasFileDescriptors();
+ mFdsKnown = true;
}
/* package */ Bundle(Parcel parcelledData, int length) {
- readFromParcelInner(parcelledData, length);
+ super(parcelledData, length);
+
+ mHasFds = mParcelledData.hasFileDescriptors();
+ mFdsKnown = true;
}
/**
@@ -94,8 +77,7 @@
* inside of the Bundle.
*/
public Bundle(ClassLoader loader) {
- mMap = new ArrayMap<String, Object>();
- mClassLoader = loader;
+ super(loader);
}
/**
@@ -105,8 +87,7 @@
* @param capacity the initial capacity of the Bundle
*/
public Bundle(int capacity) {
- mMap = new ArrayMap<String, Object>(capacity);
- mClassLoader = getClass().getClassLoader();
+ super(capacity);
}
/**
@@ -116,27 +97,20 @@
* @param b a Bundle to be copied.
*/
public Bundle(Bundle b) {
- if (b.mParcelledData != null) {
- if (b.mParcelledData == EMPTY_PARCEL) {
- mParcelledData = EMPTY_PARCEL;
- } else {
- mParcelledData = Parcel.obtain();
- mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize());
- mParcelledData.setDataPosition(0);
- }
- } else {
- mParcelledData = null;
- }
-
- if (b.mMap != null) {
- mMap = new ArrayMap<String, Object>(b.mMap);
- } else {
- mMap = null;
- }
+ super(b);
mHasFds = b.mHasFds;
mFdsKnown = b.mFdsKnown;
- mClassLoader = b.mClassLoader;
+ }
+
+ /**
+ * Constructs a Bundle containing a copy of the mappings from the given
+ * PersistableBundle.
+ *
+ * @param b a Bundle to be copied.
+ */
+ public Bundle(PersistableBundle b) {
+ super(b);
}
/**
@@ -145,37 +119,17 @@
* @hide
*/
public static Bundle forPair(String key, String value) {
- // TODO: optimize this case.
Bundle b = new Bundle(1);
b.putString(key, value);
return b;
}
/**
- * TODO: optimize this later (getting just the value part of a Bundle
- * with a single pair) once Bundle.forPair() above is implemented
- * with a special single-value Map implementation/serialization.
- *
- * Note: value in single-pair Bundle may be null.
- *
* @hide
*/
+ @Override
public String getPairValue() {
- unparcel();
- int size = mMap.size();
- if (size > 1) {
- Log.w(TAG, "getPairValue() used on Bundle with multiple pairs.");
- }
- if (size == 0) {
- return null;
- }
- Object o = mMap.valueAt(0);
- try {
- return (String) o;
- } catch (ClassCastException e) {
- typeWarning("getPairValue()", o, "String", e);
- return null;
- }
+ return super.getPairValue();
}
/**
@@ -184,15 +138,17 @@
* @param loader An explicit ClassLoader to use when instantiating objects
* inside of the Bundle.
*/
+ @Override
public void setClassLoader(ClassLoader loader) {
- mClassLoader = loader;
+ super.setClassLoader(loader);
}
/**
* Return the ClassLoader currently associated with this Bundle.
*/
+ @Override
public ClassLoader getClassLoader() {
- return mClassLoader;
+ return super.getClassLoader();
}
/** @hide */
@@ -212,52 +168,11 @@
}
/**
- * If the underlying data are stored as a Parcel, unparcel them
- * using the currently assigned class loader.
- */
- /* package */ synchronized void unparcel() {
- if (mParcelledData == null) {
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + ": no parcelled data");
- return;
- }
-
- if (mParcelledData == EMPTY_PARCEL) {
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + ": empty");
- if (mMap == null) {
- mMap = new ArrayMap<String, Object>(1);
- } else {
- mMap.erase();
- }
- mParcelledData = null;
- return;
- }
-
- int N = mParcelledData.readInt();
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + ": reading " + N + " maps");
- if (N < 0) {
- return;
- }
- if (mMap == null) {
- mMap = new ArrayMap<String, Object>(N);
- } else {
- mMap.erase();
- mMap.ensureCapacity(N);
- }
- mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
- mParcelledData.recycle();
- mParcelledData = null;
- if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
- + " final map: " + mMap);
- }
-
- /**
* @hide
*/
+ @Override
public boolean isParcelled() {
- return mParcelledData != null;
+ return super.isParcelled();
}
/**
@@ -265,25 +180,26 @@
*
* @return the number of mappings as an int.
*/
+ @Override
public int size() {
- unparcel();
- return mMap.size();
+ return super.size();
}
/**
* Returns true if the mapping of this Bundle is empty, false otherwise.
*/
+ @Override
public boolean isEmpty() {
- unparcel();
- return mMap.isEmpty();
+ return super.isEmpty();
}
/**
* Removes all elements from the mapping of this Bundle.
*/
+ @Override
public void clear() {
- unparcel();
- mMap.clear();
+ super.clear();
+
mHasFds = false;
mFdsKnown = true;
}
@@ -295,9 +211,9 @@
* @param key a String key
* @return true if the key is part of the mapping, false otherwise
*/
+ @Override
public boolean containsKey(String key) {
- unparcel();
- return mMap.containsKey(key);
+ return super.containsKey(key);
}
/**
@@ -306,9 +222,9 @@
* @param key a String key
* @return an Object, or null
*/
+ @Override
public Object get(String key) {
- unparcel();
- return mMap.get(key);
+ return super.get(key);
}
/**
@@ -316,24 +232,33 @@
*
* @param key a String key
*/
+ @Override
public void remove(String key) {
- unparcel();
- mMap.remove(key);
+ super.remove(key);
}
/**
* Inserts all mappings from the given Bundle into this Bundle.
*
- * @param map a Bundle
+ * @param bundle a Bundle
*/
- public void putAll(Bundle map) {
+ public void putAll(Bundle bundle) {
unparcel();
- map.unparcel();
- mMap.putAll(map.mMap);
+ bundle.unparcel();
+ mMap.putAll(bundle.mMap);
// fd state is now known if and only if both bundles already knew
- mHasFds |= map.mHasFds;
- mFdsKnown = mFdsKnown && map.mFdsKnown;
+ mHasFds |= bundle.mHasFds;
+ mFdsKnown = mFdsKnown && bundle.mFdsKnown;
+ }
+
+ /**
+ * Inserts all mappings from the given PersistableBundle into this Bundle.
+ *
+ * @param bundle a PersistableBundle
+ */
+ public void putAll(PersistableBundle bundle) {
+ super.putAll(bundle);
}
/**
@@ -341,9 +266,9 @@
*
* @return a Set of String keys
*/
+ @Override
public Set<String> keySet() {
- unparcel();
- return mMap.keySet();
+ return super.keySet();
}
/**
@@ -352,7 +277,7 @@
public boolean hasFileDescriptors() {
if (!mFdsKnown) {
boolean fdFound = false; // keep going until we find one or run out of data
-
+
if (mParcelledData != null) {
if (mParcelledData.hasFileDescriptors()) {
fdFound = true;
@@ -390,8 +315,7 @@
ArrayList array = (ArrayList) obj;
// an ArrayList here might contain either Strings or
// Parcelables; only look inside for Parcelables
- if ((array.size() > 0)
- && (array.get(0) instanceof Parcelable)) {
+ if (!array.isEmpty() && (array.get(0) instanceof Parcelable)) {
for (int n = array.size() - 1; n >= 0; n--) {
Parcelable p = (Parcelable) array.get(n);
if (p != null && ((p.describeContents()
@@ -410,7 +334,7 @@
}
return mHasFds;
}
-
+
/**
* Inserts a Boolean value into the mapping of this Bundle, replacing
* any existing value for the given key. Either key or value may be null.
@@ -418,9 +342,9 @@
* @param key a String, or null
* @param value a Boolean, or null
*/
+ @Override
public void putBoolean(String key, boolean value) {
- unparcel();
- mMap.put(key, value);
+ super.putBoolean(key, value);
}
/**
@@ -430,9 +354,9 @@
* @param key a String, or null
* @param value a byte
*/
+ @Override
public void putByte(String key, byte value) {
- unparcel();
- mMap.put(key, value);
+ super.putByte(key, value);
}
/**
@@ -442,9 +366,9 @@
* @param key a String, or null
* @param value a char, or null
*/
+ @Override
public void putChar(String key, char value) {
- unparcel();
- mMap.put(key, value);
+ super.putChar(key, value);
}
/**
@@ -454,9 +378,9 @@
* @param key a String, or null
* @param value a short
*/
+ @Override
public void putShort(String key, short value) {
- unparcel();
- mMap.put(key, value);
+ super.putShort(key, value);
}
/**
@@ -466,9 +390,9 @@
* @param key a String, or null
* @param value an int, or null
*/
+ @Override
public void putInt(String key, int value) {
- unparcel();
- mMap.put(key, value);
+ super.putInt(key, value);
}
/**
@@ -478,9 +402,9 @@
* @param key a String, or null
* @param value a long
*/
+ @Override
public void putLong(String key, long value) {
- unparcel();
- mMap.put(key, value);
+ super.putLong(key, value);
}
/**
@@ -490,9 +414,9 @@
* @param key a String, or null
* @param value a float
*/
+ @Override
public void putFloat(String key, float value) {
- unparcel();
- mMap.put(key, value);
+ super.putFloat(key, value);
}
/**
@@ -502,9 +426,9 @@
* @param key a String, or null
* @param value a double
*/
+ @Override
public void putDouble(String key, double value) {
- unparcel();
- mMap.put(key, value);
+ super.putDouble(key, value);
}
/**
@@ -514,9 +438,9 @@
* @param key a String, or null
* @param value a String, or null
*/
+ @Override
public void putString(String key, String value) {
- unparcel();
- mMap.put(key, value);
+ super.putString(key, value);
}
/**
@@ -526,9 +450,9 @@
* @param key a String, or null
* @param value a CharSequence, or null
*/
+ @Override
public void putCharSequence(String key, CharSequence value) {
- unparcel();
- mMap.put(key, value);
+ super.putCharSequence(key, value);
}
/**
@@ -567,7 +491,7 @@
* @param value an ArrayList of Parcelable objects, or null
*/
public void putParcelableArrayList(String key,
- ArrayList<? extends Parcelable> value) {
+ ArrayList<? extends Parcelable> value) {
unparcel();
mMap.put(key, value);
mFdsKnown = false;
@@ -602,9 +526,9 @@
* @param key a String, or null
* @param value an ArrayList<Integer> object, or null
*/
+ @Override
public void putIntegerArrayList(String key, ArrayList<Integer> value) {
- unparcel();
- mMap.put(key, value);
+ super.putIntegerArrayList(key, value);
}
/**
@@ -614,9 +538,9 @@
* @param key a String, or null
* @param value an ArrayList<String> object, or null
*/
+ @Override
public void putStringArrayList(String key, ArrayList<String> value) {
- unparcel();
- mMap.put(key, value);
+ super.putStringArrayList(key, value);
}
/**
@@ -626,9 +550,9 @@
* @param key a String, or null
* @param value an ArrayList<CharSequence> object, or null
*/
+ @Override
public void putCharSequenceArrayList(String key, ArrayList<CharSequence> value) {
- unparcel();
- mMap.put(key, value);
+ super.putCharSequenceArrayList(key, value);
}
/**
@@ -638,9 +562,9 @@
* @param key a String, or null
* @param value a Serializable object, or null
*/
+ @Override
public void putSerializable(String key, Serializable value) {
- unparcel();
- mMap.put(key, value);
+ super.putSerializable(key, value);
}
/**
@@ -650,9 +574,9 @@
* @param key a String, or null
* @param value a boolean array object, or null
*/
+ @Override
public void putBooleanArray(String key, boolean[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putBooleanArray(key, value);
}
/**
@@ -662,9 +586,9 @@
* @param key a String, or null
* @param value a byte array object, or null
*/
+ @Override
public void putByteArray(String key, byte[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putByteArray(key, value);
}
/**
@@ -674,9 +598,9 @@
* @param key a String, or null
* @param value a short array object, or null
*/
+ @Override
public void putShortArray(String key, short[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putShortArray(key, value);
}
/**
@@ -686,9 +610,9 @@
* @param key a String, or null
* @param value a char array object, or null
*/
+ @Override
public void putCharArray(String key, char[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putCharArray(key, value);
}
/**
@@ -698,9 +622,9 @@
* @param key a String, or null
* @param value an int array object, or null
*/
+ @Override
public void putIntArray(String key, int[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putIntArray(key, value);
}
/**
@@ -710,9 +634,9 @@
* @param key a String, or null
* @param value a long array object, or null
*/
+ @Override
public void putLongArray(String key, long[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putLongArray(key, value);
}
/**
@@ -722,9 +646,9 @@
* @param key a String, or null
* @param value a float array object, or null
*/
+ @Override
public void putFloatArray(String key, float[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putFloatArray(key, value);
}
/**
@@ -734,9 +658,9 @@
* @param key a String, or null
* @param value a double array object, or null
*/
+ @Override
public void putDoubleArray(String key, double[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putDoubleArray(key, value);
}
/**
@@ -746,9 +670,9 @@
* @param key a String, or null
* @param value a String array object, or null
*/
+ @Override
public void putStringArray(String key, String[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putStringArray(key, value);
}
/**
@@ -758,9 +682,9 @@
* @param key a String, or null
* @param value a CharSequence array object, or null
*/
+ @Override
public void putCharSequenceArray(String key, CharSequence[] value) {
- unparcel();
- mMap.put(key, value);
+ super.putCharSequenceArray(key, value);
}
/**
@@ -776,6 +700,17 @@
}
/**
+ * Inserts a PersistableBundle value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a Bundle object, or null
+ */
+ public void putPersistableBundle(String key, PersistableBundle value) {
+ super.putPersistableBundle(key, value);
+ }
+
+ /**
* Inserts an {@link IBinder} value into the mapping of this Bundle, replacing
* any existing value for the given key. Either key or value may be null.
*
@@ -817,33 +752,9 @@
* @param key a String
* @return a boolean value
*/
+ @Override
public boolean getBoolean(String key) {
- unparcel();
- if (DEBUG) Log.d(TAG, "Getting boolean in "
- + Integer.toHexString(System.identityHashCode(this)));
- return getBoolean(key, false);
- }
-
- // Log a message if the value was non-null but not of the expected type
- private void typeWarning(String key, Object value, String className,
- Object defaultValue, ClassCastException e) {
- StringBuilder sb = new StringBuilder();
- sb.append("Key ");
- sb.append(key);
- sb.append(" expected ");
- sb.append(className);
- sb.append(" but value was a ");
- sb.append(value.getClass().getName());
- sb.append(". The default value ");
- sb.append(defaultValue);
- sb.append(" was returned.");
- Log.w(TAG, sb.toString());
- Log.w(TAG, "Attempt to cast generated internal exception:", e);
- }
-
- private void typeWarning(String key, Object value, String className,
- ClassCastException e) {
- typeWarning(key, value, className, "<null>", e);
+ return super.getBoolean(key);
}
/**
@@ -854,18 +765,9 @@
* @param defaultValue Value to return if key does not exist
* @return a boolean value
*/
+ @Override
public boolean getBoolean(String key, boolean defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Boolean) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Boolean", defaultValue, e);
- return defaultValue;
- }
+ return super.getBoolean(key, defaultValue);
}
/**
@@ -875,9 +777,9 @@
* @param key a String
* @return a byte value
*/
+ @Override
public byte getByte(String key) {
- unparcel();
- return getByte(key, (byte) 0);
+ return super.getByte(key);
}
/**
@@ -888,18 +790,9 @@
* @param defaultValue Value to return if key does not exist
* @return a byte value
*/
+ @Override
public Byte getByte(String key, byte defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Byte) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Byte", defaultValue, e);
- return defaultValue;
- }
+ return super.getByte(key, defaultValue);
}
/**
@@ -909,9 +802,9 @@
* @param key a String
* @return a char value
*/
+ @Override
public char getChar(String key) {
- unparcel();
- return getChar(key, (char) 0);
+ return super.getChar(key);
}
/**
@@ -922,18 +815,9 @@
* @param defaultValue Value to return if key does not exist
* @return a char value
*/
+ @Override
public char getChar(String key, char defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Character) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Character", defaultValue, e);
- return defaultValue;
- }
+ return super.getChar(key, defaultValue);
}
/**
@@ -943,9 +827,9 @@
* @param key a String
* @return a short value
*/
+ @Override
public short getShort(String key) {
- unparcel();
- return getShort(key, (short) 0);
+ return super.getShort(key);
}
/**
@@ -956,18 +840,9 @@
* @param defaultValue Value to return if key does not exist
* @return a short value
*/
+ @Override
public short getShort(String key, short defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Short) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Short", defaultValue, e);
- return defaultValue;
- }
+ return super.getShort(key, defaultValue);
}
/**
@@ -977,9 +852,9 @@
* @param key a String
* @return an int value
*/
+ @Override
public int getInt(String key) {
- unparcel();
- return getInt(key, 0);
+ return super.getInt(key);
}
/**
@@ -990,18 +865,9 @@
* @param defaultValue Value to return if key does not exist
* @return an int value
*/
+ @Override
public int getInt(String key, int defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Integer) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Integer", defaultValue, e);
- return defaultValue;
- }
+ return super.getInt(key, defaultValue);
}
/**
@@ -1011,9 +877,9 @@
* @param key a String
* @return a long value
*/
+ @Override
public long getLong(String key) {
- unparcel();
- return getLong(key, 0L);
+ return super.getLong(key);
}
/**
@@ -1024,18 +890,9 @@
* @param defaultValue Value to return if key does not exist
* @return a long value
*/
+ @Override
public long getLong(String key, long defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Long) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Long", defaultValue, e);
- return defaultValue;
- }
+ return super.getLong(key, defaultValue);
}
/**
@@ -1045,9 +902,9 @@
* @param key a String
* @return a float value
*/
+ @Override
public float getFloat(String key) {
- unparcel();
- return getFloat(key, 0.0f);
+ return super.getFloat(key);
}
/**
@@ -1058,18 +915,9 @@
* @param defaultValue Value to return if key does not exist
* @return a float value
*/
+ @Override
public float getFloat(String key, float defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Float) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Float", defaultValue, e);
- return defaultValue;
- }
+ return super.getFloat(key, defaultValue);
}
/**
@@ -1079,9 +927,9 @@
* @param key a String
* @return a double value
*/
+ @Override
public double getDouble(String key) {
- unparcel();
- return getDouble(key, 0.0);
+ return super.getDouble(key);
}
/**
@@ -1092,18 +940,9 @@
* @param defaultValue Value to return if key does not exist
* @return a double value
*/
+ @Override
public double getDouble(String key, double defaultValue) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return defaultValue;
- }
- try {
- return (Double) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Double", defaultValue, e);
- return defaultValue;
- }
+ return super.getDouble(key, defaultValue);
}
/**
@@ -1114,15 +953,9 @@
* @param key a String, or null
* @return a String value, or null
*/
+ @Override
public String getString(String key) {
- unparcel();
- final Object o = mMap.get(key);
- try {
- return (String) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "String", e);
- return null;
- }
+ return super.getString(key);
}
/**
@@ -1134,9 +967,9 @@
* @return the String value associated with the given key, or defaultValue
* if no valid String object is currently mapped to that key.
*/
+ @Override
public String getString(String key, String defaultValue) {
- final String s = getString(key);
- return (s == null) ? defaultValue : s;
+ return super.getString(key, defaultValue);
}
/**
@@ -1147,15 +980,9 @@
* @param key a String, or null
* @return a CharSequence value, or null
*/
+ @Override
public CharSequence getCharSequence(String key) {
- unparcel();
- final Object o = mMap.get(key);
- try {
- return (CharSequence) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "CharSequence", e);
- return null;
- }
+ return super.getCharSequence(key);
}
/**
@@ -1167,9 +994,9 @@
* @return the CharSequence value associated with the given key, or defaultValue
* if no valid CharSequence object is currently mapped to that key.
*/
+ @Override
public CharSequence getCharSequence(String key, CharSequence defaultValue) {
- final CharSequence cs = getCharSequence(key);
- return (cs == null) ? defaultValue : cs;
+ return super.getCharSequence(key, defaultValue);
}
/**
@@ -1200,6 +1027,18 @@
* value is explicitly associated with the key.
*
* @param key a String, or null
+ * @return a PersistableBundle value, or null
+ */
+ public PersistableBundle getPersistableBundle(String key) {
+ return super.getPersistableBundle(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
* @return a Parcelable value, or null
*/
public <T extends Parcelable> T getParcelable(String key) {
@@ -1291,18 +1130,9 @@
* @param key a String, or null
* @return a Serializable value, or null
*/
+ @Override
public Serializable getSerializable(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (Serializable) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "Serializable", e);
- return null;
- }
+ return super.getSerializable(key);
}
/**
@@ -1313,18 +1143,9 @@
* @param key a String, or null
* @return an ArrayList<String> value, or null
*/
+ @Override
public ArrayList<Integer> getIntegerArrayList(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (ArrayList<Integer>) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "ArrayList<Integer>", e);
- return null;
- }
+ return super.getIntegerArrayList(key);
}
/**
@@ -1335,18 +1156,9 @@
* @param key a String, or null
* @return an ArrayList<String> value, or null
*/
+ @Override
public ArrayList<String> getStringArrayList(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (ArrayList<String>) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "ArrayList<String>", e);
- return null;
- }
+ return super.getStringArrayList(key);
}
/**
@@ -1357,18 +1169,9 @@
* @param key a String, or null
* @return an ArrayList<CharSequence> value, or null
*/
+ @Override
public ArrayList<CharSequence> getCharSequenceArrayList(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (ArrayList<CharSequence>) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "ArrayList<CharSequence>", e);
- return null;
- }
+ return super.getCharSequenceArrayList(key);
}
/**
@@ -1379,18 +1182,9 @@
* @param key a String, or null
* @return a boolean[] value, or null
*/
+ @Override
public boolean[] getBooleanArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (boolean[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "byte[]", e);
- return null;
- }
+ return super.getBooleanArray(key);
}
/**
@@ -1401,18 +1195,9 @@
* @param key a String, or null
* @return a byte[] value, or null
*/
+ @Override
public byte[] getByteArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (byte[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "byte[]", e);
- return null;
- }
+ return super.getByteArray(key);
}
/**
@@ -1423,18 +1208,9 @@
* @param key a String, or null
* @return a short[] value, or null
*/
+ @Override
public short[] getShortArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (short[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "short[]", e);
- return null;
- }
+ return super.getShortArray(key);
}
/**
@@ -1445,18 +1221,9 @@
* @param key a String, or null
* @return a char[] value, or null
*/
+ @Override
public char[] getCharArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (char[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "char[]", e);
- return null;
- }
+ return super.getCharArray(key);
}
/**
@@ -1467,18 +1234,9 @@
* @param key a String, or null
* @return an int[] value, or null
*/
+ @Override
public int[] getIntArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (int[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "int[]", e);
- return null;
- }
+ return super.getIntArray(key);
}
/**
@@ -1489,18 +1247,9 @@
* @param key a String, or null
* @return a long[] value, or null
*/
+ @Override
public long[] getLongArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (long[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "long[]", e);
- return null;
- }
+ return super.getLongArray(key);
}
/**
@@ -1511,18 +1260,9 @@
* @param key a String, or null
* @return a float[] value, or null
*/
+ @Override
public float[] getFloatArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (float[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "float[]", e);
- return null;
- }
+ return super.getFloatArray(key);
}
/**
@@ -1533,18 +1273,9 @@
* @param key a String, or null
* @return a double[] value, or null
*/
+ @Override
public double[] getDoubleArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (double[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "double[]", e);
- return null;
- }
+ return super.getDoubleArray(key);
}
/**
@@ -1555,18 +1286,9 @@
* @param key a String, or null
* @return a String[] value, or null
*/
+ @Override
public String[] getStringArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (String[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "String[]", e);
- return null;
- }
+ return super.getStringArray(key);
}
/**
@@ -1577,18 +1299,9 @@
* @param key a String, or null
* @return a CharSequence[] value, or null
*/
+ @Override
public CharSequence[] getCharSequenceArray(String key) {
- unparcel();
- Object o = mMap.get(key);
- if (o == null) {
- return null;
- }
- try {
- return (CharSequence[]) o;
- } catch (ClassCastException e) {
- typeWarning(key, o, "CharSequence[]", e);
- return null;
- }
+ return super.getCharSequenceArray(key);
}
/**
@@ -1641,10 +1354,12 @@
public static final Parcelable.Creator<Bundle> CREATOR =
new Parcelable.Creator<Bundle>() {
+ @Override
public Bundle createFromParcel(Parcel in) {
return in.readBundle();
}
+ @Override
public Bundle[] newArray(int size) {
return new Bundle[size];
}
@@ -1653,6 +1368,7 @@
/**
* Report the nature of this Parcelable's contents
*/
+ @Override
public int describeContents() {
int mask = 0;
if (hasFileDescriptors()) {
@@ -1660,44 +1376,17 @@
}
return mask;
}
-
+
/**
* Writes the Bundle contents to a Parcel, typically in order for
* it to be passed through an IBinder connection.
* @param parcel The parcel to copy this bundle to.
*/
+ @Override
public void writeToParcel(Parcel parcel, int flags) {
final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
try {
- if (mParcelledData != null) {
- if (mParcelledData == EMPTY_PARCEL) {
- parcel.writeInt(0);
- } else {
- int length = mParcelledData.dataSize();
- parcel.writeInt(length);
- parcel.writeInt(BUNDLE_MAGIC);
- parcel.appendFrom(mParcelledData, 0, length);
- }
- } else {
- // Special case for empty bundles.
- if (mMap == null || mMap.size() <= 0) {
- parcel.writeInt(0);
- return;
- }
- int lengthPos = parcel.dataPosition();
- parcel.writeInt(-1); // dummy, will hold length
- parcel.writeInt(BUNDLE_MAGIC);
-
- int startPos = parcel.dataPosition();
- parcel.writeArrayMapInternal(mMap);
- int endPos = parcel.dataPosition();
-
- // Backpatch length
- parcel.setDataPosition(lengthPos);
- int length = endPos - startPos;
- parcel.writeInt(length);
- parcel.setDataPosition(endPos);
- }
+ super.writeToParcelInner(parcel, flags);
} finally {
parcel.restoreAllowFds(oldAllowFds);
}
@@ -1709,41 +1398,8 @@
* @param parcel The parcel to overwrite this bundle from.
*/
public void readFromParcel(Parcel parcel) {
- int length = parcel.readInt();
- if (length < 0) {
- throw new RuntimeException("Bad length in parcel: " + length);
- }
- readFromParcelInner(parcel, length);
- }
-
- void readFromParcelInner(Parcel parcel, int length) {
- if (length == 0) {
- // Empty Bundle or end of data.
- mParcelledData = EMPTY_PARCEL;
- mHasFds = false;
- mFdsKnown = true;
- return;
- }
- int magic = parcel.readInt();
- if (magic != BUNDLE_MAGIC) {
- //noinspection ThrowableInstanceNeverThrown
- throw new IllegalStateException("Bad magic number for Bundle: 0x"
- + Integer.toHexString(magic));
- }
-
- // Advance within this Parcel
- int offset = parcel.dataPosition();
- parcel.setDataPosition(offset + length);
-
- Parcel p = Parcel.obtain();
- p.setDataPosition(0);
- p.appendFrom(parcel, offset, length);
- if (DEBUG) Log.d(TAG, "Retrieving " + Integer.toHexString(System.identityHashCode(this))
- + ": " + length + " bundle bytes starting at " + offset);
- p.setDataPosition(0);
-
- mParcelledData = p;
- mHasFds = p.hasFileDescriptors();
+ super.readFromParcelInner(parcel);
+ mHasFds = mParcelledData.hasFileDescriptors();
mFdsKnown = true;
}
@@ -1759,4 +1415,5 @@
}
return "Bundle[" + mMap.toString() + "]";
}
+
}
diff --git a/core/java/android/os/CommonBundle.java b/core/java/android/os/CommonBundle.java
new file mode 100644
index 0000000..e11f170
--- /dev/null
+++ b/core/java/android/os/CommonBundle.java
@@ -0,0 +1,1384 @@
+/*
+ * Copyright (C) 2014 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.os;
+
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A mapping from String values to various types.
+ */
+abstract class CommonBundle implements Parcelable, Cloneable {
+ private static final String TAG = "Bundle";
+ static final boolean DEBUG = false;
+
+ static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
+ static final Parcel EMPTY_PARCEL;
+
+ static {
+ EMPTY_PARCEL = Parcel.obtain();
+ }
+
+ // Invariant - exactly one of mMap / mParcelledData will be null
+ // (except inside a call to unparcel)
+
+ ArrayMap<String, Object> mMap = null;
+
+ /*
+ * If mParcelledData is non-null, then mMap will be null and the
+ * data are stored as a Parcel containing a Bundle. When the data
+ * are unparcelled, mParcelledData willbe set to null.
+ */
+ Parcel mParcelledData = null;
+
+ /**
+ * The ClassLoader used when unparcelling data from mParcelledData.
+ */
+ private ClassLoader mClassLoader;
+
+ /**
+ * Constructs a new, empty Bundle that uses a specific ClassLoader for
+ * instantiating Parcelable and Serializable objects.
+ *
+ * @param loader An explicit ClassLoader to use when instantiating objects
+ * inside of the Bundle.
+ * @param capacity Initial size of the ArrayMap.
+ */
+ CommonBundle(ClassLoader loader, int capacity) {
+ mMap = capacity > 0 ?
+ new ArrayMap<String, Object>(capacity) : new ArrayMap<String, Object>();
+ mClassLoader = loader == null ? getClass().getClassLoader() : loader;
+ }
+
+ /**
+ * Constructs a new, empty Bundle.
+ */
+ CommonBundle() {
+ this((ClassLoader) null, 0);
+ }
+
+ /**
+ * Constructs a Bundle whose data is stored as a Parcel. The data
+ * will be unparcelled on first contact, using the assigned ClassLoader.
+ *
+ * @param parcelledData a Parcel containing a Bundle
+ */
+ CommonBundle(Parcel parcelledData) {
+ readFromParcelInner(parcelledData);
+ }
+
+ CommonBundle(Parcel parcelledData, int length) {
+ readFromParcelInner(parcelledData, length);
+ }
+
+ /**
+ * Constructs a new, empty Bundle that uses a specific ClassLoader for
+ * instantiating Parcelable and Serializable objects.
+ *
+ * @param loader An explicit ClassLoader to use when instantiating objects
+ * inside of the Bundle.
+ */
+ CommonBundle(ClassLoader loader) {
+ this(loader, 0);
+ }
+
+ /**
+ * Constructs a new, empty Bundle sized to hold the given number of
+ * elements. The Bundle will grow as needed.
+ *
+ * @param capacity the initial capacity of the Bundle
+ */
+ CommonBundle(int capacity) {
+ this((ClassLoader) null, capacity);
+ }
+
+ /**
+ * Constructs a Bundle containing a copy of the mappings from the given
+ * Bundle.
+ *
+ * @param b a Bundle to be copied.
+ */
+ CommonBundle(CommonBundle b) {
+ if (b.mParcelledData != null) {
+ if (b.mParcelledData == EMPTY_PARCEL) {
+ mParcelledData = EMPTY_PARCEL;
+ } else {
+ mParcelledData = Parcel.obtain();
+ mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize());
+ mParcelledData.setDataPosition(0);
+ }
+ } else {
+ mParcelledData = null;
+ }
+
+ if (b.mMap != null) {
+ mMap = new ArrayMap<String, Object>(b.mMap);
+ } else {
+ mMap = null;
+ }
+
+ mClassLoader = b.mClassLoader;
+ }
+
+ /**
+ * TODO: optimize this later (getting just the value part of a Bundle
+ * with a single pair) once Bundle.forPair() above is implemented
+ * with a special single-value Map implementation/serialization.
+ *
+ * Note: value in single-pair Bundle may be null.
+ *
+ * @hide
+ */
+ String getPairValue() {
+ unparcel();
+ int size = mMap.size();
+ if (size > 1) {
+ Log.w(TAG, "getPairValue() used on Bundle with multiple pairs.");
+ }
+ if (size == 0) {
+ return null;
+ }
+ Object o = mMap.valueAt(0);
+ try {
+ return (String) o;
+ } catch (ClassCastException e) {
+ typeWarning("getPairValue()", o, "String", e);
+ return null;
+ }
+ }
+
+ /**
+ * Changes the ClassLoader this Bundle uses when instantiating objects.
+ *
+ * @param loader An explicit ClassLoader to use when instantiating objects
+ * inside of the Bundle.
+ */
+ void setClassLoader(ClassLoader loader) {
+ mClassLoader = loader;
+ }
+
+ /**
+ * Return the ClassLoader currently associated with this Bundle.
+ */
+ ClassLoader getClassLoader() {
+ return mClassLoader;
+ }
+
+ /**
+ * If the underlying data are stored as a Parcel, unparcel them
+ * using the currently assigned class loader.
+ */
+ /* package */ synchronized void unparcel() {
+ if (mParcelledData == null) {
+ if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ + ": no parcelled data");
+ return;
+ }
+
+ if (mParcelledData == EMPTY_PARCEL) {
+ if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ + ": empty");
+ if (mMap == null) {
+ mMap = new ArrayMap<String, Object>(1);
+ } else {
+ mMap.erase();
+ }
+ mParcelledData = null;
+ return;
+ }
+
+ int N = mParcelledData.readInt();
+ if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ + ": reading " + N + " maps");
+ if (N < 0) {
+ return;
+ }
+ if (mMap == null) {
+ mMap = new ArrayMap<String, Object>(N);
+ } else {
+ mMap.erase();
+ mMap.ensureCapacity(N);
+ }
+ mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
+ mParcelledData.recycle();
+ mParcelledData = null;
+ if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
+ + " final map: " + mMap);
+ }
+
+ /**
+ * @hide
+ */
+ boolean isParcelled() {
+ return mParcelledData != null;
+ }
+
+ /**
+ * Returns the number of mappings contained in this Bundle.
+ *
+ * @return the number of mappings as an int.
+ */
+ int size() {
+ unparcel();
+ return mMap.size();
+ }
+
+ /**
+ * Returns true if the mapping of this Bundle is empty, false otherwise.
+ */
+ boolean isEmpty() {
+ unparcel();
+ return mMap.isEmpty();
+ }
+
+ /**
+ * Removes all elements from the mapping of this Bundle.
+ */
+ void clear() {
+ unparcel();
+ mMap.clear();
+ }
+
+ /**
+ * Returns true if the given key is contained in the mapping
+ * of this Bundle.
+ *
+ * @param key a String key
+ * @return true if the key is part of the mapping, false otherwise
+ */
+ boolean containsKey(String key) {
+ unparcel();
+ return mMap.containsKey(key);
+ }
+
+ /**
+ * Returns the entry with the given key as an object.
+ *
+ * @param key a String key
+ * @return an Object, or null
+ */
+ Object get(String key) {
+ unparcel();
+ return mMap.get(key);
+ }
+
+ /**
+ * Removes any entry with the given key from the mapping of this Bundle.
+ *
+ * @param key a String key
+ */
+ void remove(String key) {
+ unparcel();
+ mMap.remove(key);
+ }
+
+ /**
+ * Inserts all mappings from the given PersistableBundle into this CommonBundle.
+ *
+ * @param bundle a PersistableBundle
+ */
+ void putAll(PersistableBundle bundle) {
+ unparcel();
+ bundle.unparcel();
+ mMap.putAll(bundle.mMap);
+ }
+
+ /**
+ * Returns a Set containing the Strings used as keys in this Bundle.
+ *
+ * @return a Set of String keys
+ */
+ Set<String> keySet() {
+ unparcel();
+ return mMap.keySet();
+ }
+
+ /**
+ * Inserts a Boolean value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a Boolean, or null
+ */
+ void putBoolean(String key, boolean value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a byte value into the mapping of this Bundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a byte
+ */
+ void putByte(String key, byte value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a char value into the mapping of this Bundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a char, or null
+ */
+ void putChar(String key, char value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a short value into the mapping of this Bundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a short
+ */
+ void putShort(String key, short value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts an int value into the mapping of this Bundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value an int, or null
+ */
+ void putInt(String key, int value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a long value into the mapping of this Bundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a long
+ */
+ void putLong(String key, long value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a float value into the mapping of this Bundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a float
+ */
+ void putFloat(String key, float value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a double value into the mapping of this Bundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a double
+ */
+ void putDouble(String key, double value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a String value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a String, or null
+ */
+ void putString(String key, String value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a CharSequence value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a CharSequence, or null
+ */
+ void putCharSequence(String key, CharSequence value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value an ArrayList<Integer> object, or null
+ */
+ void putIntegerArrayList(String key, ArrayList<Integer> value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value an ArrayList<String> object, or null
+ */
+ void putStringArrayList(String key, ArrayList<String> value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value an ArrayList<CharSequence> object, or null
+ */
+ void putCharSequenceArrayList(String key, ArrayList<CharSequence> value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a Serializable value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a Serializable object, or null
+ */
+ void putSerializable(String key, Serializable value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a boolean array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a boolean array object, or null
+ */
+ void putBooleanArray(String key, boolean[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a byte array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a byte array object, or null
+ */
+ void putByteArray(String key, byte[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a short array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a short array object, or null
+ */
+ void putShortArray(String key, short[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a char array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a char array object, or null
+ */
+ void putCharArray(String key, char[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts an int array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value an int array object, or null
+ */
+ void putIntArray(String key, int[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a long array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a long array object, or null
+ */
+ void putLongArray(String key, long[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a float array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a float array object, or null
+ */
+ void putFloatArray(String key, float[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a double array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a double array object, or null
+ */
+ void putDoubleArray(String key, double[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a String array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a String array object, or null
+ */
+ void putStringArray(String key, String[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a CharSequence array value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a CharSequence array object, or null
+ */
+ void putCharSequenceArray(String key, CharSequence[] value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Inserts a PersistableBundle value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a Bundle object, or null
+ */
+ void putPersistableBundle(String key, PersistableBundle value) {
+ unparcel();
+ mMap.put(key, value);
+ }
+
+ /**
+ * Returns the value associated with the given key, or false if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a boolean value
+ */
+ boolean getBoolean(String key) {
+ unparcel();
+ if (DEBUG) Log.d(TAG, "Getting boolean in "
+ + Integer.toHexString(System.identityHashCode(this)));
+ return getBoolean(key, false);
+ }
+
+ // Log a message if the value was non-null but not of the expected type
+ void typeWarning(String key, Object value, String className,
+ Object defaultValue, ClassCastException e) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Key ");
+ sb.append(key);
+ sb.append(" expected ");
+ sb.append(className);
+ sb.append(" but value was a ");
+ sb.append(value.getClass().getName());
+ sb.append(". The default value ");
+ sb.append(defaultValue);
+ sb.append(" was returned.");
+ Log.w(TAG, sb.toString());
+ Log.w(TAG, "Attempt to cast generated internal exception:", e);
+ }
+
+ void typeWarning(String key, Object value, String className,
+ ClassCastException e) {
+ typeWarning(key, value, className, "<null>", e);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a boolean value
+ */
+ boolean getBoolean(String key, boolean defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Boolean) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Boolean", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or (byte) 0 if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a byte value
+ */
+ byte getByte(String key) {
+ unparcel();
+ return getByte(key, (byte) 0);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a byte value
+ */
+ Byte getByte(String key, byte defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Byte) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Byte", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or (char) 0 if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a char value
+ */
+ char getChar(String key) {
+ unparcel();
+ return getChar(key, (char) 0);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a char value
+ */
+ char getChar(String key, char defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Character) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Character", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or (short) 0 if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a short value
+ */
+ short getShort(String key) {
+ unparcel();
+ return getShort(key, (short) 0);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a short value
+ */
+ short getShort(String key, short defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Short) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Short", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or 0 if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return an int value
+ */
+ int getInt(String key) {
+ unparcel();
+ return getInt(key, 0);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return an int value
+ */
+ int getInt(String key, int defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Integer) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Integer", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or 0L if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a long value
+ */
+ long getLong(String key) {
+ unparcel();
+ return getLong(key, 0L);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a long value
+ */
+ long getLong(String key, long defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Long) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Long", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or 0.0f if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a float value
+ */
+ float getFloat(String key) {
+ unparcel();
+ return getFloat(key, 0.0f);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a float value
+ */
+ float getFloat(String key, float defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Float) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Float", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or 0.0 if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a double value
+ */
+ double getDouble(String key) {
+ unparcel();
+ return getDouble(key, 0.0);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a double value
+ */
+ double getDouble(String key, double defaultValue) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return defaultValue;
+ }
+ try {
+ return (Double) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Double", defaultValue, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a String value, or null
+ */
+ String getString(String key) {
+ unparcel();
+ final Object o = mMap.get(key);
+ try {
+ return (String) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "String", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String, or null
+ * @param defaultValue Value to return if key does not exist
+ * @return the String value associated with the given key, or defaultValue
+ * if no valid String object is currently mapped to that key.
+ */
+ String getString(String key, String defaultValue) {
+ final String s = getString(key);
+ return (s == null) ? defaultValue : s;
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a CharSequence value, or null
+ */
+ CharSequence getCharSequence(String key) {
+ unparcel();
+ final Object o = mMap.get(key);
+ try {
+ return (CharSequence) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "CharSequence", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String, or null
+ * @param defaultValue Value to return if key does not exist
+ * @return the CharSequence value associated with the given key, or defaultValue
+ * if no valid CharSequence object is currently mapped to that key.
+ */
+ CharSequence getCharSequence(String key, CharSequence defaultValue) {
+ final CharSequence cs = getCharSequence(key);
+ return (cs == null) ? defaultValue : cs;
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a Bundle value, or null
+ */
+ PersistableBundle getPersistableBundle(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (PersistableBundle) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Bundle", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a Serializable value, or null
+ */
+ Serializable getSerializable(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (Serializable) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "Serializable", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return an ArrayList<String> value, or null
+ */
+ ArrayList<Integer> getIntegerArrayList(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (ArrayList<Integer>) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "ArrayList<Integer>", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return an ArrayList<String> value, or null
+ */
+ ArrayList<String> getStringArrayList(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (ArrayList<String>) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "ArrayList<String>", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return an ArrayList<CharSequence> value, or null
+ */
+ ArrayList<CharSequence> getCharSequenceArrayList(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (ArrayList<CharSequence>) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "ArrayList<CharSequence>", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a boolean[] value, or null
+ */
+ boolean[] getBooleanArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (boolean[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "byte[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a byte[] value, or null
+ */
+ byte[] getByteArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (byte[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "byte[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a short[] value, or null
+ */
+ short[] getShortArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (short[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "short[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a char[] value, or null
+ */
+ char[] getCharArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (char[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "char[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return an int[] value, or null
+ */
+ int[] getIntArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (int[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "int[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a long[] value, or null
+ */
+ long[] getLongArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (long[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "long[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a float[] value, or null
+ */
+ float[] getFloatArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (float[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "float[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a double[] value, or null
+ */
+ double[] getDoubleArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (double[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "double[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a String[] value, or null
+ */
+ String[] getStringArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (String[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "String[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a CharSequence[] value, or null
+ */
+ CharSequence[] getCharSequenceArray(String key) {
+ unparcel();
+ Object o = mMap.get(key);
+ if (o == null) {
+ return null;
+ }
+ try {
+ return (CharSequence[]) o;
+ } catch (ClassCastException e) {
+ typeWarning(key, o, "CharSequence[]", e);
+ return null;
+ }
+ }
+
+ /**
+ * Writes the Bundle contents to a Parcel, typically in order for
+ * it to be passed through an IBinder connection.
+ * @param parcel The parcel to copy this bundle to.
+ */
+ void writeToParcelInner(Parcel parcel, int flags) {
+ if (mParcelledData != null) {
+ if (mParcelledData == EMPTY_PARCEL) {
+ parcel.writeInt(0);
+ } else {
+ int length = mParcelledData.dataSize();
+ parcel.writeInt(length);
+ parcel.writeInt(BUNDLE_MAGIC);
+ parcel.appendFrom(mParcelledData, 0, length);
+ }
+ } else {
+ // Special case for empty bundles.
+ if (mMap == null || mMap.size() <= 0) {
+ parcel.writeInt(0);
+ return;
+ }
+ int lengthPos = parcel.dataPosition();
+ parcel.writeInt(-1); // dummy, will hold length
+ parcel.writeInt(BUNDLE_MAGIC);
+
+ int startPos = parcel.dataPosition();
+ parcel.writeArrayMapInternal(mMap);
+ int endPos = parcel.dataPosition();
+
+ // Backpatch length
+ parcel.setDataPosition(lengthPos);
+ int length = endPos - startPos;
+ parcel.writeInt(length);
+ parcel.setDataPosition(endPos);
+ }
+ }
+
+ /**
+ * Reads the Parcel contents into this Bundle, typically in order for
+ * it to be passed through an IBinder connection.
+ * @param parcel The parcel to overwrite this bundle from.
+ */
+ void readFromParcelInner(Parcel parcel) {
+ int length = parcel.readInt();
+ if (length < 0) {
+ throw new RuntimeException("Bad length in parcel: " + length);
+ }
+ readFromParcelInner(parcel, length);
+ }
+
+ private void readFromParcelInner(Parcel parcel, int length) {
+ if (length == 0) {
+ // Empty Bundle or end of data.
+ mParcelledData = EMPTY_PARCEL;
+ return;
+ }
+ int magic = parcel.readInt();
+ if (magic != BUNDLE_MAGIC) {
+ //noinspection ThrowableInstanceNeverThrown
+ throw new IllegalStateException("Bad magic number for Bundle: 0x"
+ + Integer.toHexString(magic));
+ }
+
+ // Advance within this Parcel
+ int offset = parcel.dataPosition();
+ parcel.setDataPosition(offset + length);
+
+ Parcel p = Parcel.obtain();
+ p.setDataPosition(0);
+ p.appendFrom(parcel, offset, length);
+ if (DEBUG) Log.d(TAG, "Retrieving " + Integer.toHexString(System.identityHashCode(this))
+ + ": " + length + " bundle bytes starting at " + offset);
+ p.setDataPosition(0);
+
+ mParcelledData = p;
+ }
+}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 8e0ff08..95cb9f3 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -223,6 +223,7 @@
private static final int VAL_SPARSEBOOLEANARRAY = 22;
private static final int VAL_BOOLEANARRAY = 23;
private static final int VAL_CHARSEQUENCEARRAY = 24;
+ private static final int VAL_PERSISTABLEBUNDLE = 25;
// The initial int32 in a Binder call's reply Parcel header:
private static final int EX_SECURITY = -1;
@@ -638,6 +639,19 @@
}
/**
+ * Flatten a PersistableBundle into the parcel at the current dataPosition(),
+ * growing dataCapacity() if needed.
+ */
+ public final void writePersistableBundle(PersistableBundle val) {
+ if (val == null) {
+ writeInt(-1);
+ return;
+ }
+
+ val.writeToParcel(this, 0);
+ }
+
+ /**
* Flatten a List into the parcel at the current dataPosition(), growing
* dataCapacity() if needed. The List values are written using
* {@link #writeValue} and must follow the specification there.
@@ -1256,6 +1270,9 @@
} else if (v instanceof Byte) {
writeInt(VAL_BYTE);
writeInt((Byte) v);
+ } else if (v instanceof PersistableBundle) {
+ writeInt(VAL_PERSISTABLEBUNDLE);
+ writePersistableBundle((PersistableBundle) v);
} else {
Class<?> clazz = v.getClass();
if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -1633,6 +1650,35 @@
}
/**
+ * Read and return a new Bundle object from the parcel at the current
+ * dataPosition(). Returns null if the previously written Bundle object was
+ * null.
+ */
+ public final PersistableBundle readPersistableBundle() {
+ return readPersistableBundle(null);
+ }
+
+ /**
+ * Read and return a new Bundle object from the parcel at the current
+ * dataPosition(), using the given class loader to initialize the class
+ * loader of the Bundle for later retrieval of Parcelable objects.
+ * Returns null if the previously written Bundle object was null.
+ */
+ public final PersistableBundle readPersistableBundle(ClassLoader loader) {
+ int length = readInt();
+ if (length < 0) {
+ if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
+ return null;
+ }
+
+ final PersistableBundle bundle = new PersistableBundle(this, length);
+ if (loader != null) {
+ bundle.setClassLoader(loader);
+ }
+ return bundle;
+ }
+
+ /**
* Read and return a byte[] object from the parcel.
*/
public final byte[] createByteArray() {
@@ -2082,6 +2128,9 @@
case VAL_BUNDLE:
return readBundle(loader); // loading will be deferred
+ case VAL_PERSISTABLEBUNDLE:
+ return readPersistableBundle(loader);
+
default:
int off = dataPosition() - 4;
throw new RuntimeException(
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 86dc8b4..24bf05e 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -42,6 +42,7 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InterruptedIOException;
import java.net.DatagramSocket;
import java.net.Socket;
import java.nio.ByteOrder;
@@ -698,6 +699,9 @@
} catch (ErrnoException e) {
// Reporting status is best-effort
Log.w(TAG, "Failed to report status: " + e);
+ } catch (InterruptedIOException e) {
+ // Reporting status is best-effort
+ Log.w(TAG, "Failed to report status: " + e);
}
} finally {
@@ -728,6 +732,9 @@
Log.d(TAG, "Failed to read status; assuming dead: " + e);
return new Status(Status.DEAD);
}
+ } catch (InterruptedIOException e) {
+ Log.d(TAG, "Failed to read status; assuming dead: " + e);
+ return new Status(Status.DEAD);
}
}
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
new file mode 100644
index 0000000..c2cd3be
--- /dev/null
+++ b/core/java/android/os/PersistableBundle.java
@@ -0,0 +1,555 @@
+/*
+ * Copyright (C) 2014 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.os;
+
+import android.util.ArrayMap;
+
+import java.util.Set;
+
+/**
+ * A mapping from String values to various types that can be saved to persistent and later
+ * restored.
+ *
+ */
+public final class PersistableBundle extends CommonBundle {
+ public static final PersistableBundle EMPTY;
+ static final Parcel EMPTY_PARCEL;
+
+ static {
+ EMPTY = new PersistableBundle();
+ EMPTY.mMap = ArrayMap.EMPTY;
+ EMPTY_PARCEL = CommonBundle.EMPTY_PARCEL;
+ }
+
+ /**
+ * Constructs a new, empty PersistableBundle.
+ */
+ public PersistableBundle() {
+ super();
+ }
+
+ /**
+ * Constructs a PersistableBundle whose data is stored as a Parcel. The data
+ * will be unparcelled on first contact, using the assigned ClassLoader.
+ *
+ * @param parcelledData a Parcel containing a PersistableBundle
+ */
+ PersistableBundle(Parcel parcelledData) {
+ super(parcelledData);
+ }
+
+ /* package */ PersistableBundle(Parcel parcelledData, int length) {
+ super(parcelledData, length);
+ }
+
+ /**
+ * Constructs a new, empty PersistableBundle that uses a specific ClassLoader for
+ * instantiating Parcelable and Serializable objects.
+ *
+ * @param loader An explicit ClassLoader to use when instantiating objects
+ * inside of the PersistableBundle.
+ */
+ public PersistableBundle(ClassLoader loader) {
+ super(loader);
+ }
+
+ /**
+ * Constructs a new, empty PersistableBundle sized to hold the given number of
+ * elements. The PersistableBundle will grow as needed.
+ *
+ * @param capacity the initial capacity of the PersistableBundle
+ */
+ public PersistableBundle(int capacity) {
+ super(capacity);
+ }
+
+ /**
+ * Constructs a PersistableBundle containing a copy of the mappings from the given
+ * PersistableBundle.
+ *
+ * @param b a PersistableBundle to be copied.
+ */
+ public PersistableBundle(PersistableBundle b) {
+ super(b);
+ }
+
+ /**
+ * Make a PersistableBundle for a single key/value pair.
+ *
+ * @hide
+ */
+ public static PersistableBundle forPair(String key, String value) {
+ PersistableBundle b = new PersistableBundle(1);
+ b.putString(key, value);
+ return b;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public String getPairValue() {
+ return super.getPairValue();
+ }
+
+ /**
+ * Changes the ClassLoader this PersistableBundle uses when instantiating objects.
+ *
+ * @param loader An explicit ClassLoader to use when instantiating objects
+ * inside of the PersistableBundle.
+ */
+ @Override
+ public void setClassLoader(ClassLoader loader) {
+ super.setClassLoader(loader);
+ }
+
+ /**
+ * Return the ClassLoader currently associated with this PersistableBundle.
+ */
+ @Override
+ public ClassLoader getClassLoader() {
+ return super.getClassLoader();
+ }
+
+ /**
+ * Clones the current PersistableBundle. The internal map is cloned, but the keys and
+ * values to which it refers are copied by reference.
+ */
+ @Override
+ public Object clone() {
+ return new PersistableBundle(this);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public boolean isParcelled() {
+ return super.isParcelled();
+ }
+
+ /**
+ * Returns the number of mappings contained in this PersistableBundle.
+ *
+ * @return the number of mappings as an int.
+ */
+ @Override
+ public int size() {
+ return super.size();
+ }
+
+ /**
+ * Returns true if the mapping of this PersistableBundle is empty, false otherwise.
+ */
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty();
+ }
+
+ /**
+ * Removes all elements from the mapping of this PersistableBundle.
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ }
+
+ /**
+ * Returns true if the given key is contained in the mapping
+ * of this PersistableBundle.
+ *
+ * @param key a String key
+ * @return true if the key is part of the mapping, false otherwise
+ */
+ @Override
+ public boolean containsKey(String key) {
+ return super.containsKey(key);
+ }
+
+ /**
+ * Returns the entry with the given key as an object.
+ *
+ * @param key a String key
+ * @return an Object, or null
+ */
+ @Override
+ public Object get(String key) {
+ return super.get(key);
+ }
+
+ /**
+ * Removes any entry with the given key from the mapping of this PersistableBundle.
+ *
+ * @param key a String key
+ */
+ @Override
+ public void remove(String key) {
+ super.remove(key);
+ }
+
+ /**
+ * Inserts all mappings from the given PersistableBundle into this Bundle.
+ *
+ * @param bundle a PersistableBundle
+ */
+ public void putAll(PersistableBundle bundle) {
+ super.putAll(bundle);
+ }
+
+ /**
+ * Returns a Set containing the Strings used as keys in this PersistableBundle.
+ *
+ * @return a Set of String keys
+ */
+ @Override
+ public Set<String> keySet() {
+ return super.keySet();
+ }
+
+ /**
+ * Inserts an int value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value an int, or null
+ */
+ @Override
+ public void putInt(String key, int value) {
+ super.putInt(key, value);
+ }
+
+ /**
+ * Inserts a long value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a long
+ */
+ @Override
+ public void putLong(String key, long value) {
+ super.putLong(key, value);
+ }
+
+ /**
+ * Inserts a double value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key.
+ *
+ * @param key a String, or null
+ * @param value a double
+ */
+ @Override
+ public void putDouble(String key, double value) {
+ super.putDouble(key, value);
+ }
+
+ /**
+ * Inserts a String value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a String, or null
+ */
+ @Override
+ public void putString(String key, String value) {
+ super.putString(key, value);
+ }
+
+ /**
+ * Inserts an int array value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value an int array object, or null
+ */
+ @Override
+ public void putIntArray(String key, int[] value) {
+ super.putIntArray(key, value);
+ }
+
+ /**
+ * Inserts a long array value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a long array object, or null
+ */
+ @Override
+ public void putLongArray(String key, long[] value) {
+ super.putLongArray(key, value);
+ }
+
+ /**
+ * Inserts a double array value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a double array object, or null
+ */
+ @Override
+ public void putDoubleArray(String key, double[] value) {
+ super.putDoubleArray(key, value);
+ }
+
+ /**
+ * Inserts a String array value into the mapping of this PersistableBundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a String array object, or null
+ */
+ @Override
+ public void putStringArray(String key, String[] value) {
+ super.putStringArray(key, value);
+ }
+
+ /**
+ * Inserts a PersistableBundle value into the mapping of this Bundle, replacing
+ * any existing value for the given key. Either key or value may be null.
+ *
+ * @param key a String, or null
+ * @param value a Bundle object, or null
+ */
+ public void putPersistableBundle(String key, PersistableBundle value) {
+ super.putPersistableBundle(key, value);
+ }
+
+ /**
+ * Returns the value associated with the given key, or 0 if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return an int value
+ */
+ @Override
+ public int getInt(String key) {
+ return super.getInt(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return an int value
+ */
+ @Override
+ public int getInt(String key, int defaultValue) {
+ return super.getInt(key, defaultValue);
+ }
+
+ /**
+ * Returns the value associated with the given key, or 0L if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a long value
+ */
+ @Override
+ public long getLong(String key) {
+ return super.getLong(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a long value
+ */
+ @Override
+ public long getLong(String key, long defaultValue) {
+ return super.getLong(key, defaultValue);
+ }
+
+ /**
+ * Returns the value associated with the given key, or 0.0 if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @return a double value
+ */
+ @Override
+ public double getDouble(String key) {
+ return super.getDouble(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String
+ * @param defaultValue Value to return if key does not exist
+ * @return a double value
+ */
+ @Override
+ public double getDouble(String key, double defaultValue) {
+ return super.getDouble(key, defaultValue);
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a String value, or null
+ */
+ @Override
+ public String getString(String key) {
+ return super.getString(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or defaultValue if
+ * no mapping of the desired type exists for the given key.
+ *
+ * @param key a String, or null
+ * @param defaultValue Value to return if key does not exist
+ * @return the String value associated with the given key, or defaultValue
+ * if no valid String object is currently mapped to that key.
+ */
+ @Override
+ public String getString(String key, String defaultValue) {
+ return super.getString(key, defaultValue);
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a Bundle value, or null
+ */
+ @Override
+ public PersistableBundle getPersistableBundle(String key) {
+ return super.getPersistableBundle(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return an int[] value, or null
+ */
+ @Override
+ public int[] getIntArray(String key) {
+ return super.getIntArray(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a long[] value, or null
+ */
+ @Override
+ public long[] getLongArray(String key) {
+ return super.getLongArray(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a double[] value, or null
+ */
+ @Override
+ public double[] getDoubleArray(String key) {
+ return super.getDoubleArray(key);
+ }
+
+ /**
+ * Returns the value associated with the given key, or null if
+ * no mapping of the desired type exists for the given key or a null
+ * value is explicitly associated with the key.
+ *
+ * @param key a String, or null
+ * @return a String[] value, or null
+ */
+ @Override
+ public String[] getStringArray(String key) {
+ return super.getStringArray(key);
+ }
+
+ public static final Parcelable.Creator<PersistableBundle> CREATOR =
+ new Parcelable.Creator<PersistableBundle>() {
+ @Override
+ public PersistableBundle createFromParcel(Parcel in) {
+ return in.readPersistableBundle();
+ }
+
+ @Override
+ public PersistableBundle[] newArray(int size) {
+ return new PersistableBundle[size];
+ }
+ };
+
+ /**
+ * Report the nature of this Parcelable's contents
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Writes the PersistableBundle contents to a Parcel, typically in order for
+ * it to be passed through an IBinder connection.
+ * @param parcel The parcel to copy this bundle to.
+ */
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ final boolean oldAllowFds = parcel.pushAllowFds(false);
+ try {
+ super.writeToParcelInner(parcel, flags);
+ } finally {
+ parcel.restoreAllowFds(oldAllowFds);
+ }
+ }
+
+ /**
+ * Reads the Parcel contents into this PersistableBundle, typically in order for
+ * it to be passed through an IBinder connection.
+ * @param parcel The parcel to overwrite this bundle from.
+ */
+ public void readFromParcel(Parcel parcel) {
+ super.readFromParcelInner(parcel);
+ }
+
+ @Override
+ synchronized public String toString() {
+ if (mParcelledData != null) {
+ if (mParcelledData == EMPTY_PARCEL) {
+ return "PersistableBundle[EMPTY_PARCEL]";
+ } else {
+ return "PersistableBundle[mParcelledData.dataSize=" +
+ mParcelledData.dataSize() + "]";
+ }
+ }
+ return "PersistableBundle[" + mMap.toString() + "]";
+ }
+
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 8aef9bd..7bac3af 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -300,7 +300,8 @@
/**
* Sets all the user-wide restrictions for this user.
- * Requires the MANAGE_USERS permission.
+ * Requires the MANAGE_USERS permission or profile/device owner
+ * privileges.
* @param restrictions the Bundle containing all the restrictions.
*/
public void setUserRestrictions(Bundle restrictions) {
@@ -309,7 +310,8 @@
/**
* Sets all the user-wide restrictions for the specified user.
- * Requires the MANAGE_USERS permission.
+ * Requires the MANAGE_USERS permission or profile/device owner
+ * privileges.
* @param restrictions the Bundle containing all the restrictions.
* @param userHandle the UserHandle of the user for whom to set the restrictions.
*/
@@ -323,7 +325,8 @@
/**
* Sets the value of a specific restriction.
- * Requires the MANAGE_USERS permission.
+ * Requires the MANAGE_USERS permission or profile/device owner
+ * privileges.
* @param key the key of the restriction
* @param value the value for the restriction
*/
@@ -336,7 +339,8 @@
/**
* @hide
* Sets the value of a specific restriction on a specific user.
- * Requires the {@link android.Manifest.permission#MANAGE_USERS} permission.
+ * Requires the {@link android.Manifest.permission#MANAGE_USERS} permission or profile/device owner
+ * privileges.
* @param key the key of the restriction
* @param value the value for the restriction
* @param userHandle the user whose restriction is to be changed.
@@ -548,7 +552,7 @@
/**
* Returns information for all users on this device. Requires
* {@link android.Manifest.permission#MANAGE_USERS} permission.
- *
+ *
* @param excludeDying specify if the list should exclude users being
* removed.
* @return the list of users that were created.
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 966b24d..9081234 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -256,11 +256,45 @@
@Override
protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
TransitionValuesMaps endValues) {
+ startValues = removeExcludes(startValues);
+ endValues = removeExcludes(endValues);
for (Transition childTransition : mTransitions) {
childTransition.createAnimators(sceneRoot, startValues, endValues);
}
}
+ private TransitionValuesMaps removeExcludes(TransitionValuesMaps values) {
+ if (mTargetIds.isEmpty() && mTargetIdExcludes == null && mTargetTypeExcludes == null
+ && mTargets.isEmpty()) {
+ return values;
+ }
+ TransitionValuesMaps included = new TransitionValuesMaps();
+ int numValues = values.viewValues.size();
+ for (int i = 0; i < numValues; i++) {
+ View view = values.viewValues.keyAt(i);
+ if (isValidTarget(view, view.getId())) {
+ included.viewValues.put(view, values.viewValues.valueAt(i));
+ }
+ }
+ numValues = values.idValues.size();
+ for (int i = 0; i < numValues; i++) {
+ int id = values.idValues.keyAt(i);
+ TransitionValues transitionValues = values.idValues.valueAt(i);
+ if (isValidTarget(transitionValues.view, id)) {
+ included.idValues.put(id, transitionValues);
+ }
+ }
+ numValues = values.itemIdValues.size();
+ for (int i = 0; i < numValues; i++) {
+ long id = values.itemIdValues.keyAt(i);
+ TransitionValues transitionValues = values.itemIdValues.valueAt(i);
+ if (isValidTarget(transitionValues.view, id)) {
+ included.itemIdValues.put(id, transitionValues);
+ }
+ }
+ return included;
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java
index 13cc88b..2cc91b9 100644
--- a/core/java/android/util/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -130,7 +130,10 @@
private static final String IRI
= "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
- private static final String HOST_NAME = IRI + "(?:\\." + IRI + ")+";
+ private static final String GOOD_GTLD_CHAR =
+ "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
+ private static final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
+ private static final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
public static final Pattern DOMAIN_NAME
= Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java
index a7ee12b..71296fa 100644
--- a/core/java/android/view/MenuInflater.java
+++ b/core/java/android/view/MenuInflater.java
@@ -161,6 +161,7 @@
} else if (tagName.equals(XML_MENU)) {
// A menu start tag denotes a submenu for an item
SubMenu subMenu = menuState.addSubMenuItem();
+ registerMenu(subMenu, attrs);
// Parse the submenu into returned SubMenu
parseMenu(parser, attrs, subMenu);
@@ -183,9 +184,9 @@
if (!menuState.hasAddedItem()) {
if (menuState.itemActionProvider != null &&
menuState.itemActionProvider.hasSubMenu()) {
- menuState.addSubMenuItem();
+ registerMenu(menuState.addSubMenuItem(), attrs);
} else {
- menuState.addItem();
+ registerMenu(menuState.addItem(), attrs);
}
}
} else if (tagName.equals(XML_MENU)) {
@@ -200,7 +201,30 @@
eventType = parser.next();
}
}
-
+
+ /**
+ * The method is a hook for layoutlib to do its magic.
+ * Nothing is needed outside of LayoutLib. However, it should not be deleted because it
+ * appears to do nothing.
+ */
+ private void registerMenu(@SuppressWarnings("unused") MenuItem item,
+ @SuppressWarnings("unused") AttributeSet set) {
+ }
+
+ /**
+ * The method is a hook for layoutlib to do its magic.
+ * Nothing is needed outside of LayoutLib. However, it should not be deleted because it
+ * appears to do nothing.
+ */
+ private void registerMenu(@SuppressWarnings("unused") SubMenu subMenu,
+ @SuppressWarnings("unused") AttributeSet set) {
+ }
+
+ // Needed by layoutlib.
+ /*package*/ Context getContext() {
+ return mContext;
+ }
+
private static class InflatedOnMenuItemClickListener
implements MenuItem.OnMenuItemClickListener {
private static final Class<?>[] PARAM_TYPES = new Class[] { MenuItem.class };
@@ -446,9 +470,11 @@
}
}
- public void addItem() {
+ public MenuItem addItem() {
itemAdded = true;
- setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle));
+ MenuItem item = menu.add(groupId, itemId, itemCategoryOrder, itemTitle);
+ setItem(item);
+ return item;
}
public SubMenu addSubMenuItem() {
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 60d7c78..924c331 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -178,11 +178,14 @@
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
HardwareCanvas canvas = mRootNode.start(mWidth, mHeight);
- callbacks.onHardwarePostDraw(canvas);
- canvas.drawDisplayList(view.getDisplayList());
- callbacks.onHardwarePostDraw(canvas);
- mRootNode.end(canvas);
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ try {
+ callbacks.onHardwarePostDraw(canvas);
+ canvas.drawDisplayList(view.getDisplayList());
+ callbacks.onHardwarePostDraw(canvas);
+ } finally {
+ mRootNode.end(canvas);
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
view.mRecreateDisplayList = false;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index be316e2..cb05b05 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14897,8 +14897,11 @@
final int width = bounds.width();
final int height = bounds.height();
final HardwareCanvas canvas = displayList.start(width, height);
- drawable.draw(canvas);
- displayList.end(canvas);
+ try {
+ drawable.draw(canvas);
+ } finally {
+ displayList.end(canvas);
+ }
// Set up drawable properties that are view-independent.
displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 374787e..23be203 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1514,43 +1514,46 @@
mResizeBuffer.prepare(mWidth, mHeight, false);
RenderNode layerRenderNode = mResizeBuffer.startRecording();
HardwareCanvas layerCanvas = layerRenderNode.start(mWidth, mHeight);
- final int restoreCount = layerCanvas.save();
+ try {
+ final int restoreCount = layerCanvas.save();
- int yoff;
- final boolean scrolling = mScroller != null
- && mScroller.computeScrollOffset();
- if (scrolling) {
- yoff = mScroller.getCurrY();
- mScroller.abortAnimation();
- } else {
- yoff = mScrollY;
+ int yoff;
+ final boolean scrolling = mScroller != null
+ && mScroller.computeScrollOffset();
+ if (scrolling) {
+ yoff = mScroller.getCurrY();
+ mScroller.abortAnimation();
+ } else {
+ yoff = mScrollY;
+ }
+
+ layerCanvas.translate(0, -yoff);
+ if (mTranslator != null) {
+ mTranslator.translateCanvas(layerCanvas);
+ }
+
+ RenderNode renderNode = mView.mRenderNode;
+ if (renderNode != null && renderNode.isValid()) {
+ layerCanvas.drawDisplayList(renderNode, null,
+ RenderNode.FLAG_CLIP_CHILDREN);
+ } else {
+ mView.draw(layerCanvas);
+ }
+
+ drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
+
+ mResizeBufferStartTime = SystemClock.uptimeMillis();
+ mResizeBufferDuration = mView.getResources().getInteger(
+ com.android.internal.R.integer.config_mediumAnimTime);
+
+ layerCanvas.restoreToCount(restoreCount);
+ layerRenderNode.end(layerCanvas);
+ layerRenderNode.setCaching(true);
+ layerRenderNode.setLeftTopRightBottom(0, 0, mWidth, mHeight);
+ mTempRect.set(0, 0, mWidth, mHeight);
+ } finally {
+ mResizeBuffer.endRecording(mTempRect);
}
-
- layerCanvas.translate(0, -yoff);
- if (mTranslator != null) {
- mTranslator.translateCanvas(layerCanvas);
- }
-
- RenderNode renderNode = mView.mRenderNode;
- if (renderNode != null && renderNode.isValid()) {
- layerCanvas.drawDisplayList(renderNode, null,
- RenderNode.FLAG_CLIP_CHILDREN);
- } else {
- mView.draw(layerCanvas);
- }
-
- drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
-
- mResizeBufferStartTime = SystemClock.uptimeMillis();
- mResizeBufferDuration = mView.getResources().getInteger(
- com.android.internal.R.integer.config_mediumAnimTime);
-
- layerCanvas.restoreToCount(restoreCount);
- layerRenderNode.end(layerCanvas);
- layerRenderNode.setCaching(true);
- layerRenderNode.setLeftTopRightBottom(0, 0, mWidth, mHeight);
- mTempRect.set(0, 0, mWidth, mHeight);
- mResizeBuffer.endRecording(mTempRect);
mAttachInfo.mHardwareRenderer.flushLayerUpdates();
}
mAttachInfo.mContentInsets.set(mPendingContentInsets);
@@ -2949,7 +2952,7 @@
}
}
}
-
+
/**
* Return true if child is an ancestor of parent, (or equal to the parent).
*/
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 8a30def..225cd6d 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -314,7 +314,7 @@
final int right = left + thumbWidth;
final Drawable background = getBackground();
- if (background.supportsHotspots()) {
+ if (background != null && background.supportsHotspots()) {
final Rect bounds = mThumb.getBounds();
final int offsetX = mPaddingLeft - mThumbOffset;
final int offsetY = mPaddingTop;
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index ddc8b05..9e17cca 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -285,7 +285,7 @@
buttonDrawable.setBounds(left, top, right, bottom);
final Drawable background = getBackground();
- if (background.supportsHotspots()) {
+ if (background != null && background.supportsHotspots()) {
background.setHotspotBounds(left, top, right, bottom);
}
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index d013e7b..08af4de 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -799,7 +799,7 @@
thumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
final Drawable background = getBackground();
- if (background.supportsHotspots()) {
+ if (background != null && background.supportsHotspots()) {
background.setHotspotBounds(thumbLeft, switchTop, thumbRight, switchBottom);
}
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index b776226..5d7d322 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -392,8 +392,8 @@
private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) {
final int ordering = getOrdering(categoryOrder);
- final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder,
- ordering, title, mDefaultShowAsAction);
+ final MenuItemImpl item = createNewMenuItem(group, id, categoryOrder, ordering, title,
+ mDefaultShowAsAction);
if (mCurrentMenuInfo != null) {
// Pass along the current menu info
@@ -405,7 +405,14 @@
return item;
}
-
+
+ // Layoutlib overrides this method to return its custom implementation of MenuItemImpl
+ private MenuItemImpl createNewMenuItem(int group, int id, int categoryOrder, int ordering,
+ CharSequence title, int defaultShowAsAction) {
+ return new MenuItemImpl(this, group, id, categoryOrder, ordering, title,
+ defaultShowAsAction);
+ }
+
public MenuItem add(CharSequence title) {
return addInternal(0, 0, 0, title);
}
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 7a4728d..fcf8f83e 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -160,7 +160,6 @@
ASensorEvent buffer[16];
while ((n = q->read(buffer, 16)) > 0) {
for (int i=0 ; i<n ; i++) {
-
if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
// step-counter returns a uint64, but the java API only deals with floats
float value = float(buffer[i].u64.step_counter);
@@ -183,17 +182,17 @@
buffer[i].vector.status,
buffer[i].timestamp);
}
-
if (env->ExceptionCheck()) {
+ mSensorQueue->sendAck(buffer, n);
ALOGE("Exception dispatching input event.");
return 1;
}
}
+ mSensorQueue->sendAck(buffer, n);
}
if (n<0 && n != -EAGAIN) {
// FIXME: error receiving events, what to do in this case?
}
-
return 1;
}
};
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 8549004..ef5ebd0 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -287,7 +287,7 @@
jlong rendererPtr, jlong paintPtr, jint saveFlags) {
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
- const android::uirenderer::Rect& bounds(renderer->getClipBounds());
+ const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
paint, saveFlags);
}
@@ -302,7 +302,7 @@
static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz,
jlong rendererPtr, jint alpha, jint saveFlags) {
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- const android::uirenderer::Rect& bounds(renderer->getClipBounds());
+ const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
alpha, saveFlags);
}
@@ -356,7 +356,7 @@
static jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
jlong rendererPtr, jobject rect) {
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
- const android::uirenderer::Rect& bounds(renderer->getClipBounds());
+ const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
env->CallVoidMethod(rect, gRectClassInfo.set,
int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
@@ -870,8 +870,7 @@
return reinterpret_cast<jlong>(renderer->finishRecording());
}
-static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env,
- jobject clazz) {
+static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, jobject clazz) {
return reinterpret_cast<jlong>(new DisplayListRenderer);
}
diff --git a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
index 1958cfe..3b9d513 100644
--- a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
+++ b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
@@ -25,12 +25,13 @@
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
-import android.graphics.drawable.Ripple.RippleAnimator;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
+import android.graphics.drawable.Ripple.RippleAnimator;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
+import android.util.Log;
import android.util.SparseArray;
import com.android.internal.R;
@@ -45,6 +46,7 @@
* Documentation pending.
*/
public class TouchFeedbackDrawable extends LayerDrawable {
+ private static final String LOG_TAG = TouchFeedbackDrawable.class.getSimpleName();
private static final PorterDuffXfermode DST_IN = new PorterDuffXfermode(Mode.DST_IN);
/** The maximum number of ripples supported. */
@@ -308,6 +310,11 @@
mTouchedRipples = new SparseArray<Ripple>();
mActiveRipples = new Ripple[MAX_RIPPLES];
}
+
+ if (mActiveRipplesCount >= MAX_RIPPLES) {
+ Log.e(LOG_TAG, "Max ripple count exceeded", new RuntimeException());
+ return;
+ }
final Ripple ripple = mTouchedRipples.get(id);
if (ripple == null) {
@@ -428,8 +435,7 @@
// first. This will merge SRC_OVER (directly) onto the canvas.
if (!projected && rippleRestoreCount < 0) {
rippleRestoreCount = canvas.saveLayer(bounds.left, bounds.top,
- bounds.right, bounds.bottom, null, 0);
- canvas.clipRect(bounds);
+ bounds.right, bounds.bottom, null);
}
drewRipples |= ripple.draw(canvas, getRipplePaint());
@@ -447,7 +453,7 @@
if (drewRipples && !projected && rippleRestoreCount >= 0) {
final PorterDuffXfermode xfermode = mState.getTintXfermode();
canvas.saveLayer(bounds.left, bounds.top,
- bounds.right, bounds.bottom, getMaskingPaint(xfermode), 0);
+ bounds.right, bounds.bottom, getMaskingPaint(xfermode));
}
Drawable mask = null;
@@ -465,7 +471,7 @@
if (mask != null && drewRipples) {
// TODO: This will also mask the lower layer, which is bad.
canvas.saveLayer(bounds.left, bounds.top, bounds.right,
- bounds.bottom, getMaskingPaint(DST_IN), 0);
+ bounds.bottom, getMaskingPaint(DST_IN));
mask.draw(canvas);
}
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index a5d8dcb..dac86cb 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -29,7 +29,10 @@
namespace android {
namespace uirenderer {
-DisplayListData::DisplayListData() : projectionReceiveIndex(-1), functorCount(0), hasDrawOps(false) {
+DisplayListData::DisplayListData()
+ : projectionReceiveIndex(-1)
+ , functorCount(0)
+ , hasDrawOps(false) {
}
DisplayListData::~DisplayListData() {
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index f19da9d..6dfb918 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -318,12 +318,19 @@
class SaveLayerOp : public StateOp {
public:
SaveLayerOp(float left, float top, float right, float bottom, int alpha, int flags)
- : mArea(left, top, right, bottom), mPaint(&mCachedPaint), mFlags(flags) {
+ : mArea(left, top, right, bottom)
+ , mPaint(&mCachedPaint)
+ , mFlags(flags)
+ , mConvexMask(NULL) {
mCachedPaint.setAlpha(alpha);
}
SaveLayerOp(float left, float top, float right, float bottom, const SkPaint* paint, int flags)
- : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {}
+ : mArea(left, top, right, bottom)
+ , mPaint(paint)
+ , mFlags(flags)
+ , mConvexMask(NULL)
+ {}
virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
bool useQuickReject) {
@@ -338,7 +345,8 @@
}
virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
- renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, mPaint, mFlags);
+ renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom,
+ mPaint, mFlags, mConvexMask);
}
virtual void output(int level, uint32_t logFlags) const {
@@ -350,6 +358,11 @@
int getFlags() { return mFlags; }
+ // Called to make SaveLayerOp clip to the provided mask when drawing back/restored
+ void setMask(const SkPath* convexMask) {
+ mConvexMask = convexMask;
+ }
+
private:
bool isSaveLayerAlpha() const {
SkXfermode::Mode mode = OpenGLRenderer::getXfermodeDirect(mPaint);
@@ -361,6 +374,10 @@
const SkPaint* mPaint;
SkPaint mCachedPaint;
int mFlags;
+
+ // Convex path, points at data in RenderNode, valid for the duration of the frame only
+ // Only used for masking the SaveLayer which wraps projected RenderNodes
+ const SkPath* mConvexMask;
};
class TranslateOp : public StateOp {
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 6c73d68..e36d975 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -184,20 +184,15 @@
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
- // TODO: To be safe, the display list should be ref-counted in the
- // resources cache, but we rely on the caller (UI toolkit) to
- // do the right thing for now
+ if (displayList->stagingProperties().isProjectionReceiver()) {
+ // use staging property, since recording on UI thread
+ mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size();
+ }
DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList,
flags, *currentTransform());
addDrawOp(op);
mDisplayListData->addChild(op);
-
- if (displayList->stagingProperties().isProjectionReceiver()) {
- // use staging property, since recording on UI thread
- mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1;
- }
-
return DrawGlInfo::kStatusDone;
}
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index bfe4eda..9606e58 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -48,6 +48,7 @@
hasDrawnSinceUpdate = false;
forceFilter = false;
deferredList = NULL;
+ convexMask = NULL;
caches.resourceCache.incrementRefcount(this);
}
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 5375b45..49610d5 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -227,6 +227,14 @@
ANDROID_API void setColorFilter(SkColorFilter* filter);
+ inline void setConvexMask(const SkPath* convexMask) {
+ this->convexMask = convexMask;
+ }
+
+ inline const SkPath* getConvexMask() {
+ return convexMask;
+ }
+
void bindStencilRenderBuffer() const;
void bindTexture() const;
@@ -378,6 +386,13 @@
*/
DeferredDisplayList* deferredList;
+ /**
+ * This convex path should be used to mask the layer's draw to the screen.
+ *
+ * Data not owned/managed by layer object.
+ */
+ const SkPath* convexMask;
+
}; // struct Layer
}; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index f37487f..1f5389c 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -704,11 +704,11 @@
///////////////////////////////////////////////////////////////////////////////
int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, int flags) {
+ const SkPaint* paint, int flags, const SkPath* convexMask) {
const int count = saveSnapshot(flags);
if (!currentSnapshot()->isIgnored()) {
- createLayer(left, top, right, bottom, paint, flags);
+ createLayer(left, top, right, bottom, paint, flags, convexMask);
}
return count;
@@ -782,7 +782,6 @@
return count;
}
-
/**
* Layers are viewed by Skia are slightly different than layers in image editing
* programs (for instance.) When a layer is created, previously created layers
@@ -835,7 +834,7 @@
* something actually gets drawn are the layers regions cleared.
*/
bool OpenGLRenderer::createLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, int flags) {
+ const SkPaint* paint, int flags, const SkPath* convexMask) {
LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top);
LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize());
@@ -865,6 +864,7 @@
layer->setBlend(true);
layer->setDirty(false);
+ layer->setConvexMask(convexMask); // note: the mask must be cleared before returning to the cache
// Save the layer in the snapshot
mSnapshot->flags |= Snapshot::kFlagIsLayer;
@@ -1013,6 +1013,7 @@
dirtyClip();
// Failing to add the layer to the cache should happen only if the layer is too large
+ layer->setConvexMask(NULL);
if (!mCaches.layerCache.put(layer)) {
LAYER_LOGD("Deleting layer");
Caches::getInstance().resourceCache.decrementRefcount(layer);
@@ -1122,6 +1123,38 @@
#define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND)
void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
+ if (CC_UNLIKELY(layer->region.isEmpty())) return; // nothing to draw
+
+ if (layer->getConvexMask()) {
+ save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
+
+ // clip to the area of the layer the mask can be larger
+ clipRect(rect.left, rect.top, rect.right, rect.bottom, SkRegion::kIntersect_Op);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(SkColorSetARGB(int(getLayerAlpha(layer) * 255), 0, 0, 0));
+
+ SkiaShader* oldShader = mDrawModifiers.mShader;
+
+ // create LayerShader to map SaveLayer content into subsequent draw
+ SkMatrix shaderMatrix;
+ shaderMatrix.setTranslate(rect.left, rect.bottom);
+ shaderMatrix.preScale(1, -1);
+ SkiaLayerShader layerShader(layer, &shaderMatrix);
+ mDrawModifiers.mShader = &layerShader;
+
+ // Since the drawing primitive is defined in local drawing space,
+ // we don't need to modify the draw matrix
+ const SkPath* maskPath = layer->getConvexMask();
+ DRAW_DOUBLE_STENCIL(drawConvexPath(*maskPath, &paint));
+
+ mDrawModifiers.mShader = oldShader;
+ restore();
+
+ return;
+ }
+
if (layer->region.isRect()) {
layer->setRegionAsRect();
@@ -1131,88 +1164,87 @@
return;
}
- if (CC_LIKELY(!layer->region.isEmpty())) {
- size_t count;
- const android::Rect* rects;
- Region safeRegion;
- if (CC_LIKELY(hasRectToRectTransform())) {
- rects = layer->region.getArray(&count);
- } else {
- safeRegion = Region::createTJunctionFreeRegion(layer->region);
- rects = safeRegion.getArray(&count);
- }
+ // standard Region based draw
+ size_t count;
+ const android::Rect* rects;
+ Region safeRegion;
+ if (CC_LIKELY(hasRectToRectTransform())) {
+ rects = layer->region.getArray(&count);
+ } else {
+ safeRegion = Region::createTJunctionFreeRegion(layer->region);
+ rects = safeRegion.getArray(&count);
+ }
- const float alpha = getLayerAlpha(layer);
- const float texX = 1.0f / float(layer->getWidth());
- const float texY = 1.0f / float(layer->getHeight());
- const float height = rect.getHeight();
+ const float alpha = getLayerAlpha(layer);
+ const float texX = 1.0f / float(layer->getWidth());
+ const float texY = 1.0f / float(layer->getHeight());
+ const float height = rect.getHeight();
- setupDraw();
+ setupDraw();
- // We must get (and therefore bind) the region mesh buffer
- // after we setup drawing in case we need to mess with the
- // stencil buffer in setupDraw()
- TextureVertex* mesh = mCaches.getRegionMesh();
- uint32_t numQuads = 0;
+ // We must get (and therefore bind) the region mesh buffer
+ // after we setup drawing in case we need to mess with the
+ // stencil buffer in setupDraw()
+ TextureVertex* mesh = mCaches.getRegionMesh();
+ uint32_t numQuads = 0;
- setupDrawWithTexture();
- setupDrawColor(alpha, alpha, alpha, alpha);
- setupDrawColorFilter(layer->getColorFilter());
- setupDrawBlending(layer);
- setupDrawProgram();
- setupDrawDirtyRegionsDisabled();
- setupDrawPureColorUniforms();
- setupDrawColorFilterUniforms(layer->getColorFilter());
- setupDrawTexture(layer->getTexture());
- if (currentTransform()->isPureTranslate()) {
- const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
- const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
+ setupDrawWithTexture();
+ setupDrawColor(alpha, alpha, alpha, alpha);
+ setupDrawColorFilter(layer->getColorFilter());
+ setupDrawBlending(layer);
+ setupDrawProgram();
+ setupDrawDirtyRegionsDisabled();
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms(layer->getColorFilter());
+ setupDrawTexture(layer->getTexture());
+ if (currentTransform()->isPureTranslate()) {
+ const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
+ const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
- layer->setFilter(GL_NEAREST);
- setupDrawModelView(kModelViewMode_Translate, false,
- x, y, x + rect.getWidth(), y + rect.getHeight(), true);
- } else {
- layer->setFilter(GL_LINEAR);
- setupDrawModelView(kModelViewMode_Translate, false,
- rect.left, rect.top, rect.right, rect.bottom);
- }
- setupDrawMeshIndices(&mesh[0].x, &mesh[0].u);
+ layer->setFilter(GL_NEAREST);
+ setupDrawModelView(kModelViewMode_Translate, false,
+ x, y, x + rect.getWidth(), y + rect.getHeight(), true);
+ } else {
+ layer->setFilter(GL_LINEAR);
+ setupDrawModelView(kModelViewMode_Translate, false,
+ rect.left, rect.top, rect.right, rect.bottom);
+ }
+ setupDrawMeshIndices(&mesh[0].x, &mesh[0].u);
- for (size_t i = 0; i < count; i++) {
- const android::Rect* r = &rects[i];
+ for (size_t i = 0; i < count; i++) {
+ const android::Rect* r = &rects[i];
- const float u1 = r->left * texX;
- const float v1 = (height - r->top) * texY;
- const float u2 = r->right * texX;
- const float v2 = (height - r->bottom) * texY;
+ const float u1 = r->left * texX;
+ const float v1 = (height - r->top) * texY;
+ const float u2 = r->right * texX;
+ const float v2 = (height - r->bottom) * texY;
- // TODO: Reject quads outside of the clip
- TextureVertex::set(mesh++, r->left, r->top, u1, v1);
- TextureVertex::set(mesh++, r->right, r->top, u2, v1);
- TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
- TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
+ // TODO: Reject quads outside of the clip
+ TextureVertex::set(mesh++, r->left, r->top, u1, v1);
+ TextureVertex::set(mesh++, r->right, r->top, u2, v1);
+ TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
+ TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
- numQuads++;
+ numQuads++;
- if (numQuads >= gMaxNumberOfQuads) {
- DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6,
- GL_UNSIGNED_SHORT, NULL));
- numQuads = 0;
- mesh = mCaches.getRegionMesh();
- }
- }
-
- if (numQuads > 0) {
+ if (numQuads >= gMaxNumberOfQuads) {
DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6,
GL_UNSIGNED_SHORT, NULL));
+ numQuads = 0;
+ mesh = mCaches.getRegionMesh();
}
+ }
+
+ if (numQuads > 0) {
+ DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6,
+ GL_UNSIGNED_SHORT, NULL));
+ }
#if DEBUG_LAYERS_AS_REGIONS
- drawRegionRectsDebug(layer->region);
+ drawRegionRectsDebug(layer->region);
#endif
- layer->region.clear();
- }
+ layer->region.clear();
}
#if DEBUG_LAYERS_AS_REGIONS
@@ -2926,7 +2958,7 @@
if (layer->isTextureLayer()) {
transform = &layer->getTransform();
if (!transform->isIdentity()) {
- save(0);
+ save(SkCanvas::kMatrix_SaveFlag);
concatMatrix(*transform);
}
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 2debd2e..b49d1e1 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -161,7 +161,14 @@
ANDROID_API void flushLayerUpdates();
ANDROID_API virtual int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, int flags);
+ const SkPaint* paint, int flags) {
+ return saveLayer(left, top, right, bottom, paint, flags, NULL);
+ }
+
+ // Specialized saveLayer implementation, which will pass the convexMask to an FBO layer, if
+ // created, which will in turn clip to that mask when drawn back/restored.
+ int saveLayer(float left, float top, float right, float bottom,
+ const SkPaint* paint, int flags, const SkPath* convexMask);
int saveLayerDeferred(float left, float top, float right, float bottom,
const SkPaint* paint, int flags);
@@ -523,11 +530,12 @@
* @param alpha The translucency of the layer
* @param mode The blending mode of the layer
* @param flags The layer save flags
+ * @param mask A mask to use when drawing the layer back, may be empty
*
* @return True if the layer was successfully created, false otherwise
*/
bool createLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, int flags);
+ const SkPaint* paint, int flags, const SkPath* convexMask);
/**
* Creates a new layer stored in the specified snapshot as an FBO.
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 0083b77..92964a8 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -30,6 +30,8 @@
#define RECT_STRING "%7.2f %7.2f %7.2f %7.2f"
#define RECT_ARGS(r) \
(r).left, (r).top, (r).right, (r).bottom
+#define SK_RECT_ARGS(r) \
+ (r).left(), (r).top(), (r).right(), (r).bottom()
///////////////////////////////////////////////////////////////////////////////
// Structs
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index cf21834..2008f02 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -26,6 +26,7 @@
#include "Debug.h"
#include "DisplayListOp.h"
#include "DisplayListLogBuffer.h"
+#include "utils/MathUtils.h"
namespace android {
namespace uirenderer {
@@ -76,7 +77,7 @@
*/
void RenderNode::output(uint32_t level) {
ALOGD("%*sStart display list (%p, %s, render=%d)", (level - 1) * 2, "", this,
- mName.string(), isRenderable());
+ getName(), isRenderable());
ALOGD("%*s%s %d", level * 2, "", "Save",
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
@@ -86,7 +87,7 @@
mDisplayListData->displayListOps[i]->output(level, flags);
}
- ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
+ ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, getName());
}
void RenderNode::prepareTree(TreeInfo& info) {
@@ -217,7 +218,9 @@
mat4 anim(*properties().getAnimationMatrix());
matrix.multiply(anim);
}
- if (properties().hasTransformMatrix()) {
+
+ bool applyTranslationZ = true3dTransform && !MathUtils::isZero(properties().getTranslationZ());
+ if (properties().hasTransformMatrix() || applyTranslationZ) {
if (properties().isTransformTranslateOnly()) {
matrix.translate(properties().getTranslationX(), properties().getTranslationY(),
true3dTransform ? properties().getTranslationZ() : 0.0f);
@@ -260,12 +263,13 @@
for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
DrawDisplayListOp* childOp = mDisplayListData->children()[i];
childOp->mDisplayList->computeOrderingImpl(childOp,
- &mProjectedNodes, &mat4::identity());
+ properties().getOutline().getPath(), &mProjectedNodes, &mat4::identity());
}
}
void RenderNode::computeOrderingImpl(
DrawDisplayListOp* opState,
+ const SkPath* outlineOfProjectionSurface,
Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface,
const mat4* transformFromProjectionSurface) {
mProjectedNodes.clear();
@@ -293,6 +297,7 @@
DrawDisplayListOp* childOp = mDisplayListData->children()[i];
RenderNode* child = childOp->mDisplayList;
+ const SkPath* projectionOutline = NULL;
Vector<DrawDisplayListOp*>* projectionChildren = NULL;
const mat4* projectionTransform = NULL;
if (isProjectionReceiver && !child->properties().getProjectBackwards()) {
@@ -301,6 +306,7 @@
// Note that if a direct descendent is projecting backwards, we pass it's
// grandparent projection collection, since it shouldn't project onto it's
// parent, where it will already be drawing.
+ projectionOutline = properties().getOutline().getPath();
projectionChildren = &mProjectedNodes;
projectionTransform = &mat4::identity();
} else {
@@ -308,10 +314,12 @@
applyViewPropertyTransforms(localTransformFromProjectionSurface);
haveAppliedPropertiesToProjection = true;
}
+ projectionOutline = outlineOfProjectionSurface;
projectionChildren = compositedChildrenOfProjectionSurface;
projectionTransform = &localTransformFromProjectionSurface;
}
- child->computeOrderingImpl(childOp, projectionChildren, projectionTransform);
+ child->computeOrderingImpl(childOp,
+ projectionOutline, projectionChildren, projectionTransform);
}
}
}
@@ -351,7 +359,7 @@
: mReplayStruct(replayStruct), mLevel(level) {}
inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
- properties().getReplayStruct().mRenderer.eventMark(operation->name());
+ mReplayStruct.mRenderer.eventMark(operation->name());
#endif
operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds);
}
@@ -361,8 +369,6 @@
}
inline void endMark() {
mReplayStruct.mRenderer.endMark();
- DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", level * 2, "", this, mName.string(),
- mReplayStruct.mDrawGlStatus);
}
inline int level() { return mLevel; }
inline int replayFlags() { return mReplayStruct.mReplayFlags; }
@@ -391,7 +397,7 @@
RenderNode* child = childOp->mDisplayList;
float childZ = child->properties().getTranslationZ();
- if (childZ != 0.0f) {
+ if (!MathUtils::isZero(childZ)) {
zTranslatedNodes.add(ZDrawDisplayListOpPair(childZ, childOp));
childOp->mSkipInOrderDraw = true;
} else if (!child->properties().getProjectBackwards()) {
@@ -467,6 +473,10 @@
endIndex = size;
shadowIndex = drawIndex; // potentially draw shadow for each pos Z child
}
+
+ DISPLAY_LIST_LOGD("%*s%d %s 3d children:", (handler.level() + 1) * 2, "",
+ endIndex - drawIndex, mode == kNegativeZChildren ? "negative" : "positive");
+
float lastCasterZ = 0.0f;
while (shadowIndex < endIndex || drawIndex < endIndex) {
if (shadowIndex < endIndex) {
@@ -503,6 +513,42 @@
template <class T>
void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler) {
+ DISPLAY_LIST_LOGD("%*s%d projected children:", (handler.level() + 1) * 2, "", mProjectedNodes.size());
+ const SkPath* projectionReceiverOutline = properties().getOutline().getPath();
+ bool maskProjecteesWithPath = projectionReceiverOutline != NULL
+ && !projectionReceiverOutline->isRect(NULL);
+ int restoreTo = renderer.getSaveCount();
+
+ // If the projection reciever has an outline, we mask each of the projected rendernodes to it
+ // Either with clipRect, or special saveLayer masking
+ LinearAllocator& alloc = handler.allocator();
+ if (projectionReceiverOutline != NULL) {
+ const SkRect& outlineBounds = projectionReceiverOutline->getBounds();
+ if (projectionReceiverOutline->isRect(NULL)) {
+ // mask to the rect outline simply with clipRect
+ handler(new (alloc) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
+ PROPERTY_SAVECOUNT, properties().getClipToBounds());
+ ClipRectOp* clipOp = new (alloc) ClipRectOp(
+ outlineBounds.left(), outlineBounds.top(),
+ outlineBounds.right(), outlineBounds.bottom(), SkRegion::kIntersect_Op);
+ handler(clipOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
+ } else {
+ // wrap the projected RenderNodes with a SaveLayer that will mask to the outline
+ SaveLayerOp* op = new (alloc) SaveLayerOp(
+ outlineBounds.left(), outlineBounds.top(),
+ outlineBounds.right(), outlineBounds.bottom(),
+ 255, SkCanvas::kARGB_ClipLayer_SaveFlag);
+ op->setMask(projectionReceiverOutline);
+ handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
+
+ /* TODO: add optimizations here to take advantage of placement/size of projected
+ * children (which may shrink saveLayer area significantly). This is dependent on
+ * passing actual drawing/dirtying bounds of projected content down to native.
+ */
+ }
+ }
+
+ // draw projected nodes
for (size_t i = 0; i < mProjectedNodes.size(); i++) {
DrawDisplayListOp* childOp = mProjectedNodes[i];
@@ -514,6 +560,11 @@
childOp->mSkipInOrderDraw = true;
renderer.restoreToCount(restoreTo);
}
+
+ if (projectionReceiverOutline != NULL) {
+ handler(new (alloc) RestoreToCountOp(restoreTo),
+ PROPERTY_SAVECOUNT, properties().getClipToBounds());
+ }
}
/**
@@ -529,17 +580,17 @@
void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
const int level = handler.level();
if (mDisplayListData->isEmpty() || properties().getAlpha() <= 0) {
- DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string());
+ DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, getName());
return;
}
- handler.startMark(mName.string());
+ handler.startMark(getName());
#if DEBUG_DISPLAY_LIST
- Rect* clipRect = renderer.getClipRect();
- DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.0f, %.0f, %.0f",
- level * 2, "", this, mName.string(), clipRect->left, clipRect->top,
- clipRect->right, clipRect->bottom);
+ const Rect& clipRect = renderer.getLocalClipBounds();
+ DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), localClipBounds: %.0f, %.0f, %.0f, %.0f",
+ level * 2, "", this, getName(),
+ clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
#endif
LinearAllocator& alloc = handler.allocator();
@@ -587,6 +638,7 @@
PROPERTY_SAVECOUNT, properties().getClipToBounds());
renderer.setOverrideLayerAlpha(1.0f);
+ DISPLAY_LIST_LOGD("%*sDone (%p, %s)", level * 2, "", this, getName());
handler.endMark();
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 6688952..b9edbe5 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -172,6 +172,7 @@
void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false);
void computeOrderingImpl(DrawDisplayListOp* opState,
+ const SkPath* outlineOfProjectionSurface,
Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface,
const mat4* transformFromProjectionSurface);
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index 58ec32d..a922db8 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -26,16 +26,7 @@
#include <SkPathOps.h>
#include "Matrix.h"
-
-/**
- * Convenience value to check for float values that are close enough to zero to be considered
- * zero.
- */
-#define NONZERO_EPSILON .001f
-
-static inline bool is_zero(float value) {
- return (value >= -NONZERO_EPSILON) && (value <= NONZERO_EPSILON);
-}
+#include "utils/MathUtils.h"
namespace android {
namespace uirenderer {
@@ -151,7 +142,7 @@
}
SkMatrix* transform = mComputedFields.mTransformMatrix;
transform->reset();
- if (is_zero(getRotationX()) && is_zero(getRotationY())) {
+ if (MathUtils::isZero(getRotationX()) && MathUtils::isZero(getRotationY())) {
transform->setTranslate(getTranslationX(), getTranslationY());
transform->preRotate(getRotation(), getPivotX(), getPivotY());
transform->preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY());
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index efcea5f..3209a53 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -167,7 +167,7 @@
virtual void concatMatrix(const SkMatrix* matrix) = 0;
// clip
- virtual const Rect& getClipBounds() const = 0;
+ virtual const Rect& getLocalClipBounds() const = 0;
virtual bool quickRejectConservative(float left, float top,
float right, float bottom) const = 0;
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) = 0;
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 4f2a432..6a4a0c8 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -73,7 +73,7 @@
}
SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
- SkShader::TileMode tileY, SkMatrix* matrix, bool blend):
+ SkShader::TileMode tileY, const SkMatrix* matrix, bool blend):
mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend),
mCaches(NULL) {
setMatrix(matrix);
@@ -101,6 +101,49 @@
}
///////////////////////////////////////////////////////////////////////////////
+// Layer shader
+///////////////////////////////////////////////////////////////////////////////
+
+SkiaLayerShader::SkiaLayerShader(Layer* layer, const SkMatrix* matrix):
+ SkiaShader(kBitmap, NULL, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
+ matrix, layer->isBlend()), mLayer(layer) {
+ updateLocalMatrix(matrix);
+}
+
+SkiaShader* SkiaLayerShader::copy() {
+ SkiaLayerShader* copy = new SkiaLayerShader();
+ copy->copyFrom(*this);
+ copy->mLayer = mLayer;
+ return copy;
+}
+
+void SkiaLayerShader::describe(ProgramDescription& description, const Extensions& extensions) {
+ description.hasBitmap = true;
+}
+
+void SkiaLayerShader::setupProgram(Program* program, const mat4& modelView,
+ const Snapshot& snapshot, GLuint* textureUnit) {
+ GLuint textureSlot = (*textureUnit)++;
+ Caches::getInstance().activeTexture(textureSlot);
+
+ const float width = mLayer->getWidth();
+ const float height = mLayer->getHeight();
+
+ mat4 textureTransform;
+ computeScreenSpaceMatrix(textureTransform, modelView);
+
+ // Uniforms
+ mLayer->bindTexture();
+ mLayer->setWrap(GL_CLAMP_TO_EDGE);
+ mLayer->setFilter(GL_LINEAR);
+
+ glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
+ glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
+ GL_FALSE, &textureTransform.data[0]);
+ glUniform2f(program->getUniform("textureDimension"), 1.0f / width, 1.0f / height);
+}
+
+///////////////////////////////////////////////////////////////////////////////
// Bitmap shader
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 6015761..9f30257 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -58,7 +58,7 @@
};
ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
- SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
+ SkShader::TileMode tileY, const SkMatrix* matrix, bool blend);
virtual ~SkiaShader();
virtual SkiaShader* copy() = 0;
@@ -88,7 +88,7 @@
return mGenerationId;
}
- void setMatrix(SkMatrix* matrix) {
+ void setMatrix(const SkMatrix* matrix) {
updateLocalMatrix(matrix);
mGenerationId++;
}
@@ -134,6 +134,24 @@
///////////////////////////////////////////////////////////////////////////////
/**
+ * A shader that draws a layer.
+ */
+struct SkiaLayerShader: public SkiaShader {
+ SkiaLayerShader(Layer* layer, const SkMatrix* matrix);
+ SkiaShader* copy();
+
+ void describe(ProgramDescription& description, const Extensions& extensions);
+ void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
+ GLuint* textureUnit);
+
+private:
+ SkiaLayerShader() {
+ }
+
+ Layer* mLayer;
+}; // struct SkiaLayerShader
+
+/**
* A shader that draws a bitmap.
*/
struct SkiaBitmapShader: public SkiaShader {
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 5bdb18a..038aea8 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -108,7 +108,12 @@
* Returns the current clip in local coordinates. The clip rect is
* transformed by the inverse transform matrix.
*/
- ANDROID_API const Rect& getLocalClip();
+ const Rect& getLocalClip();
+
+ /**
+ * Returns the current clip in render target coordinates.
+ */
+ const Rect& getRenderTargetClip() { return *clipRect; }
/**
* Resets the clip to the specified rect.
@@ -238,7 +243,7 @@
mat4 mTransformRoot;
Rect mClipRectRoot;
- Rect mLocalClip;
+ Rect mLocalClip; // don't use directly, call getLocalClip() which initializes this
SkRegion mClipRegionRoot;
diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h
index bf34bec..64354ac 100644
--- a/libs/hwui/StatefulBaseRenderer.h
+++ b/libs/hwui/StatefulBaseRenderer.h
@@ -75,7 +75,8 @@
void concatMatrix(const Matrix4& matrix); // internal only convenience method
// Clip
- const Rect& getClipBounds() const { return mSnapshot->getLocalClip(); }
+ virtual const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); }
+
virtual bool quickRejectConservative(float left, float top, float right, float bottom) const;
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
@@ -83,6 +84,8 @@
virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
protected:
+ const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }
+
int getWidth() { return mWidth; }
int getHeight() { return mHeight; }
diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h
new file mode 100644
index 0000000..57ba8fa
--- /dev/null
+++ b/libs/hwui/utils/MathUtils.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+#ifndef MATHUTILS_H
+#define MATHUTILS_H
+
+namespace android {
+namespace uirenderer {
+
+class MathUtils {
+private:
+ static const float gNonZeroEpsilon = 0.001f;
+public:
+ /**
+ * Check for floats that are close enough to zero.
+ */
+ inline static bool isZero(float value) {
+ return (value >= -gNonZeroEpsilon) && (value <= gNonZeroEpsilon);
+ }
+}; // class MathUtils
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* RENDERNODE_H */
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index fb4de9e..acfcd83 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -123,10 +123,13 @@
ssize_t ASensorEventQueue_getEvents(ASensorEventQueue* queue,
ASensorEvent* events, size_t count)
{
- return static_cast<SensorEventQueue*>(queue)->read(events, count);
+ ssize_t actual = static_cast<SensorEventQueue*>(queue)->read(events, count);
+ if (actual > 0) {
+ static_cast<SensorEventQueue*>(queue)->sendAck(events, actual);
+ }
+ return actual;
}
-
/*****************************************************************************/
const char* ASensor_getName(ASensor const* sensor)
diff --git a/packages/DefaultContainerService/res/values-th/strings.xml b/packages/DefaultContainerService/res/values-th/strings.xml
index 3a7080c..621d7ed 100644
--- a/packages/DefaultContainerService/res/values-th/strings.xml
+++ b/packages/DefaultContainerService/res/values-th/strings.xml
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="service_name" msgid="4841491635055379553">"ตัวช่วยเหลือของการเข้าถึงแพคเกจ"</string>
+ <string name="service_name" msgid="4841491635055379553">"ตัวช่วยเหลือของการเข้าถึงแพ็กเกจ"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 41fd63a..65dbe18 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Stoor"</string>
<string name="menu_share" msgid="3075149983979628146">"Deel"</string>
<string name="menu_delete" msgid="8138799623850614177">"Vee uit"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> gekies"</string>
<string name="sort_name" msgid="9183560467917256779">"Volgens naam"</string>
<string name="sort_date" msgid="586080032956151448">"Volgens datum gewysig"</string>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index c77a8ee..1003c0a 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"አስቀምጥ"</string>
<string name="menu_share" msgid="3075149983979628146">"አጋራ"</string>
<string name="menu_delete" msgid="8138799623850614177">"ሰርዝ"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ተመርጠዋል"</string>
<string name="sort_name" msgid="9183560467917256779">"በስም"</string>
<string name="sort_date" msgid="586080032956151448">"በተለወጠበት ቀን"</string>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index c59c0ee..e939b3e 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"حفظ"</string>
<string name="menu_share" msgid="3075149983979628146">"مشاركة"</string>
<string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"تم تحديد <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"بحسب الاسم"</string>
<string name="sort_date" msgid="586080032956151448">"بحسب تاريخ التعديل"</string>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index c3242b2..18cdb9c 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Запазване"</string>
<string name="menu_share" msgid="3075149983979628146">"Споделяне"</string>
<string name="menu_delete" msgid="8138799623850614177">"Изтриване"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Избрахте <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"По име"</string>
<string name="sort_date" msgid="586080032956151448">"По дата на промяната"</string>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 68c7b0e..b883869 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Desa"</string>
<string name="menu_share" msgid="3075149983979628146">"Comparteix"</string>
<string name="menu_delete" msgid="8138799623850614177">"Suprimeix"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Seleccionats: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Per nom"</string>
<string name="sort_date" msgid="586080032956151448">"Per data de modificació"</string>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index f089c8b..3827b94 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Uložit"</string>
<string name="menu_share" msgid="3075149983979628146">"Sdílet"</string>
<string name="menu_delete" msgid="8138799623850614177">"Smazat"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Vybráno: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Podle názvu"</string>
<string name="sort_date" msgid="586080032956151448">"Podle data úpravy"</string>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index 816f9a7..25c74e3 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Gem"</string>
<string name="menu_share" msgid="3075149983979628146">"Del"</string>
<string name="menu_delete" msgid="8138799623850614177">"Slet"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> er valgt"</string>
<string name="sort_name" msgid="9183560467917256779">"Efter navn"</string>
<string name="sort_date" msgid="586080032956151448">"Efter ændringsdato"</string>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index e43a1e2..93fad32 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Speichern"</string>
<string name="menu_share" msgid="3075149983979628146">"Teilen"</string>
<string name="menu_delete" msgid="8138799623850614177">"Löschen"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ausgewählt"</string>
<string name="sort_name" msgid="9183560467917256779">"Nach Name"</string>
<string name="sort_date" msgid="586080032956151448">"Nach Änderungsdatum"</string>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 5a91484..db83aea 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Αποθήκευση"</string>
<string name="menu_share" msgid="3075149983979628146">"Κοινοποίηση"</string>
<string name="menu_delete" msgid="8138799623850614177">"Διαγραφή"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Επιλέχθηκαν <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Κατά όνομα"</string>
<string name="sort_date" msgid="586080032956151448">"Κατά ημερομηνία τροποποίησης"</string>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index a95e7f1..a0fe3b7 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
<string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
<string name="sort_name" msgid="9183560467917256779">"By name"</string>
<string name="sort_date" msgid="586080032956151448">"By date modified"</string>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index a95e7f1..a0fe3b7 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
<string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
<string name="sort_name" msgid="9183560467917256779">"By name"</string>
<string name="sort_date" msgid="586080032956151448">"By date modified"</string>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 4a3ff33..3319011 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> seleccionado(s)"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nombre"</string>
<string name="sort_date" msgid="586080032956151448">"Por fecha de modificación"</string>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index 1682542..7189f1d 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Seleccionado: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nombre"</string>
<string name="sort_date" msgid="586080032956151448">"Por fecha de modificación"</string>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index 5412956..a12b695 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Salvesta"</string>
<string name="menu_share" msgid="3075149983979628146">"Jaga"</string>
<string name="menu_delete" msgid="8138799623850614177">"Kustuta"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> on valitud"</string>
<string name="sort_name" msgid="9183560467917256779">"Nime järgi"</string>
<string name="sort_date" msgid="586080032956151448">"Muutmiskuupäeva järgi"</string>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index c922b37..ba04522 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"ذخیره"</string>
<string name="menu_share" msgid="3075149983979628146">"اشتراکگذاری"</string>
<string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> انتخاب شد"</string>
<string name="sort_name" msgid="9183560467917256779">"بر اساس نام"</string>
<string name="sort_date" msgid="586080032956151448">"بر اساس تاریخ اصلاح"</string>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index 5e40ecd..8ea10be 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Tallenna"</string>
<string name="menu_share" msgid="3075149983979628146">"Jaa"</string>
<string name="menu_delete" msgid="8138799623850614177">"Poista"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> valittua"</string>
<string name="sort_name" msgid="9183560467917256779">"Nimen mukaan"</string>
<string name="sort_date" msgid="586080032956151448">"Muokkauspäivän mukaan"</string>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index a837379..0549707 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
<string name="menu_share" msgid="3075149983979628146">"Partager"</string>
<string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> sélectionné(s)"</string>
<string name="sort_name" msgid="9183560467917256779">"Par nom"</string>
<string name="sort_date" msgid="586080032956151448">"Par date de modification"</string>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index ff9aeda..292ec86 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
<string name="menu_share" msgid="3075149983979628146">"Partager"</string>
<string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> élément(s) sélectionné(s)"</string>
<string name="sort_name" msgid="9183560467917256779">"Par nom"</string>
<string name="sort_date" msgid="586080032956151448">"Par date de modification"</string>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index 8d7fcba..579bd37 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"सहेजें"</string>
<string name="menu_share" msgid="3075149983979628146">"साझा करें"</string>
<string name="menu_delete" msgid="8138799623850614177">"हटाएं"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> चयनित"</string>
<string name="sort_name" msgid="9183560467917256779">"नाम के अनुसार"</string>
<string name="sort_date" msgid="586080032956151448">"बदलाव के दिनांक के अनुसार"</string>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 73c2f04..6baae95 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Spremi"</string>
<string name="menu_share" msgid="3075149983979628146">"Dijeli"</string>
<string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Odabrano: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Po korisniku"</string>
<string name="sort_date" msgid="586080032956151448">"Po datumu izmjene"</string>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index db7854b..b8ef2d4 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Mentés"</string>
<string name="menu_share" msgid="3075149983979628146">"Megosztás"</string>
<string name="menu_delete" msgid="8138799623850614177">"Törlés"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> kiválasztva"</string>
<string name="sort_name" msgid="9183560467917256779">"Név szerint"</string>
<string name="sort_date" msgid="586080032956151448">"Módosítás dátuma szerint"</string>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index c683f3e..69fdfb6 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Պահել"</string>
<string name="menu_share" msgid="3075149983979628146">"Համօգտագործել"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ջնջել"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ընտրված"</string>
<string name="sort_name" msgid="9183560467917256779">"Ըստ անվան"</string>
<string name="sort_date" msgid="586080032956151448">"Ըստ փոփոխման ամսաթվի"</string>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index d9f4475..d5c69bf 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Simpan"</string>
<string name="menu_share" msgid="3075149983979628146">"Bagikan"</string>
<string name="menu_delete" msgid="8138799623850614177">"Hapus"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> dipilih"</string>
<string name="sort_name" msgid="9183560467917256779">"Menurut nama"</string>
<string name="sort_date" msgid="586080032956151448">"Menurut tanggal diubah"</string>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index baca387..9d1fc94 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Salva"</string>
<string name="menu_share" msgid="3075149983979628146">"Condividi"</string>
<string name="menu_delete" msgid="8138799623850614177">"Elimina"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selezionati"</string>
<string name="sort_name" msgid="9183560467917256779">"Per nome"</string>
<string name="sort_date" msgid="586080032956151448">"Per data di modifica"</string>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index 712c060..af47c6c 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"שמור"</string>
<string name="menu_share" msgid="3075149983979628146">"שתף"</string>
<string name="menu_delete" msgid="8138799623850614177">"מחק"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> נבחרו"</string>
<string name="sort_name" msgid="9183560467917256779">"לפי שם"</string>
<string name="sort_date" msgid="586080032956151448">"לפי תאריך שינוי"</string>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index 996496d..ca64914 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"保存"</string>
<string name="menu_share" msgid="3075149983979628146">"共有"</string>
<string name="menu_delete" msgid="8138799623850614177">"削除"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g>件選択済み"</string>
<string name="sort_name" msgid="9183560467917256779">"名前順"</string>
<string name="sort_date" msgid="586080032956151448">"更新日順"</string>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index f3e1274..3e3d509 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"შენახვა"</string>
<string name="menu_share" msgid="3075149983979628146">"გაზიარება"</string>
<string name="menu_delete" msgid="8138799623850614177">"წაშლა"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> მონიშნული"</string>
<string name="sort_name" msgid="9183560467917256779">"სახელით"</string>
<string name="sort_date" msgid="586080032956151448">"ცვლილების თარიღით"</string>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index 80f3698..2ecbba7 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"រក្សាទុក"</string>
<string name="menu_share" msgid="3075149983979628146">"ចែករំលែក"</string>
<string name="menu_delete" msgid="8138799623850614177">"លុប"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"បានជ្រើស <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"តាមឈ្មោះ"</string>
<string name="sort_date" msgid="586080032956151448">"តាមកាលបរិច្ឆេទបានកែប្រែ"</string>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index 2cd0d44..0ece450 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"저장"</string>
<string name="menu_share" msgid="3075149983979628146">"공유"</string>
<string name="menu_delete" msgid="8138799623850614177">"삭제"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g>개 선택됨"</string>
<string name="sort_name" msgid="9183560467917256779">"이름순"</string>
<string name="sort_date" msgid="586080032956151448">"수정된 날짜순"</string>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 9a6f32f..0bc0b8b 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"ບັນທຶກ"</string>
<string name="menu_share" msgid="3075149983979628146">"ແບ່ງປັນ"</string>
<string name="menu_delete" msgid="8138799623850614177">"ລຶບ"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"ເລືອກແລ້ວ <xliff:g id="COUNT">%1$d</xliff:g> ລາຍການ"</string>
<string name="sort_name" msgid="9183560467917256779">"ຕາມຊື່"</string>
<string name="sort_date" msgid="586080032956151448">"ຕາມວັນທີທີ່ແກ້ໄຂ"</string>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index f861b99..04825f9 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Išsaugoti"</string>
<string name="menu_share" msgid="3075149983979628146">"Bendrinti"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ištrinti"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Pasirinkta: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Pagal pavadinimą"</string>
<string name="sort_date" msgid="586080032956151448">"Pagal keitimo datą"</string>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index 651a59fe0d..5157327 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Saglabāt"</string>
<string name="menu_share" msgid="3075149983979628146">"Kopīgot"</string>
<string name="menu_delete" msgid="8138799623850614177">"Dzēst"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Atlasīts: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Pēc nosaukuma"</string>
<string name="sort_date" msgid="586080032956151448">"Pēc pārveidošanas datuma"</string>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index 22c9fcd..8fd8f52 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Хадгалах"</string>
<string name="menu_share" msgid="3075149983979628146">"Хуваалцах"</string>
<string name="menu_delete" msgid="8138799623850614177">"Устгах"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> сонгогдсон"</string>
<string name="sort_name" msgid="9183560467917256779">"Нэрээр"</string>
<string name="sort_date" msgid="586080032956151448">"Өөрчлөгдсөн огноогоор"</string>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index 7e09c57..48e30305 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Simpan"</string>
<string name="menu_share" msgid="3075149983979628146">"Kongsi"</string>
<string name="menu_delete" msgid="8138799623850614177">"Padam"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> dipilih"</string>
<string name="sort_name" msgid="9183560467917256779">"Mengikut nama"</string>
<string name="sort_date" msgid="586080032956151448">"Diubah suai mengikut tarikh"</string>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 8831bd8..09a11d5 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Lagre"</string>
<string name="menu_share" msgid="3075149983979628146">"Del"</string>
<string name="menu_delete" msgid="8138799623850614177">"Slett"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> valgt"</string>
<string name="sort_name" msgid="9183560467917256779">"Etter navn"</string>
<string name="sort_date" msgid="586080032956151448">"«Etter dato» endret"</string>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index 08862e8..ca626a86 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Opslaan"</string>
<string name="menu_share" msgid="3075149983979628146">"Delen"</string>
<string name="menu_delete" msgid="8138799623850614177">"Verwijderen"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> geselecteerd"</string>
<string name="sort_name" msgid="9183560467917256779">"Op naam"</string>
<string name="sort_date" msgid="586080032956151448">"Op aanpassingsdatum"</string>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 42cec9c..7a7978b 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Zapisz"</string>
<string name="menu_share" msgid="3075149983979628146">"Udostępnij"</string>
<string name="menu_delete" msgid="8138799623850614177">"Usuń"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Wybrano: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Według nazwy"</string>
<string name="sort_date" msgid="586080032956151448">"Według daty edycji"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index f1be722..0443c35 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Partilhar"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selecionado(s)"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
<string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index 78fcaf8..f9038d1 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Salvar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
<string name="menu_delete" msgid="8138799623850614177">"Excluir"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selecionados"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
<string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 5fd44c8..26cd77f 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Salvați"</string>
<string name="menu_share" msgid="3075149983979628146">"Distribuiți"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ștergeți"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selectate"</string>
<string name="sort_name" msgid="9183560467917256779">"După nume"</string>
<string name="sort_date" msgid="586080032956151448">"După data modificării"</string>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index 85fd70e0..f8e1f1b 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Сохранить"</string>
<string name="menu_share" msgid="3075149983979628146">"Поделиться"</string>
<string name="menu_delete" msgid="8138799623850614177">"Удалить"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Выбрано: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"По названию"</string>
<string name="sort_date" msgid="586080032956151448">"По дате изменения"</string>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index 4b5ebcd..cb4b718 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Uložiť"</string>
<string name="menu_share" msgid="3075149983979628146">"Zdieľať"</string>
<string name="menu_delete" msgid="8138799623850614177">"Odstrániť"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Vybraté: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Podľa názvu"</string>
<string name="sort_date" msgid="586080032956151448">"Podľa dátumu zmeny"</string>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index f984a0a..a6dc20b 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Shrani"</string>
<string name="menu_share" msgid="3075149983979628146">"Skupna raba"</string>
<string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Št. izbranih: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Po imenu"</string>
<string name="sort_date" msgid="586080032956151448">"Po datumu spremembe"</string>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index eb0b197..06e0d08 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Сачувај"</string>
<string name="menu_share" msgid="3075149983979628146">"Дели"</string>
<string name="menu_delete" msgid="8138799623850614177">"Избриши"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Изабрано је <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Према имену"</string>
<string name="sort_date" msgid="586080032956151448">"Према датуму измене"</string>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 7aa5c50..da8432e 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Spara"</string>
<string name="menu_share" msgid="3075149983979628146">"Dela"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ta bort"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Har valt <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Efter namn"</string>
<string name="sort_date" msgid="586080032956151448">"Efter ändringsdatum"</string>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index 299fda7..c769a59 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Hifadhi"</string>
<string name="menu_share" msgid="3075149983979628146">"Shiriki"</string>
<string name="menu_delete" msgid="8138799623850614177">"Futa"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> zimechaguliwa"</string>
<string name="sort_name" msgid="9183560467917256779">"Kwa jina"</string>
<string name="sort_date" msgid="586080032956151448">"Kwa tarehe viliporekebishwa"</string>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index 6ac8810..bf92893 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"บันทึก"</string>
<string name="menu_share" msgid="3075149983979628146">"แชร์"</string>
<string name="menu_delete" msgid="8138799623850614177">"ลบ"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"เลือกไว้ <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"ตามชื่อ"</string>
<string name="sort_date" msgid="586080032956151448">"ตามวันที่ที่ปรับเปลี่ยน"</string>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index e0fd8c8..bc363e7 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"I-save"</string>
<string name="menu_share" msgid="3075149983979628146">"Ibahagi"</string>
<string name="menu_delete" msgid="8138799623850614177">"Tanggalin"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ang pinili"</string>
<string name="sort_name" msgid="9183560467917256779">"Ayon sa pangalan"</string>
<string name="sort_date" msgid="586080032956151448">"Ayon sa petsa ng pagbago"</string>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 699a5cd..5d7a2be 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Kaydet"</string>
<string name="menu_share" msgid="3075149983979628146">"Paylaş"</string>
<string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> tane seçildi"</string>
<string name="sort_name" msgid="9183560467917256779">"Ada göre"</string>
<string name="sort_date" msgid="586080032956151448">"Değişiklik tarihine göre"</string>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index f87b6a2..dbd44b7 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Зберегти"</string>
<string name="menu_share" msgid="3075149983979628146">"Поділитися"</string>
<string name="menu_delete" msgid="8138799623850614177">"Видалити"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Вибрано <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"За назвою"</string>
<string name="sort_date" msgid="586080032956151448">"За датою змінення"</string>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index 41e29fa..919708f 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Lưu"</string>
<string name="menu_share" msgid="3075149983979628146">"Chia sẻ"</string>
<string name="menu_delete" msgid="8138799623850614177">"Xóa"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"Đã chọn <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="sort_name" msgid="9183560467917256779">"Theo tên"</string>
<string name="sort_date" msgid="586080032956151448">"Theo ngày sửa đổi"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index 742cda7..a916b87 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"保存"</string>
<string name="menu_share" msgid="3075149983979628146">"分享"</string>
<string name="menu_delete" msgid="8138799623850614177">"删除"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"已选择<xliff:g id="COUNT">%1$d</xliff:g>项"</string>
<string name="sort_name" msgid="9183560467917256779">"按名称"</string>
<string name="sort_date" msgid="586080032956151448">"按修改日期"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 67ed587..7cae910 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"儲存"</string>
<string name="menu_share" msgid="3075149983979628146">"分享"</string>
<string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 個"</string>
<string name="sort_name" msgid="9183560467917256779">"按名稱"</string>
<string name="sort_date" msgid="586080032956151448">"按修改日期"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index 75ecbcf..387fdba 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"儲存"</string>
<string name="menu_share" msgid="3075149983979628146">"共用"</string>
<string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 個項目"</string>
<string name="sort_name" msgid="9183560467917256779">"依名稱"</string>
<string name="sort_date" msgid="586080032956151448">"依修改日期"</string>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index bedd2cdf..564b2d7 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -29,6 +29,8 @@
<string name="menu_save" msgid="2394743337684426338">"Londoloza"</string>
<string name="menu_share" msgid="3075149983979628146">"Yabelana"</string>
<string name="menu_delete" msgid="8138799623850614177">"Susa"</string>
+ <!-- no translation found for menu_select (8711270657353563424) -->
+ <skip />
<string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> okukhethiwe"</string>
<string name="sort_name" msgid="9183560467917256779">"Ngegama"</string>
<string name="sort_date" msgid="586080032956151448">"Ngedethi yokuguqula"</string>
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 4442bca..ddc0dbf 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -22,26 +22,26 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.android.systemui.recents.views.TaskInfoView
- android:id="@+id/task_view_info_pane"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible"
- android:background="#e6444444">
+ android:id="@+id/task_view_info_pane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ android:background="@color/recents_task_bar_default_background_color">
<Button
- android:id="@+id/task_view_app_info_button"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="20dp"
- android:layout_marginEnd="20dp"
- android:layout_gravity="top|center_horizontal"
- android:text="@string/recents_app_info_button_label" />
+ android:id="@+id/task_view_app_info_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="20dp"
+ android:layout_marginEnd="20dp"
+ android:layout_gravity="top|center_horizontal"
+ android:text="@string/recents_app_info_button_label" />
</com.android.systemui.recents.views.TaskInfoView>
<com.android.systemui.recents.views.TaskBarView
android:id="@+id/task_view_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
- android:background="#e6444444">
+ android:background="@color/recents_task_bar_default_background_color">
<ImageView
android:id="@+id/application_icon"
android:layout_width="@dimen/recents_task_view_application_icon_size"
@@ -54,8 +54,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:layout_marginStart="@dimen/recents_task_view_application_icon_size"
- android:layout_marginEnd="@dimen/recents_task_view_activity_icon_size"
- android:textSize="24sp"
+ android:layout_marginEnd="8dp"
+ android:textSize="22sp"
android:textColor="#ffffffff"
android:text="@string/recents_empty_message"
android:fontFamily="sans-serif-thin"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 098ecdd..285978b 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Kleurregstellingmodus"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ONLANGS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Programinligting"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk word\ndalk gemonitor"</string>
<string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d kennisgewings versteek"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Raak om te wys"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Moenie steur nie"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d meer"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 75fbaf0..430c209 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"የቀለም እርማት ሁነታ"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"የቅርብ ጊዜዎች"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"የመተግበሪያ መረጃ"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"አውታረ መረብ\nክትትል ሊደረግበት ይችላል"</string>
<string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
<string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d ማሳወቂያዎች ተደብቀዋል"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"ለማሳየት ነካ ያድርጉ"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d ተጨማሪ"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index fd7f791..3186791 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"وضع تصحيح الألوان"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"الأخيرة"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"معلومات التطبيق"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"قد تكون الشبكة\nخاضعة للرقابة"</string>
<string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
<string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"تم إخفاء %d من الإشعارات"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"المس للعرض"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"الرجاء عدم الإزعاج"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d أخرى"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 426471c..b79429c 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим на коригиране на цветовете"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"СКОРОШНИ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Информация за приложението"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежата може\nда се наблюдава"</string>
<string name="description_target_search" msgid="3091587249776033139">"Търсене"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d известия са скрити"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Докоснете за показване"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Още %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 7365377..1841622 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correcció de color"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informació de l\'aplicació"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"És possible que la xarxa\nestigui controlada"</string>
<string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Fes lliscar el dit cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -217,6 +218,7 @@
<item quantity="other" msgid="7388721375827338153">"%d notificacions ocultes"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Toca per mostrar-ho."</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"No molesteu"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d més"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 8455e43..1c2e122 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekce barev"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"POSLEDNÍ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informace o aplikaci"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Síť může být\nmonitorována"</string>
<string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -217,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"Skrytá oznámení: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Oznámení zobrazíte kliknutím"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Další: %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 56bf53b..62ab0c3 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Farvekorrigeringstilstand"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"SENESTE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Oplysninger om applikationen"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netværket kan\nvære overvåget"</string>
<string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d underretninger er skjult"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Tryk for at vise"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Vil ikke forstyrres"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d mere"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 04b1767..a73e6d7 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -165,7 +165,7 @@
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Daten erneut aktivieren"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Keine Internetverbindung"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN verbunden"</string>
- <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS wird gesucht"</string>
+ <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS wird gesucht..."</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Farbkorrekturmodus"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"Letzte"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"App-Info"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netzwerk wird\neventuell überwacht."</string>
<string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
@@ -217,6 +218,7 @@
<item quantity="other" msgid="7388721375827338153">"%d Benachrichtigungen ausgeblendet"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Zum Ansehen tippen"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Nicht stören"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d mehr"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index b3404be..caf64f5 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Λειτουργία διόρθωσης χρώματος"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ΠΡΟΣΦΑΤΑ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Πληροφορίες εφαρμογής"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Το δίκτυο μπορεί\nνα παρακολουθείται"</string>
<string name="description_target_search" msgid="3091587249776033139">"Αναζήτηση"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Κύλιση προς τα επάνω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -217,6 +218,7 @@
<item quantity="other" msgid="7388721375827338153">"Έγινε απόκρυψη %d ειδοποιήσεων"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Αγγίξτε για εμφάνιση"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Μην ενοχλείτε"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d ακόμη"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index ff2e525..7eff6ee 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
<string name="description_target_search" msgid="3091587249776033139">"Search"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d notifications hidden"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Touch to show"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d more"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index ff2e525..7eff6ee 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
<string name="description_target_search" msgid="3091587249776033139">"Search"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d notifications hidden"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Touch to show"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d more"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index bdd5885..d2a1125 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Es posible que la red\nesté supervisada."</string>
<string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -217,6 +218,7 @@
<item quantity="other" msgid="7388721375827338153">"%d notificaciones ocultas"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Toca para mostrar"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"No molestar"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d más"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index c8e26d2..822db03 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La red se\npuede supervisar"</string>
<string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d notificaciones ocultas"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Toca para mostrar"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"No molestar"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d más"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 2a8314d..027de0c 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -205,7 +205,8 @@
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Täiustatud kontrasti režiim"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Värviparandusrežiim"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"HILJUTISED"</string>
- <string name="recents_app_info_button_label" msgid="2890317189376000030">"Rakenduse teave"</string>
+ <string name="recents_app_info_button_label" msgid="2890317189376000030">"Rakenduste teave"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Võrku võidakse\njälgida"</string>
<string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -213,6 +214,8 @@
<!-- String.format failed for translation -->
<!-- no translation found for zen_mode_notification_title:other (7388721375827338153) -->
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Puudutage kuvamiseks"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Veel %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 9461948..53353ae 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"حالت تصحیح رنگ"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"موارد اخیر"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"اطلاعات برنامه"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ممکن است شبکه\nتحت نظارت باشد"</string>
<string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
<string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d اعلان پنهان شده"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"برای نمایش لمس کنید"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d بیشتر"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index bb81ffa..dad857c 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Värinkorjaustila"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"VIIMEISIMMÄT"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Sovellustiedot"</string>
+ <!-- no translation found for recents_search_bar_label (8074997400187836677) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Verkkoa saatetaan\nvalvoa"</string>
<string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +217,8 @@
<item quantity="other" msgid="7388721375827338153">"%d ilmoitusta piilotettu"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Näytä koskettamalla"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d muuta"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5232d22..f0eb784 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Détails de l\'application"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
<string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -217,6 +218,7 @@
<item quantity="other" msgid="7388721375827338153">"%d notifications masquées"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Touchez pour afficher la notification"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Ne pas déranger"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d autres"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1cc8072..84dae3f 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informations sur l\'application"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
<string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -217,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"%d notifications masquées"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Appuyer pour afficher"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"+ %d autres"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index fd7783d..2cdff20 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"रंग सुधार मोड"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"हाल ही का"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"एप्लिकेशन जानकारी"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"नेटवर्क को\nमॉनीटर किया जा सकता है"</string>
<string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्लाइड करें."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d सूचनाएं छिपी हुई हैं"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"दिखाने के लिए स्पर्श करें"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"परेशान न करें"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d और"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b7c69d5..8b69a4d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Način korekcije boje"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNO"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacije o aplikaciji"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža se\nmožda prati"</string>
<string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"Broj skrivenih obavijesti: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Dodirnite za prikaz"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Još %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index f374743..e9c7c7b 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Színjavítás mód"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"LEGUTÓBBIAK"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Az alkalmazás adatai"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Lehet, hogy a\nhálózat felügyelt"</string>
<string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
<string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d értesítés elrejtve"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"A megtekintéshez érintse meg"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Ne zavarjanak"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d további"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index f2bbb7c..e2d69a0 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Գույների կարգավորման ռեժիմ"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ՎԵՐՋԻՆՆԵՐԸ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Հավելվածի մասին"</string>
+ <!-- no translation found for recents_search_bar_label (8074997400187836677) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ցանցը կարող է\nվերահսկվել"</string>
<string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
@@ -215,6 +217,8 @@
<item quantity="other" msgid="7388721375827338153">"%d ծանուցում թաքցված է"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Հպեք՝ ցուցադրելու համար"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Եվս %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index ccd6c68..c3ec03b 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode koreksi warna"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"TERBARU"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Info Aplikasi"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Jaringan bisa\ndiawasi"</string>
<string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d pemberitahuan disembunyikan"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Sentuh untuk menampilkan"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Jangan ganggu"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d lainnya"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 1c0f712..60f9fc8 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modalità di correzione del colore"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"MESSAGGI RECENTI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informazioni sull\'applicazione"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La rete potrebbe\nessere monitorata"</string>
<string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -217,6 +218,7 @@
<item quantity="other" msgid="7388721375827338153">"%d notifiche nascoste"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Tocca per visualizzare"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Non disturbare"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Altre %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 67ed8c5..f9dc2e7 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"מצב תיקון צבע"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"אחרונים"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"מידע על האפליקציה"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ייתכן שהרשת\nמנוטרת"</string>
<string name="description_target_search" msgid="3091587249776033139">"חיפוש"</string>
<string name="description_direction_up" msgid="7169032478259485180">"הסט למעלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d הודעות הוסתרו"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"גע כדי להציג"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"נא לא להפריע"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"עוד %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 14309ab..73fb622 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"色補正モード"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"アプリ情報"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ネットワークが監視される\n場合があります"</string>
<string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
<string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
@@ -217,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"%d件の通知が非表示"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"表示するにはタップします"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"他%d件"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 904ae01..0cd7812 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -205,7 +205,8 @@
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"გაუმჯობესებული კონტრასტის რეჟიმი"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"ფერთა კორექციის რეჟიმი"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ბოლო დროის"</string>
- <!-- no translation found for recents_app_info_button_label (2890317189376000030) -->
+ <string name="recents_app_info_button_label" msgid="2890317189376000030">"აპლიკაციის შესახებ"</string>
+ <!-- no translation found for recents_search_bar_label (8074997400187836677) -->
<skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"შესაძლოა ქსელზე\nმონიტორინგი ხორციელდებოდეს"</string>
<string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
@@ -216,6 +217,8 @@
<item quantity="other" msgid="7388721375827338153">"%d შეტყობინება დამალულია"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"შეეხეთ საჩვენებლად"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d სხვა"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 5ce1be3..30eae2e 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"របៀបកែពណ៌"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ថ្មីៗ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ព័ត៌មានកម្មវិធី"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញអាច\nត្រូវបានត្រួតពិនិត្យ"</string>
<string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
<string name="description_direction_up" msgid="7169032478259485180">"រុញឡើងលើដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"បានលាក់ការជូនដំណឹង %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"ប៉ះដើម្បីបង្ហាញ"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"កុំរំខាន"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d ទៀត"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 99e1ac0..e1ab831 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"색상 보정 모드"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"최근"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"애플리케이션 정보"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"네트워크가\n모니터링될 수 있음"</string>
<string name="description_target_search" msgid="3091587249776033139">"검색"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"알림 %d개 숨김"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"표시하려면 터치"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d개 더보기"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index a09a310..3ade551 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"ໂໝດການແກ້ໄຂສີ"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ບໍ່ດົນມານີ້"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ຂໍ້ມູນແອັບພລິເຄຊັນ"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ເຄືອຄ່າຍອາດ\nຖືກຕິດຕາມ"</string>
<string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
<string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"ເຊື່ອງ %d ການແຈ້ງເຕືອນແລ້ວ"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"ແຕະເພື່ອສະແດງ"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d ເພີ່ມເຕີມ"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 6fa96aa..3dc6a7a 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Spalvų taisymo režimas"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"PASTARIEJI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Programos informacija"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tinklas gali\nbūti stebimas"</string>
<string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"Paslėpta pranešimų: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Palieskite, kad būtų rodoma"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Netrukdyti"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Dar %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 19602a6..9405545 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Krāsu korekcijas režīms"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"JAUNĀKIE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informācija par lietojumprogrammu"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tīkls var\ntikt uzraudzīts"</string>
<string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d paziņojumi paslēpti"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Pieskarieties, lai rādītu"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Netraucēt"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"vēl %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 1ff647f..99ecacf 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Өнгө залруулах горим"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"СҮҮЛИЙН"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Аппликешны мэдээлэл"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Сүлжээ хянагдаж\nбайж болзошгүй"</string>
<string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d мэдэгдлийг нуусан"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Харуулах бол хүрнэ үү"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Бүү саад бол"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"өөр %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 77c1c9d..886d644 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -205,8 +205,8 @@
<string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod kontras dipertingkat"</string>
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod pembetulan warna"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"TERBAHARU"</string>
- <!-- no translation found for recents_app_info_button_label (2890317189376000030) -->
- <skip />
+ <string name="recents_app_info_button_label" msgid="2890317189376000030">"Maklumat Aplikasi"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rangkaian mungkin\nboleh dipantau"</string>
<string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -216,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d pemberitahuan disembunyikan"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Sentuh untuk menunjukkan"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d lagi"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index dd8c531..1892632 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus for fargekorrigering"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NYLIGE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformasjon"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nettverket kan\nvære overvåket"</string>
<string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d varsler er skjult"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Trykk for å vise"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d til"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index a4d8d22..bf4d765 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus voor kleurcorrectie"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"App-informatie"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk kan\nworden gecontroleerd"</string>
<string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d meldingen verborgen"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Raak aan om weer te geven"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Niet storen"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Nog %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 2a5b0f8..57605b2 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Tryb korekcji kolorów"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"OSTATNIE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacje o aplikacji"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieć może być\nmonitorowana"</string>
<string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"Ukryte powiadomienia: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Dotknij, by zobaczyć"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Nie przeszkadzać"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d więcej"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 39cfe4d..fc71887 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações da aplicação"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode ser\nmonitorizada"</string>
<string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d notificações ocultas"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Toque para mostrar"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Não incomodar"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Mais %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 6d712c3..d1ed7ac 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações do aplicativo"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode estar\nsob monitoração"</string>
<string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
@@ -217,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"%d notificações ocultas"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Toque para mostrar"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Mais %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 4ab5e75..4e0f0f6 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -382,6 +382,8 @@
<skip />
<!-- no translation found for recents_app_info_button_label (2890317189376000030) -->
<skip />
+ <!-- no translation found for recents_search_bar_label (8074997400187836677) -->
+ <skip />
<!-- no translation found for ssl_ca_cert_warning (9005954106902053641) -->
<skip />
<!-- no translation found for description_target_search (3091587249776033139) -->
@@ -394,5 +396,7 @@
<!-- no translation found for zen_mode_notification_title:other (7388721375827338153) -->
<!-- no translation found for zen_mode_notification_text (8336623711388065713) -->
<skip />
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<!-- no translation found for keyguard_more_overflow_text:other (9180696159506883684) -->
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2e8c7a6..cef305c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -206,6 +206,8 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod de corectare a culorilor"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"RECENTE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informații despre aplicație"</string>
+ <!-- no translation found for recents_search_bar_label (8074997400187836677) -->
+ <skip />
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rețeaua poate\nfi monitorizată"</string>
<string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +217,8 @@
<item quantity="other" msgid="7388721375827338153">"%d de notificări ascunse"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Atingeți pentru a afișa"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Încă %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 643759f..ef4b6ee 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -178,9 +178,7 @@
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Режим полета"</string>
<string name="quick_settings_battery_charging_label" msgid="490074774465309209">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for quick_settings_battery_charged_label (8865413079414246081) -->
- <skip />
+ <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"100%%"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g>)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth выкл."</string>
@@ -210,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Коррекция цвета"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"НЕДАВНИЕ СООБЩЕНИЯ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Сведения о приложении"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Действия в сети\nмогут отслеживаться"</string>
<string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -219,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"Скрыто оповещений: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Нажмите, чтобы открыть"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Ещё %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 3daf9f9..11e8b26 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekcie farieb"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NEDÁVNE"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Informácie o aplikácii"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieť môže byť\nmonitorovaná"</string>
<string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -217,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"Skryté upozornenia: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Upozornenie zobrazíte dotykom"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d ďalších"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index acda247..00d0086 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Način popravljanja barv"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Podatki o aplikaciji"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Omrežje je\nlahko spremljano"</string>
<string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"Skritih je toliko obvestil: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Dotaknite se za prikaz"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Ne moti"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"še %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4331c7f..0f8686c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим корекције боје"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"НАЈНОВИЈЕ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Информације о апликацији"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежа се можда\nнадгледа"</string>
<string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"Сакривена обавештења: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Додирните за приказ"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Још %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index cb591c12..a0e1468 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Färgkorrigeringsläge"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"NYA"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformation"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nätverket kan\nvara övervakat"</string>
<string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d aviseringar har dolts"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Tryck här om du vill visa aviseringar"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Stör ej"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d till"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 11e2435..2c84b19 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -204,6 +204,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Hali ya kusahihisha rangi"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"YA HIVI KARIBUNI"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Maelezo ya Programu"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Huenda mtandao\nunafuatiliwa"</string>
<string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
@@ -213,6 +214,8 @@
<item quantity="other" msgid="7388721375827338153">"Arifa %d zimefichwa"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Gusa ili zionekane"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d zaidi"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 33fded2..1ebe21c 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"โหมดการแก้ไขสี"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ล่าสุด"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ข้อมูลแอปพลิเคชัน"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"เครือข่ายอาจ\nถูกตรวจสอบ"</string>
<string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
<string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"ซ่อน %d การแจ้งเตือนแล้ว"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"แตะเพื่อแสดง"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"ห้ามรบกวน"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"อีก %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 57b882c..eb8f236 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode ng pagtatama ng kulay"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"MGA KAMAKAILAN"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Impormasyon ng Application"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Maaaring\nsinusubaybayan ang network"</string>
<string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"Nakatago ang %d (na) notification"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Pindutin upang ipakita"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d pa"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 43e199e..1b57a94 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Renk düzeltme modu"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"SON İLETİLER"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Uygulama Bilgileri"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ağ izleniyor\nolabilir"</string>
<string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d bildirim gizli"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Görüntülemek için dokunun"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d adet daha"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index cab6b65..60192d7 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим коригування кольору"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"ОСТАННІ"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Інформація про додаток"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мережа може\nвідстежуватися"</string>
<string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"Сховано сповіщень: %d"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Торкніться, щоб показати"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Не турбувати"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"Ще %d"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index bfbbf01..8770854 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Chế độ hiệu chỉnh màu sắc"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"GẦN ĐÂY"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Thông tin ứng dụng"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mạng có thể\nđược giám sát"</string>
<string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,8 @@
<item quantity="other" msgid="7388721375827338153">"%d thông báo ẩn"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Chạm để hiển thị"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d thông báo khác"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index ede3b61..89250a5 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"颜色校正模式"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"应用信息"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"网络可能会\n受到监控"</string>
<string name="description_target_search" msgid="3091587249776033139">"搜索"</string>
<string name="description_direction_up" msgid="7169032478259485180">"向上滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
@@ -217,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"隐藏了%d条通知"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"触摸即可显示"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"还有%d条"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 006ce3e..6fb723e 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校準模式"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"近期"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資料"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網絡可能會\n受到監控"</string>
<string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
<string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
@@ -217,6 +218,7 @@
<item quantity="other" msgid="7388721375827338153">"已隱藏 %d 則通知"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"輕觸即可顯示"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"請勿騷擾"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"還有 %d 個"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 2a56c3f..9ceb4e9 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -208,6 +208,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校正模式"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"近期"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資訊"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網路可能\n受到監控"</string>
<string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
<string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
@@ -217,6 +218,8 @@
<item quantity="other" msgid="7388721375827338153">"已隱藏 %d 則通知"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"輕觸即可顯示"</string>
+ <!-- no translation found for zen_mode_title (8793432092004749188) -->
+ <skip />
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"還有 %d 則"</item>
</plurals>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index a2defee..81a08d9 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -206,6 +206,7 @@
<string name="quick_settings_color_space_label" msgid="853443689745584770">"Imodi yokulungisa umbala"</string>
<string name="recents_empty_message" msgid="2269156590813544104">"OKWAKAMUVA"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Ulwazi lohlelo lokusebenza"</string>
+ <string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Kungenzeka inethiwekhi\niqashiwe"</string>
<string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -215,6 +216,7 @@
<item quantity="other" msgid="7388721375827338153">"%d izaziso zifihliwe"</item>
</plurals>
<string name="zen_mode_notification_text" msgid="8336623711388065713">"Thinta ukuze ubonise"</string>
+ <string name="zen_mode_title" msgid="8793432092004749188">"Ungaphazamisi"</string>
<plurals name="keyguard_more_overflow_text">
<item quantity="other" msgid="9180696159506883684">"%d okuningi"</item>
</plurals>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 59e8360..9281265 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -49,4 +49,14 @@
<!-- Tint color for the content on the notification overflow card. -->
<color name="keyguard_overflow_content_color">#ff666666</color>
+
+ <!-- The default recents task bar background color. -->
+ <color name="recents_task_bar_default_background_color">#e6444444</color>
+ <!-- The default recents task bar text color. -->
+ <color name="recents_task_bar_default_text_color">#ffffffff</color>
+ <!-- The recents task bar light text color to be drawn on top of dark backgrounds. -->
+ <color name="recents_task_bar_light_text_color">#ffffffff</color>
+ <!-- The recents task bar dark text color to be drawn on top of light backgrounds. -->
+ <color name="recents_task_bar_dark_text_color">#ff222222</color>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 081e8de..ffdb620 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -157,24 +157,6 @@
private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
/**
- * Allow the user to expand the status bar when the keyguard is engaged
- * (without a pattern or password).
- */
- private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
-
- /**
- * Allow the user to expand the status bar when a SECURE keyguard is engaged
- * and {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS} is set
- * (private notifications will be masked).
- */
- private static final boolean ENABLE_SECURE_STATUS_BAR_EXPAND = true;
-
- /**
- * Default value of {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
- */
- private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false;
-
- /**
* Secure setting whether analytics are collected on the keyguard.
*/
private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
@@ -277,11 +259,6 @@
private int mLockSoundStreamId;
/**
- * Tracks value of {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
- */
- private boolean mAllowNotificationsWhenSecure;
-
- /**
* The volume applied to the lock/unlock sounds.
*/
private float mLockSoundVolume;
@@ -895,13 +872,6 @@
return;
}
- // note whether notification access should be allowed
- mAllowNotificationsWhenSecure = ENABLE_SECURE_STATUS_BAR_EXPAND
- && 0 != Settings.Global.getInt(
- mContext.getContentResolver(),
- Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
- ALLOW_NOTIFICATIONS_DEFAULT ? 1 : 0);
-
// if the keyguard is already showing, don't bother
if (mStatusBarKeyguardViewManager.isShowing()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
@@ -1271,11 +1241,6 @@
// (like recents). Temporary enable/disable (e.g. the "back" button) are
// done in KeyguardHostView.
flags |= StatusBarManager.DISABLE_RECENT;
- if (isSecure()) {
- // showing secure lockscreen; disable ticker and switch private notifications
- // to show their public versions, if available.
- flags |= StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS;
- }
if (!isAssistantAvailable()) {
flags |= StatusBarManager.DISABLE_SEARCH;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index da265e1..52bba4a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -413,6 +413,8 @@
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = tasks.get(i);
ActivityInfo info = ssp.getActivityInfo(t.baseIntent.getComponent(), t.userId);
+ if (info == null) continue;
+
String activityLabel = (t.activityLabel == null ? ssp.getActivityLabel(info) :
t.activityLabel.toString());
BitmapDrawable activityIcon = null;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserSwitcherHostView.java b/packages/SystemUI/src/com/android/systemui/settings/UserSwitcherHostView.java
index 87ebcc1..d67e7cb 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserSwitcherHostView.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserSwitcherHostView.java
@@ -38,6 +38,7 @@
import android.widget.TextView;
import java.util.ArrayList;
+import java.util.List;
/**
* A quick and dirty view to show a user switcher.
@@ -118,7 +119,12 @@
public void refreshUsers() {
mUserInfo.clear();
- mUserInfo.addAll(mUserManager.getUsers(true));
+ List<UserInfo> users = mUserManager.getUsers(true);
+ for (UserInfo user : users) {
+ if (!user.isManagedProfile()) {
+ mUserInfo.add(user);
+ }
+ }
mAdapter.notifyDataSetChanged();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index cf31b44..1ffb4ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -143,6 +143,10 @@
return false;
}
+ public boolean isSecure() {
+ return mKeyguardView == null || mKeyguardView.getSecurityMode() != SecurityMode.None;
+ }
+
public boolean onMenuPressed() {
ensureView();
if (mKeyguardView.handleMenuKey()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 2d96c5e..7f1ddaf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -25,7 +25,6 @@
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
-import static com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -77,7 +76,6 @@
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewPropertyAnimator;
-import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
@@ -148,6 +146,11 @@
private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
+ /**
+ * Default value of {@link android.provider.Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
+ */
+ private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false;
+
private static final int STATUS_OR_NAV_TRANSIENT =
View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
private static final long AUTOHIDE_TIMEOUT_MS = 3000;
@@ -781,10 +784,11 @@
if (!qsTap && !inButton) {
mSettingsTracker.computeCurrentVelocity(1000);
final float vy = mSettingsTracker.getYVelocity();
+ final boolean animate = true;
if (dy <= slop || vy <= 0) {
- flipToNotifications();
+ flipToNotifications(animate);
} else {
- flipToSettings();
+ flipToSettings(animate);
}
}
mSettingsTracker.recycle();
@@ -1452,8 +1456,6 @@
flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
- flagdbg.append(((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "PRIVATE" : "private");
- flagdbg.append(((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "* " : " ");
flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
@@ -1538,15 +1540,6 @@
.setDuration(175)
.start();
}
- } else if ((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
- if ((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
- // we are outside a secure keyguard, so we need to switch to "public" mode
- setLockscreenPublicMode(true);
- } else {
- // user has authenticated the device; full notifications may be shown
- setLockscreenPublicMode(false);
- }
- updateNotificationIcons();
}
}
@@ -1669,7 +1662,7 @@
mStatusBarWindow.cancelExpandHelper();
mStatusBarView.collapseAllPanels(true);
if (isFlippedToSettings()) {
- flipToNotifications();
+ flipToNotifications(true /*animate*/);
}
}
}
@@ -1729,36 +1722,49 @@
mNotificationPanel.expand();
if (mStackScroller.getVisibility() != View.VISIBLE) {
- flipToNotifications();
+ flipToNotifications(true /*animate*/);
}
if (false) postStartTracing();
}
- public void flipToNotifications() {
- if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
- if (mScrollViewAnim != null) mScrollViewAnim.cancel();
+ private static void cancelAnim(Animator anim) {
+ if (anim != null) {
+ anim.cancel();
+ }
+ }
+
+ public void flipToNotifications(boolean animate) {
+ cancelAnim(mFlipSettingsViewAnim);
+ cancelAnim(mScrollViewAnim);
+ cancelAnim(mClearButtonAnim);
mHeaderFlipper.cancel();
mKeyguardFlipper.cancel();
- if (mClearButtonAnim != null) mClearButtonAnim.cancel();
mStackScroller.setVisibility(View.VISIBLE);
final int h = mNotificationPanel.getMeasuredHeight();
- final float settingsY = mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : 0;
- final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : h;
- mScrollViewAnim = start(
- interpolator(mDecelerateInterpolator,
- ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, 0)
- .setDuration(FLIP_DURATION)
- ));
- mFlipSettingsViewAnim = start(
- setVisibilityWhenDone(
- interpolator(mDecelerateInterpolator,
- ObjectAnimator.ofFloat(mFlipSettingsView, View.TRANSLATION_Y, settingsY, -h)
- )
- .setDuration(FLIP_DURATION),
- mFlipSettingsView, View.INVISIBLE));
- mHeaderFlipper.flipToNotifications();
- mKeyguardFlipper.flipToNotifications();
+ if (animate) {
+ final float settingsY =
+ mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : 0;
+ final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : h;
+ mScrollViewAnim = start(
+ interpolator(mDecelerateInterpolator,
+ ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, 0)
+ .setDuration(FLIP_DURATION)
+ ));
+ mFlipSettingsViewAnim = start(
+ setVisibilityWhenDone(
+ interpolator(mDecelerateInterpolator,
+ ObjectAnimator.ofFloat(
+ mFlipSettingsView, View.TRANSLATION_Y, settingsY, -h))
+ .setDuration(FLIP_DURATION),
+ mFlipSettingsView, View.INVISIBLE));
+ } else {
+ mStackScroller.setTranslationY(0);
+ mFlipSettingsView.setTranslationY(-h);
+ mFlipSettingsView.setVisibility(View.INVISIBLE);
+ }
+ mHeaderFlipper.flipToNotifications(animate);
+ mKeyguardFlipper.flipToNotifications(animate);
mClearButton.setVisibility(View.VISIBLE);
mClearButton.setAlpha(0f);
setAreThereNotifications(); // this will show/hide the button as necessary
@@ -1766,7 +1772,7 @@
public void run() {
updateCarrierLabelVisibility(false);
}
- }, FLIP_DURATION - 150);
+ }, animate ? FLIP_DURATION - 150 : 0);
if (mOnFlipRunnable != null) {
mOnFlipRunnable.run();
}
@@ -1785,7 +1791,7 @@
mNotificationPanel.expand();
if (mFlipSettingsView.getVisibility() != View.VISIBLE
|| mFlipSettingsView.getTranslationY() < 0) {
- flipToSettings();
+ flipToSettings(true /*animate*/);
}
if (false) postStartTracing();
@@ -1798,58 +1804,63 @@
return false;
}
- public void flipToSettings() {
+ public void flipToSettings(boolean animate) {
// Settings are not available in setup
if (!mUserSetup) return;
- if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
- if (mScrollViewAnim != null) mScrollViewAnim.cancel();
+ cancelAnim(mFlipSettingsViewAnim);
+ cancelAnim(mScrollViewAnim);
mHeaderFlipper.cancel();
mKeyguardFlipper.cancel();
- if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+ cancelAnim(mClearButtonAnim);
mFlipSettingsView.setVisibility(View.VISIBLE);
final int h = mNotificationPanel.getMeasuredHeight();
- final float settingsY = mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : -h;
- final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : 0;
- mFlipSettingsViewAnim = start(
- startDelay(0,
+ if (animate) {
+ final float settingsY
+ = mSettingsTracker != null ? mFlipSettingsView.getTranslationY() : -h;
+ final float scrollerY = mSettingsTracker != null ? mStackScroller.getTranslationY() : 0;
+ mFlipSettingsViewAnim = start(
+ startDelay(0,
+ interpolator(mDecelerateInterpolator,
+ ObjectAnimator.ofFloat(mFlipSettingsView, View.TRANSLATION_Y,
+ settingsY, 0f)
+ .setDuration(FLIP_DURATION)
+ )));
+ mScrollViewAnim = start(
+ setVisibilityWhenDone(
interpolator(mDecelerateInterpolator,
- ObjectAnimator.ofFloat(mFlipSettingsView, View.TRANSLATION_Y, settingsY, 0f)
- .setDuration(FLIP_DURATION)
- )));
- mScrollViewAnim = start(
- setVisibilityWhenDone(
- interpolator(mDecelerateInterpolator,
- ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, h)
- )
+ ObjectAnimator.ofFloat(mStackScroller, View.TRANSLATION_Y, scrollerY, h)
+ )
+ .setDuration(FLIP_DURATION),
+ mStackScroller, View.INVISIBLE));
+ } else {
+ mFlipSettingsView.setTranslationY(0);
+ mStackScroller.setTranslationY(h);
+ mStackScroller.setVisibility(View.INVISIBLE);
+ }
+ mHeaderFlipper.flipToSettings(animate);
+ mKeyguardFlipper.flipToSettings(animate);
+ if (animate) {
+ mClearButtonAnim = start(
+ setVisibilityWhenDone(
+ ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
.setDuration(FLIP_DURATION),
- mStackScroller, View.INVISIBLE));
- mHeaderFlipper.flipToSettings();
- mKeyguardFlipper.flipToSettings();
- mClearButtonAnim = start(
- setVisibilityWhenDone(
- ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
- .setDuration(FLIP_DURATION),
- mClearButton, View.INVISIBLE));
+ mClearButton, View.INVISIBLE));
+ } else {
+ mClearButton.setAlpha(0);
+ mClearButton.setVisibility(View.INVISIBLE);
+ }
mNotificationPanel.postDelayed(new Runnable() {
public void run() {
updateCarrierLabelVisibility(false);
}
- }, FLIP_DURATION - 150);
+ }, animate ? FLIP_DURATION - 150 : 0);
if (mOnFlipRunnable != null) {
mOnFlipRunnable.run();
}
}
- public void flipPanels() {
- if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
- flipToSettings();
- } else {
- flipToNotifications();
- }
- }
-
public void animateCollapseQuickSettings() {
mStatusBarView.collapseAllPanels(true);
}
@@ -2910,31 +2921,44 @@
public void showKeyguard() {
mOnKeyguard = true;
+ updateKeyguardState();
instantExpandNotificationsPanel();
- if (isFlippedToSettings()) {
- flipToNotifications();
- }
- mKeyguardStatusView.setVisibility(View.VISIBLE);
- mKeyguardBottomArea.setVisibility(View.VISIBLE);
- mNotificationPanelHeader.setVisibility(View.GONE);
-
- mKeyguardFlipper.setVisibility(View.VISIBLE);
- mSettingsContainer.setKeyguardShowing(true);
- updateRowStates();
- checkBarModes();
}
public void hideKeyguard() {
mOnKeyguard = false;
- mKeyguardStatusView.setVisibility(View.GONE);
- mKeyguardBottomArea.setVisibility(View.GONE);
- mNotificationPanelHeader.setVisibility(View.VISIBLE);
-
- mKeyguardFlipper.setVisibility(View.GONE);
- mSettingsContainer.setKeyguardShowing(false);
- updateRowStates();
+ updateKeyguardState();
instantCollapseNotificationPanel();
+ }
+
+ private void updatePublicMode() {
+ setLockscreenPublicMode(mOnKeyguard && mStatusBarKeyguardViewManager.isSecure());
+ }
+
+ private void updateKeyguardState() {
+ if (mOnKeyguard) {
+ if (isFlippedToSettings()) {
+ flipToNotifications(false /*animate*/);
+ }
+ mKeyguardStatusView.setVisibility(View.VISIBLE);
+ mKeyguardBottomArea.setVisibility(View.VISIBLE);
+ mNotificationPanelHeader.setVisibility(View.GONE);
+
+ mKeyguardFlipper.setVisibility(View.VISIBLE);
+ mSettingsContainer.setKeyguardShowing(true);
+ } else {
+ mKeyguardStatusView.setVisibility(View.GONE);
+ mKeyguardBottomArea.setVisibility(View.GONE);
+ mNotificationPanelHeader.setVisibility(View.VISIBLE);
+
+ mKeyguardFlipper.setVisibility(View.GONE);
+ mSettingsContainer.setKeyguardShowing(false);
+ }
+
+ updatePublicMode();
+ updateRowStates();
checkBarModes();
+ updateNotificationIcons();
}
public void userActivity() {
@@ -3075,36 +3099,48 @@
}
}
- public void flipToSettings() {
- mSettingsButtonAnim = start(
- setVisibilityWhenDone(
- ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
- .setDuration(FLIP_DURATION_OUT),
- mStackScroller, View.INVISIBLE));
+ public void flipToSettings(boolean animate) {
mNotificationButton.setVisibility(View.VISIBLE);
- mNotificationButtonAnim = start(
- startDelay(FLIP_DURATION_OUT,
- ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
- .setDuration(FLIP_DURATION_IN)));
+ if (animate) {
+ mSettingsButtonAnim = start(
+ setVisibilityWhenDone(
+ ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
+ .setDuration(FLIP_DURATION_OUT),
+ mStackScroller, View.INVISIBLE));
+ mNotificationButtonAnim = start(
+ startDelay(FLIP_DURATION_OUT,
+ ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
+ .setDuration(FLIP_DURATION_IN)));
+ } else {
+ mSettingsButton.setAlpha(0f);
+ mSettingsButton.setVisibility(View.INVISIBLE);
+ mNotificationButton.setAlpha(1f);
+ }
}
- public void flipToNotifications() {
- mNotificationButtonAnim = start(
- setVisibilityWhenDone(
- ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
- .setDuration(FLIP_DURATION_OUT),
- mNotificationButton, View.INVISIBLE));
-
+ public void flipToNotifications(boolean animate) {
mSettingsButton.setVisibility(View.VISIBLE);
- mSettingsButtonAnim = start(
- startDelay(FLIP_DURATION_OUT,
- ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
- .setDuration(FLIP_DURATION_IN)));
+ if (animate) {
+ mNotificationButtonAnim = start(
+ setVisibilityWhenDone(
+ ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
+ .setDuration(FLIP_DURATION_OUT),
+ mNotificationButton, View.INVISIBLE));
+
+ mSettingsButtonAnim = start(
+ startDelay(FLIP_DURATION_OUT,
+ ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
+ .setDuration(FLIP_DURATION_IN)));
+ } else {
+ mNotificationButton.setVisibility(View.INVISIBLE);
+ mNotificationButton.setAlpha(0f);
+ mSettingsButton.setAlpha(1f);
+ }
}
public void cancel() {
- if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
- if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+ cancelAnim(mSettingsButtonAnim);
+ cancelAnim(mNotificationButtonAnim);
}
public void setVisibility(int vis) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index b3fba76..f3ebf1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -280,6 +280,7 @@
addUserTiles(mContainerView, inflater);
addSystemTiles(mContainerView, inflater);
addTemporaryTiles(mContainerView, inflater);
+ addAccessibilityTiles(mContainerView);
queryForUserInformation();
queryForSslCaCerts();
@@ -311,6 +312,34 @@
collapsePanels();
}
+ private void addAccessibilityTiles(ViewGroup parent) {
+ if (!DEBUG_GONE_TILES && !SHOW_ACCESSIBILITY_TILES) return;
+
+ // Color inversion tile
+ final SystemSettingTile inversionTile = new SystemSettingTile(mContext);
+ inversionTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
+ SystemSettingTile.TYPE_SECURE);
+ inversionTile.setFragment("Settings$AccessibilityInversionSettingsActivity");
+ mModel.addInversionTile(inversionTile, inversionTile.getRefreshCallback());
+ parent.addView(inversionTile);
+
+ // Contrast enhancement tile
+ final SystemSettingTile contrastTile = new SystemSettingTile(mContext);
+ contrastTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED,
+ SystemSettingTile.TYPE_SECURE);
+ contrastTile.setFragment("Settings$AccessibilityContrastSettingsActivity");
+ mModel.addContrastTile(contrastTile, contrastTile.getRefreshCallback());
+ parent.addView(contrastTile);
+
+ // Color space adjustment tile
+ final SystemSettingTile colorSpaceTile = new SystemSettingTile(mContext);
+ colorSpaceTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
+ SystemSettingTile.TYPE_SECURE);
+ colorSpaceTile.setFragment("Settings$AccessibilityDaltonizerSettingsActivity");
+ mModel.addColorSpaceTile(colorSpaceTile, colorSpaceTile.getRefreshCallback());
+ parent.addView(colorSpaceTile);
+ }
+
private void addUserTiles(final ViewGroup parent, final LayoutInflater inflater) {
QuickSettingsTileView userTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
@@ -384,35 +413,6 @@
new QuickSettingsModel.BasicRefreshCallback(settingsTile));
parent.addView(settingsTile);
mDynamicSpannedTiles.add(settingsTile);
-
- if (SHOW_ACCESSIBILITY_TILES) {
- // Color inversion tile
- final SystemSettingTile inversionTile = new SystemSettingTile(mContext);
- inversionTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
- SystemSettingTile.TYPE_SECURE);
- inversionTile.setFragment("Settings$AccessibilityInversionSettingsActivity");
- mModel.addInversionTile(inversionTile, inversionTile.getRefreshCallback());
- parent.addView(inversionTile);
- mDynamicSpannedTiles.add(inversionTile);
-
- // Contrast enhancement tile
- final SystemSettingTile contrastTile = new SystemSettingTile(mContext);
- contrastTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED,
- SystemSettingTile.TYPE_SECURE);
- contrastTile.setFragment("Settings$AccessibilityContrastSettingsActivity");
- mModel.addContrastTile(contrastTile, contrastTile.getRefreshCallback());
- parent.addView(contrastTile);
- mDynamicSpannedTiles.add(contrastTile);
-
- // Color space adjustment tile
- final SystemSettingTile colorSpaceTile = new SystemSettingTile(mContext);
- colorSpaceTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
- SystemSettingTile.TYPE_SECURE);
- colorSpaceTile.setFragment("Settings$AccessibilityDaltonizerSettingsActivity");
- mModel.addColorSpaceTile(colorSpaceTile, colorSpaceTile.getRefreshCallback());
- parent.addView(colorSpaceTile);
- mDynamicSpannedTiles.add(colorSpaceTile);
- }
}
private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
@@ -574,49 +574,6 @@
});
parent.addView(batteryTile);
- // Airplane Mode
- final QuickSettingsBasicTile airplaneTile
- = new QuickSettingsBasicTile(mContext);
- mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
- @Override
- public void refreshView(QuickSettingsTileView unused, State state) {
- airplaneTile.setImageResource(state.iconId);
-
- String airplaneState = mContext.getString(
- (state.enabled) ? R.string.accessibility_desc_on
- : R.string.accessibility_desc_off);
- airplaneTile.setContentDescription(
- mContext.getString(R.string.accessibility_quick_settings_airplane, airplaneState));
- airplaneTile.setText(state.label);
- }
- });
- parent.addView(airplaneTile);
-
- // Zen Mode
- final QuickSettingsBasicTile zenModeTile = new QuickSettingsBasicTile(mContext);
- zenModeTile.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showZenModeDialog();
- }
- });
- mModel.addZenModeTile(zenModeTile, new QuickSettingsModel.RefreshCallback() {
- @Override
- public void refreshView(QuickSettingsTileView unused, State state) {
- zenModeTile.setImageResource(state.iconId);
- // TODO cut new assets
- zenModeTile.getImageView().setAlpha(state.enabled ? 1 : .2f);
- zenModeTile.getImageView().setScaleX(1.5f);
- zenModeTile.getImageView().setScaleY(1.5f);
- // for landscape version
- zenModeTile.getTextView().setMaxLines(2);
- zenModeTile.getTextView().setEllipsize(TruncateAt.END);
- // TODO content description
- zenModeTile.setText(state.label);
- }
- });
- parent.addView(zenModeTile);
-
// Bluetooth
if (mModel.deviceSupportsBluetooth()
|| DEBUG_GONE_TILES) {
@@ -710,6 +667,50 @@
}
});
parent.addView(locationTile);
+
+ // Airplane Mode
+ final QuickSettingsBasicTile airplaneTile
+ = new QuickSettingsBasicTile(mContext);
+ mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
+ @Override
+ public void refreshView(QuickSettingsTileView unused, State state) {
+ airplaneTile.setImageResource(state.iconId);
+
+ String airplaneState = mContext.getString(
+ (state.enabled) ? R.string.accessibility_desc_on
+ : R.string.accessibility_desc_off);
+ airplaneTile.setContentDescription(
+ mContext.getString(R.string.accessibility_quick_settings_airplane,
+ airplaneState));
+ airplaneTile.setText(state.label);
+ }
+ });
+ parent.addView(airplaneTile);
+
+ // Zen Mode
+ final QuickSettingsBasicTile zenModeTile = new QuickSettingsBasicTile(mContext);
+ zenModeTile.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showZenModeDialog();
+ }
+ });
+ mModel.addZenModeTile(zenModeTile, new QuickSettingsModel.RefreshCallback() {
+ @Override
+ public void refreshView(QuickSettingsTileView unused, State state) {
+ zenModeTile.setImageResource(state.iconId);
+ // TODO cut new assets
+ zenModeTile.getImageView().setAlpha(state.enabled ? 1 : .2f);
+ zenModeTile.getImageView().setScaleX(1.5f);
+ zenModeTile.getImageView().setScaleY(1.5f);
+ // for landscape version
+ zenModeTile.getTextView().setMaxLines(2);
+ zenModeTile.getTextView().setEllipsize(TruncateAt.END);
+ // TODO content description
+ zenModeTile.setText(state.label);
+ }
+ });
+ parent.addView(zenModeTile);
}
private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 501d3f2..c2595cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -179,6 +179,10 @@
}
}
+ public boolean isSecure() {
+ return mBouncer.isSecure();
+ }
+
/**
* @return Whether the keyguard is showing
*/
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 51296c1..8fa076b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3453,11 +3453,14 @@
* @param token The Binder token referencing the Activity we want to finish.
* @param resultCode Result code, if any, from this Activity.
* @param resultData Result data (Intent), if any, from this Activity.
+ * @param finishTask Whether to finish the task associated with this Activity. Only applies to
+ * the root Activity in the task.
*
* @return Returns true if the activity successfully finished, or false if it is still running.
*/
@Override
- public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
+ public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
+ boolean finishTask) {
// Refuse possible leaked file descriptors
if (resultData != null && resultData.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -3468,6 +3471,9 @@
if (r == null) {
return true;
}
+ // Keep track of the root activity of the task before we finish it
+ TaskRecord tr = r.task;
+ ActivityRecord rootR = tr.getRootActivity();
if (mController != null) {
// Find the first activity that is not finishing.
ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
@@ -3487,10 +3493,21 @@
}
}
final long origId = Binder.clearCallingIdentity();
- boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
- resultData, "app-request", true);
- Binder.restoreCallingIdentity(origId);
- return res;
+ try {
+ boolean res;
+ if (finishTask && r == rootR) {
+ // If requested, remove the task that is associated to this activity only if it
+ // was the root activity in the task. The result code and data is ignored because
+ // we don't support returning them across task boundaries.
+ res = removeTaskByIdLocked(tr.taskId, 0);
+ } else {
+ res = tr.stack.requestFinishActivityLocked(token, resultCode,
+ resultData, "app-request", true);
+ }
+ return res;
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
}
}
@@ -7144,6 +7161,24 @@
}
}
+ /**
+ * Removes the task with the specified task id.
+ *
+ * @param taskId Identifier of the task to be removed.
+ * @param flags Additional operational flags. May be 0 or
+ * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
+ * @return Returns true if the given task was found and removed.
+ */
+ private boolean removeTaskByIdLocked(int taskId, int flags) {
+ TaskRecord tr = recentTaskForIdLocked(taskId);
+ if (tr != null) {
+ tr.removeTaskActivitiesLocked(-1, false);
+ cleanUpRemovedTaskLocked(tr, flags);
+ return true;
+ }
+ return false;
+ }
+
@Override
public boolean removeTask(int taskId, int flags) {
synchronized (this) {
@@ -7151,29 +7186,11 @@
"removeTask()");
long ident = Binder.clearCallingIdentity();
try {
- TaskRecord tr = recentTaskForIdLocked(taskId);
- if (tr != null) {
- ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
- if (r != null) {
- cleanUpRemovedTaskLocked(tr, flags);
- return true;
- }
- if (tr.mActivities.size() == 0) {
- // Caller is just removing a recent task that is
- // not actively running. That is easy!
- cleanUpRemovedTaskLocked(tr, flags);
- return true;
- }
- Slog.w(TAG, "removeTask: task " + taskId
- + " does not have activities to remove, "
- + " but numActivities=" + tr.numActivities
- + ": " + tr);
- }
+ return removeTaskByIdLocked(taskId, flags);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- return false;
}
/**
diff --git a/services/core/java/com/android/server/am/NativeCrashListener.java b/services/core/java/com/android/server/am/NativeCrashListener.java
index b12843b..443218c 100644
--- a/services/core/java/com/android/server/am/NativeCrashListener.java
+++ b/services/core/java/com/android/server/am/NativeCrashListener.java
@@ -29,6 +29,7 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
import java.net.InetUnixAddress;
@@ -178,7 +179,7 @@
}
static int readExactly(FileDescriptor fd, byte[] buffer, int offset, int numBytes)
- throws ErrnoException {
+ throws ErrnoException, InterruptedIOException {
int totalRead = 0;
while (numBytes > 0) {
int n = Libcore.os.read(fd, buffer, offset + totalRead, numBytes);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 3a43521..80a219dd 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -139,6 +139,18 @@
}
}
+ /** Returns the first non-finishing activity from the root. */
+ ActivityRecord getRootActivity() {
+ for (int i = 0; i < mActivities.size(); i++) {
+ final ActivityRecord r = mActivities.get(i);
+ if (r.finishing) {
+ continue;
+ }
+ return r;
+ }
+ return null;
+ }
+
ActivityRecord getTopActivity() {
for (int i = mActivities.size() - 1; i >= 0; --i) {
final ActivityRecord r = mActivities.get(i);
@@ -305,7 +317,7 @@
}
public ActivityManager.TaskThumbnails getTaskThumbnailsLocked() {
- TaskAccessInfo info = getTaskAccessInfoLocked(true);
+ TaskAccessInfo info = getTaskAccessInfoLocked();
final ActivityRecord resumedActivity = stack.mResumedActivity;
if (resumedActivity != null && resumedActivity.thumbHolder == this) {
info.mainThumbnail = stack.screenshotActivities(resumedActivity);
@@ -325,7 +337,7 @@
}
// Return the information about the task, to figure out the top
// thumbnail to return.
- TaskAccessInfo info = getTaskAccessInfoLocked(true);
+ TaskAccessInfo info = getTaskAccessInfoLocked();
if (info.numSubThumbbails <= 0) {
return info.mainThumbnail != null ? info.mainThumbnail : lastThumbnail;
}
@@ -334,7 +346,7 @@
public ActivityRecord removeTaskActivitiesLocked(int subTaskIndex,
boolean taskRequired) {
- TaskAccessInfo info = getTaskAccessInfoLocked(false);
+ TaskAccessInfo info = getTaskAccessInfoLocked();
if (info.root == null) {
if (taskRequired) {
Slog.w(TAG, "removeTaskLocked: unknown taskId " + taskId);
@@ -369,7 +381,7 @@
return mTaskType == ActivityRecord.APPLICATION_ACTIVITY_TYPE;
}
- public TaskAccessInfo getTaskAccessInfoLocked(boolean inclThumbs) {
+ public TaskAccessInfo getTaskAccessInfoLocked() {
final TaskAccessInfo thumbs = new TaskAccessInfo();
// How many different sub-thumbnails?
final int NA = mActivities.size();
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a6e83a7..53db9ef 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -22,6 +22,7 @@
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
+import android.app.admin.DevicePolicyManager;
import android.app.IStopUserCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -437,7 +438,7 @@
@Override
public void setUserRestrictions(Bundle restrictions, int userId) {
- checkManageUsersPermission("setUserRestrictions");
+ checkProfileOwnerOrManageUsersPermission("setUserRestrictions");
if (restrictions == null) return;
synchronized (mPackagesLock) {
@@ -463,16 +464,53 @@
* @param message used as message if SecurityException is thrown
* @throws SecurityException if the caller is not system or root
*/
- private static final void checkManageUsersPermission(String message) {
+ private final void checkManageUsersPermission(String message) {
final int uid = Binder.getCallingUid();
- if (uid != Process.SYSTEM_UID && uid != 0
- && ActivityManager.checkComponentPermission(
- android.Manifest.permission.MANAGE_USERS,
- uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
+
+ if (missingManageUsersPermission(uid)) {
throw new SecurityException("You need MANAGE_USERS permission to: " + message);
}
}
+ /**
+ * Enforces that only the system UID, root's UID, apps that have the
+ * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
+ * permission, the profile owner, or the device owner can make certain calls to the
+ * UserManager.
+ *
+ * @param message used as message if SecurityException is thrown
+ * @throws SecurityException if the caller is not system, root, or device
+ * owner
+ */
+ private final void checkProfileOwnerOrManageUsersPermission(String message) {
+ final int uid = Binder.getCallingUid();
+ boolean isProfileOwner = false;
+ if (mContext != null && mContext.getPackageManager() != null) {
+ String[] pkgs = mContext.getPackageManager().getPackagesForUid(uid);
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ if (dpm != null) {
+ for (String pkg : pkgs) {
+ if (dpm.isDeviceOwnerApp(pkg) || dpm.isProfileOwnerApp(pkg)) {
+ isProfileOwner = true;
+ }
+ }
+ }
+ }
+
+ if (missingManageUsersPermission(uid) && !isProfileOwner) {
+ throw new SecurityException(
+ "You need MANAGE_USERS permission or device owner privileges to: " + message);
+ }
+ }
+
+ private boolean missingManageUsersPermission(int uid) {
+ return uid != Process.SYSTEM_UID && uid != 0
+ && ActivityManager.checkComponentPermission(
+ android.Manifest.permission.MANAGE_USERS,
+ uid, -1, true) != PackageManager.PERMISSION_GRANTED;
+ }
+
private void writeBitmapLocked(UserInfo info, Bitmap bitmap) {
try {
File dir = new File(mUsersDir, Integer.toString(info.id));
@@ -1175,7 +1213,8 @@
public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
if (UserHandle.getCallingUserId() != userId
|| !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
- checkManageUsersPermission("Only system can get restrictions for other users/apps");
+ checkProfileOwnerOrManageUsersPermission(
+ "Only system or device owner can get restrictions for other users/apps");
}
synchronized (mPackagesLock) {
// Read the restrictions from XML
@@ -1188,7 +1227,8 @@
int userId) {
if (UserHandle.getCallingUserId() != userId
|| !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
- checkManageUsersPermission("Only system can set restrictions for other users/apps");
+ checkProfileOwnerOrManageUsersPermission(
+ "Only system or device owner can set restrictions for other users/apps");
}
synchronized (mPackagesLock) {
// Write the restrictions to XML
@@ -1290,7 +1330,8 @@
@Override
public void removeRestrictions() {
- checkManageUsersPermission("Only system can remove restrictions");
+ checkProfileOwnerOrManageUsersPermission(
+ "Only system or device owner can remove restrictions");
final int userHandle = UserHandle.getCallingUserId();
removeRestrictionsForUser(userHandle, true);
}
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 0ad3456..ac741e7 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -867,5 +867,16 @@
</intent-filter>
</activity>
+ <activity
+ android:name=".ProjectionClippingActivity"
+ android:label="Reordering/Projection Clipping">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.hwui.TEST" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/tests/HwAccelerationTest/res/drawable/round_rect_background.xml b/tests/HwAccelerationTest/res/drawable/round_rect_background.xml
new file mode 100644
index 0000000..14d4073
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable/round_rect_background.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <solid android:color="#eee" />
+ <corners android:radius="30dp" />
+</shape>
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/layout/projection_clipping.xml b/tests/HwAccelerationTest/res/layout/projection_clipping.xml
new file mode 100644
index 0000000..7caf90a
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/projection_clipping.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:translationX="50dp"
+ android:translationY="50dp"
+ android:translationZ="30dp"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ android:background="@drawable/round_rect_background">
+ <View
+ android:id="@+id/clickable1"
+ android:layout_width="100dp"
+ android:layout_height="100dp"
+ android:background="?android:attr/selectableItemBackground"/>
+ <View
+ android:id="@+id/clickable2"
+ android:translationX="50dp"
+ android:translationY="10dp"
+ android:layout_width="150dp"
+ android:layout_height="100dp"
+ android:background="?android:attr/selectableItemBackground"/>
+ </FrameLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
new file mode 100644
index 0000000..2ae960b
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
@@ -0,0 +1,27 @@
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.RenderNode;
+import android.view.View;
+
+public class ProjectionClippingActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.projection_clipping);
+ View.OnClickListener listener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // woo! nothing!
+ }
+ };
+ findViewById(R.id.clickable1).setOnClickListener(listener);
+ findViewById(R.id.clickable2).setOnClickListener(listener);
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index cdbe200..af22f44 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -32,10 +32,6 @@
import android.content.Context;
import android.util.AttributeSet;
-import android.view.InflateException;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
import java.io.File;
@@ -155,6 +151,9 @@
@Override
public View inflate(int resource, ViewGroup root) {
Context context = getContext();
+ if (context instanceof ContextThemeWrapper) {
+ context = ((ContextThemeWrapper) context).getBaseContext();
+ }
if (context instanceof BridgeContext) {
BridgeContext bridgeContext = (BridgeContext)context;
@@ -217,43 +216,16 @@
}
private void setupViewInContext(View view, AttributeSet attrs) {
- if (getContext() instanceof BridgeContext) {
- BridgeContext bc = (BridgeContext) getContext();
- if (attrs instanceof BridgeXmlBlockParser) {
- BridgeXmlBlockParser parser = (BridgeXmlBlockParser) attrs;
-
- // get the view key
- Object viewKey = parser.getViewCookie();
-
- if (viewKey == null) {
- int currentDepth = parser.getDepth();
-
- // test whether we are in an included file or in a adapter binding view.
- BridgeXmlBlockParser previousParser = bc.getPreviousParser();
- if (previousParser != null) {
- // looks like we inside an embedded layout.
- // only apply the cookie of the calling node (<include>) if we are at the
- // top level of the embedded layout. If there is a merge tag, then
- // skip it and look for the 2nd level
- int testDepth = mIsInMerge ? 2 : 1;
- if (currentDepth == testDepth) {
- viewKey = previousParser.getViewCookie();
- // if we are in a merge, wrap the cookie in a MergeCookie.
- if (viewKey != null && mIsInMerge) {
- viewKey = new MergeCookie(viewKey);
- }
- }
- } else if (mResourceReference != null && currentDepth == 1) {
- // else if there's a resource reference, this means we are in an adapter
- // binding case. Set the resource ref as the view cookie only for the top
- // level view.
- viewKey = mResourceReference;
- }
- }
-
- if (viewKey != null) {
- bc.addViewKey(view, viewKey);
- }
+ Context context = getContext();
+ if (context instanceof ContextThemeWrapper) {
+ context = ((ContextThemeWrapper) context).getBaseContext();
+ }
+ if (context instanceof BridgeContext) {
+ BridgeContext bc = (BridgeContext) context;
+ // get the view key
+ Object viewKey = getViewKeyFromParser(attrs, bc, mResourceReference, mIsInMerge);
+ if (viewKey != null) {
+ bc.addViewKey(view, viewKey);
}
}
}
@@ -270,4 +242,44 @@
public LayoutInflater cloneInContext(Context newContext) {
return new BridgeInflater(this, newContext);
}
+
+ /*package*/ static Object getViewKeyFromParser(AttributeSet attrs, BridgeContext bc,
+ ResourceReference resourceReference, boolean isInMerge) {
+
+ if (!(attrs instanceof BridgeXmlBlockParser)) {
+ return null;
+ }
+ BridgeXmlBlockParser parser = ((BridgeXmlBlockParser) attrs);
+
+ // get the view key
+ Object viewKey = parser.getViewCookie();
+
+ if (viewKey == null) {
+ int currentDepth = parser.getDepth();
+
+ // test whether we are in an included file or in a adapter binding view.
+ BridgeXmlBlockParser previousParser = bc.getPreviousParser();
+ if (previousParser != null) {
+ // looks like we are inside an embedded layout.
+ // only apply the cookie of the calling node (<include>) if we are at the
+ // top level of the embedded layout. If there is a merge tag, then
+ // skip it and look for the 2nd level
+ int testDepth = isInMerge ? 2 : 1;
+ if (currentDepth == testDepth) {
+ viewKey = previousParser.getViewCookie();
+ // if we are in a merge, wrap the cookie in a MergeCookie.
+ if (viewKey != null && isInMerge) {
+ viewKey = new MergeCookie(viewKey);
+ }
+ }
+ } else if (resourceReference != null && currentDepth == 1) {
+ // else if there's a resource reference, this means we are in an adapter
+ // binding case. Set the resource ref as the view cookie only for the top
+ // level view.
+ viewKey = resourceReference;
+ }
+ }
+
+ return viewKey;
+ }
}
diff --git a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
new file mode 100644
index 0000000..0dddf3d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 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.view;
+
+import android.content.Context;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.internal.view.menu.BridgeMenuItemImpl;
+import com.android.internal.view.menu.MenuView;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.util.AttributeSet;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link MenuInflater}
+ * <p/>
+ * Through the layoutlib_create tool, the original methods of MenuInflater have been
+ * replaced by calls to methods of the same name in this delegate class.
+ * <p/>
+ * The main purpose of the class is to get the view key from the menu xml parser and add it to
+ * the menu item. The view key is used by the IDE to match the individual view elements to the
+ * corresponding xml tag in the menu/layout file.
+ * <p/>
+ * For Menus, the views may be reused and the {@link MenuItem} is a better object to hold the
+ * view key than the {@link MenuView.ItemView}. At the time of computation of the rest of {@link
+ * ViewInfo}, we check the corresponding view key in the menu item for the view and add it
+ */
+public class MenuInflater_Delegate {
+
+ @LayoutlibDelegate
+ /*package*/ static void registerMenu(MenuInflater thisInflater, MenuItem menuItem,
+ AttributeSet attrs) {
+ if (menuItem instanceof BridgeMenuItemImpl) {
+ Context context = thisInflater.getContext();
+ if (context instanceof ContextThemeWrapper) {
+ context = ((ContextThemeWrapper) context).getBaseContext();
+ }
+ if (context instanceof BridgeContext) {
+ Object viewKey = BridgeInflater.getViewKeyFromParser(
+ attrs, ((BridgeContext) context), null, false);
+ ((BridgeMenuItemImpl) menuItem).setViewCookie(viewKey);
+ return;
+ }
+ }
+ // This means that Bridge did not take over the instantiation of some object properly.
+ // This is most likely a bug in the LayoutLib code.
+ Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
+ "Action Bar Menu rendering may be incorrect.", null);
+
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void registerMenu(MenuInflater thisInflater, SubMenu subMenu,
+ AttributeSet parser) {
+ registerMenu(thisInflater, subMenu.getItem(), parser);
+ }
+
+}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
new file mode 100644
index 0000000..4bef424
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 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;
+
+/**
+ * An extension of the {@link MenuItemImpl} to store the view cookie also.
+ */
+public class BridgeMenuItemImpl extends MenuItemImpl {
+
+ /**
+ * An object returned by the IDE that helps mapping each View to the corresponding XML tag in
+ * the layout. For Menus, we store this cookie here and attach it to the corresponding view
+ * at the time of rendering.
+ */
+ private Object viewCookie;
+
+ /**
+ * Instantiates this menu item.
+ */
+ BridgeMenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering,
+ CharSequence title, int showAsAction) {
+ super(menu, group, id, categoryOrder, ordering, title, showAsAction);
+ }
+
+
+ public Object getViewCookie() {
+ return viewCookie;
+ }
+
+ public void setViewCookie(Object viewCookie) {
+ this.viewCookie = viewCookie;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
new file mode 100644
index 0000000..505fb81
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 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 com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link MenuBuilder}
+ * <p/>
+ * Through the layoutlib_create tool, the original methods of {@code MenuBuilder} have been
+ * replaced by calls to methods of the same name in this delegate class.
+ */
+public class MenuBuilder_Delegate {
+ /**
+ * The method overrides the instantiation of the {@link MenuItemImpl} with an instance of
+ * {@link BridgeMenuItemImpl} so that view cookies may be stored.
+ */
+ @LayoutlibDelegate
+ /*package*/ static MenuItemImpl createNewMenuItem(MenuBuilder thisMenu, int group, int id,
+ int categoryOrder, int ordering, CharSequence title, int defaultShowAsAction) {
+ return new BridgeMenuItemImpl(thisMenu, group, id, categoryOrder, ordering, title,
+ defaultShowAsAction);
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index afcadef..9787432 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -28,7 +28,6 @@
import com.android.ide.common.rendering.api.IAnimationListener;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback;
-import com.android.ide.common.rendering.api.RenderParams;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.ResourceReference;
@@ -39,6 +38,12 @@
import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.internal.util.XmlUtils;
+import com.android.internal.view.menu.ActionMenuItemView;
+import com.android.internal.view.menu.BridgeMenuItemImpl;
+import com.android.internal.view.menu.IconMenuItemView;
+import com.android.internal.view.menu.ListMenuItemView;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuView;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
@@ -101,11 +106,10 @@
/**
* Class implementing the render session.
- *
+ * <p/>
* A session is a stateful representation of a layout file. It is initialized with data coming
* through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
* be done on the layout.
- *
*/
public class RenderSessionImpl extends RenderAction<SessionParams> {
@@ -172,7 +176,7 @@
@Override
public Result init(long timeout) {
Result result = super.init(timeout);
- if (result.isSuccess() == false) {
+ if (!result.isSuccess()) {
return result;
}
@@ -196,6 +200,7 @@
// FIXME: find those out, and possibly add them to the render params
boolean hasNavigationBar = true;
+ //noinspection ConstantConditions
IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
metrics, Surface.ROTATION_0,
hasNavigationBar);
@@ -229,10 +234,9 @@
BridgeContext context = getContext();
boolean isRtl = Bridge.isLocaleRtl(params.getLocale());
int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
- ActionBarLayout actionBar = null;
// the view group that receives the window background.
- ViewGroup backgroundView = null;
+ ViewGroup backgroundView;
if (mWindowIsFloating || params.isForceNoDecor()) {
backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
@@ -266,7 +270,7 @@
NavigationBar navigationBar = createNavigationBar(context,
hardwareConfig.getDensity(), isRtl, params.isRtlSupported());
topLayout.addView(navigationBar);
- } catch (XmlPullParserException e) {
+ } catch (XmlPullParserException ignored) {
}
}
@@ -322,7 +326,7 @@
StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(),
layoutDirection, params.isRtlSupported());
topLayout.addView(statusBar);
- } catch (XmlPullParserException e) {
+ } catch (XmlPullParserException ignored) {
}
}
@@ -339,20 +343,16 @@
// if the theme says no title/action bar, then the size will be 0
if (mActionBarSize > 0) {
- try {
- actionBar = createActionBar(context, params);
- backgroundLayout.addView(actionBar);
- actionBar.createMenuPopup();
- mContentRoot = actionBar.getContentRoot();
- } catch (XmlPullParserException e) {
-
- }
+ ActionBarLayout actionBar = createActionBar(context, params);
+ backgroundLayout.addView(actionBar);
+ actionBar.createMenuPopup();
+ mContentRoot = actionBar.getContentRoot();
} else if (mTitleBarSize > 0) {
try {
TitleBar titleBar = createTitleBar(context,
hardwareConfig.getDensity(), params.getAppLabel());
backgroundLayout.addView(titleBar);
- } catch (XmlPullParserException e) {
+ } catch (XmlPullParserException ignored) {
}
}
@@ -374,7 +374,7 @@
NavigationBar navigationBar = createNavigationBar(context,
hardwareConfig.getDensity(), isRtl, params.isRtlSupported());
topLayout.addView(navigationBar);
- } catch (XmlPullParserException e) {
+ } catch (XmlPullParserException ignored) {
}
}
@@ -399,7 +399,7 @@
postInflateProcess(view, params.getProjectCallback());
// get the background drawable
- if (mWindowBackground != null && backgroundView != null) {
+ if (mWindowBackground != null) {
Drawable d = ResourceHelper.getDrawable(mWindowBackground, context);
backgroundView.setBackground(d);
}
@@ -476,6 +476,7 @@
// first measure the full layout, with EXACTLY to get the size of the
// content as it is inside the decor/dialog
+ @SuppressWarnings("deprecation")
Pair<Integer, Integer> exactMeasure = measureView(
mViewRoot, mContentRoot.getChildAt(0),
mMeasuredScreenWidth, MeasureSpec.EXACTLY,
@@ -483,6 +484,7 @@
// now measure the content only using UNSPECIFIED (where applicable, based on
// the rendering mode). This will give us the size the content needs.
+ @SuppressWarnings("deprecation")
Pair<Integer, Integer> result = measureView(
mContentRoot, mContentRoot.getChildAt(0),
mMeasuredScreenWidth, widthMeasureSpecMode,
@@ -558,7 +560,7 @@
mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
}
- if (freshRender && newImage == false) {
+ if (freshRender && !newImage) {
Graphics2D gc = mImage.createGraphics();
gc.setComposite(AlphaComposite.Src);
@@ -573,7 +575,8 @@
mViewRoot.draw(mCanvas);
}
- mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), false);
+ mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(),
+ false);
// success!
return SUCCESS.createResult();
@@ -603,6 +606,7 @@
* @param heightMode the MeasureSpec mode to use for the height.
* @return the measured width/height if measuredView is non-null, null otherwise.
*/
+ @SuppressWarnings("deprecation") // For the use of Pair
private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
int width, int widthMode, int height, int heightMode) {
int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
@@ -633,7 +637,7 @@
BridgeContext context = getContext();
// find the animation file.
- ResourceValue animationResource = null;
+ ResourceValue animationResource;
int animationId = 0;
if (isFrameworkAnimation) {
animationResource = context.getRenderResources().getFrameworkResource(
@@ -723,7 +727,7 @@
// add it to the parentView in the correct location
Result result = addView(parentView, child, index);
- if (result.isSuccess() == false) {
+ if (!result.isSuccess()) {
return result;
}
@@ -793,13 +797,13 @@
public void run() {
Result result = moveView(previousParent, newParentView, childView, index,
params);
- if (result.isSuccess() == false) {
+ if (!result.isSuccess()) {
listener.done(result);
}
// ready to do the work, acquire the scene.
result = acquire(250);
- if (result.isSuccess() == false) {
+ if (!result.isSuccess()) {
listener.done(result);
return;
}
@@ -857,7 +861,7 @@
}
Result result = moveView(previousParent, newParentView, childView, index, layoutParams);
- if (result.isSuccess() == false) {
+ if (!result.isSuccess()) {
return result;
}
@@ -991,7 +995,7 @@
}
Result result = removeView(parent, childView);
- if (result.isSuccess() == false) {
+ if (!result.isSuccess()) {
return result;
}
@@ -1019,7 +1023,7 @@
private void findBackground(RenderResources resources) {
- if (getParams().isBgColorOverridden() == false) {
+ if (!getParams().isBgColorOverridden()) {
mWindowBackground = resources.findItemInTheme("windowBackground",
true /*isFrameworkAttr*/);
if (mWindowBackground != null) {
@@ -1036,7 +1040,7 @@
boolean windowFullscreen = getBooleanThemeValue(resources,
"windowFullscreen", false /*defaultValue*/);
- if (windowFullscreen == false && mWindowIsFloating == false) {
+ if (!windowFullscreen && !mWindowIsFloating) {
// default value
mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
@@ -1090,7 +1094,7 @@
boolean windowNoTitle = getBooleanThemeValue(resources,
"windowNoTitle", false /*defaultValue*/);
- if (windowNoTitle == false) {
+ if (!windowNoTitle) {
// default size of the window title bar
mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT;
@@ -1117,7 +1121,7 @@
}
private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) {
- if (hasSoftwareButtons() && mWindowIsFloating == false) {
+ if (hasSoftwareButtons() && !mWindowIsFloating) {
// default value
mNavigationBarSize = 48; // ??
@@ -1131,15 +1135,12 @@
int shortSize = hardwareConfig.getScreenHeight();
// compute in dp
- int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / hardwareConfig.getDensity().getDpiValue();
+ int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT /
+ hardwareConfig.getDensity().getDpiValue();
- if (shortSizeDp < 600) {
- // 0-599dp: "phone" UI with bar on the side
- barOnBottom = false;
- } else {
- // 600+dp: "tablet" UI with bar on the bottom
- barOnBottom = true;
- }
+ // 0-599dp: "phone" UI with bar on the side
+ // 600+dp: "tablet" UI with bar on the bottom
+ barOnBottom = shortSizeDp >= 600;
}
if (barOnBottom) {
@@ -1190,13 +1191,15 @@
}
/**
- * Post process on a view hierachy that was just inflated.
- * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
+ * Post process on a view hierarchy that was just inflated.
+ * <p/>
+ * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the
* {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
* based on the content of the {@link FrameLayout}.
* @param view the root view to process.
* @param projectCallback callback to the project.
*/
+ @SuppressWarnings("deprecation") // For the use of Pair
private void postInflateProcess(View view, IProjectCallback projectCallback)
throws PostInflateException {
if (view instanceof TabHost) {
@@ -1299,7 +1302,7 @@
"TabHost requires a TabWidget with id \"android:id/tabs\".\n");
}
- if ((v instanceof TabWidget) == false) {
+ if (!(v instanceof TabWidget)) {
throw new PostInflateException(String.format(
"TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
"View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
@@ -1308,12 +1311,14 @@
v = tabHost.findViewById(android.R.id.tabcontent);
if (v == null) {
- // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
+ // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty)
+ //noinspection SpellCheckingInspection
throw new PostInflateException(
"TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
}
- if ((v instanceof FrameLayout) == false) {
+ if (!(v instanceof FrameLayout)) {
+ //noinspection SpellCheckingInspection
throw new PostInflateException(String.format(
"TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
"View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
@@ -1321,7 +1326,7 @@
FrameLayout content = (FrameLayout)v;
- // now process the content of the framelayout and dynamically create tabs for it.
+ // now process the content of the frameLayout and dynamically create tabs for it.
final int count = content.getChildCount();
// this must be called before addTab() so that the TabHost searches its TabWidget
@@ -1339,13 +1344,13 @@
}
});
tabHost.addTab(spec);
- return;
} else {
- // for each child of the framelayout, add a new TabSpec
+ // for each child of the frameLayout, add a new TabSpec
for (int i = 0 ; i < count ; i++) {
View child = content.getChildAt(i);
String tabSpec = String.format("tab_spec%d", i+1);
int id = child.getId();
+ @SuppressWarnings("deprecation")
Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id);
String name;
if (resource != null) {
@@ -1468,13 +1473,13 @@
ViewInfo result;
if (isContentFrame) {
result = new ViewInfo(view.getClass().getName(),
- getContext().getViewKey(view),
+ getViewKey(view),
view.getLeft(), view.getTop() + offset, view.getRight(),
view.getBottom() + offset, view, view.getLayoutParams());
} else {
result = new SystemViewInfo(view.getClass().getName(),
- getContext().getViewKey(view),
+ getViewKey(view),
view.getLeft(), view.getTop(), view.getRight(),
view.getBottom(), view, view.getLayoutParams());
}
@@ -1495,6 +1500,32 @@
return result;
}
+ /**
+ * The cookie for menu items are stored in menu item and not in the map from View stored in
+ * BridgeContext.
+ */
+ private Object getViewKey(View view) {
+ BridgeContext context = getContext();
+ if (!(view instanceof MenuView.ItemView)) {
+ return context.getViewKey(view);
+ }
+ MenuItemImpl menuItem;
+ if (view instanceof ActionMenuItemView) {
+ menuItem = ((ActionMenuItemView) view).getItemData();
+ } else if (view instanceof ListMenuItemView) {
+ menuItem = ((ListMenuItemView) view).getItemData();
+ } else if (view instanceof IconMenuItemView) {
+ menuItem = ((IconMenuItemView) view).getItemData();
+ } else {
+ menuItem = null;
+ }
+ if (menuItem instanceof BridgeMenuItemImpl) {
+ return ((BridgeMenuItemImpl) menuItem).getViewCookie();
+ }
+
+ return null;
+ }
+
private void invalidateRenderingSize() {
mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
}
@@ -1545,8 +1576,7 @@
/**
* Creates the action bar. Also queries the project callback for missing information.
*/
- private ActionBarLayout createActionBar(BridgeContext context, SessionParams params)
- throws XmlPullParserException {
+ private ActionBarLayout createActionBar(BridgeContext context, SessionParams params) {
ActionBarLayout actionBar = new ActionBarLayout(context, params);
actionBar.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index e0c05de..813a895 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -143,6 +143,8 @@
"android.view.ViewRootImpl#isInTouchMode",
"android.view.WindowManagerGlobal#getWindowManagerService",
"android.view.inputmethod.InputMethodManager#getInstance",
+ "android.view.MenuInflater#registerMenu",
+ "com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
"com.android.internal.util.XmlUtils#convertValueToInt",
"com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
};