Merge "Be more discriminating when canceling notifications on changing packages." into jb-dev
diff --git a/api/16.txt b/api/16.txt
index b8aeb39..8a7ac00 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -754,7 +754,6 @@
field public static final int pathPrefix = 16842795; // 0x101002b
field public static final int permission = 16842758; // 0x1010006
field public static final int permissionGroup = 16842762; // 0x101000a
- field public static final int permissionGroupFlags = 16843688; // 0x10103a8
field public static final int persistent = 16842765; // 0x101000d
field public static final int persistentDrawingCache = 16842990; // 0x10100ee
field public static final deprecated int phoneNumber = 16843111; // 0x1010167
@@ -6596,11 +6595,8 @@
method public int describeContents();
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final android.os.Parcelable.Creator CREATOR;
- field public static final int FLAG_PERSONAL_INFO = 1; // 0x1
field public int descriptionRes;
- field public int flags;
field public java.lang.CharSequence nonLocalizedDescription;
- field public int priority;
}
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
diff --git a/api/current.txt b/api/current.txt
index b8aeb39..8a7ac00 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -754,7 +754,6 @@
field public static final int pathPrefix = 16842795; // 0x101002b
field public static final int permission = 16842758; // 0x1010006
field public static final int permissionGroup = 16842762; // 0x101000a
- field public static final int permissionGroupFlags = 16843688; // 0x10103a8
field public static final int persistent = 16842765; // 0x101000d
field public static final int persistentDrawingCache = 16842990; // 0x10100ee
field public static final deprecated int phoneNumber = 16843111; // 0x1010167
@@ -6596,11 +6595,8 @@
method public int describeContents();
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final android.os.Parcelable.Creator CREATOR;
- field public static final int FLAG_PERSONAL_INFO = 1; // 0x1
field public int descriptionRes;
- field public int flags;
field public java.lang.CharSequence nonLocalizedDescription;
- field public int priority;
}
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e180df4..679a8ac 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1464,8 +1464,7 @@
perm.info.descriptionRes = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestPermissionGroup_description,
0);
- perm.info.flags = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags, 0);
+ perm.info.flags = 0;
perm.info.priority = sa.getInt(
com.android.internal.R.styleable.AndroidManifestPermissionGroup_priority, 0);
if (perm.info.priority > 0 && (flags&PARSE_IS_SYSTEM) == 0) {
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
index 452bf0d..96d30d4 100644
--- a/core/java/android/content/pm/PermissionGroupInfo.java
+++ b/core/java/android/content/pm/PermissionGroupInfo.java
@@ -44,17 +44,20 @@
/**
* Flag for {@link #flags}, corresponding to <code>personalInfo</code>
* value of {@link android.R.attr#permissionGroupFlags}.
+ * @hide
*/
public static final int FLAG_PERSONAL_INFO = 1<<0;
/**
* Additional flags about this group as given by
* {@link android.R.attr#permissionGroupFlags}.
+ * @hide
*/
public int flags;
/**
* Prioritization of this group, for visually sorting with other groups.
+ * @hide
*/
public int priority;
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 6dc31dd..bd86a8d 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -62,6 +62,8 @@
private final int mMyProcessId;
+ private final ArrayList<View> mTempArrayList = new ArrayList<View>();
+
public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
Looper looper = viewRootImpl.mHandler.getLooper();
mMyLooperThreadId = looper.getThread().getId();
@@ -313,7 +315,7 @@
infos = provider.findAccessibilityNodeInfosByText(text,
virtualDescendantId);
} else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED) {
- ArrayList<View> foundViews = mViewRootImpl.mAttachInfo.mTempArrayList;
+ ArrayList<View> foundViews = mTempArrayList;
foundViews.clear();
root.findViewsWithText(foundViews, text, View.FIND_VIEWS_WITH_TEXT
| View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index da666b5..a42e156 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -62,6 +62,13 @@
public static final int STATUS_INVOKE = 0x2;
/**
+ * Indicates that the display list performed GL drawing operations.
+ *
+ * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
+ */
+ public static final int STATUS_DREW = 0x4;
+
+ /**
* Starts recording the display list. All operations performed on the
* returned canvas are recorded and stored in this display list.
*
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index cba488e..7e86ea3 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1104,6 +1104,7 @@
onPreDraw(dirty);
+ int status = DisplayList.STATUS_DONE;
int saveCount = canvas.save();
callbacks.onHardwarePreDraw(canvas);
@@ -1137,7 +1138,7 @@
drawDisplayListStartTime = System.nanoTime();
}
- int status = canvas.drawDisplayList(displayList, mRedrawClip,
+ status = canvas.drawDisplayList(displayList, mRedrawClip,
DisplayList.FLAG_CLIP_CHILDREN);
if (mProfileEnabled) {
@@ -1173,22 +1174,25 @@
onPostDraw();
attachInfo.mIgnoreDirtyState = false;
+
+ if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) {
- long eglSwapBuffersStartTime = 0;
- if (mProfileEnabled) {
- eglSwapBuffersStartTime = System.nanoTime();
+ long eglSwapBuffersStartTime = 0;
+ if (mProfileEnabled) {
+ eglSwapBuffersStartTime = System.nanoTime();
+ }
+
+ sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
+
+ if (mProfileEnabled) {
+ long now = System.nanoTime();
+ float total = (now - eglSwapBuffersStartTime) * 0.000001f;
+ mProfileData[mProfileCurrentFrame + 2] = total;
+ }
+
+ checkEglErrors();
}
- sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
-
- if (mProfileEnabled) {
- long now = System.nanoTime();
- float total = (now - eglSwapBuffersStartTime) * 0.000001f;
- mProfileData[mProfileCurrentFrame + 2] = total;
- }
-
- checkEglErrors();
-
return dirty == null;
}
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index dae9c6a..edffb5e9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -57,7 +57,6 @@
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewParent;
-import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -1331,43 +1330,42 @@
@Override
public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
- if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY
- && (direction == ACCESSIBILITY_FOCUS_FORWARD
- || direction == ACCESSIBILITY_FOCUS_BACKWARD)) {
- if (canTakeAccessibilityFocusFromHover()) {
- views.add(this);
+ if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY) {
+ switch(direction) {
+ case ACCESSIBILITY_FOCUS_BACKWARD: {
+ View focusable = (getChildCount() > 0) ? getChildAt(getChildCount() - 1) : this;
+ if (focusable.canTakeAccessibilityFocusFromHover()) {
+ views.add(focusable);
+ }
+ } return;
+ case ACCESSIBILITY_FOCUS_FORWARD: {
+ if (canTakeAccessibilityFocusFromHover()) {
+ views.add(this);
+ }
+ } return;
}
- } else {
super.addFocusables(views, direction, focusableMode);
}
}
@Override
public View focusSearch(int direction) {
- return focusSearch(null, direction);
+ return focusSearch(this, direction);
}
@Override
public View focusSearch(View focused, int direction) {
switch (direction) {
case ACCESSIBILITY_FOCUS_FORWARD: {
- ViewRootImpl viewRootImpl = getViewRootImpl();
- if (viewRootImpl == null) {
- return null;
- }
- View currentFocus = viewRootImpl.getAccessibilityFocusedHost();
- if (currentFocus == null) {
- return super.focusSearch(this, direction);
- }
- // If we have the focus try giving it to the first child.
- if (currentFocus == this) {
+ // If we are the focused view try giving it to the first child.
+ if (focused == this) {
if (getChildCount() > 0) {
return getChildAt(0);
}
return super.focusSearch(this, direction);
}
- // Find the item that has accessibility focus.
- final int currentPosition = getPositionForView(currentFocus);
+ // Find the item that has the focused view.
+ final int currentPosition = getPositionForView(focused);
if (currentPosition < 0 || currentPosition >= getCount()) {
return super.focusSearch(this, direction);
}
@@ -1376,9 +1374,9 @@
if (currentItem instanceof ViewGroup) {
ViewGroup currentItemGroup = (ViewGroup) currentItem;
View nextFocus = FocusFinder.getInstance().findNextFocus(currentItemGroup,
- currentFocus, direction);
+ focused, direction);
if (nextFocus != null && nextFocus != currentItemGroup
- && nextFocus != currentFocus) {
+ && nextFocus != focused) {
return nextFocus;
}
}
@@ -1386,50 +1384,54 @@
final int nextPosition = currentPosition - getFirstVisiblePosition() + 1;
if (nextPosition < getChildCount()) {
return getChildAt(nextPosition);
- } else {
- return super.focusSearch(this, direction);
}
+ // No next item start searching from the list.
+ return super.focusSearch(this, direction);
}
case ACCESSIBILITY_FOCUS_BACKWARD: {
- ViewRootImpl viewRootImpl = getViewRootImpl();
- if (viewRootImpl == null) {
- return null;
- }
- View currentFocus = viewRootImpl.getAccessibilityFocusedHost();
- if (currentFocus == null) {
- return super.focusSearch(this, direction);
- }
- // If we have the focus do a generic search.
- if (currentFocus == this) {
- final int lastChildIndex = getChildCount() - 1;
- if (lastChildIndex >= 0) {
- return getChildAt(lastChildIndex);
+ // If we are the focused search from the view that is
+ // as closer to the bottom as possible.
+ if (focused == this) {
+ final int childCount = getChildCount();
+ if (childCount > 0) {
+ return super.focusSearch(getChildAt(childCount - 1), direction);
}
return super.focusSearch(this, direction);
}
- // Find the item that has accessibility focus.
- final int currentPosition = getPositionForView(currentFocus);
+ // Find the item that has the focused view.
+ final int currentPosition = getPositionForView(focused);
if (currentPosition < 0 || currentPosition >= getCount()) {
return super.focusSearch(this, direction);
}
- // Try to advance focus in the current item.
+
View currentItem = getChildAt(currentPosition - getFirstVisiblePosition());
+
+ // If a list item is the focused view we try to find a view
+ // in the previous item since in reverse the item contents
+ // get accessibility focus before the item itself.
+ if (currentItem == focused) {
+ // This list gets accessibility focus after the last first item.
+ final int previoustPosition = currentPosition - getFirstVisiblePosition() - 1;
+ if (previoustPosition < 0) {
+ return this;
+ }
+ currentItem = getChildAt(previoustPosition);
+ focused = null;
+ }
+
+ // Search for into the item.
if (currentItem instanceof ViewGroup) {
ViewGroup currentItemGroup = (ViewGroup) currentItem;
View nextFocus = FocusFinder.getInstance().findNextFocus(currentItemGroup,
- currentFocus, direction);
+ focused, direction);
if (nextFocus != null && nextFocus != currentItemGroup
- && nextFocus != currentFocus) {
+ && nextFocus != focused) {
return nextFocus;
}
}
- // Try to move focus to the previous item.
- final int nextPosition = currentPosition - getFirstVisiblePosition() - 1;
- if (nextPosition >= 0) {
- return getChildAt(nextPosition);
- } else {
- return super.focusSearch(this, direction);
- }
+
+ // If not item content wants focus we give it to the item.
+ return currentItem;
}
}
return super.focusSearch(focused, direction);
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 64f6c07..988760d 100755
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -18,9 +18,7 @@
import com.android.internal.R;
-import android.app.AlertDialog;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -28,14 +26,9 @@
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.graphics.drawable.Drawable;
-import android.os.Parcel;
-import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import java.text.Collator;
import java.util.ArrayList;
@@ -43,6 +36,7 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -58,200 +52,52 @@
*
* {@hide}
*/
-public class AppSecurityPermissions {
+public class AppSecurityPermissions implements View.OnClickListener {
- public static final int WHICH_PERSONAL = 1<<0;
- public static final int WHICH_DEVICE = 1<<1;
- public static final int WHICH_NEW = 1<<2;
- public static final int WHICH_ALL = 0xffff;
+ private enum State {
+ NO_PERMS,
+ DANGEROUS_ONLY,
+ NORMAL_ONLY,
+ BOTH
+ }
private final static String TAG = "AppSecurityPermissions";
private boolean localLOGV = false;
private Context mContext;
private LayoutInflater mInflater;
private PackageManager mPm;
- private PackageInfo mInstalledPackageInfo;
- private final Map<String, MyPermissionGroupInfo> mPermGroups
- = new HashMap<String, MyPermissionGroupInfo>();
- private final List<MyPermissionGroupInfo> mPermGroupsList
- = new ArrayList<MyPermissionGroupInfo>();
- private final PermissionGroupInfoComparator mPermGroupComparator;
- private final PermissionInfoComparator mPermComparator;
- private List<MyPermissionInfo> mPermsList;
- private CharSequence mNewPermPrefix;
+ private LinearLayout mPermsView;
+ private Map<String, String> mDangerousMap;
+ private Map<String, String> mNormalMap;
+ private List<PermissionInfo> mPermsList;
+ private String mDefaultGrpLabel;
+ private String mDefaultGrpName="DefaultGrp";
+ private String mPermFormat;
private Drawable mNormalIcon;
private Drawable mDangerousIcon;
-
- static class MyPermissionGroupInfo extends PermissionGroupInfo {
- CharSequence mLabel;
-
- final ArrayList<MyPermissionInfo> mNewPermissions = new ArrayList<MyPermissionInfo>();
- final ArrayList<MyPermissionInfo> mPersonalPermissions = new ArrayList<MyPermissionInfo>();
- final ArrayList<MyPermissionInfo> mDevicePermissions = new ArrayList<MyPermissionInfo>();
- final ArrayList<MyPermissionInfo> mAllPermissions = new ArrayList<MyPermissionInfo>();
-
- MyPermissionGroupInfo(PermissionInfo perm) {
- name = perm.packageName;
- packageName = perm.packageName;
- }
-
- MyPermissionGroupInfo(PermissionGroupInfo info) {
- super(info);
- }
-
- public Drawable loadGroupIcon(PackageManager pm) {
- if (icon != 0) {
- return loadIcon(pm);
- } else {
- ApplicationInfo appInfo;
- try {
- appInfo = pm.getApplicationInfo(packageName, 0);
- return appInfo.loadIcon(pm);
- } catch (NameNotFoundException e) {
- }
- }
- return null;
- }
- }
-
- static class MyPermissionInfo extends PermissionInfo {
- CharSequence mLabel;
-
- /**
- * PackageInfo.requestedPermissionsFlags for the new package being installed.
- */
- int mNewReqFlags;
-
- /**
- * PackageInfo.requestedPermissionsFlags for the currently installed
- * package, if it is installed.
- */
- int mExistingReqFlags;
-
- /**
- * True if this should be considered a new permission.
- */
- boolean mNew;
-
- MyPermissionInfo() {
- }
-
- MyPermissionInfo(PermissionInfo info) {
- super(info);
- }
-
- MyPermissionInfo(MyPermissionInfo info) {
- super(info);
- mNewReqFlags = info.mNewReqFlags;
- mExistingReqFlags = info.mExistingReqFlags;
- mNew = info.mNew;
- }
- }
-
- public static class PermissionItemView extends LinearLayout implements View.OnClickListener {
- MyPermissionGroupInfo mGroup;
- MyPermissionInfo mPerm;
- AlertDialog mDialog;
-
- public PermissionItemView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setClickable(true);
- }
-
- public void setPermission(MyPermissionGroupInfo grp, MyPermissionInfo perm,
- boolean first, CharSequence newPermPrefix) {
- mGroup = grp;
- mPerm = perm;
-
- ImageView permGrpIcon = (ImageView) findViewById(R.id.perm_icon);
- TextView permNameView = (TextView) findViewById(R.id.perm_name);
-
- PackageManager pm = getContext().getPackageManager();
- Drawable icon = null;
- if (first) {
- icon = grp.loadGroupIcon(pm);
- }
- CharSequence label = perm.mLabel;
- if (perm.mNew && newPermPrefix != null) {
- // If this is a new permission, format it appropriately.
- SpannableStringBuilder builder = new SpannableStringBuilder();
- Parcel parcel = Parcel.obtain();
- TextUtils.writeToParcel(newPermPrefix, parcel, 0);
- parcel.setDataPosition(0);
- CharSequence newStr = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
- parcel.recycle();
- builder.append(newStr);
- builder.append(label);
- label = builder;
- }
-
- permGrpIcon.setImageDrawable(icon);
- permNameView.setText(label);
- setOnClickListener(this);
- }
-
- @Override
- public void onClick(View v) {
- if (mGroup != null && mPerm != null) {
- if (mDialog != null) {
- mDialog.dismiss();
- }
- PackageManager pm = getContext().getPackageManager();
- AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
- builder.setTitle(mGroup.mLabel);
- if (mPerm.descriptionRes != 0) {
- builder.setMessage(mPerm.loadDescription(pm));
- } else {
- CharSequence appName;
- try {
- ApplicationInfo app = pm.getApplicationInfo(mPerm.packageName, 0);
- appName = app.loadLabel(pm);
- } catch (NameNotFoundException e) {
- appName = mPerm.packageName;
- }
- StringBuilder sbuilder = new StringBuilder(128);
- sbuilder.append(getContext().getString(
- R.string.perms_description_app, appName));
- sbuilder.append("\n\n");
- sbuilder.append(mPerm.name);
- builder.setMessage(sbuilder.toString());
- }
- builder.setCancelable(true);
- builder.setIcon(mGroup.loadGroupIcon(pm));
- mDialog = builder.show();
- mDialog.setCanceledOnTouchOutside(true);
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (mDialog != null) {
- mDialog.dismiss();
- }
- }
- }
-
+ private boolean mExpanded;
+ private Drawable mShowMaxIcon;
+ private Drawable mShowMinIcon;
+ private View mShowMore;
+ private TextView mShowMoreText;
+ private ImageView mShowMoreIcon;
+ private State mCurrentState;
+ private LinearLayout mNonDangerousList;
+ private LinearLayout mDangerousList;
+ private HashMap<String, CharSequence> mGroupLabelCache;
+ private View mNoPermsView;
+
public AppSecurityPermissions(Context context, List<PermissionInfo> permList) {
mContext = context;
mPm = mContext.getPackageManager();
- loadResources();
- mPermComparator = new PermissionInfoComparator();
- mPermGroupComparator = new PermissionGroupInfoComparator();
- for (PermissionInfo pi : permList) {
- mPermsList.add(new MyPermissionInfo(pi));
- }
- setPermissions(mPermsList);
+ mPermsList = permList;
}
public AppSecurityPermissions(Context context, String packageName) {
mContext = context;
mPm = mContext.getPackageManager();
- loadResources();
- mPermComparator = new PermissionInfoComparator();
- mPermGroupComparator = new PermissionGroupInfoComparator();
- mPermsList = new ArrayList<MyPermissionInfo>();
- Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
+ mPermsList = new ArrayList<PermissionInfo>();
+ Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
PackageInfo pkgInfo;
try {
pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
@@ -263,39 +109,29 @@
if((pkgInfo.applicationInfo != null) && (pkgInfo.applicationInfo.uid != -1)) {
getAllUsedPermissions(pkgInfo.applicationInfo.uid, permSet);
}
- for(MyPermissionInfo tmpInfo : permSet) {
+ for(PermissionInfo tmpInfo : permSet) {
mPermsList.add(tmpInfo);
}
- setPermissions(mPermsList);
}
-
+
public AppSecurityPermissions(Context context, PackageParser.Package pkg) {
mContext = context;
mPm = mContext.getPackageManager();
- loadResources();
- mPermComparator = new PermissionInfoComparator();
- mPermGroupComparator = new PermissionGroupInfoComparator();
- mPermsList = new ArrayList<MyPermissionInfo>();
- Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
+ mPermsList = new ArrayList<PermissionInfo>();
+ Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
if(pkg == null) {
return;
}
-
- // Convert to a PackageInfo
- PackageInfo info = PackageParser.generatePackageInfo(pkg, null,
- PackageManager.GET_PERMISSIONS, 0, 0, null);
- PackageInfo installedPkgInfo = null;
// Get requested permissions
- if (info.requestedPermissions != null) {
- try {
- installedPkgInfo = mPm.getPackageInfo(info.packageName,
- PackageManager.GET_PERMISSIONS);
- } catch (NameNotFoundException e) {
+ if (pkg.requestedPermissions != null) {
+ ArrayList<String> strList = pkg.requestedPermissions;
+ int size = strList.size();
+ if (size > 0) {
+ extractPerms(strList.toArray(new String[size]), permSet);
}
- extractPerms(info, permSet, installedPkgInfo);
}
// Get permissions related to shared user if any
- if (pkg.mSharedUserId != null) {
+ if(pkg.mSharedUserId != null) {
int sharedUid;
try {
sharedUid = mPm.getUidForSharedUser(pkg.mSharedUserId);
@@ -305,23 +141,13 @@
}
}
// Retrieve list of permissions
- for (MyPermissionInfo tmpInfo : permSet) {
+ for(PermissionInfo tmpInfo : permSet) {
mPermsList.add(tmpInfo);
}
- setPermissions(mPermsList);
}
-
- private void loadResources() {
- // Pick up from framework resources instead.
- mNewPermPrefix = mContext.getText(R.string.perms_new_perm_prefix);
- mNormalIcon = mContext.getResources().getDrawable(R.drawable.ic_text_dot);
- mDangerousIcon = mContext.getResources().getDrawable(R.drawable.ic_bullet_key_permission);
- }
-
+
/**
- * Utility to retrieve a view displaying a single permission. This provides
- * the old UI layout for permissions; it is only here for the device admin
- * settings to continue to use.
+ * Utility to retrieve a view displaying a single permission.
*/
public static View getPermissionItemView(Context context,
CharSequence grpName, CharSequence description, boolean dangerous) {
@@ -329,15 +155,11 @@
Context.LAYOUT_INFLATER_SERVICE);
Drawable icon = context.getResources().getDrawable(dangerous
? R.drawable.ic_bullet_key_permission : R.drawable.ic_text_dot);
- return getPermissionItemViewOld(context, inflater, grpName,
+ return getPermissionItemView(context, inflater, grpName,
description, dangerous, icon);
}
- public PackageInfo getInstalledPackageInfo() {
- return mInstalledPackageInfo;
- }
-
- private void getAllUsedPermissions(int sharedUid, Set<MyPermissionInfo> permSet) {
+ private void getAllUsedPermissions(int sharedUid, Set<PermissionInfo> permSet) {
String sharedPkgList[] = mPm.getPackagesForUid(sharedUid);
if(sharedPkgList == null || (sharedPkgList.length == 0)) {
return;
@@ -348,95 +170,29 @@
}
private void getPermissionsForPackage(String packageName,
- Set<MyPermissionInfo> permSet) {
+ Set<PermissionInfo> permSet) {
PackageInfo pkgInfo;
try {
pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
} catch (NameNotFoundException e) {
- Log.w(TAG, "Couldn't retrieve permissions for package:"+packageName);
+ Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
return;
}
if ((pkgInfo != null) && (pkgInfo.requestedPermissions != null)) {
- extractPerms(pkgInfo, permSet, pkgInfo);
+ extractPerms(pkgInfo.requestedPermissions, permSet);
}
}
-
- private void extractPerms(PackageInfo info, Set<MyPermissionInfo> permSet,
- PackageInfo installedPkgInfo) {
- String[] strList = info.requestedPermissions;
- int[] flagsList = info.requestedPermissionsFlags;
- if ((strList == null) || (strList.length == 0)) {
+
+ private void extractPerms(String strList[], Set<PermissionInfo> permSet) {
+ if((strList == null) || (strList.length == 0)) {
return;
}
- mInstalledPackageInfo = installedPkgInfo;
- for (int i=0; i<strList.length; i++) {
- String permName = strList[i];
- // If we are only looking at an existing app, then we only
- // care about permissions that have actually been granted to it.
- if (installedPkgInfo != null && info == installedPkgInfo) {
- if ((flagsList[i]&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
- continue;
- }
- }
+ for(String permName:strList) {
try {
PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
- if (tmpPermInfo == null) {
- continue;
+ if(tmpPermInfo != null) {
+ permSet.add(tmpPermInfo);
}
- int existingIndex = -1;
- if (installedPkgInfo != null
- && installedPkgInfo.requestedPermissions != null) {
- for (int j=0; j<installedPkgInfo.requestedPermissions.length; j++) {
- if (permName.equals(installedPkgInfo.requestedPermissions[j])) {
- existingIndex = j;
- break;
- }
- }
- }
- final int existingFlags = existingIndex >= 0 ?
- installedPkgInfo.requestedPermissionsFlags[existingIndex] : 0;
- if (!isDisplayablePermission(tmpPermInfo, flagsList[i], existingFlags)) {
- // This is not a permission that is interesting for the user
- // to see, so skip it.
- continue;
- }
- final String origGroupName = tmpPermInfo.group;
- String groupName = origGroupName;
- if (groupName == null) {
- groupName = tmpPermInfo.packageName;
- tmpPermInfo.group = groupName;
- }
- MyPermissionGroupInfo group = mPermGroups.get(groupName);
- if (group == null) {
- PermissionGroupInfo grp = null;
- if (origGroupName != null) {
- grp = mPm.getPermissionGroupInfo(origGroupName, 0);
- }
- if (grp != null) {
- group = new MyPermissionGroupInfo(grp);
- } else {
- // We could be here either because the permission
- // didn't originally specify a group or the group it
- // gave couldn't be found. In either case, we consider
- // its group to be the permission's package name.
- tmpPermInfo.group = tmpPermInfo.packageName;
- group = mPermGroups.get(tmpPermInfo.group);
- if (group == null) {
- group = new MyPermissionGroupInfo(tmpPermInfo);
- }
- group = new MyPermissionGroupInfo(tmpPermInfo);
- }
- mPermGroups.put(tmpPermInfo.group, group);
- }
- final boolean newPerm = installedPkgInfo != null
- && (existingFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0;
- MyPermissionInfo myPerm = new MyPermissionInfo(tmpPermInfo);
- myPerm.mNewReqFlags = flagsList[i];
- myPerm.mExistingReqFlags = existingFlags;
- // This is a new permission if the app is already installed and
- // doesn't currently hold this permission.
- myPerm.mNew = newPerm;
- permSet.add(myPerm);
} catch (NameNotFoundException e) {
Log.i(TAG, "Ignoring unknown permission:"+permName);
}
@@ -444,99 +200,131 @@
}
public int getPermissionCount() {
- return getPermissionCount(WHICH_ALL);
- }
-
- private List<MyPermissionInfo> getPermissionList(MyPermissionGroupInfo grp, int which) {
- if (which == WHICH_NEW) {
- return grp.mNewPermissions;
- } else if (which == WHICH_PERSONAL) {
- return grp.mPersonalPermissions;
- } else if (which == WHICH_DEVICE) {
- return grp.mDevicePermissions;
- } else {
- return grp.mAllPermissions;
- }
- }
-
- public int getPermissionCount(int which) {
- int N = 0;
- for (int i=0; i<mPermGroupsList.size(); i++) {
- N += getPermissionList(mPermGroupsList.get(i), which).size();
- }
- return N;
+ return mPermsList.size();
}
public View getPermissionsView() {
- return getPermissionsView(WHICH_ALL);
+
+ mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mPermsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
+ mShowMore = mPermsView.findViewById(R.id.show_more);
+ mShowMoreIcon = (ImageView) mShowMore.findViewById(R.id.show_more_icon);
+ mShowMoreText = (TextView) mShowMore.findViewById(R.id.show_more_text);
+ mDangerousList = (LinearLayout) mPermsView.findViewById(R.id.dangerous_perms_list);
+ mNonDangerousList = (LinearLayout) mPermsView.findViewById(R.id.non_dangerous_perms_list);
+ mNoPermsView = mPermsView.findViewById(R.id.no_permissions);
+
+ // Set up the LinearLayout that acts like a list item.
+ mShowMore.setClickable(true);
+ mShowMore.setOnClickListener(this);
+ mShowMore.setFocusable(true);
+
+ // Pick up from framework resources instead.
+ mDefaultGrpLabel = mContext.getString(R.string.default_permission_group);
+ mPermFormat = mContext.getString(R.string.permissions_format);
+ mNormalIcon = mContext.getResources().getDrawable(R.drawable.ic_text_dot);
+ mDangerousIcon = mContext.getResources().getDrawable(R.drawable.ic_bullet_key_permission);
+ mShowMaxIcon = mContext.getResources().getDrawable(R.drawable.expander_close_holo_dark);
+ mShowMinIcon = mContext.getResources().getDrawable(R.drawable.expander_open_holo_dark);
+
+ // Set permissions view
+ setPermissions(mPermsList);
+ return mPermsView;
}
- public View getPermissionsView(int which) {
- mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- LinearLayout permsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
- LinearLayout displayList = (LinearLayout) permsView.findViewById(R.id.perms_list);
- View noPermsView = permsView.findViewById(R.id.no_permissions);
-
- displayPermissions(mPermGroupsList, displayList, which);
- if (displayList.getChildCount() <= 0) {
- noPermsView.setVisibility(View.VISIBLE);
+ /**
+ * Canonicalizes the group description before it is displayed to the user.
+ *
+ * TODO check for internationalization issues remove trailing '.' in str1
+ */
+ private String canonicalizeGroupDesc(String groupDesc) {
+ if ((groupDesc == null) || (groupDesc.length() == 0)) {
+ return null;
}
+ // Both str1 and str2 are non-null and are non-zero in size.
+ int len = groupDesc.length();
+ if(groupDesc.charAt(len-1) == '.') {
+ groupDesc = groupDesc.substring(0, len-1);
+ }
+ return groupDesc;
+ }
- return permsView;
+ /**
+ * Utility method that concatenates two strings defined by mPermFormat.
+ * a null value is returned if both str1 and str2 are null, if one of the strings
+ * is null the other non null value is returned without formatting
+ * this is to placate initial error checks
+ */
+ private String formatPermissions(String groupDesc, CharSequence permDesc) {
+ if(groupDesc == null) {
+ if(permDesc == null) {
+ return null;
+ }
+ return permDesc.toString();
+ }
+ groupDesc = canonicalizeGroupDesc(groupDesc);
+ if(permDesc == null) {
+ return groupDesc;
+ }
+ // groupDesc and permDesc are non null
+ return String.format(mPermFormat, groupDesc, permDesc.toString());
+ }
+
+ private CharSequence getGroupLabel(String grpName) {
+ if (grpName == null) {
+ //return default label
+ return mDefaultGrpLabel;
+ }
+ CharSequence cachedLabel = mGroupLabelCache.get(grpName);
+ if (cachedLabel != null) {
+ return cachedLabel;
+ }
+ PermissionGroupInfo pgi;
+ try {
+ pgi = mPm.getPermissionGroupInfo(grpName, 0);
+ } catch (NameNotFoundException e) {
+ Log.i(TAG, "Invalid group name:" + grpName);
+ return null;
+ }
+ CharSequence label = pgi.loadLabel(mPm).toString();
+ mGroupLabelCache.put(grpName, label);
+ return label;
}
/**
* Utility method that displays permissions from a map containing group name and
* list of permission descriptions.
*/
- private void displayPermissions(List<MyPermissionGroupInfo> groups,
- LinearLayout permListView, int which) {
+ private void displayPermissions(boolean dangerous) {
+ Map<String, String> permInfoMap = dangerous ? mDangerousMap : mNormalMap;
+ LinearLayout permListView = dangerous ? mDangerousList : mNonDangerousList;
permListView.removeAllViews();
- int spacing = (int)(8*mContext.getResources().getDisplayMetrics().density);
-
- for (int i=0; i<groups.size(); i++) {
- MyPermissionGroupInfo grp = groups.get(i);
- final List<MyPermissionInfo> perms = getPermissionList(grp, which);
- for (int j=0; j<perms.size(); j++) {
- MyPermissionInfo perm = perms.get(j);
- View view = getPermissionItemView(grp, perm, j == 0,
- which != WHICH_NEW ? mNewPermPrefix : null);
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- if (j == 0) {
- lp.topMargin = spacing;
- }
- if (j == grp.mAllPermissions.size()-1) {
- lp.bottomMargin = spacing;
- }
- if (permListView.getChildCount() == 0) {
- lp.topMargin *= 2;
- }
- permListView.addView(view, lp);
- }
+ Set<String> permInfoStrSet = permInfoMap.keySet();
+ for (String loopPermGrpInfoStr : permInfoStrSet) {
+ CharSequence grpLabel = getGroupLabel(loopPermGrpInfoStr);
+ //guaranteed that grpLabel wont be null since permissions without groups
+ //will belong to the default group
+ if(localLOGV) Log.i(TAG, "Adding view group:" + grpLabel + ", desc:"
+ + permInfoMap.get(loopPermGrpInfoStr));
+ permListView.addView(getPermissionItemView(grpLabel,
+ permInfoMap.get(loopPermGrpInfoStr), dangerous));
}
}
- private PermissionItemView getPermissionItemView(MyPermissionGroupInfo grp,
- MyPermissionInfo perm, boolean first, CharSequence newPermPrefix) {
- return getPermissionItemView(mContext, mInflater, grp, perm, first, newPermPrefix);
+ private void displayNoPermissions() {
+ mNoPermsView.setVisibility(View.VISIBLE);
}
- private static PermissionItemView getPermissionItemView(Context context, LayoutInflater inflater,
- MyPermissionGroupInfo grp, MyPermissionInfo perm, boolean first,
- CharSequence newPermPrefix) {
- PermissionItemView permView = (PermissionItemView)inflater.inflate(
- R.layout.app_permission_item, null);
- permView.setPermission(grp, perm, first, newPermPrefix);
- return permView;
+ private View getPermissionItemView(CharSequence grpName, CharSequence permList,
+ boolean dangerous) {
+ return getPermissionItemView(mContext, mInflater, grpName, permList,
+ dangerous, dangerous ? mDangerousIcon : mNormalIcon);
}
- private static View getPermissionItemViewOld(Context context, LayoutInflater inflater,
+ private static View getPermissionItemView(Context context, LayoutInflater inflater,
CharSequence grpName, CharSequence permList, boolean dangerous, Drawable icon) {
- View permView = inflater.inflate(R.layout.app_permission_item_old, null);
+ View permView = inflater.inflate(R.layout.app_permission_item, null);
TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
@@ -553,107 +341,159 @@
return permView;
}
- private boolean isDisplayablePermission(PermissionInfo pInfo, int newReqFlags,
- int existingReqFlags) {
- final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
- // Dangerous and normal permissions are always shown to the user.
- if (base == PermissionInfo.PROTECTION_DANGEROUS ||
- base == PermissionInfo.PROTECTION_NORMAL) {
- return true;
+ private void showPermissions() {
+
+ switch(mCurrentState) {
+ case NO_PERMS:
+ displayNoPermissions();
+ break;
+
+ case DANGEROUS_ONLY:
+ displayPermissions(true);
+ break;
+
+ case NORMAL_ONLY:
+ displayPermissions(false);
+ break;
+
+ case BOTH:
+ displayPermissions(true);
+ if (mExpanded) {
+ displayPermissions(false);
+ mShowMoreIcon.setImageDrawable(mShowMaxIcon);
+ mShowMoreText.setText(R.string.perms_hide);
+ mNonDangerousList.setVisibility(View.VISIBLE);
+ } else {
+ mShowMoreIcon.setImageDrawable(mShowMinIcon);
+ mShowMoreText.setText(R.string.perms_show_all);
+ mNonDangerousList.setVisibility(View.GONE);
+ }
+ mShowMore.setVisibility(View.VISIBLE);
+ break;
}
- // Development permissions are only shown to the user if they are already
- // granted to the app -- if we are installing an app and they are not
- // already granted, they will not be granted as part of the install.
- if ((existingReqFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
- && (pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
+ }
+
+ private boolean isDisplayablePermission(PermissionInfo pInfo) {
+ if(pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS ||
+ pInfo.protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
return true;
}
return false;
}
- private static class PermissionGroupInfoComparator implements Comparator<MyPermissionGroupInfo> {
- private final Collator sCollator = Collator.getInstance();
- PermissionGroupInfoComparator() {
+ /*
+ * Utility method that aggregates all permission descriptions categorized by group
+ * Say group1 has perm11, perm12, perm13, the group description will be
+ * perm11_Desc, perm12_Desc, perm13_Desc
+ */
+ private void aggregateGroupDescs(
+ Map<String, List<PermissionInfo> > map, Map<String, String> retMap) {
+ if(map == null) {
+ return;
}
- public final int compare(MyPermissionGroupInfo a, MyPermissionGroupInfo b) {
- if (((a.flags^b.flags)&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
- return ((a.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) ? -1 : 1;
+ if(retMap == null) {
+ return;
+ }
+ Set<String> grpNames = map.keySet();
+ Iterator<String> grpNamesIter = grpNames.iterator();
+ while(grpNamesIter.hasNext()) {
+ String grpDesc = null;
+ String grpNameKey = grpNamesIter.next();
+ List<PermissionInfo> grpPermsList = map.get(grpNameKey);
+ if(grpPermsList == null) {
+ continue;
}
- if (a.priority != b.priority) {
- return a.priority > b.priority ? -1 : 1;
+ for(PermissionInfo permInfo: grpPermsList) {
+ CharSequence permDesc = permInfo.loadLabel(mPm);
+ grpDesc = formatPermissions(grpDesc, permDesc);
}
- return sCollator.compare(a.mLabel, b.mLabel);
+ // Insert grpDesc into map
+ if(grpDesc != null) {
+ if(localLOGV) Log.i(TAG, "Group:"+grpNameKey+" description:"+grpDesc.toString());
+ retMap.put(grpNameKey, grpDesc.toString());
+ }
}
}
- private static class PermissionInfoComparator implements Comparator<MyPermissionInfo> {
+ private static class PermissionInfoComparator implements Comparator<PermissionInfo> {
+ private PackageManager mPm;
private final Collator sCollator = Collator.getInstance();
- PermissionInfoComparator() {
+ PermissionInfoComparator(PackageManager pm) {
+ mPm = pm;
}
- public final int compare(MyPermissionInfo a, MyPermissionInfo b) {
- return sCollator.compare(a.mLabel, b.mLabel);
+ public final int compare(PermissionInfo a, PermissionInfo b) {
+ CharSequence sa = a.loadLabel(mPm);
+ CharSequence sb = b.loadLabel(mPm);
+ return sCollator.compare(sa, sb);
}
}
-
- private void addPermToList(List<MyPermissionInfo> permList,
- MyPermissionInfo pInfo) {
- if (pInfo.mLabel == null) {
- pInfo.mLabel = pInfo.loadLabel(mPm);
- }
- int idx = Collections.binarySearch(permList, pInfo, mPermComparator);
- if(localLOGV) Log.i(TAG, "idx="+idx+", list.size="+permList.size());
- if (idx < 0) {
- idx = -idx-1;
- permList.add(idx, pInfo);
- }
- }
-
- private void setPermissions(List<MyPermissionInfo> permList) {
+
+ private void setPermissions(List<PermissionInfo> permList) {
+ mGroupLabelCache = new HashMap<String, CharSequence>();
+ //add the default label so that uncategorized permissions can go here
+ mGroupLabelCache.put(mDefaultGrpName, mDefaultGrpLabel);
+
+ // Map containing group names and a list of permissions under that group
+ // categorized as dangerous
+ mDangerousMap = new HashMap<String, String>();
+ // Map containing group names and a list of permissions under that group
+ // categorized as normal
+ mNormalMap = new HashMap<String, String>();
+
+ // Additional structures needed to ensure that permissions are unique under
+ // each group
+ Map<String, List<PermissionInfo>> dangerousMap =
+ new HashMap<String, List<PermissionInfo>>();
+ Map<String, List<PermissionInfo> > normalMap =
+ new HashMap<String, List<PermissionInfo>>();
+ PermissionInfoComparator permComparator = new PermissionInfoComparator(mPm);
+
if (permList != null) {
// First pass to group permissions
- for (MyPermissionInfo pInfo : permList) {
+ for (PermissionInfo pInfo : permList) {
if(localLOGV) Log.i(TAG, "Processing permission:"+pInfo.name);
- if(!isDisplayablePermission(pInfo, pInfo.mNewReqFlags, pInfo.mExistingReqFlags)) {
+ if(!isDisplayablePermission(pInfo)) {
if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" is not displayable");
continue;
}
- MyPermissionGroupInfo group = mPermGroups.get(pInfo.group);
- if (group != null) {
- pInfo.mLabel = pInfo.loadLabel(mPm);
- addPermToList(group.mAllPermissions, pInfo);
- if (pInfo.mNew) {
- addPermToList(group.mNewPermissions, pInfo);
- }
- if ((group.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0) {
- addPermToList(group.mPersonalPermissions, pInfo);
- } else {
- addPermToList(group.mDevicePermissions, pInfo);
+ Map<String, List<PermissionInfo> > permInfoMap =
+ (pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) ?
+ dangerousMap : normalMap;
+ String grpName = (pInfo.group == null) ? mDefaultGrpName : pInfo.group;
+ if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" belongs to group:"+grpName);
+ List<PermissionInfo> grpPermsList = permInfoMap.get(grpName);
+ if(grpPermsList == null) {
+ grpPermsList = new ArrayList<PermissionInfo>();
+ permInfoMap.put(grpName, grpPermsList);
+ grpPermsList.add(pInfo);
+ } else {
+ int idx = Collections.binarySearch(grpPermsList, pInfo, permComparator);
+ if(localLOGV) Log.i(TAG, "idx="+idx+", list.size="+grpPermsList.size());
+ if (idx < 0) {
+ idx = -idx-1;
+ grpPermsList.add(idx, pInfo);
}
}
}
+ // Second pass to actually form the descriptions
+ // Look at dangerous permissions first
+ aggregateGroupDescs(dangerousMap, mDangerousMap);
+ aggregateGroupDescs(normalMap, mNormalMap);
}
- for (MyPermissionGroupInfo pgrp : mPermGroups.values()) {
- if (pgrp.labelRes != 0 || pgrp.nonLocalizedLabel != null) {
- pgrp.mLabel = pgrp.loadLabel(mPm);
- } else {
- ApplicationInfo app;
- try {
- app = mPm.getApplicationInfo(pgrp.packageName, 0);
- pgrp.mLabel = app.loadLabel(mPm);
- } catch (NameNotFoundException e) {
- pgrp.mLabel = pgrp.loadLabel(mPm);
- }
- }
- mPermGroupsList.add(pgrp);
+ mCurrentState = State.NO_PERMS;
+ if(mDangerousMap.size() > 0) {
+ mCurrentState = (mNormalMap.size() > 0) ? State.BOTH : State.DANGEROUS_ONLY;
+ } else if(mNormalMap.size() > 0) {
+ mCurrentState = State.NORMAL_ONLY;
}
- Collections.sort(mPermGroupsList, mPermGroupComparator);
- if (false) {
- for (MyPermissionGroupInfo grp : mPermGroupsList) {
- Log.i("foo", "Group " + grp.name + " personal="
- + ((grp.flags&PermissionGroupInfo.FLAG_PERSONAL_INFO) != 0)
- + " priority=" + grp.priority);
- }
- }
+ if(localLOGV) Log.i(TAG, "mCurrentState=" + mCurrentState);
+ showPermissions();
+ }
+
+ public void onClick(View v) {
+ if(localLOGV) Log.i(TAG, "mExpanded="+mExpanded);
+ mExpanded = !mExpanded;
+ showPermissions();
}
}
diff --git a/core/res/res/layout/app_permission_item.xml b/core/res/res/layout/app_permission_item.xml
index c448bd1..1bd267f 100644
--- a/core/res/res/layout/app_permission_item.xml
+++ b/core/res/res/layout/app_permission_item.xml
@@ -19,33 +19,37 @@
Contains the group name and a list of permission labels under the group.
-->
-<view class="android.widget.AppSecurityPermissions$PermissionItemView"
+<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:background="?android:attr/selectableItemBackground">
+ android:layout_height="wrap_content">
<ImageView
android:id="@+id/perm_icon"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_marginLeft="16dp"
- android:layout_marginRight="8dp"
+ android:layout_width="30dip"
+ android:layout_height="30dip"
+ android:layout_alignParentLeft="true"
android:scaleType="fitCenter" />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:background="?android:attr/dividerVertical" />
<TextView
- android:id="@+id/perm_name"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textSize="16sp"
- android:layout_marginLeft="8dp"
+ android:id="@+id/permission_group"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textStyle="bold"
+ android:paddingLeft="6dip"
+ android:layout_toRightOf="@id/perm_icon"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|left" />
+ android:layout_height="wrap_content" />
-</view>
+ <TextView
+ android:id="@+id/permission_list"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_marginTop="-4dip"
+ android:paddingBottom="8dip"
+ android:paddingLeft="6dip"
+ android:layout_below="@id/permission_group"
+ android:layout_toRightOf="@id/perm_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</RelativeLayout>
diff --git a/core/res/res/layout/app_perms_summary.xml b/core/res/res/layout/app_perms_summary.xml
index 509c502..3f99dde 100755
--- a/core/res/res/layout/app_perms_summary.xml
+++ b/core/res/res/layout/app_perms_summary.xml
@@ -26,17 +26,79 @@
android:id="@+id/no_permissions"
android:text="@string/no_permissions"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:paddingLeft="8dp"
- android:paddingRight="8dp"
+ android:paddingLeft="16dip"
+ android:paddingRight="12dip"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
- <!-- Populated with all permissions. -->
+ <!-- List view containing list of dangerous permissions categorized by groups. -->
<LinearLayout
- android:id="@+id/perms_list"
+ android:id="@+id/dangerous_perms_list"
android:orientation="vertical"
android:layout_width="match_parent"
+ android:paddingLeft="16dip"
+ android:paddingRight="12dip"
+ android:layout_height="wrap_content" />
+
+ <!-- Clickable area letting user display additional permissions. -->
+ <LinearLayout
+ android:id="@+id/show_more"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:layout_marginTop="12dip"
+ android:layout_marginBottom="16dip">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="16dip"
+ android:paddingBottom="12dip"
+ android:paddingLeft="16dip"
+ android:duplicateParentState="true"
+ android:background="?android:attr/selectableItemBackground">
+
+ <TextView
+ android:id="@+id/show_more_text"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:duplicateParentState="true"
+ android:layout_alignTop="@+id/show_more_icon"
+ android:layout_gravity="center_vertical"
+ android:paddingLeft="36dip"
+ android:layout_weight="1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@id/show_more_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="12dip" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="?android:attr/listDivider" />
+
+ </LinearLayout>
+
+ <!-- List view containing list of permissions that aren't dangerous. -->
+ <LinearLayout
+ android:id="@+id/non_dangerous_perms_list"
+ android:orientation="vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="12dip"
+ android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index ca5d5f6..62c1723 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Выдаліць запыт"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Адправіць запыт"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Галасавы пошук"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Уключыць функцыю Explore by Touch?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Служба доступу <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> запытвае ўключэнне функцыі Explore by Touch. Калі функцыя Explore by Touch будзе ўключаная, вы зможаце пачуць або ўбачыць апісанні таго, што знаходзіцца пад вашым пальцам, або выконваць жэсты для ўзаемадзеяння з планшэтам."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Служба доступу <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> запытвае ўключэнне функцыі Explore by Touch. Калі функцыя Explore by Touch будзе ўключаная, вы зможаце пачуць або ўбачыць апісанні таго, што знаходзіцца пад вашым пальцам, або выконваць жэсты для ўзаемадзеяння з тэлефонам."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 месяц таму"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Раней, чым 1 месяц таму"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Наладзіць метады ўводу"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Фізічная клавіятура"</string>
<string name="hardware" msgid="7517821086888990278">"Апар. ср."</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Выбраць раскладку клавіятуры"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Націсніце, каб выбраць раскладку клавіятуры."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандыдат."</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Прыняць выклік?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Заўсёды"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Толькі адзін раз"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 98c7ac5..e33bda8 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Smazat dotaz"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Odeslat dotaz"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Hlasové vyhledávání"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Povolit funkci Prozkoumání dotykem?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolení funkce Prozkoumání dotykem. Pokud je funkce Prozkoumání dotykem zapnuta, můžete slyšet nebo vidět popisy objektů pod vaším prstem nebo ovládat tablet gesty."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolení funkce Prozkoumání dotykem. Pokud je funkce Prozkoumání dotykem zapnuta, můžete slyšet nebo vidět popisy objektů pod vaším prstem nebo ovládat telefon gesty."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"před 1 měsícem"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Déle než před 1 měsícem"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody zadávání"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnice"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Výběr rozložení klávesnice"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotykem vyberte rozložení klávesnice."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -1323,5 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Přijmout hovor?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
- <string name="activity_resolver_use_once" msgid="2404644797149173758">"Jen jednou"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Pouze jednou"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a326e2d..b76da67 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Anfrage löschen"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Anfrage senden"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Sprachsuche"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\"Tippen & Entdecken\" aktivieren?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen & Entdecken\". Wenn \"Tippen & Entdecken\" aktiviert ist, können Sie Beschreibungen dessen hören oder sehen, was sich unter ihren Fingern befindet, oder Gesten ausführen, um mit dem Tablet zu interagieren."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen & Entdecken\". Wenn \"Tippen & Entdecken\" aktiviert ist, können Sie Beschreibungen dessen hören oder sehen, was sich unter ihren Fingern befindet, oder Gesten ausführen, um mit dem Telefon zu interagieren."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Vor 1 Monat"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vor mehr als 1 Monat"</string>
<plurals name="num_seconds_ago">
@@ -1009,7 +1006,7 @@
<string name="smv_application" msgid="3307209192155442829">"Die App <xliff:g id="APPLICATION">%1$s</xliff:g> (Prozess <xliff:g id="PROCESS">%2$s</xliff:g>) hat gegen ihre selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
<string name="smv_process" msgid="5120397012047462446">"Der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> hat gegen seine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert..."</string>
- <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert."</string>
+ <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> läuft"</string>
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Eingabemethoden einrichten"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Physische Tastatur"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Tastaturlayout auswählen"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Zum Auswählen eines Tastaturlayouts berühren"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Anruf annehmen?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Immer"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Nur einmal"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index e53e3bc..043ee30 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -662,7 +662,7 @@
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Busca del trabajo"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistente"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
- <string name="eventTypeCustom" msgid="7837586198458073404">"Personalizados"</string>
+ <string name="eventTypeCustom" msgid="7837586198458073404">"Personalizado"</string>
<string name="eventTypeBirthday" msgid="2813379844211390740">"Cumpleaños"</string>
<string name="eventTypeAnniversary" msgid="3876779744518284000">"Aniversario"</string>
<string name="eventTypeOther" msgid="7388178939010143077">"Otros"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 1ec3a3e..d3d8e4f 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Tyhjennä kysely"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Lähetä kysely"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Puhehaku"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Otetaanko Tutki koskettamalla käyttöön?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> haluaa ottaa Tutki koskettamalla -ominaisuuden käyttöön. Kun Tutki koskettamalla on käytössä, näet tai kuulet kuvauksen sormen alla olevista kohteista ja voit käyttää tablet-laitetta sormieleiden avulla."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> haluaa ottaa Tutustu koskettamalla -ominaisuuden käyttöön. Kun Tutustu koskettamalla on käytössä, näet tai kuulet kuvauksen sormen alla olevista kohteista ja voit käyttää puhelinta sormieleiden avulla."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"kuukausi sitten"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Yli kuukausi sitten"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Määritä syöttötavat"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fyysinen näppäimistö"</string>
<string name="hardware" msgid="7517821086888990278">"Laitteisto"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Valitse näppäimistöasettelu"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Kosketa ja valitse näppäimistöasettelu."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vastataanko puheluun?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Aina"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Vain kerran"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d7cb12c..0d96e6d 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Effacer la requête"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Envoyer la requête"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Recherche vocale"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Activer \"Explorer au toucher\" ?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> souhaite activer la fonctionnalité \"Explorer au toucher\". Lorsque celle-ci est activée, vous pouvez entendre ou voir les descriptions des éléments que vous sélectionnez, ou bien interagir avec la tablette en effectuant certains gestes."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> souhaite activer la fonctionnalité \"Explorer au toucher\". Lorsque celle-ci est activée, vous pouvez entendre ou voir les descriptions des éléments que vous sélectionnez, ou bien interagir avec le téléphone en effectuant certains gestes."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Il y a 1 mois"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Il y a plus d\'un mois"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
<string name="hardware" msgid="7517821086888990278">"Matériel"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Sélectionnez la disposition du clavier"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Appuyez ici pour sélectionner une disposition de clavier."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel ?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Une seule fois"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2a83a16..b0fd087 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"क्वेरी साफ़ करें"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"क्वेरी सबमिट करें"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"ध्वनि खोज"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"स्पर्श के द्वारा अन्वेषण करें सक्षम करें?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श के द्वारा अन्वेषण करें सक्षम करना चाहती है. स्पर्श के द्वारा अन्वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या टेबलेट से संवाद करने के लिए जेस्चर निष्पादित कर सकते हैं."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श के द्वारा अन्वेषण करें सक्षम करना चाहती है. स्पर्श के द्वारा अन्वेष करें चालू होने पर, आप अपनी अंगुली के नीचे क्या है उसका विवरण सुन सकते हैं या देख सकते हैं या फ़ोन से संवाद करने के लिए जेस्चर निष्पादित कर सकते हैं."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 माह पहले"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 माह से पहले"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"इनपुट पद्धतियां सेट करें"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"भौतिक कीबोर्ड"</string>
<string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"कीबोर्ड लेआउट का चयन करें"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"कीबोर्ड लेआउट का चयन करने के लिए स्पर्श करें."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"उम्मीदवार"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"कॉल स्वीकार करें?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"हमेशा"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"केवल एक बार"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index d8bd15f..edb0032 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Izbriši upit"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Pošalji upit"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Glasovno pretraživanje"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Omogućiti Istraživanje dodirom?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Usluga <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogućiti značajku Istraživanje dodirom. Kad je značajka Istraživanje dodirom uključena, možete čuti ili vidjeti opise onoga što je pod vašim prstom ili izvršiti pokrete za interakciju s tabletnim računalom."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Usluga <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogućiti značajku Istraživanje dodirom. Kad je značajka Istraživanje dodirom uključena, možete čuti ili vidjeti opise onoga što je pod vašim prstom ili izvršiti pokrete za interakciju s telefonom."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Prije 1 mjesec"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Prije 1 mjesec"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Postavljanje načina unosa"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fizička tipkovnica"</string>
<string name="hardware" msgid="7517821086888990278">"Hardver"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Odaberite izgled tipkovnice"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dodirnite za odabir izgleda tipkovnice."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Prihvatiti poziv?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Uvijek"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo jednom"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 188f6d7..8334d44 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Lekérdezés törlése"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Lekérdezés küldése"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Hangalapú keresés"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Aktiválja a Felfedezés érintésselt?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> aktiválni szeretné a Felfedezés érintéssel funkciót. Amikor be van kapcsolva a Felfedezés érintéssel, akkor hallhatja vagy láthatja annak leírását, ami az ujja alatt van, illetve végrehajthat kézmozdulatokat a táblagép kezeléséhez."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> aktiválni szeretné a Felfedezés érintéssel funkciót. Amikor be van kapcsolva a Felfedezés érintéssel, akkor hallhatja vagy láthatja annak leírását, ami az ujja alatt van, illetve végrehajthat kézmozdulatokat a telefon kezeléséhez."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 hónapja"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Több mint 1 hónapja"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Beviteli módok beállítása"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fizikai billentyűzet"</string>
<string name="hardware" msgid="7517821086888990278">"Hardver"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Válasszon billentyűzetkiosztást"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Érintse meg az egyik billentyűzetkiosztás kiválasztásához."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Fogadja a hívást?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Mindig"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Csak egyszer"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 604e163..2220454 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"検索キーワードを削除"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"検索キーワードを送信"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"音声検索"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"タッチガイドをONにしますか?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>がタッチガイドをONにしようとしています。タッチガイドをONにすると、指の位置にあるアイテムの説明を読み上げたり表示したりできます。また、タブレットを通常とは違うジェスチャーで操作できます。"</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>がタッチガイドをONにしようとしています。タッチガイドをONにすると、指の位置にあるアイテムの説明を読み上げたり表示したりできます。また、携帯端末を通常とは違うジェスチャーで操作できます。"</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1か月前"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1か月前"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"入力方法をセットアップ"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"物理キーボード"</string>
<string name="hardware" msgid="7517821086888990278">"ハードウェア"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"キーボードレイアウトの選択"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"タップしてキーボードレイアウトを選択してください。"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"通話を受けますか?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"常時"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"1回のみ"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 6ed825f..c7e818d 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Slett søket"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Send inn spørsmål"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Talesøk"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Aktivere Utforsk ved å trykke?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ber om aktivering av Utforsk ved å trykke. Når Utforsk ved å trykke er slått på, kan du høre og se beskrivelser av det som er under fingrene dine. Du kan også utføre handlinger på nettbrettet ved hjelp av bevegelser."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ber om aktivering av Utforsk ved å trykke. Når Utforsk ved å trykke er slått på, kan du høre eller se beskrivelser av det som er under fingrene dine. Du kan også utføre handlinger på nettbrettet ved hjelp av bevegelser."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"For én måned siden"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"For over en måned siden"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inndatametoder"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
<string name="hardware" msgid="7517821086888990278">"Maskinvare"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Velg tastaturoppsett"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Trykk for å velge et tastaturoppsett"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare anropet?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltid"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Bare én gang"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b92c38c..857e655 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Zoekopdracht wissen"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Zoekopdracht verzenden"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Spraakgestuurd zoeken"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\'Verkennen via aanraking\' aan?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de telefoon."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 maand geleden"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Meer dan 1 maand geleden"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Invoermethoden instellen"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fysiek toetsenbord"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Toetsenbordindeling selecteren"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Tik om een toetsenbordindeling te selecteren."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Oproep accepteren?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Altijd"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Eén keer"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 6c5ea32..fdce9ea 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Jasný dopyt"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Odoslať dopyt"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Hlasové vyhľadávanie"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Povoliť Preskúmanie dotykom?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolenie funkcie Preskúmanie dotykom. Ak je funkcia Explore by Touch zapnutá, môžete počuť alebo vidieť popisy objektov pod vaším prstom alebo ovládať tablet gestami."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Služba <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> požaduje povolenie funkcie Preskúmanie dotykom. Ak je funkcia Explore by Touch zapnutá, môžete počuť alebo vidieť popisy objektov pod vaším prstom alebo ovládať telefón gestami."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"pred 1 mesiacom"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Viac ako pred 1 mesiacom"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Nastavenie metód vstupu"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnica"</string>
<string name="hardware" msgid="7517821086888990278">"Hardvér"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Zvoľte rozloženie klávesnice"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotykom zvoľte rozloženie klávesnice."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Prijať hovor?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Len raz"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 049c1d8..b3929e2 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Izbris poizvedbe"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Pošlji poizvedbo"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Glasovno iskanje"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Vklop raziskovanja z dotikom?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Storitev <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogočiti raziskovanje z dotikom. Ko je raziskovanje z dotikom vklopljeno, lahko slišite ali vidite opise tega, kar je pod vašim prstom, ali izvajate poteze za interakcijo s tabličnim računalnikom."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Storitev <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogočiti raziskovanje z dotikom. Ko je raziskovanje z dotikom vklopljeno, lahko slišite ali vidite opise tega, kar je pod vašim prstom, ali izvajate poteze za interakcijo s telefonom."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Pred 1 mesecem"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Pred več kot 1 mesecem"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Nastavi načine vnosa"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fizična tipkovnica"</string>
<string name="hardware" msgid="7517821086888990278">"Strojna oprema"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Izberite razporeditev tipkovnice"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dotaknite se, da izberete razporeditev tipkovnice"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Ali želite sprejeti klic?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vedno"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo tokrat"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index fa7da01..5438262 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Обриши упит"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Пошаљи упит"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Гласовна претрага"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Желите да омог. Истражив. додиром?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са таблетом помоћу покрета."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> жели да омогући Истраживање додиром. Када је Истраживање додиром укључено, можете да чујете или видите описе ставке на коју сте ставили прст или да комуницирате са телефоном помоћу покрета."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Пре месец дана"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Пре месец дана"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Подеси методе уноса"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Физичка тастатура"</string>
<string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Избор распореда тастатуре"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Додирните да бисте изабрали распоред тастатуре."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Желите ли да прихватите позив?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Увек"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Само једном"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index f2430c2..2beeb39 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Sorguyu temizle"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Sorguyu gönder"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Sesli arama"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Dokunarak Keşfet etkinleştirilsin mi?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda, parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da tabletle etkileşimde bulunmak için ilgili hareketleri yapabilirsiniz."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>, Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da telefonla etkileşimde bulunmak için ilgili hareketleri yapabilirsiniz."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ay önce"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 ay önce"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Giriş yöntemlerini ayarla"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziksel klavye"</string>
<string name="hardware" msgid="7517821086888990278">"Donanım"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Bir klavye düzeni seç"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Bir klavye düzeni seçmek için dokunun."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Çağrı kabul edilsin mi?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Her zaman"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Yalnızca bir defa"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 2c6a4ed..3df0de5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -855,12 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"清除查詢"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"提交查詢"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"語音搜尋"</string>
- <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
- <skip />
- <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
- <skip />
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"啟用輕觸探索?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在您的手指時顯示或朗讀說明,您也可以執行手勢來與平板電腦互動。"</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> 需要啟用「輕觸探索」。開啟這項功能時,系統會在您的手指輕觸螢幕上的物件時顯示或朗讀說明,您也可以執行手勢來與手機互動。"</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 個月以前"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 個月前"</string>
<plurals name="num_seconds_ago">
@@ -1127,10 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"設定輸入法"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"實體鍵盤"</string>
<string name="hardware" msgid="7517821086888990278">"硬體"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
- <skip />
- <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"選取鍵盤配置"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"輕觸即可選取鍵盤配置。"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
@@ -1323,6 +1318,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"啟動「瀏覽器」嗎?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"接聽電話嗎?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"一律採用"</string>
- <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
- <skip />
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"僅限一次"</string>
</resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f24733c..f971d39 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -199,7 +199,7 @@
<flag name="development" value="0x20" />
</attr>
- <!-- Flags indicating more context for a permission group. -->
+ <!-- Flags indicating more context for a permission group. @hide -->
<attr name="permissionGroupFlags">
<!-- Set to indicate that this permission group contains permissions
protecting access to some information that is considered
@@ -903,7 +903,6 @@
<attr name="icon" />
<attr name="logo" />
<attr name="description" />
- <attr name="permissionGroupFlags" />
<attr name="priority" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index bf9fe42..51be22d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -123,9 +123,12 @@
<java-symbol type="id" name="package_label" />
<java-symbol type="id" name="packages_list" />
<java-symbol type="id" name="pause" />
- <java-symbol type="id" name="perms_list" />
+ <java-symbol type="id" name="show_more" />
<java-symbol type="id" name="perm_icon" />
- <java-symbol type="id" name="perm_name" />
+ <java-symbol type="id" name="show_more_icon" />
+ <java-symbol type="id" name="show_more_text" />
+ <java-symbol type="id" name="dangerous_perms_list" />
+ <java-symbol type="id" name="non_dangerous_perms_list" />
<java-symbol type="id" name="permission_group" />
<java-symbol type="id" name="permission_list" />
<java-symbol type="id" name="pickers" />
@@ -660,6 +663,10 @@
<java-symbol type="string" name="passwordIncorrect" />
<java-symbol type="string" name="perms_description_app" />
<java-symbol type="string" name="perms_new_perm_prefix" />
+ <java-symbol type="string" name="perms_hide" />
+ <java-symbol type="string" name="perms_show_all" />
+ <java-symbol type="string" name="default_permission_group" />
+ <java-symbol type="string" name="permissions_format" />
<java-symbol type="string" name="petabyteShort" />
<java-symbol type="string" name="phoneTypeAssistant" />
<java-symbol type="string" name="phoneTypeCallback" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 65457b3..4cac3ec 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2505,7 +2505,7 @@
<!-- Title for a warning message about the interaction model changes after allowing an accessibility
service to put the device into explore by touch mode, displayed as a dialog message when
- the user selects to enables the service. (default). [CHAR LIMIT=35] -->
+ the user selects to enables the service. (default). [CHAR LIMIT=45] -->
<string name="enable_explore_by_touch_warning_title">Enable Explore by Touch?</string>
<!-- Summary for a warning message about the interaction model changes after allowing an accessibility
service to put the device into explore by touch mode, displayed as a dialog message when
@@ -3010,13 +3010,23 @@
<!-- Name of the button in the date/time picker to accept the date/time change -->
<string name="date_time_done">Done</string>
- <!-- Security Permissions strings-->
+ <!-- Security Permissions strings (old)-->
+ <!-- The default permission group for any permissions that have not explicitly set a group. -->
+ <string name="default_permission_group">Default</string>
+ <!-- Do not translate. -->
+ <string name="permissions_format"><xliff:g id="perm_line1">%1$s</xliff:g>, <xliff:g id="perm_line2">%2$s</xliff:g></string>
+ <!-- Shown for an application when it doesn't require any permission grants. -->
+ <string name="no_permissions">No permissions required</string>
+ <!-- When installing an application, the less-dangerous permissions are hidden. If the user showed those, this is the text to hide them again. -->
+ <string name="perms_hide"><b>Hide</b></string>
+ <!-- When installing an application, the less-dangerous permissions are hidden. This is the text to show those. -->
+ <string name="perms_show_all"><b>Show all</b></string>
+
+ <!-- Security Permissions strings (new)-->
<!-- Text that is placed at the front of a permission name that is being added to an app [CHAR LIMIT=NONE] -->
<string name="perms_new_perm_prefix"><font size="12" fgcolor="#ff900000">NEW: </font></string>
<!-- Text that is placed at the front of a permission name that is being added to an app [CHAR LIMIT=NONE] -->
<string name="perms_description_app">Provided by <xliff:g id="app_name">%1$s</xliff:g>.</string>
- <!-- Shown for an application when it doesn't require any permission grants. -->
- <string name="no_permissions">No permissions required</string>
<!-- USB storage dialog strings -->
<!-- This is the title for the activity's window. -->
diff --git a/include/private/hwui/DrawGlInfo.h b/include/private/hwui/DrawGlInfo.h
index e33823e..fc810be 100644
--- a/include/private/hwui/DrawGlInfo.h
+++ b/include/private/hwui/DrawGlInfo.h
@@ -72,7 +72,14 @@
// The functor needs to be invoked again but will
// not redraw. Only the functor is invoked again
// (unless another functor requests a redraw.)
- kStatusInvoke = 0x2
+ kStatusInvoke = 0x2,
+ // DisplayList actually issued GL drawing commands.
+ // This is used to signal the HardwareRenderer that the
+ // buffers should be flipped - otherwise, there were no
+ // changes to the buffer, so no need to flip. Some hardware
+ // has issues with stale buffer contents when no GL
+ // commands are issued.
+ kStatusDrew = 0x4
};
}; // struct DrawGlInfo
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 546925e..88d2209 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -833,7 +833,7 @@
* purposes of logging display list info for a given view.
*/
status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
- status_t drawGlStatus = 0;
+ status_t drawGlStatus = DrawGlInfo::kStatusDone;
TextContainer text;
mReader.rewind();
@@ -859,7 +859,7 @@
DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
renderer.restoreToCount(restoreTo);
renderer.endMark();
- return false;
+ return drawGlStatus;
}
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
@@ -1002,7 +1002,7 @@
}
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
layer, x, y, paint);
- renderer.drawLayer(layer, x, y, paint);
+ drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
}
break;
case DrawBitmap: {
@@ -1015,7 +1015,7 @@
}
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
bitmap, x, y, paint);
- renderer.drawBitmap(bitmap, x, y, paint);
+ drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
}
break;
case DrawBitmapMatrix: {
@@ -1024,7 +1024,7 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
bitmap, matrix, paint);
- renderer.drawBitmap(bitmap, matrix, paint);
+ drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
}
break;
case DrawBitmapRect: {
@@ -1041,7 +1041,7 @@
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
(char*) indent, OP_NAMES[op], bitmap,
f1, f2, f3, f4, f5, f6, f7, f8,paint);
- renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
+ drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
}
break;
case DrawBitmapData: {
@@ -1051,7 +1051,7 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
bitmap, x, y, paint);
- renderer.drawBitmap(bitmap, x, y, paint);
+ drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
}
break;
case DrawBitmapMesh: {
@@ -1067,7 +1067,8 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
- renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, paint);
+ drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
+ colors, paint);
}
break;
case DrawPatch: {
@@ -1091,15 +1092,15 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
- renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
- numColors, left, top, right, bottom, paint);
+ drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
+ xDivsCount, yDivsCount, numColors, left, top, right, bottom, paint);
}
break;
case DrawColor: {
int32_t color = getInt();
int32_t xferMode = getInt();
DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
- renderer.drawColor(color, (SkXfermode::Mode) xferMode);
+ drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
}
break;
case DrawRect: {
@@ -1110,7 +1111,7 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
f1, f2, f3, f4, paint);
- renderer.drawRect(f1, f2, f3, f4, paint);
+ drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
}
break;
case DrawRoundRect: {
@@ -1123,7 +1124,7 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
(char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
- renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
+ drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
}
break;
case DrawCircle: {
@@ -1133,7 +1134,7 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
(char*) indent, OP_NAMES[op], f1, f2, f3, paint);
- renderer.drawCircle(f1, f2, f3, paint);
+ drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
}
break;
case DrawOval: {
@@ -1144,7 +1145,7 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
(char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
- renderer.drawOval(f1, f2, f3, f4, paint);
+ drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
}
break;
case DrawArc: {
@@ -1158,14 +1159,14 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
(char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
- renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
+ drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
}
break;
case DrawPath: {
SkPath* path = getPath();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
- renderer.drawPath(path, paint);
+ drawGlStatus |= renderer.drawPath(path, paint);
}
break;
case DrawLines: {
@@ -1173,7 +1174,7 @@
float* points = getFloats(count);
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
- renderer.drawLines(points, count, paint);
+ drawGlStatus |= renderer.drawLines(points, count, paint);
}
break;
case DrawPoints: {
@@ -1181,7 +1182,7 @@
float* points = getFloats(count);
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
- renderer.drawPoints(points, count, paint);
+ drawGlStatus |= renderer.drawPoints(points, count, paint);
}
break;
case DrawText: {
@@ -1193,7 +1194,8 @@
float length = getFloat();
DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
- renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
+ drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y,
+ paint, length);
}
break;
case DrawTextOnPath: {
@@ -1205,7 +1207,7 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
text.text(), text.length(), count, paint);
- renderer.drawTextOnPath(text.text(), text.length(), count, path,
+ drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
hOffset, vOffset, paint);
}
break;
@@ -1217,7 +1219,8 @@
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
OP_NAMES[op], text.text(), text.length(), count, paint);
- renderer.drawPosText(text.text(), text.length(), count, positions, paint);
+ drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
+ positions, paint);
}
break;
case ResetShader: {
@@ -1490,23 +1493,25 @@
return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
+status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
addOp(DisplayList::DrawLayer);
addInt((int) layer);
addPoint(x, y);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
addBitmap(bitmap);
addPoint(left, top);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
const mat4 transform(*matrix);
transform.mapRect(r);
@@ -1517,9 +1522,10 @@
addMatrix(matrix);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint) {
const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
@@ -1529,18 +1535,21 @@
addBounds(dstLeft, dstTop, dstRight, dstBottom);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
+ SkPaint* paint) {
const bool reject = quickReject(left, top, left + bitmap->width(), bitmap->height());
uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
addBitmapData(bitmap);
addPoint(left, top);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
float* vertices, int* colors, SkPaint* paint) {
addOp(DisplayList::DrawBitmapMesh);
addBitmap(bitmap);
@@ -1554,11 +1563,12 @@
addInt(0);
}
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
- const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, SkPaint* paint) {
+status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
+ const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
+ int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
const bool reject = quickReject(left, top, right, bottom);
uint32_t* location = addOp(DisplayList::DrawPatch, reject);
addBitmap(bitmap);
@@ -1568,15 +1578,17 @@
addBounds(left, top, right, bottom);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
+status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
addOp(DisplayList::DrawColor);
addInt(color);
addInt(mode);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
SkPaint* paint) {
const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
quickReject(left, top, right, bottom);
@@ -1584,9 +1596,10 @@
addBounds(left, top, right, bottom);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint) {
const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
quickReject(left, top, right, bottom);
@@ -1595,32 +1608,36 @@
addPoint(rx, ry);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
addOp(DisplayList::DrawCircle);
addPoint(x, y);
addFloat(radius);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
SkPaint* paint) {
addOp(DisplayList::DrawOval);
addBounds(left, top, right, bottom);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
+status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
addOp(DisplayList::DrawArc);
addBounds(left, top, right, bottom);
addPoint(startAngle, sweepAngle);
addInt(useCenter ? 1 : 0);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
+status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
float left, top, offset;
uint32_t width, height;
computePathBounds(path, paint, left, top, offset, width, height);
@@ -1630,23 +1647,26 @@
addPath(path);
addPaint(paint);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
addOp(DisplayList::DrawLines);
addFloats(points, count);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
addOp(DisplayList::DrawPoints);
addFloats(points, count);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
+status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint, float length) {
- if (!text || count <= 0) return;
+ if (!text || count <= 0) return DrawGlInfo::kStatusDone;
// TODO: We should probably make a copy of the paint instead of modifying
// it; modifying the paint will change its generationID the first
@@ -1672,11 +1692,12 @@
addPaint(paint);
addFloat(length);
addSkip(location);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
- if (!text || count <= 0) return;
+ if (!text || count <= 0) return DrawGlInfo::kStatusDone;
addOp(DisplayList::DrawTextOnPath);
addText(text, bytesCount);
addInt(count);
@@ -1685,17 +1706,19 @@
addFloat(vOffset);
paint->setAntiAlias(true);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
-void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
+status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint) {
- if (!text || count <= 0) return;
+ if (!text || count <= 0) return DrawGlInfo::kStatusDone;
addOp(DisplayList::DrawPosText);
addText(text, bytesCount);
addInt(count);
addFloats(positions, count * 2);
paint->setAntiAlias(true);
addPaint(paint);
+ return DrawGlInfo::kStatusDone;
}
void DisplayListRenderer::resetShader() {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 0ba4078..4fa1baa 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -576,35 +576,35 @@
virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
uint32_t level = 0);
- virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
- virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
- virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
- virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+ virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint);
+ virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
+ virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint);
- virtual void drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
- virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+ virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
float* vertices, int* colors, SkPaint* paint);
- virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+ virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint);
- virtual void drawColor(int color, SkXfermode::Mode mode);
- virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
- virtual void drawRoundRect(float left, float top, float right, float bottom,
+ virtual status_t drawColor(int color, SkXfermode::Mode mode);
+ virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual status_t drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint);
- virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
- virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
- virtual void drawArc(float left, float top, float right, float bottom,
+ virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
+ virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual status_t drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
- virtual void drawPath(SkPath* path, SkPaint* paint);
- virtual void drawLines(float* points, int count, SkPaint* paint);
- virtual void drawPoints(float* points, int count, SkPaint* paint);
- virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
+ virtual status_t drawPath(SkPath* path, SkPaint* paint);
+ virtual status_t drawLines(float* points, int count, SkPaint* paint);
+ virtual status_t drawPoints(float* points, int count, SkPaint* paint);
+ virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint, float length = -1.0f);
- virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
float hOffset, float vOffset, SkPaint* paint);
- virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
- SkPaint* paint);
+ virtual status_t drawPosText(const char* text, int bytesCount, int count,
+ const float* positions, SkPaint* paint);
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2a8b32c..2dc9726 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -336,7 +336,7 @@
info.height = getSnapshot()->height;
getSnapshot()->transform->copyTo(&info.transform[0]);
- status_t result = (*functor)(DrawGlInfo::kModeDraw, &info);
+ status_t result = (*functor)(DrawGlInfo::kModeDraw, &info) | DrawGlInfo::kStatusDrew;
if (result != DrawGlInfo::kStatusDone) {
Rect localDirty(info.dirtyLeft, info.dirtyTop, info.dirtyRight, info.dirtyBottom);
@@ -1472,17 +1472,17 @@
finishDrawTexture();
}
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
const float right = left + bitmap->width();
const float bottom = top + bitmap->height();
if (quickReject(left, top, right, bottom)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
- if (!texture) return;
+ if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
@@ -1490,20 +1490,22 @@
} else {
drawTextureRect(left, top, right, bottom, texture, paint);
}
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
const mat4 transform(*matrix);
transform.mapRect(r);
if (quickReject(r.left, r.top, r.right, r.bottom)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
- if (!texture) return;
+ if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
// This could be done in a cheaper way, all we need is pass the matrix
@@ -1512,14 +1514,16 @@
concatMatrix(matrix);
drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint);
restore();
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
const float right = left + bitmap->width();
const float bottom = top + bitmap->height();
if (quickReject(left, top, right, bottom)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
mCaches.activeTexture(0);
@@ -1527,18 +1531,20 @@
const AutoTexture autoCleanup(texture);
drawTextureRect(left, top, right, bottom, texture, paint);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
float* vertices, int* colors, SkPaint* paint) {
// TODO: Do a quickReject
if (!vertices || mSnapshot->isIgnored()) {
- return;
+ return DrawGlInfo::kStatusDone;
}
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
- if (!texture) return;
+ if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
@@ -1611,19 +1617,21 @@
drawTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f,
mode, texture->blend, &mesh[0].position[0], &mesh[0].texture[0],
GL_TRIANGLES, count, false, false, 0, false, false);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
+status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
SkPaint* paint) {
if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
- if (!texture) return;
+ if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
const float width = texture->width;
@@ -1666,18 +1674,20 @@
}
resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint) {
if (quickReject(left, top, right, bottom)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
mCaches.activeTexture(0);
Texture* texture = mCaches.textureCache.get(bitmap);
- if (!texture) return;
+ if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
texture->setFilter(GL_LINEAR, true);
@@ -1726,6 +1736,8 @@
true, !mesh->hasEmptyQuads);
}
}
+
+ return DrawGlInfo::kStatusDrew;
}
/**
@@ -1826,8 +1838,8 @@
* 'inside' the line area being filled opaquely and the other pixels being filled according to
* how far into the boundary region they are, which is determined by shader interpolation.
*/
-void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
const bool isAA = paint->isAntiAlias();
// We use half the stroke width here because we're going to position the quad
@@ -2083,10 +2095,12 @@
if (isAA) {
finishDrawAALine(widthSlot, lengthSlot);
}
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
// TODO: The paint's cap style defines whether the points are square or circular
// TODO: Handle AA for round points
@@ -2138,86 +2152,92 @@
}
glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
+status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
// No need to check against the clip, we fill the clip region
- if (mSnapshot->isIgnored()) return;
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
Rect& clip(*mSnapshot->clipRect);
clip.snapToPixelBoundaries();
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture, SkPaint* paint) {
- if (!texture) return;
+status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture,
+ SkPaint* paint) {
+ if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
const float x = left + texture->left - texture->offset;
const float y = top + texture->top - texture->offset;
drawPathTexture(texture, x, y, paint);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
+status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
right - left, bottom - top, rx, ry, paint);
- drawShape(left, top, texture, paint);
+ return drawShape(left, top, texture, paint);
}
-void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
- drawShape(x - radius, y - radius, texture, paint);
+ return drawShape(x - radius, y - radius, texture, paint);
}
-void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
+ SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.ovalShapeCache.getOval(right - left, bottom - top, paint);
- drawShape(left, top, texture, paint);
+ return drawShape(left, top, texture, paint);
}
-void OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
+status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
if (fabs(sweepAngle) >= 360.0f) {
- drawOval(left, top, right, bottom, paint);
- return;
+ return drawOval(left, top, right, bottom, paint);
}
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
startAngle, sweepAngle, useCenter, paint);
- drawShape(left, top, texture, paint);
+ return drawShape(left, top, texture, paint);
}
-void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom,
+status_t OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom,
SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
mCaches.activeTexture(0);
const PathTexture* texture = mCaches.rectShapeCache.getRect(right - left, bottom - top, paint);
- drawShape(left, top, texture, paint);
+ return drawShape(left, top, texture, paint);
}
-void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
+status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
if (p->getStyle() != SkPaint::kFill_Style) {
- drawRectAsShape(left, top, right, bottom, p);
- return;
+ return drawRectAsShape(left, top, right, bottom, p);
}
if (quickReject(left, top, right, bottom)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
SkXfermode::Mode mode;
@@ -2237,18 +2257,20 @@
} else {
drawColorRect(left, top, right, bottom, color, mode);
}
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
+status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint) {
if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
(paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
// NOTE: Skia does not support perspective transform on drawPosText yet
if (!mSnapshot->transform->isSimple()) {
- return;
+ return DrawGlInfo::kStatusDone;
}
float x = 0.0f;
@@ -2308,13 +2330,15 @@
}
#endif
}
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
+status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint, float length) {
if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
(paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
if (length < 0.0f) length = paint->measureText(text, bytesCount);
@@ -2332,7 +2356,7 @@
SkPaint::FontMetrics metrics;
paint->getFontMetrics(&metrics, 0.0f);
if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
const float oldX = x;
@@ -2432,13 +2456,15 @@
}
drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
float hOffset, float vOffset, SkPaint* paint) {
if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
(paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
- return;
+ return DrawGlInfo::kStatusDone;
}
FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
@@ -2482,27 +2508,31 @@
}
#endif
}
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
- if (mSnapshot->isIgnored()) return;
+status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
mCaches.activeTexture(0);
// TODO: Perform early clip test before we rasterize the path
const PathTexture* texture = mCaches.pathCache.get(path, paint);
- if (!texture) return;
+ if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
const float x = texture->left - texture->offset;
const float y = texture->top - texture->offset;
drawPathTexture(texture, x, y, paint);
+
+ return DrawGlInfo::kStatusDrew;
}
-void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
+status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
if (!layer || quickReject(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight())) {
- return;
+ return DrawGlInfo::kStatusDone;
}
if (layer->deferredUpdateScheduled && layer->renderer && layer->displayList) {
@@ -2575,6 +2605,8 @@
const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
composeLayerRect(layer, r);
#endif
+
+ return DrawGlInfo::kStatusDrew;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index ad83b31..7703e80 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -111,34 +111,34 @@
virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags,
uint32_t level = 0);
virtual void outputDisplayList(DisplayList* displayList, uint32_t level = 0);
- virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
- virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
- virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
- virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+ virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint);
+ virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
+ virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint);
- virtual void drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
- virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+ virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
float* vertices, int* colors, SkPaint* paint);
- virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
+ virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint);
- virtual void drawColor(int color, SkXfermode::Mode mode);
- virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
- virtual void drawRoundRect(float left, float top, float right, float bottom,
+ virtual status_t drawColor(int color, SkXfermode::Mode mode);
+ virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual status_t drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint);
- virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
- virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
- virtual void drawArc(float left, float top, float right, float bottom,
+ virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
+ virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual status_t drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
- virtual void drawPath(SkPath* path, SkPaint* paint);
- virtual void drawLines(float* points, int count, SkPaint* paint);
- virtual void drawPoints(float* points, int count, SkPaint* paint);
- virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
+ virtual status_t drawPath(SkPath* path, SkPaint* paint);
+ virtual status_t drawLines(float* points, int count, SkPaint* paint);
+ virtual status_t drawPoints(float* points, int count, SkPaint* paint);
+ virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint, float length = -1.0f);
- virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
float hOffset, float vOffset, SkPaint* paint);
- virtual void drawPosText(const char* text, int bytesCount, int count,
+ virtual status_t drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint);
virtual void resetShader();
@@ -336,7 +336,7 @@
* @param texture The texture reprsenting the shape
* @param paint The paint to draw the shape with
*/
- void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
+ status_t drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
/**
* Renders the rect defined by the specified bounds as a shape.
@@ -349,7 +349,7 @@
* @param bottom The bottom coordinate of the rect to draw
* @param p The paint to draw the rect with
*/
- void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);
+ status_t drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);
/**
* Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 84856bf..a2c20fd 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -135,8 +135,8 @@
private static final int MSG_RCDISPLAY_UPDATE = 13;
private static final int MSG_SET_ALL_VOLUMES = 14;
private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
- private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
- private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
+ private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;//handled under wakelock
+ private static final int MSG_SET_A2DP_CONNECTION_STATE = 17; //handled under wakelock
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -410,7 +410,7 @@
com.android.internal.R.bool.config_voice_capable);
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "mediaKeyEvent");
+ mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
@@ -2228,6 +2228,15 @@
}
// Message helper methods
+ /**
+ * Queue a message on the given handler's message queue, after acquiring the service wake lock.
+ * Note that the wake lock needs to be released after the message has been handled.
+ */
+ private void queueMsgUnderWakeLock(Handler handler, int msg,
+ int arg1, int arg2, Object obj, int delay) {
+ mMediaEventWakeLock.acquire();
+ sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
+ }
private static void sendMsg(Handler handler, int msg,
int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
@@ -2273,9 +2282,8 @@
public void setWiredDeviceConnectionState(int device, int state, String name) {
synchronized (mConnectedDevices) {
int delay = checkSendBecomingNoisyIntent(device, state);
- sendMsg(mAudioHandler,
+ queueMsgUnderWakeLock(mAudioHandler,
MSG_SET_WIRED_DEVICE_CONNECTION_STATE,
- SENDMSG_QUEUE,
device,
state,
name,
@@ -2289,9 +2297,8 @@
synchronized (mConnectedDevices) {
delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
(state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
- sendMsg(mAudioHandler,
+ queueMsgUnderWakeLock(mAudioHandler,
MSG_SET_A2DP_CONNECTION_STATE,
- SENDMSG_QUEUE,
state,
0,
device,
@@ -3000,10 +3007,12 @@
case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);
+ mMediaEventWakeLock.release();
break;
case MSG_SET_A2DP_CONNECTION_STATE:
onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ mMediaEventWakeLock.release();
break;
}
}
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 ecdaa39..d40a763 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1054,6 +1054,9 @@
}
private static void makeSlippery(View view, boolean slippery) {
+ if (view == null) {
+ return;
+ }
WindowManager.LayoutParams lp = (WindowManager.LayoutParams) view.getLayoutParams();
if (slippery) {
lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 584a69e4..273076c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -127,6 +127,7 @@
private static final int INET_CONDITION_THRESHOLD = 50;
private boolean mAirplaneMode = false;
+ private boolean mLastAirplaneMode = true;
// our ui
Context mContext;
@@ -1062,7 +1063,8 @@
|| mLastDataDirectionOverlayIconId != combinedActivityIconId
|| mLastWifiIconId != mWifiIconId
|| mLastWimaxIconId != mWimaxIconId
- || mLastDataTypeIconId != mDataTypeIconId)
+ || mLastDataTypeIconId != mDataTypeIconId
+ || mLastAirplaneMode != mAirplaneMode)
{
// NB: the mLast*s will be updated later
for (SignalCluster cluster : mSignalClusters) {
@@ -1070,6 +1072,10 @@
}
}
+ if (mLastAirplaneMode != mAirplaneMode) {
+ mLastAirplaneMode = mAirplaneMode;
+ }
+
// the phone icon on phones
if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
mLastPhoneSignalIconId = mPhoneSignalIconId;
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 4c38ab9..67bdabd 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -1247,25 +1247,45 @@
@Override
public void run() {
- final int pointerIndex = mEvent.getActionIndex();
+ // If the last touched explored location is not within the focused
+ // window we will long press at that exact spot, otherwise we find the
+ // accessibility focus and if the tap is within its bounds we long press
+ // there, otherwise we pick the middle of the focus rectangle.
+ MotionEvent lastEvent = mInjectedPointerTracker.getLastInjectedHoverEvent();
+ if (lastEvent == null) {
+ return;
+ }
+
+ final int exploreLocationX = (int) lastEvent.getX(lastEvent.getActionIndex());
+ final int exploreLocationY = (int) lastEvent.getY(lastEvent.getActionIndex());
+
+ Rect bounds = mTempRect;
+ boolean useFocusedBounds = false;
+
+ final int pointerId = mEvent.getPointerId(mEvent.getActionIndex());
+ final int pointerIndex = mEvent.findPointerIndex(pointerId);
+ if (mAms.getAccessibilityFocusBounds(exploreLocationX, exploreLocationY, bounds)) {
+ // If the user's last touch explored location is not
+ // within the accessibility focus bounds we use the center
+ // of the accessibility focused rectangle.
+ if (!bounds.contains((int) mEvent.getX(pointerIndex),
+ (int) mEvent.getY(pointerIndex))) {
+ useFocusedBounds = true;
+ }
+ }
+
+ mLongPressingPointerId = mEvent.getPointerId(pointerIndex);
+
final int eventX = (int) mEvent.getX(pointerIndex);
final int eventY = (int) mEvent.getY(pointerIndex);
- Rect bounds = mTempRect;
- if (mAms.getAccessibilityFocusBounds(eventX, eventY, bounds)
- && !bounds.contains(eventX, eventY)) {
- mLongPressingPointerId = mEvent.getPointerId(pointerIndex);
+ if (useFocusedBounds) {
mLongPressingPointerDeltaX = eventX - bounds.centerX();
mLongPressingPointerDeltaY = eventY - bounds.centerY();
} else {
- mLongPressingPointerId = -1;
- mLongPressingPointerDeltaX = 0;
- mLongPressingPointerDeltaY = 0;
+ mLongPressingPointerDeltaX = eventX - exploreLocationX;
+ mLongPressingPointerDeltaY = eventY - exploreLocationY;
}
- // We are sending events so send exit and gesture
- // end since we transition to another state.
- final int pointerId = mReceivedPointerTracker.getPrimaryActivePointerId();
- final int pointerIdBits = (1 << pointerId);
- mAms.touchExplorationGestureEnded();
+
sendExitEventsIfNeeded(mPolicyFlags);
mCurrentState = STATE_DELEGATING;
diff --git a/services/java/com/android/server/pm/ShutdownThread.java b/services/java/com/android/server/pm/ShutdownThread.java
index 1d6e068..69406c8 100644
--- a/services/java/com/android/server/pm/ShutdownThread.java
+++ b/services/java/com/android/server/pm/ShutdownThread.java
@@ -51,11 +51,11 @@
public final class ShutdownThread extends Thread {
// constants
private static final String TAG = "ShutdownThread";
- private static final int MAX_NUM_PHONE_STATE_READS = 24;
private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500;
// maximum time we wait for the shutdown broadcast before going on.
private static final int MAX_BROADCAST_TIME = 10*1000;
private static final int MAX_SHUTDOWN_WAIT_TIME = 20*1000;
+ private static final int MAX_RADIO_WAIT_TIME = 12*1000;
// length of vibration before shutting down
private static final int SHUTDOWN_VIBRATE_MS = 500;
@@ -263,10 +263,6 @@
* Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
*/
public void run() {
- boolean nfcOff;
- boolean bluetoothOff;
- boolean radioOff;
-
BroadcastReceiver br = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
// We don't allow apps to cancel this, so ignore the result.
@@ -324,89 +320,9 @@
} catch (RemoteException e) {
}
}
-
- final INfcAdapter nfc =
- INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc"));
- final ITelephony phone =
- ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- final IBluetooth bluetooth =
- IBluetooth.Stub.asInterface(ServiceManager.checkService(
- BluetoothAdapter.BLUETOOTH_SERVICE));
- final IMountService mount =
- IMountService.Stub.asInterface(
- ServiceManager.checkService("mount"));
- try {
- nfcOff = nfc == null ||
- nfc.getState() == NfcAdapter.STATE_OFF;
- if (!nfcOff) {
- Log.w(TAG, "Turning off NFC...");
- nfc.disable(false); // Don't persist new state
- }
- } catch (RemoteException ex) {
- Log.e(TAG, "RemoteException during NFC shutdown", ex);
- nfcOff = true;
- }
-
- try {
- bluetoothOff = bluetooth == null ||
- bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
- if (!bluetoothOff) {
- Log.w(TAG, "Disabling Bluetooth...");
- bluetooth.disable(false); // disable but don't persist new state
- }
- } catch (RemoteException ex) {
- Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
- bluetoothOff = true;
- }
-
- try {
- radioOff = phone == null || !phone.isRadioOn();
- if (!radioOff) {
- Log.w(TAG, "Turning off radio...");
- phone.setRadio(false);
- }
- } catch (RemoteException ex) {
- Log.e(TAG, "RemoteException during radio shutdown", ex);
- radioOff = true;
- }
-
- Log.i(TAG, "Waiting for NFC, Bluetooth and Radio...");
-
- // Wait a max of 32 seconds for clean shutdown
- for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
- if (!bluetoothOff) {
- try {
- bluetoothOff =
- bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
- } catch (RemoteException ex) {
- Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
- bluetoothOff = true;
- }
- }
- if (!radioOff) {
- try {
- radioOff = !phone.isRadioOn();
- } catch (RemoteException ex) {
- Log.e(TAG, "RemoteException during radio shutdown", ex);
- radioOff = true;
- }
- }
- if (!nfcOff) {
- try {
- nfcOff = nfc.getState() == NfcAdapter.STATE_OFF;
- } catch (RemoteException ex) {
- Log.e(TAG, "RemoteException during NFC shutdown", ex);
- nfcOff = true;
- }
- }
-
- if (radioOff && bluetoothOff && nfcOff) {
- Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
- break;
- }
- SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
- }
+ // Shutdown radios.
+ shutdownRadios(MAX_RADIO_WAIT_TIME);
// Shutdown MountService to ensure media is in a safe state
IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {
@@ -417,11 +333,14 @@
};
Log.i(TAG, "Shutting down MountService");
+
// Set initial variables and time out time.
mActionDone = false;
final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
synchronized (mActionDoneSync) {
try {
+ final IMountService mount = IMountService.Stub.asInterface(
+ ServiceManager.checkService("mount"));
if (mount != null) {
mount.shutdown(observer);
} else {
@@ -446,6 +365,118 @@
rebootOrShutdown(mReboot, mRebootReason);
}
+ private void shutdownRadios(int timeout) {
+ // If a radio is wedged, disabling it may hang so we do this work in another thread,
+ // just in case.
+ final long endTime = SystemClock.elapsedRealtime() + timeout;
+ final boolean[] done = new boolean[1];
+ Thread t = new Thread() {
+ public void run() {
+ boolean nfcOff;
+ boolean bluetoothOff;
+ boolean radioOff;
+
+ final INfcAdapter nfc =
+ INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc"));
+ final ITelephony phone =
+ ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+ final IBluetooth bluetooth =
+ IBluetooth.Stub.asInterface(ServiceManager.checkService(
+ BluetoothAdapter.BLUETOOTH_SERVICE));
+
+ try {
+ nfcOff = nfc == null ||
+ nfc.getState() == NfcAdapter.STATE_OFF;
+ if (!nfcOff) {
+ Log.w(TAG, "Turning off NFC...");
+ nfc.disable(false); // Don't persist new state
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during NFC shutdown", ex);
+ nfcOff = true;
+ }
+
+ try {
+ bluetoothOff = bluetooth == null ||
+ bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
+ if (!bluetoothOff) {
+ Log.w(TAG, "Disabling Bluetooth...");
+ bluetooth.disable(false); // disable but don't persist new state
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
+ bluetoothOff = true;
+ }
+
+ try {
+ radioOff = phone == null || !phone.isRadioOn();
+ if (!radioOff) {
+ Log.w(TAG, "Turning off radio...");
+ phone.setRadio(false);
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during radio shutdown", ex);
+ radioOff = true;
+ }
+
+ Log.i(TAG, "Waiting for NFC, Bluetooth and Radio...");
+
+ while (SystemClock.elapsedRealtime() < endTime) {
+ if (!bluetoothOff) {
+ try {
+ bluetoothOff =
+ bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
+ bluetoothOff = true;
+ }
+ if (bluetoothOff) {
+ Log.i(TAG, "Bluetooth turned off.");
+ }
+ }
+ if (!radioOff) {
+ try {
+ radioOff = !phone.isRadioOn();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during radio shutdown", ex);
+ radioOff = true;
+ }
+ if (radioOff) {
+ Log.i(TAG, "Radio turned off.");
+ }
+ }
+ if (!nfcOff) {
+ try {
+ nfcOff = nfc.getState() == NfcAdapter.STATE_OFF;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "RemoteException during NFC shutdown", ex);
+ nfcOff = true;
+ }
+ if (radioOff) {
+ Log.i(TAG, "NFC turned off.");
+ }
+ }
+
+ if (radioOff && bluetoothOff && nfcOff) {
+ Log.i(TAG, "NFC, Radio and Bluetooth shutdown complete.");
+ done[0] = true;
+ break;
+ }
+ SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
+ }
+ }
+ };
+
+ t.start();
+ try {
+ t.join(timeout);
+ } catch (InterruptedException ex) {
+ }
+ if (!done[0]) {
+ Log.w(TAG, "Timed out waiting for NFC, Radio and Bluetooth shutdown.");
+ }
+ }
+
/**
* Do not call this directly. Use {@link #reboot(Context, String, boolean)}
* or {@link #shutdown(Context, boolean)} instead.
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index c800182..806730c 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -897,7 +897,11 @@
break;
case WifiMonitor.P2P_DEVICE_LOST_EVENT:
WifiP2pDevice device = (WifiP2pDevice) message.obj;
- if (!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
+
+ // If we lose a device during an autonomous group creation,
+ // mSavedPeerConfig can be empty
+ if (mSavedPeerConfig != null &&
+ !mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
// Do the regular device lost handling
ret = NOT_HANDLED;
break;