Merge "Import translations. DO NOT MERGE"
diff --git a/Android.mk b/Android.mk
index bb65398..44ffc04 100644
--- a/Android.mk
+++ b/Android.mk
@@ -332,6 +332,7 @@
telecomm/java/com/android/internal/telecomm/ICallServiceLookupResponse.aidl \
telecomm/java/com/android/internal/telecomm/ICallServiceProvider.aidl \
telecomm/java/com/android/internal/telecomm/ICallVideoProvider.aidl \
+ telecomm/java/com/android/internal/telecomm/ICallVideoClient.aidl \
telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl \
telecomm/java/com/android/internal/telecomm/IInCallService.aidl \
telecomm/java/com/android/internal/telecomm/ITelecommService.aidl \
diff --git a/api/current.txt b/api/current.txt
index fbbae6c..009655c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21,6 +21,7 @@
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
+ field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
@@ -1310,6 +1311,7 @@
field public static final int viewportHeight = 16843805; // 0x101041d
field public static final int viewportWidth = 16843804; // 0x101041c
field public static final int visibility = 16842972; // 0x10100dc
+ field public static final int visibilityMode = 16843902; // 0x101047e
field public static final int visible = 16843156; // 0x1010194
field public static final int vmSafeMode = 16843448; // 0x10102b8
field public static final int voiceLanguage = 16843349; // 0x1010255
@@ -11583,7 +11585,7 @@
}
public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
- ctor public RippleDrawable(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ ctor public RippleDrawable(android.content.res.ColorStateList, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method public void setColor(android.content.res.ColorStateList);
}
@@ -12517,6 +12519,7 @@
field public static final int CONTROL_SCENE_MODE_DISABLED = 0; // 0x0
field public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1; // 0x1
field public static final int CONTROL_SCENE_MODE_FIREWORKS = 12; // 0xc
+ field public static final int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17; // 0x11
field public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4; // 0x4
field public static final int CONTROL_SCENE_MODE_NIGHT = 5; // 0x5
field public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6; // 0x6
@@ -22867,6 +22870,7 @@
field public static final java.lang.String CACHED_NUMBER_LABEL = "numberlabel";
field public static final java.lang.String CACHED_NUMBER_TYPE = "numbertype";
field public static final java.lang.String CACHED_PHOTO_ID = "photo_id";
+ field public static final java.lang.String SUBSCRIPTION_COMPONENT_NAME = "component_name";
field public static final android.net.Uri CONTENT_FILTER_URI;
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
@@ -22890,6 +22894,7 @@
field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
+ field public static final java.lang.String SUBSCRIPTION_ID = "subscription_id";
field public static final java.lang.String TYPE = "type";
field public static final int VOICEMAIL_TYPE = 4; // 0x4
field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
@@ -23195,6 +23200,7 @@
field public static final java.lang.String AUTHORITY = "com.android.contacts";
field public static final android.net.Uri AUTHORITY_URI;
field public static final java.lang.String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
+ field public static final java.lang.String DEFERRED_SNIPPETING = "deferred_snippeting";
field public static final java.lang.String DIRECTORY_PARAM_KEY = "directory";
field public static final java.lang.String LIMIT_PARAM_KEY = "limit";
field public static final java.lang.String PRIMARY_ACCOUNT_NAME = "name_for_primary_account";
@@ -23498,6 +23504,7 @@
method public static java.io.InputStream openContactPhotoInputStream(android.content.ContentResolver, android.net.Uri, boolean);
method public static java.io.InputStream openContactPhotoInputStream(android.content.ContentResolver, android.net.Uri);
field public static final android.net.Uri CONTENT_FILTER_URI;
+ field public static final android.net.Uri CONTENT_FREQUENT_URI;
field public static final android.net.Uri CONTENT_GROUP_URI;
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact";
field public static final android.net.Uri CONTENT_LOOKUP_URI;
@@ -23543,6 +23550,7 @@
field public static final java.lang.String IN_VISIBLE_GROUP = "in_visible_group";
field public static final java.lang.String IS_USER_PROFILE = "is_user_profile";
field public static final java.lang.String LOOKUP_KEY = "lookup";
+ field public static final java.lang.String NAME_RAW_CONTACT_ID = "name_raw_contact_id";
field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
field public static final java.lang.String PHOTO_ID = "photo_id";
field public static final java.lang.String PHOTO_THUMBNAIL_URI = "photo_thumb_uri";
@@ -23578,6 +23586,7 @@
field public static final java.lang.String IS_SUPER_PRIMARY = "is_super_primary";
field public static final java.lang.String MIMETYPE = "mimetype";
field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
+ field public static final java.lang.String RES_PACKAGE = "res_package";
field public static final java.lang.String SYNC1 = "data_sync1";
field public static final java.lang.String SYNC2 = "data_sync2";
field public static final java.lang.String SYNC3 = "data_sync3";
@@ -23681,11 +23690,13 @@
field public static final java.lang.String GROUP_IS_READ_ONLY = "group_is_read_only";
field public static final java.lang.String GROUP_VISIBLE = "group_visible";
field public static final java.lang.String NOTES = "notes";
+ field public static final java.lang.String RES_PACKAGE = "res_package";
field public static final java.lang.String SHOULD_SYNC = "should_sync";
field public static final java.lang.String SUMMARY_COUNT = "summ_count";
field public static final java.lang.String SUMMARY_WITH_PHONES = "summ_phones";
field public static final java.lang.String SYSTEM_ID = "system_id";
field public static final java.lang.String TITLE = "title";
+ field public static final java.lang.String TITLE_RES = "title_res";
}
public static final class ContactsContract.Intents {
@@ -23838,10 +23849,12 @@
}
protected static abstract interface ContactsContract.RawContactsColumns {
+ field public static final java.lang.String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set";
field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
field public static final java.lang.String CONTACT_ID = "contact_id";
field public static final java.lang.String DATA_SET = "data_set";
field public static final java.lang.String DELETED = "deleted";
+ field public static final java.lang.String NAME_VERIFIED = "name_verified";
field public static final java.lang.String RAW_CONTACT_IS_READ_ONLY = "raw_contact_is_read_only";
field public static final java.lang.String RAW_CONTACT_IS_USER_PROFILE = "raw_contact_is_user_profile";
}
@@ -23853,6 +23866,13 @@
field public static final android.net.Uri PROFILE_CONTENT_URI;
}
+ public static class ContactsContract.SearchSnippetColumns {
+ ctor public ContactsContract.SearchSnippetColumns();
+ field public static final java.lang.String DEFERRED_SNIPPETING_KEY = "deferred_snippeting";
+ field public static final java.lang.String SNIPPET = "snippet";
+ field public static final java.lang.String SNIPPET_ARGS_PARAM_KEY = "snippet_args";
+ }
+
public static final class ContactsContract.Settings implements android.provider.ContactsContract.SettingsColumns {
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/setting";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/setting";
@@ -27543,6 +27563,15 @@
field public final int supportedRouteMask;
}
+ public final class CallCameraCapabilities implements android.os.Parcelable {
+ ctor public CallCameraCapabilities(boolean, float);
+ method public int describeContents();
+ method public float getMaxZoom();
+ method public boolean isZoomSupported();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ }
+
public final class CallCapabilities {
method public static java.lang.String toString(int);
field public static final int ADD_CALL = 16; // 0x10
@@ -27567,6 +27596,7 @@
method public java.lang.String getId();
method public android.net.Uri getOriginalHandle();
method public android.telecomm.CallState getState();
+ method public android.telecomm.Subscription getSubscription();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
@@ -27611,6 +27641,7 @@
method public void notifyIncomingCall(android.telecomm.CallInfo);
method public void onPostDialWait(java.lang.String, java.lang.String);
method public void setActive(java.lang.String);
+ method public void setCallVideoProvider(java.lang.String, android.telecomm.CallVideoProvider);
method public void setDialing(java.lang.String);
method public void setDisconnected(java.lang.String, int, java.lang.String);
method public void setOnHold(java.lang.String);
@@ -27660,16 +27691,43 @@
enum_constant public static final android.telecomm.CallState RINGING;
}
+ public abstract class CallVideoClient {
+ ctor protected CallVideoClient();
+ method public abstract void onCallSessionEvent(int);
+ method public abstract void onCameraCapabilitiesChange(android.telecomm.CallCameraCapabilities);
+ method public abstract void onReceiveSessionModifyRequest(android.telecomm.VideoCallProfile);
+ method public abstract void onReceiveSessionModifyResponse(int, android.telecomm.VideoCallProfile, android.telecomm.VideoCallProfile);
+ method public abstract void onUpdateCallDataUsage(int);
+ method public abstract void onUpdatedPeerDimensions(int, int);
+ field public static final int SESSION_EVENT_RX_PAUSE = 1; // 0x1
+ field public static final int SESSION_EVENT_RX_RESUME = 2; // 0x2
+ field public static final int SESSION_EVENT_TX_START = 3; // 0x3
+ field public static final int SESSION_EVENT_TX_STOP = 4; // 0x4
+ field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2
+ field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3
+ field public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; // 0x1
+ }
+
+ public abstract class CallVideoProvider {
+ ctor protected CallVideoProvider();
+ method public abstract void setCamera(java.lang.String);
+ }
+
+ public class CallVideoProviderWrapper implements android.os.IBinder.DeathRecipient {
+ method public void binderDied();
+ method public void setCamera(java.lang.String) throws android.os.RemoteException;
+ }
+
public abstract class Connection {
ctor protected Connection();
- method public final void conference();
method public final android.telecomm.CallAudioState getCallAudioState();
- method public java.util.List<android.telecomm.Connection> getChildConnections();
+ method public final java.util.List<android.telecomm.Connection> getChildConnections();
method public final android.net.Uri getHandle();
- method public android.telecomm.Connection getParentConnection();
- method public boolean isConferenceCapable();
- method public boolean isConferenceConnection();
- method public boolean isRequestingRingback();
+ method public final android.telecomm.Connection getParentConnection();
+ method public final int getState();
+ method public final boolean isConferenceCapable();
+ method public final boolean isConferenceConnection();
+ method public final boolean isRequestingRingback();
method protected void onAbort();
method protected void onAnswer();
method protected void onChildrenChanged(java.util.List<android.telecomm.Connection>);
@@ -27681,21 +27739,21 @@
method protected void onReject();
method protected void onSeparate();
method protected void onSetAudioState(android.telecomm.CallAudioState);
- method protected void onSetSignal(android.os.Bundle);
method protected void onSetState(int);
method protected void onStopDtmfTone();
method protected void onUnhold();
- method protected void setActive();
- method public void setAudioState(android.telecomm.CallAudioState);
- method protected void setDestroyed();
- method protected void setDialing();
- method protected void setDisconnected(int, java.lang.String);
- method protected void setHandle(android.net.Uri);
- method protected void setIsConferenceCapable(boolean);
- method protected void setOnHold();
- method public void setParentConnection(android.telecomm.Connection);
- method protected void setRequestingRingback(boolean);
- method protected void setRinging();
+ method public final void setActive();
+ method public final void setCallVideoProvider(android.telecomm.CallVideoProvider);
+ method public final void setDestroyed();
+ method public final void setDialing();
+ method public final void setDisconnected(int, java.lang.String);
+ method public final void setHandle(android.net.Uri);
+ method public final void setIsConferenceCapable(boolean);
+ method public final void setOnHold();
+ method public final void setParentConnection(android.telecomm.Connection);
+ method public final void setRequestingRingback(boolean);
+ method public final void setRinging();
+ method public final void setSignal(android.os.Bundle);
method public static java.lang.String stateToString(int);
}
@@ -27707,6 +27765,7 @@
method public abstract void onHandleChanged(android.telecomm.Connection, android.net.Uri);
method public abstract void onParentConnectionChanged(android.telecomm.Connection, android.telecomm.Connection);
method public abstract void onRequestingRingback(android.telecomm.Connection, boolean);
+ method public abstract void onSetCallVideoProvider(android.telecomm.Connection, android.telecomm.CallVideoProvider);
method public abstract void onSignalChanged(android.telecomm.Connection, android.os.Bundle);
method public abstract void onStateChanged(android.telecomm.Connection, int);
}
@@ -27720,6 +27779,7 @@
method public void onHandleChanged(android.telecomm.Connection, android.net.Uri);
method public void onParentConnectionChanged(android.telecomm.Connection, android.telecomm.Connection);
method public void onRequestingRingback(android.telecomm.Connection, boolean);
+ method public void onSetCallVideoProvider(android.telecomm.Connection, android.telecomm.CallVideoProvider);
method public void onSignalChanged(android.telecomm.Connection, android.os.Bundle);
method public void onStateChanged(android.telecomm.Connection, int);
}
@@ -27815,6 +27875,7 @@
method public android.telecomm.CallServiceDescriptor getHandoffCallServiceDescriptor();
method public java.lang.String getId();
method public android.telecomm.CallState getState();
+ method public android.telecomm.Subscription getSubscription();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
@@ -27905,6 +27966,24 @@
public class TelecommManager {
}
+ public class VideoCallProfile implements android.os.Parcelable {
+ ctor public VideoCallProfile(int, int);
+ method public int describeContents();
+ method public int getQuality();
+ method public int getVideoState();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int QUALITY_DEFAULT = 4; // 0x4
+ field public static final int QUALITY_HIGH = 1; // 0x1
+ field public static final int QUALITY_LOW = 3; // 0x3
+ field public static final int QUALITY_MEDIUM = 2; // 0x2
+ field public static final int VIDEO_STATE_AUDIO_ONLY = 0; // 0x0
+ field public static final int VIDEO_STATE_BIDIRECTIONAL = 3; // 0x3
+ field public static final int VIDEO_STATE_PAUSED = 4; // 0x4
+ field public static final int VIDEO_STATE_RX_ENABLED = 2; // 0x2
+ field public static final int VIDEO_STATE_TX_ENABLED = 1; // 0x1
+ }
+
}
package android.telephony {
@@ -30520,6 +30599,12 @@
method public void captureStartValues(android.transition.TransitionValues);
}
+ public class ChangeImageTransform extends android.transition.Transition {
+ ctor public ChangeImageTransform();
+ method public void captureEndValues(android.transition.TransitionValues);
+ method public void captureStartValues(android.transition.TransitionValues);
+ }
+
public class ChangeTransform extends android.transition.Transition {
ctor public ChangeTransform();
method public void captureEndValues(android.transition.TransitionValues);
@@ -30543,12 +30628,6 @@
field public static final int OUT = 2; // 0x2
}
- public class MoveImage extends android.transition.Transition {
- ctor public MoveImage();
- method public void captureEndValues(android.transition.TransitionValues);
- method public void captureStartValues(android.transition.TransitionValues);
- }
-
public final class Scene {
ctor public Scene(android.view.ViewGroup);
ctor public Scene(android.view.ViewGroup, android.view.View);
@@ -30687,6 +30766,9 @@
method public android.animation.Animator onAppear(android.view.ViewGroup, android.view.View, android.transition.TransitionValues, android.transition.TransitionValues);
method public android.animation.Animator onDisappear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
method public android.animation.Animator onDisappear(android.view.ViewGroup, android.view.View, android.transition.TransitionValues, android.transition.TransitionValues);
+ method public void setMode(int);
+ field public static final int IN = 1; // 0x1
+ field public static final int OUT = 2; // 0x2
}
public abstract class VisibilityPropagation extends android.transition.TransitionPropagation {
@@ -34840,7 +34922,7 @@
ctor public CursorAnchorInfo(android.os.Parcel);
method public int describeContents();
method public android.graphics.RectF getCharacterRect(int);
- method public java.lang.String getComposingText();
+ method public java.lang.CharSequence getComposingText();
method public int getComposingTextStart();
method public float getInsertionMarkerBaseline();
method public float getInsertionMarkerBottom();
@@ -35267,6 +35349,7 @@
public class CookieManager {
method public synchronized boolean acceptCookie();
+ method public synchronized boolean acceptThirdPartyCookies(android.webkit.WebView);
method public static boolean allowFileSchemeCookies();
method public java.lang.String getCookie(java.lang.String);
method public static synchronized android.webkit.CookieManager getInstance();
@@ -35278,6 +35361,7 @@
method public void removeSessionCookies(android.webkit.ValueCallback<java.lang.Boolean>);
method public synchronized void setAcceptCookie(boolean);
method public static void setAcceptFileSchemeCookies(boolean);
+ method public synchronized void setAcceptThirdPartyCookies(android.webkit.WebView, boolean);
method public void setCookie(java.lang.String, java.lang.String);
method public void setCookie(java.lang.String, java.lang.String, android.webkit.ValueCallback<java.lang.Boolean>);
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9e84df99..228d82e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3666,11 +3666,7 @@
* @see #startActivity
*/
public void startActivityForResult(Intent intent, int requestCode) {
- Bundle options = null;
- if (mWindow.hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
- options = ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
- }
- startActivityForResult(intent, requestCode, options);
+ startActivityForResult(intent, requestCode, null);
}
/**
@@ -4221,11 +4217,7 @@
*/
public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
int requestCode) {
- Bundle options = null;
- if (mWindow.hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
- options = ActivityOptions.makeSceneTransitionAnimation(this).toBundle();
- }
- startActivityFromFragment(fragment, intent, requestCode, options);
+ startActivityFromFragment(fragment, intent, requestCode, null);
}
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 88746bf4..87140a3 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -538,6 +538,30 @@
}
/**
+ * Sets the label for this task description.
+ * @hide
+ */
+ public void setLabel(String label) {
+ mLabel = label;
+ }
+
+ /**
+ * Sets the primary color for this task description.
+ * @hide
+ */
+ public void setPrimaryColor(int primaryColor) {
+ mColorPrimary = primaryColor;
+ }
+
+ /**
+ * Sets the icon for this task description.
+ * @hide
+ */
+ public void setIcon(Bitmap icon) {
+ mIcon = icon;
+ }
+
+ /**
* @return The label and description of the current state of this task.
*/
public String getLabel() {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 8ecd608..79dc6a8 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -218,17 +218,20 @@
if (getViewsTransition() != null) {
getDecor().captureTransitioningViews(mTransitioningViews);
mTransitioningViews.removeAll(mSharedElements);
- Rect r = new Rect();
- for (int i = mTransitioningViews.size() - 1; i >= 0; i--) {
- View view = mTransitioningViews.get(i);
- if (!view.getGlobalVisibleRect(r)) {
- mTransitioningViews.remove(i);
- }
- }
}
setEpicenter();
}
+ protected void stripOffscreenViews() {
+ Rect r = new Rect();
+ for (int i = mTransitioningViews.size() - 1; i >= 0; i--) {
+ View view = mTransitioningViews.get(i);
+ if (!view.getGlobalVisibleRect(r)) {
+ mTransitioningViews.remove(i);
+ }
+ }
+ }
+
protected Window getWindow() {
return mWindow;
}
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 389f42c..6c71bb1 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -286,6 +286,13 @@
mResultReceiver = null; // all done sending messages.
}
+ @Override
+ protected void stripOffscreenViews() {
+ setViewVisibility(mTransitioningViews, View.VISIBLE);
+ super.stripOffscreenViews();
+ setViewVisibility(mTransitioningViews, View.INVISIBLE);
+ }
+
private void onTakeSharedElements() {
if (!mIsReadyForTransition || mSharedElementsBundle == null) {
return;
@@ -325,7 +332,10 @@
Transition viewsTransition = null;
if (startEnterTransition && !mTransitioningViews.isEmpty()) {
viewsTransition = configureTransition(getViewsTransition());
- viewsTransition = addTargets(viewsTransition, mTransitioningViews);
+ if (viewsTransition != null) {
+ stripOffscreenViews();
+ viewsTransition = addTargets(viewsTransition, mTransitioningViews);
+ }
}
Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 18a9468..e38f527 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -72,6 +72,7 @@
super(activity.getWindow(), names, getListener(activity, isReturning),
isReturning);
viewsReady(mapSharedElements(accepted, mapped));
+ stripOffscreenViews();
mIsBackgroundReady = !isReturning;
mActivity = activity;
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ba42f51b..2287246 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2079,12 +2079,15 @@
public void onMultiAdvertiseCallback(int status) {
// no op
}
- /**
- * Callback reporting LE ATT MTU.
- * @hide
- */
+
+ @Override
public void onConfigureMTU(String address, int mtu, int status) {
// no op
}
+
+ @Override
+ public void onConnectionCongested(String address, boolean congested) {
+ // no op
+ }
}
}
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 7b5bfbd..6c1a45e 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -85,6 +85,11 @@
/** A write operation exceeds the maximum length of the attribute */
public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 0xd;
+ /** A remote device connection is congested.
+ * @hide
+ */
+ public static final int GATT_CONNECTION_CONGESTED = 0x8f;
+
/** A GATT operation failed, errors other than the above */
public static final int GATT_FAILURE = 0x101;
@@ -607,6 +612,21 @@
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
+
+ /**
+ * Callback indicating the remote device connection is congested.
+ * @hide
+ */
+ public void onConnectionCongested(String address, boolean congested) {
+ if (DBG) Log.d(TAG, "onConnectionCongested() - Device=" + address
+ + " congested=" + congested);
+ if (!address.equals(mDevice.getAddress())) return;
+ try {
+ mCallback.onConnectionCongested(BluetoothGatt.this, congested);
+ } catch (Exception ex) {
+ Log.w(TAG, "Unhandled exception in callback", ex);
+ }
+ }
};
/*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device,
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 5180259..b5e60f2 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -153,4 +153,19 @@
*/
public void onConfigureMTU(BluetoothGatt gatt, int mtu, int status) {
}
+
+ /**
+ * Callback indicating that a remote device connection congestestion status has changed.
+ *
+ * An application should refrain from sending additional data to a remote device when
+ * a callback is received with the congested flag set to true. Once the congestion status
+ * is cleared up, the application will receive an additional callback with the congested
+ * flag set to false.
+ *
+ * @param gatt The GATT client associated with the remote device
+ * @param congested true, if the connection is currently congested
+ * @hide
+ */
+ public void onConnectionCongested(BluetoothGatt gatt, boolean congested) {
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 34e8605..2e993c9d 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -265,6 +265,42 @@
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
+
+ /**
+ * A notification/indication has been sent.
+ * @hide
+ */
+ public void onNotificationSent(String address, int status) {
+ if (DBG) Log.d(TAG, "onNotificationSent() - "
+ + "device=" + address + ", status=" + status);
+
+ BluetoothDevice device = mAdapter.getRemoteDevice(address);
+ if (device == null) return;
+
+ try {
+ mCallback.onNotificationSent(device, status);
+ } catch (Exception ex) {
+ Log.w(TAG, "Unhandled exception: " + ex);
+ }
+ }
+
+ /**
+ * Callback indicating the remote device connection is congested.
+ * @hide
+ */
+ public void onConnectionCongested(String address, boolean congested) {
+ if (DBG) Log.d(TAG, "onConnectionCongested() - Device=" + address
+ + " congested=" + congested);
+
+ BluetoothDevice device = mAdapter.getRemoteDevice(address);
+ if (device == null) return;
+
+ try {
+ mCallback.onConnectionCongested(device, congested);
+ } catch (Exception ex) {
+ Log.w(TAG, "Unhandled exception in callback", ex);
+ }
+ }
};
/**
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index fc3ffe8..4fbeb46 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -131,4 +131,34 @@
*/
public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
}
+
+ /**
+ * Callback invoked when a notification or indication has been sent to
+ * a remote device.
+ *
+ * <p>When multiple notifications are to be sent, an application must
+ * wait for this callback to be received before sending additional
+ * notifications.
+ *
+ * @param device The remote device the notification has been sent to
+ * @param status 0 if the operation was successful
+ * @hide
+ */
+ public void onNotificationSent(BluetoothDevice device, int status) {
+ }
+
+ /**
+ * Callback indicating that a remote device connection congestestion status has changed.
+ *
+ * An application should refrain from sending additional data (notifications, indications
+ * etc.) to a remote device when a callback is received with the congested flag set
+ * to true. Once the congestion status is cleared up, the application will receive an
+ * additional callback with the congested flag set to false.
+ *
+ * @param device The remote device that triggered the congestion state change
+ * @param congested true, if the connection is currently congested
+ * @hide
+ */
+ public void onConnectionCongested(BluetoothDevice device, boolean congested) {
+ }
}
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index 2d8eed4..946a6f6 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -66,4 +66,5 @@
void onAdvertiseStateChange(in int advertiseState, in int status);
void onMultiAdvertiseCallback(in int status);
void onConfigureMTU(in String address, in int mtu, in int status);
+ void onConnectionCongested(in String address, in boolean congested);
}
diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
index ae9bffc..6e31da1 100644
--- a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
@@ -22,7 +22,7 @@
* Callback definitions for interacting with BLE / GATT
* @hide
*/
-interface IBluetoothGattServerCallback {
+oneway interface IBluetoothGattServerCallback {
void onServerRegistered(in int status, in int serverIf);
void onScanResult(in String address, in int rssi, in byte[] advData);
void onServerConnectionState(in int status, in int serverIf,
@@ -58,4 +58,6 @@
in ParcelUuid descrId,
in byte[] value);
void onExecuteWrite(in String address, in int transId, in boolean execWrite);
+ void onNotificationSent(in String address, in int status);
+ void onConnectionCongested(in String address, in boolean congested);
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index ed43407..c20b81b 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -355,6 +355,11 @@
public void onConfigureMTU(String address, int mtu, int status) {
// no op
}
+
+ @Override
+ public void onConnectionCongested(String address, boolean congested) {
+ // no op
+ }
}
private void postCallbackFailure(final AdvertiseCallback callback, final int error) {
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 4c6346c..fbaf5d2 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -358,6 +358,11 @@
public void onConfigureMTU(String address, int mtu, int status) {
// no op
}
+
+ @Override
+ public void onConnectionCongested(String address, boolean congested) {
+ // no op
+ }
}
private void postCallbackError(final ScanCallback callback, final int errorCode) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index ef8c67b..14e6f92 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -466,6 +466,34 @@
new Key<Integer>("android.control.maxRegionsAf", int.class);
/**
+ * <p>List of available high speed video size and fps range configurations
+ * supported by the camera device, in the format of (width, height, fps_min, fps_max).</p>
+ * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes},
+ * this metadata will list the supported high speed video size and fps range
+ * configurations. All the sizes listed in this configuration will be a subset
+ * of the sizes reported by StreamConfigurationMap#getOutputSizes for processed
+ * non-stalling formats.</p>
+ * <p>For the high speed video use case, where the application will set
+ * {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the application must
+ * select the video size and fps range from this metadata to configure the recording and
+ * preview streams and setup the recording requests. For example, if the application intends
+ * to do high speed recording, it can select the maximum size reported by this metadata to
+ * configure output streams. Once the size is selected, application can filter this metadata
+ * by selected size and get the supported fps ranges, and use these fps ranges to setup the
+ * recording requests.</p>
+ * <p>For normal video recording use case, where some application will NOT set
+ * {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the fps ranges
+ * reported in this metadata must not be used to setup capture requests, or it will cause
+ * request error.</p>
+ *
+ * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
+ * @see CaptureRequest#CONTROL_SCENE_MODE
+ * @hide
+ */
+ public static final Key<int[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS =
+ new Key<int[]>("android.control.availableHighSpeedVideoConfigurations", int[].class);
+
+ /**
* <p>The set of edge enhancement modes supported by this camera device.</p>
* <p>This tag lists the valid modes for {@link CaptureRequest#EDGE_MODE android.edge.mode}.</p>
* <p>Full-capability camera devices must always support OFF and FAST.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 889b127..e464f2a 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1393,6 +1393,84 @@
*/
public static final int CONTROL_SCENE_MODE_BARCODE = 16;
+ /**
+ * <p>Optimized for high speed video recording (frame rate >=60fps) use case.</p>
+ * <p>The supported high speed video sizes and fps ranges are specified in
+ * android.control.availableHighSpeedVideoConfigurations. To get desired
+ * output frame rates, the application is only allowed to select video size
+ * and fps range combinations listed in this static metadata. The fps range
+ * can be control via {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange}.</p>
+ * <p>In this mode, the camera device will override aeMode, awbMode, and afMode to
+ * ON, ON, and CONTINUOUS_VIDEO, respectively. All post-processing block mode
+ * controls will be overridden to be FAST. Therefore, no manual control of capture
+ * and post-processing parameters is possible. All other controls operate the
+ * same as when {@link CaptureRequest#CONTROL_MODE android.control.mode} == AUTO. This means that all other
+ * android.control.* fields continue to work, such as</p>
+ * <ul>
+ * <li>{@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange}</li>
+ * <li>{@link CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION android.control.aeExposureCompensation}</li>
+ * <li>{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock}</li>
+ * <li>{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock}</li>
+ * <li>{@link CaptureRequest#CONTROL_EFFECT_MODE android.control.effectMode}</li>
+ * <li>{@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}</li>
+ * <li>{@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}</li>
+ * <li>{@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}</li>
+ * <li>{@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}</li>
+ * <li>{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}</li>
+ * </ul>
+ * <p>Outside of android.control.*, the following controls will work:</p>
+ * <ul>
+ * <li>{@link CaptureRequest#FLASH_MODE android.flash.mode} (automatic flash for still capture will not work since aeMode is ON)</li>
+ * <li>{@link CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE android.lens.opticalStabilizationMode} (if it is supported)</li>
+ * <li>{@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}</li>
+ * <li>{@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode}</li>
+ * </ul>
+ * <p>For high speed recording use case, the actual maximum supported frame rate may
+ * be lower than what camera can output, depending on the destination Surfaces for
+ * the image data. For example, if the destination surface is from video encoder,
+ * the application need check if the video encoder is capable of supporting the
+ * high frame rate for a given video size, or it will end up with lower recording
+ * frame rate. If the destination surface is from preview window, the preview frame
+ * rate will be bounded by the screen refresh rate.</p>
+ * <p>The camera device will only support up to 2 output high speed streams
+ * (processed non-stalling format defined in android.request.maxNumOutputStreams)
+ * in this mode. This control will be effective only if all of below conditions are true:</p>
+ * <ul>
+ * <li>The application created no more than maxNumHighSpeedStreams processed non-stalling
+ * format output streams, where maxNumHighSpeedStreams is calculated as
+ * min(2, android.request.maxNumOutputStreams[Processed (but not-stalling)]).</li>
+ * <li>The stream sizes are selected from the sizes reported by
+ * android.control.availableHighSpeedVideoConfigurations.</li>
+ * <li>No processed non-stalling or raw streams are configured.</li>
+ * </ul>
+ * <p>When above conditions are NOT satistied, the controls of this mode and
+ * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange} will be ignored by the camera device,
+ * the camera device will fall back to {@link CaptureRequest#CONTROL_MODE android.control.mode} <code>==</code> AUTO,
+ * and the returned capture result metadata will give the fps range choosen
+ * by the camera device.</p>
+ * <p>Switching into or out of this mode may trigger some camera ISP/sensor
+ * reconfigurations, which may introduce extra latency. It is recommended that
+ * the application avoids unnecessary scene mode switch as much as possible.</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION
+ * @see CaptureRequest#CONTROL_AE_LOCK
+ * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+ * @see CaptureRequest#CONTROL_AE_REGIONS
+ * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE
+ * @see CaptureRequest#CONTROL_AF_REGIONS
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
+ * @see CaptureRequest#CONTROL_AWB_LOCK
+ * @see CaptureRequest#CONTROL_AWB_REGIONS
+ * @see CaptureRequest#CONTROL_EFFECT_MODE
+ * @see CaptureRequest#CONTROL_MODE
+ * @see CaptureRequest#FLASH_MODE
+ * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
+ * @see CaptureRequest#SCALER_CROP_REGION
+ * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
+ * @see CaptureRequest#CONTROL_SCENE_MODE
+ */
+ public static final int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17;
+
//
// Enumeration values for CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 5bc59dc..91ff7fa 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1011,6 +1011,7 @@
* @see #CONTROL_SCENE_MODE_PARTY
* @see #CONTROL_SCENE_MODE_CANDLELIGHT
* @see #CONTROL_SCENE_MODE_BARCODE
+ * @see #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO
*/
public static final Key<Integer> CONTROL_SCENE_MODE =
new Key<Integer>("android.control.sceneMode", int.class);
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 9097220..be2d960 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1581,6 +1581,7 @@
* @see #CONTROL_SCENE_MODE_PARTY
* @see #CONTROL_SCENE_MODE_CANDLELIGHT
* @see #CONTROL_SCENE_MODE_BARCODE
+ * @see #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO
*/
public static final Key<Integer> CONTROL_SCENE_MODE =
new Key<Integer>("android.control.sceneMode", int.class);
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index 1646120..4797e20 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -346,6 +346,14 @@
}
private static void mapControlOther(CameraMetadataNative m, Camera.Parameters p) {
+ /*
+ * android.control.maxRegions
+ */
+ int[] maxRegions = new int[3];
+ maxRegions[0] = p.getMaxNumMeteringAreas();
+ maxRegions[1] = 0; // AWB regions not supported in API1
+ maxRegions[2] = p.getMaxNumFocusAreas();
+ m.set(CONTROL_MAX_REGIONS, maxRegions);
// TODO
}
diff --git a/core/java/android/hardware/hdmi/HdmiCec.java b/core/java/android/hardware/hdmi/HdmiCec.java
index d86dd5e7..c87b674 100644
--- a/core/java/android/hardware/hdmi/HdmiCec.java
+++ b/core/java/android/hardware/hdmi/HdmiCec.java
@@ -101,6 +101,9 @@
/** Logical address used to indicate it is not initialized or invalid. */
public static final int ADDR_INVALID = -1;
+ /** Logical address used to indicate the source comes from internal device. */
+ public static final int ADDR_INTERNAL = 0xFFFF;
+
// TODO: Complete the list of CEC messages definition.
public static final int MESSAGE_FEATURE_ABORT = 0x00;
public static final int MESSAGE_IMAGE_VIEW_ON = 0x04;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index b68ce36..396efff 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2372,12 +2372,10 @@
*/
public static boolean setProcessDefaultNetwork(Network network) {
if (network == null) {
- NetworkUtils.unbindProcessToNetwork();
+ return NetworkUtils.unbindProcessToNetwork();
} else {
- NetworkUtils.bindProcessToNetwork(network.netId);
+ return NetworkUtils.bindProcessToNetwork(network.netId);
}
- // TODO fix return value
- return true;
}
/**
@@ -2404,11 +2402,9 @@
*/
public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
if (network == null) {
- NetworkUtils.unbindProcessToNetworkForHostResolution();
+ return NetworkUtils.unbindProcessToNetworkForHostResolution();
} else {
- NetworkUtils.bindProcessToNetworkForHostResolution(network.netId);
+ return NetworkUtils.bindProcessToNetworkForHostResolution(network.netId);
}
- // TODO hook up the return value.
- return true;
}
}
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 0a422c6..9a22d78 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -24,6 +24,7 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.SocketException;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
@@ -148,7 +149,9 @@
// Query a property of the underlying socket to ensure the underlying
// socket exists so a file descriptor is available to bind to a network.
socket.getReuseAddress();
- NetworkUtils.bindSocketToNetwork(socket.getFileDescriptor$().getInt$(), mNetId);
+ if (!NetworkUtils.bindSocketToNetwork(socket.getFileDescriptor$().getInt$(), mNetId)) {
+ throw new SocketException("Failed to bind socket to network.");
+ }
return socket;
}
}
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 352512e..1a9a6378 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -20,6 +20,7 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.content.Intent;
+import android.net.NetworkScorerAppManager.NetworkScorerAppData;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -38,7 +39,9 @@
* <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
* <li>Includes a receiver for {@link #ACTION_SCORE_NETWORKS} guarded by the
* {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission which scores networks
- * and (eventually) calls {@link #updateScores} with the results.
+ * and (eventually) calls {@link #updateScores} with the results. If this receiver specifies an
+ * android:label attribute, this label will be used when referring to the application throughout
+ * system settings; otherwise, the application label will be used.
* </ul>
*
* <p>The system keeps track of an active scorer application; at any time, only this application
@@ -105,7 +108,11 @@
* scorer.
*/
public String getActiveScorerPackage() {
- return NetworkScorerAppManager.getActiveScorer(mContext);
+ NetworkScorerAppData app = NetworkScorerAppManager.getActiveScorer(mContext);
+ if (app == null) {
+ return null;
+ }
+ return app.mPackageName;
}
/**
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 3660e7a..7c61710 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -24,7 +24,6 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.provider.Settings;
-import android.provider.Settings.Global;
import android.text.TextUtils;
import android.util.Log;
@@ -35,6 +34,8 @@
/**
* Internal class for managing the primary network scorer application.
*
+ * TODO: Rename this to something more generic.
+ *
* @hide
*/
public final class NetworkScorerAppManager {
@@ -46,8 +47,21 @@
/** This class cannot be instantiated. */
private NetworkScorerAppManager() {}
+ public static class NetworkScorerAppData {
+ /** Package name of this scorer app. */
+ public final String mPackageName;
+
+ /** Name of this scorer app for display. */
+ public final CharSequence mScorerName;
+
+ public NetworkScorerAppData(String packageName, CharSequence scorerName) {
+ mScorerName = scorerName;
+ mPackageName = packageName;
+ }
+ }
+
/**
- * Returns the list of available scorer app package names.
+ * Returns the list of available scorer apps.
*
* <p>A network scorer is any application which:
* <ul>
@@ -58,8 +72,8 @@
*
* @return the list of scorers, or the empty list if there are no valid scorers.
*/
- public static Collection<String> getAllValidScorers(Context context) {
- List<String> scorers = new ArrayList<>();
+ public static Collection<NetworkScorerAppData> getAllValidScorers(Context context) {
+ List<NetworkScorerAppData> scorers = new ArrayList<>();
PackageManager pm = context.getPackageManager();
List<ResolveInfo> receivers = pm.queryBroadcastReceivers(SCORE_INTENT, 0 /* flags */);
@@ -81,33 +95,32 @@
// approved it as a network scorer.
continue;
}
- scorers.add(receiverInfo.packageName);
+ // NOTE: loadLabel will attempt to load the receiver's label and fall back to the app
+ // label if none is present.
+ scorers.add(new NetworkScorerAppData(
+ receiverInfo.packageName, receiverInfo.loadLabel(pm)));
}
return scorers;
}
/**
- * Get the application package name to use for scoring networks.
+ * Get the application to use for scoring networks.
*
- * @return the scorer package or null if scoring is disabled (including if no scorer was ever
+ * @return the scorer app info or null if scoring is disabled (including if no scorer was ever
* selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because
* it was disabled or uninstalled).
*/
- public static String getActiveScorer(Context context) {
+ public static NetworkScorerAppData getActiveScorer(Context context) {
String scorerPackage = Settings.Global.getString(context.getContentResolver(),
- Global.NETWORK_SCORER_APP);
- if (isPackageValidScorer(context, scorerPackage)) {
- return scorerPackage;
- } else {
- return null;
- }
+ Settings.Global.NETWORK_SCORER_APP);
+ return getScorer(context, scorerPackage);
}
/**
* Set the specified package as the default scorer application.
*
- * <p>The caller must have permission to write to {@link Settings.Global}.
+ * <p>The caller must have permission to write to {@link android.provider.Settings.Global}.
*
* @param context the context of the calling application
* @param packageName the packageName of the new scorer to use. If null, scoring will be
@@ -125,12 +138,12 @@
Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName);
if (packageName == null) {
- Settings.Global.putString(context.getContentResolver(), Global.NETWORK_SCORER_APP,
- null);
+ Settings.Global.putString(context.getContentResolver(),
+ Settings.Global.NETWORK_SCORER_APP, null);
return true;
} else {
// We only make the change if the new package is valid.
- if (isPackageValidScorer(context, packageName)) {
+ if (getScorer(context, packageName) != null) {
Settings.Global.putString(context.getContentResolver(),
Settings.Global.NETWORK_SCORER_APP, packageName);
return true;
@@ -143,22 +156,30 @@
/** Determine whether the application with the given UID is the enabled scorer. */
public static boolean isCallerActiveScorer(Context context, int callingUid) {
- String defaultApp = getActiveScorer(context);
+ NetworkScorerAppData defaultApp = getActiveScorer(context);
if (defaultApp == null) {
return false;
}
AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
try {
- appOpsMgr.checkPackage(callingUid, defaultApp);
+ appOpsMgr.checkPackage(callingUid, defaultApp.mPackageName);
return true;
} catch (SecurityException e) {
return false;
}
}
- /** Returns true if the given package is a valid scorer. */
- public static boolean isPackageValidScorer(Context context, String packageName) {
- Collection<String> applications = getAllValidScorers(context);
- return packageName != null && applications.contains(packageName);
+ /** Returns the {@link NetworkScorerAppData} for the given app, or null if it's not a scorer. */
+ public static NetworkScorerAppData getScorer(Context context, String packageName) {
+ if (TextUtils.isEmpty(packageName)) {
+ return null;
+ }
+ Collection<NetworkScorerAppData> applications = getAllValidScorers(context);
+ for (NetworkScorerAppData app : applications) {
+ if (packageName.equals(app.mPackageName)) {
+ return app;
+ }
+ }
+ return null;
}
}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 15c0a71..c4b17b6 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -118,13 +118,13 @@
* is by design so an application doesn't accidentally use sockets it thinks are still bound to
* a particular {@code Network}.
*/
- public native static void bindProcessToNetwork(int netId);
+ public native static boolean bindProcessToNetwork(int netId);
/**
* Clear any process specific {@code Network} binding. This reverts a call to
* {@link #bindProcessToNetwork}.
*/
- public native static void unbindProcessToNetwork();
+ public native static boolean unbindProcessToNetwork();
/**
* Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
@@ -138,7 +138,7 @@
*
* @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
*/
- public native static void bindProcessToNetworkForHostResolution(int netId);
+ public native static boolean bindProcessToNetworkForHostResolution(int netId);
/**
* Clears any process specific {@link Network} binding for host resolution. This does
@@ -146,13 +146,13 @@
*
* @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
*/
- public native static void unbindProcessToNetworkForHostResolution();
+ public native static boolean unbindProcessToNetworkForHostResolution();
/**
* Explicitly binds {@code socketfd} to the network designated by {@code netId}. This
* overrides any binding via {@link #bindProcessToNetwork}.
*/
- public native static void bindSocketToNetwork(int socketfd, int netId);
+ public native static boolean bindSocketToNetwork(int socketfd, int netId);
/**
* Convert a IPv4 address from an integer to an InetAddress.
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 3b0d7ff..8eefd9ce9 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -25,6 +25,7 @@
import android.provider.ContactsContract.CommonDataKinds.Callable;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.DataUsageFeedback;
+import android.telecomm.Subscription;
import android.text.TextUtils;
import com.android.internal.telephony.CallerInfo;
@@ -276,6 +277,18 @@
public static final String CACHED_FORMATTED_NUMBER = "formatted_number";
/**
+ * The component name of the subscription in string form.
+ * <P>Type: TEXT</P>
+ */
+ public static final String SUBSCRIPTION_COMPONENT_NAME = "subscription_component_name";
+
+ /**
+ * The identifier of a subscription that is unique to a specified component.
+ * <P>Type: TEXT</P>
+ */
+ public static final String SUBSCRIPTION_ID = "subscription_id";
+
+ /**
* Adds a call to the call log.
*
* @param ci the CallerInfo object to get the target contact from. Can be null
@@ -286,13 +299,14 @@
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
* @param callType enumerated values for "incoming", "outgoing", or "missed"
+ * @param subscription The subscription object describing the provider of the call
* @param start time stamp for the call in milliseconds
* @param duration call duration in seconds
*
* {@hide}
*/
public static Uri addCall(CallerInfo ci, Context context, String number,
- int presentation, int callType, long start, int duration) {
+ int presentation, int callType, Subscription subscription, long start, int duration) {
final ContentResolver resolver = context.getContentResolver();
int numberPresentation = PRESENTATION_ALLOWED;
@@ -316,6 +330,14 @@
}
}
+ // subscription information
+ String subscriptionComponentString = null;
+ String subscriptionId = null;
+ if (subscription != null) {
+ subscriptionComponentString = subscription.getComponentName().flattenToString();
+ subscriptionId = subscription.getId();
+ }
+
ContentValues values = new ContentValues(6);
values.put(NUMBER, number);
@@ -323,6 +345,8 @@
values.put(TYPE, Integer.valueOf(callType));
values.put(DATE, Long.valueOf(start));
values.put(DURATION, Long.valueOf(duration));
+ values.put(SUBSCRIPTION_COMPONENT_NAME, subscriptionComponentString);
+ values.put(SUBSCRIPTION_ID, subscriptionId);
values.put(NEW, Integer.valueOf(1));
if (callType == MISSED_TYPE) {
values.put(IS_READ, Integer.valueOf(0));
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 0d69b3b..b839613 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -171,8 +171,6 @@
* A key to a boolean in the "extras" bundle of the cursor.
* The boolean indicates that the provider did not create a snippet and that the client asking
* for the snippet should do it (true means the snippeting was deferred to the client).
- *
- * @hide
*/
public static final String DEFERRED_SNIPPETING = "deferred_snippeting";
@@ -849,7 +847,6 @@
/**
* Reference to the row in the RawContacts table holding the contact name.
* <P>Type: INTEGER REFERENCES raw_contacts(_id)</P>
- * @hide
*/
public static final String NAME_RAW_CONTACT_ID = "name_raw_contact_id";
@@ -1609,8 +1606,7 @@
CONTENT_URI, "strequent");
/**
- * The content:// style URI for showing frequently contacted person listing.
- * @hide
+ * The content:// style URI for showing a list of frequently contacted people.
*/
public static final Uri CONTENT_FREQUENT_URI = Uri.withAppendedPath(
CONTENT_URI, "frequent");
@@ -2229,7 +2225,6 @@
* type. For applications that need to be aware of the data set, this can
* be used instead of account type to distinguish sets of data. This is
* never intended to be used for specifying accounts.
- * @hide
*/
public static final String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set";
@@ -2273,8 +2268,6 @@
* The default value is "0"
* </p>
* <p>Type: INTEGER</p>
- *
- * @hide
*/
public static final String NAME_VERIFIED = "name_verified";
@@ -3793,8 +3786,6 @@
* The package name to use when creating {@link Resources} objects for
* this data row. This value is only designed for use when building user
* interfaces, and should not be used to infer the owner.
- *
- * @hide
*/
public static final String RES_PACKAGE = "res_package";
@@ -5096,12 +5087,10 @@
}
/**
- * Additional column returned by the {@link Contacts#CONTENT_FILTER_URI} providing the
- * explanation of why the filter matched the contact. Specifically, it contains the
- * data elements that matched the query. The overall number of words in the snippet
- * can be capped.
- *
- * @hide
+ * Additional column returned by
+ * {@link ContactsContract.Contacts#CONTENT_FILTER_URI Contacts.CONTENT_FILTER_URI} explaining
+ * why the filter matched the contact. Specifically, it contains the data elements that
+ * matched the query. The overall number of words in the snippet can be capped.
*/
public static class SearchSnippetColumns {
@@ -5111,8 +5100,6 @@
* <p>
* The snippet may contain (parts of) several data elements comprising
* the contact.
- *
- * @hide
*/
public static final String SNIPPET = "snippet";
@@ -5128,8 +5115,6 @@
* tokens can be returned in total. A negative number indicates how many
* tokens can be returned per occurrence of the search terms.</li>
* </ul>
- *
- * @hide
*/
public static final String SNIPPET_ARGS_PARAM_KEY = "snippet_args";
@@ -5140,8 +5125,6 @@
* {@link ContactsContract#DEFERRED_SNIPPETING} in the cursor. If it exists, the client
* should do its own snippeting. If it doesn't exist, the snippet column in the cursor
* should already contain a snippetized string.
- *
- * @hide
*/
public static final String DEFERRED_SNIPPETING_KEY = "deferred_snippeting";
}
@@ -7007,8 +6990,6 @@
* The package name to use when creating {@link Resources} objects for
* this group. This value is only designed for use when building user
* interfaces, and should not be used to infer the owner.
- *
- * @hide
*/
public static final String RES_PACKAGE = "res_package";
@@ -7016,8 +6997,6 @@
* The display title of this group to load as a resource from
* {@link #RES_PACKAGE}, which may be localized.
* <P>Type: TEXT</P>
- *
- * @hide
*/
public static final String TITLE_RES = "title_res";
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 9da3a51..6bb3458 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -124,6 +124,19 @@
* }
* }
* </pre>
+ *
+ * <p>When targeting api level 21 and above, you must declare the service in your manifest file
+ * with the {@link android.Manifest.permission#BIND_DREAM_SERVICE} permission. For example:</p>
+ * <pre>
+ * <service
+ * android:name=".MyDream"
+ * android:exported="true"
+ * android:icon="@drawable/my_icon"
+ * android:label="@string/my_dream_label"
+ * android:permission="android.permission.BIND_DREAM_SERVICE" >
+ * ...
+ * </service>
+ * </pre>
*/
public class DreamService extends Service implements Window.Callback {
private final String TAG = DreamService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]";
diff --git a/core/java/android/transition/ChangeImageTransform.java b/core/java/android/transition/ChangeImageTransform.java
new file mode 100644
index 0000000..b003690
--- /dev/null
+++ b/core/java/android/transition/ChangeImageTransform.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.TypeEvaluator;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.Property;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import java.util.Map;
+
+/**
+ * Transitions changes in ImageView {@link ImageView#setScaleType(ImageView.ScaleType)} as
+ * well as image scaling due to ImageView size changes. When combined with
+ * {@link android.transition.ChangeBounds}, an ImageView that changes size will
+ * scale smoothly.
+ */
+public class ChangeImageTransform extends Transition {
+
+ private static final String TAG = "ChangeScaleType";
+
+ private static final String PROPNAME_MATRIX = "android:changeScaleType:matrix";
+ private static final String PROPNAME_BOUNDS = "android:changeScaleType:bounds";
+
+ private static final String[] sTransitionProperties = {
+ PROPNAME_MATRIX,
+ PROPNAME_BOUNDS,
+ };
+
+ private static TypeEvaluator<Matrix> NULL_MATRIX_EVALUATOR = new TypeEvaluator<Matrix>() {
+ @Override
+ public Matrix evaluate(float fraction, Matrix startValue, Matrix endValue) {
+ return null;
+ }
+ };
+
+ private static Property<ImageView, Matrix> ANIMATED_TRANSFORM_PROPERTY
+ = new Property<ImageView, Matrix>(Matrix.class, "animatedTransform") {
+ @Override
+ public void set(ImageView object, Matrix value) {
+ object.animateTransform(value);
+ }
+
+ @Override
+ public Matrix get(ImageView object) {
+ return null;
+ }
+ };
+
+ private void captureValues(TransitionValues transitionValues) {
+ View view = transitionValues.view;
+ if (!(view instanceof ImageView) || view.getVisibility() != View.VISIBLE) {
+ return;
+ }
+ ImageView imageView = (ImageView) view;
+ Drawable drawable = imageView.getDrawable();
+ if (drawable == null) {
+ return;
+ }
+ Map<String, Object> values = transitionValues.values;
+
+ int left = view.getLeft();
+ int top = view.getTop();
+ int right = view.getRight();
+ int bottom = view.getBottom();
+
+ Rect bounds = new Rect(left, top, right, bottom);
+ values.put(PROPNAME_BOUNDS, bounds);
+ Matrix matrix;
+ ImageView.ScaleType scaleType = imageView.getScaleType();
+ if (scaleType == ImageView.ScaleType.FIT_XY) {
+ matrix = imageView.getImageMatrix();
+ if (!matrix.isIdentity()) {
+ matrix = new Matrix(matrix);
+ } else {
+ int drawableWidth = drawable.getIntrinsicWidth();
+ int drawableHeight = drawable.getIntrinsicHeight();
+ if (drawableWidth > 0 && drawableHeight > 0) {
+ float scaleX = ((float) bounds.width()) / drawableWidth;
+ float scaleY = ((float) bounds.height()) / drawableHeight;
+ matrix = new Matrix();
+ matrix.setScale(scaleX, scaleY);
+ } else {
+ matrix = null;
+ }
+ }
+ } else {
+ matrix = new Matrix(imageView.getImageMatrix());
+ }
+ values.put(PROPNAME_MATRIX, matrix);
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public String[] getTransitionProperties() {
+ return sTransitionProperties;
+ }
+
+ /**
+ * Creates an Animator for ImageViews moving, changing dimensions, and/or changing
+ * {@link android.widget.ImageView.ScaleType}.
+ *
+ * @param sceneRoot The root of the transition hierarchy.
+ * @param startValues The values for a specific target in the start scene.
+ * @param endValues The values for the target in the end scene.
+ * @return An Animator to move an ImageView or null if the View is not an ImageView,
+ * the Drawable changed, the View is not VISIBLE, or there was no change.
+ */
+ @Override
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
+ Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
+ if (startBounds == null || endBounds == null) {
+ return null;
+ }
+
+ Matrix startMatrix = (Matrix) startValues.values.get(PROPNAME_MATRIX);
+ Matrix endMatrix = (Matrix) endValues.values.get(PROPNAME_MATRIX);
+
+ boolean matricesEqual = (startMatrix == null && endMatrix == null) ||
+ (startMatrix != null && startMatrix.equals(endMatrix));
+
+ if (startBounds.equals(endBounds) && matricesEqual) {
+ return null;
+ }
+
+ ImageView imageView = (ImageView) endValues.view;
+ Drawable drawable = imageView.getDrawable();
+ int drawableWidth = drawable.getIntrinsicWidth();
+ int drawableHeight = drawable.getIntrinsicHeight();
+
+ ObjectAnimator animator;
+ if (drawableWidth == 0 || drawableHeight == 0) {
+ animator = createNullAnimator(imageView);
+ } else {
+ if (startMatrix == null) {
+ startMatrix = Matrix.IDENTITY_MATRIX;
+ }
+ if (endMatrix == null) {
+ endMatrix = Matrix.IDENTITY_MATRIX;
+ }
+ animator = createMatrixAnimator(imageView, startMatrix, endMatrix);
+ }
+ return animator;
+ }
+
+ private ObjectAnimator createNullAnimator(ImageView imageView) {
+ return ObjectAnimator.ofObject(imageView, ANIMATED_TRANSFORM_PROPERTY,
+ NULL_MATRIX_EVALUATOR, null, null);
+ }
+
+ private ObjectAnimator createMatrixAnimator(final ImageView imageView, Matrix startMatrix,
+ final Matrix endMatrix) {
+ ObjectAnimator animator = ObjectAnimator.ofObject(imageView, ANIMATED_TRANSFORM_PROPERTY,
+ new MatrixEvaluator(), startMatrix, endMatrix);
+ /*
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ private Matrix mPausedMatrix;
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ if (mPausedMatrix == null) {
+ mPausedMatrix = new Matrix();
+ }
+ Matrix imageMatrix = imageView.getImageMatrix();
+ mPausedMatrix.set(imageMatrix);
+ imageView.animateTransform(endMatrix);
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ imageView.animateTransform(mPausedMatrix);
+ }
+ };
+ animator.addPauseListener(listener);
+ */
+ return animator;
+ }
+
+ private static class MatrixEvaluator implements TypeEvaluator<Matrix> {
+
+ float[] mTempStartValues = new float[9];
+
+ float[] mTempEndValues = new float[9];
+
+ Matrix mTempMatrix = new Matrix();
+
+ @Override
+ public Matrix evaluate(float fraction, Matrix startValue, Matrix endValue) {
+ startValue.getValues(mTempStartValues);
+ endValue.getValues(mTempEndValues);
+ for (int i = 0; i < 9; i++) {
+ float diff = mTempEndValues[i] - mTempStartValues[i];
+ mTempEndValues[i] = mTempStartValues[i] + (fraction * diff);
+ }
+ mTempMatrix.setValues(mTempEndValues);
+ return mTempMatrix;
+ }
+ }
+
+}
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index e70dc0c..71559da 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -63,23 +63,23 @@
/**
* Fading mode used in {@link #Fade(int)} to make the transition
* operate on targets that are appearing. Maybe be combined with
- * {@link #OUT} to fade both in and out.
+ * {@link #OUT} to fade both in and out. Equivalent to
+ * {@link Visibility#IN}.
*/
- public static final int IN = 0x1;
+ public static final int IN = Visibility.IN;
+
/**
* Fading mode used in {@link #Fade(int)} to make the transition
* operate on targets that are disappearing. Maybe be combined with
- * {@link #IN} to fade both in and out.
+ * {@link #IN} to fade both in and out. Equivalent to
+ * {@link Visibility#OUT}.
*/
- public static final int OUT = 0x2;
-
- private int mFadingMode;
+ public static final int OUT = Visibility.OUT;
/**
* Constructs a Fade transition that will fade targets in and out.
*/
public Fade() {
- this(IN | OUT);
}
/**
@@ -90,7 +90,7 @@
* {@link #IN} and {@link #OUT}.
*/
public Fade(int fadingMode) {
- mFadingMode = fadingMode;
+ setMode(fadingMode);
}
/**
@@ -115,9 +115,6 @@
public Animator onAppear(ViewGroup sceneRoot, View view,
TransitionValues startValues,
TransitionValues endValues) {
- if ((mFadingMode & IN) != IN || endValues == null) {
- return null;
- }
if (DBG) {
View startView = (startValues != null) ? startValues.view : null;
Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = " +
@@ -129,10 +126,6 @@
@Override
public Animator onDisappear(ViewGroup sceneRoot, final View view, TransitionValues startValues,
TransitionValues endValues) {
- if ((mFadingMode & OUT) != OUT) {
- return null;
- }
-
return createAnimation(view, 1, 0);
}
diff --git a/core/java/android/transition/MatrixClippedDrawable.java b/core/java/android/transition/MatrixClippedDrawable.java
deleted file mode 100644
index ebaad59..0000000
--- a/core/java/android/transition/MatrixClippedDrawable.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.transition;
-
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.Property;
-
-/**
- * Used in MoveImage to mock an ImageView as a Drawable to be scaled in the scene root Overlay.
- * @hide
- */
-class MatrixClippedDrawable extends Drawable implements Drawable.Callback {
- private static final String TAG = "MatrixClippedDrawable";
-
- private ClippedMatrixState mClippedMatrixState;
-
- public static final Property<MatrixClippedDrawable, Rect> CLIP_PROPERTY
- = new Property<MatrixClippedDrawable, Rect>(Rect.class, "clipRect") {
-
- @Override
- public Rect get(MatrixClippedDrawable object) {
- return object.getClipRect();
- }
-
- @Override
- public void set(MatrixClippedDrawable object, Rect value) {
- object.setClipRect(value);
- }
- };
-
- public static final Property<MatrixClippedDrawable, Matrix> MATRIX_PROPERTY
- = new Property<MatrixClippedDrawable, Matrix>(Matrix.class, "matrix") {
- @Override
- public void set(MatrixClippedDrawable object, Matrix value) {
- object.setMatrix(value);
- }
-
- @Override
- public Matrix get(MatrixClippedDrawable object) {
- return object.getMatrix();
- }
- };
-
- public MatrixClippedDrawable(Drawable drawable) {
- this(null, null);
-
- mClippedMatrixState.mDrawable = drawable;
-
- if (drawable != null) {
- drawable.setCallback(this);
- }
- }
-
- public void setMatrix(Matrix matrix) {
- if (matrix == null) {
- mClippedMatrixState.mMatrix = null;
- } else {
- if (mClippedMatrixState.mMatrix == null) {
- mClippedMatrixState.mMatrix = new Matrix();
- }
- mClippedMatrixState.mMatrix.set(matrix);
- }
- invalidateSelf();
- }
-
- public Matrix getMatrix() {
- return mClippedMatrixState.mMatrix;
- }
-
- public Rect getClipRect() {
- return mClippedMatrixState.mClipRect;
- }
-
- public void setClipRect(Rect clipRect) {
- if (clipRect == null) {
- if (mClippedMatrixState.mClipRect != null) {
- mClippedMatrixState.mClipRect = null;
- invalidateSelf();
- }
- } else {
- if (mClippedMatrixState.mClipRect == null) {
- mClippedMatrixState.mClipRect = new Rect(clipRect);
- } else {
- mClippedMatrixState.mClipRect.set(clipRect);
- }
- invalidateSelf();
- }
- }
-
- // overrides from Drawable.Callback
-
- public void invalidateDrawable(Drawable who) {
- final Drawable.Callback callback = getCallback();
- if (callback != null) {
- callback.invalidateDrawable(this);
- }
- }
-
- public void scheduleDrawable(Drawable who, Runnable what, long when) {
- final Drawable.Callback callback = getCallback();
- if (callback != null) {
- callback.scheduleDrawable(this, what, when);
- }
- }
-
- public void unscheduleDrawable(Drawable who, Runnable what) {
- final Drawable.Callback callback = getCallback();
- if (callback != null) {
- callback.unscheduleDrawable(this, what);
- }
- }
-
- // overrides from Drawable
-
- @Override
- public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mClippedMatrixState.mChangingConfigurations
- | mClippedMatrixState.mDrawable.getChangingConfigurations();
- }
-
- @Override
- public boolean getPadding(Rect padding) {
- // XXX need to adjust padding!
- return mClippedMatrixState.mDrawable.getPadding(padding);
- }
-
- @Override
- public boolean setVisible(boolean visible, boolean restart) {
- mClippedMatrixState.mDrawable.setVisible(visible, restart);
- return super.setVisible(visible, restart);
- }
-
- @Override
- public void setAlpha(int alpha) {
- mClippedMatrixState.mDrawable.setAlpha(alpha);
- }
-
- @Override
- public int getAlpha() {
- return mClippedMatrixState.mDrawable.getAlpha();
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- mClippedMatrixState.mDrawable.setColorFilter(cf);
- }
-
- @Override
- public int getOpacity() {
- return mClippedMatrixState.mDrawable.getOpacity();
- }
-
- @Override
- public boolean isStateful() {
- return mClippedMatrixState.mDrawable.isStateful();
- }
-
- @Override
- protected boolean onStateChange(int[] state) {
- return mClippedMatrixState.mDrawable.setState(state);
- }
-
- @Override
- protected boolean onLevelChange(int level) {
- mClippedMatrixState.mDrawable.setLevel(level);
- invalidateSelf();
- return true;
- }
-
- @Override
- protected void onBoundsChange(Rect bounds) {
- super.setBounds(bounds);
- if (mClippedMatrixState.mMatrix == null) {
- mClippedMatrixState.mDrawable.setBounds(bounds);
- } else {
- int drawableWidth = mClippedMatrixState.mDrawable.getIntrinsicWidth();
- int drawableHeight = mClippedMatrixState.mDrawable.getIntrinsicHeight();
- mClippedMatrixState.mDrawable.setBounds(bounds.left, bounds.top,
- drawableWidth + bounds.left, drawableHeight + bounds.top);
- }
- invalidateSelf();
- }
-
- @Override
- public void draw(Canvas canvas) {
- Rect bounds = getBounds();
- int left = bounds.left;
- int top = bounds.top;
- int saveCount = canvas.getSaveCount();
- canvas.save();
- if (mClippedMatrixState.mClipRect != null) {
- canvas.clipRect(mClippedMatrixState.mClipRect);
- } else {
- canvas.clipRect(bounds);
- }
-
- if (mClippedMatrixState != null && !mClippedMatrixState.mMatrix.isIdentity()) {
- canvas.translate(left, top);
- canvas.concat(mClippedMatrixState.mMatrix);
- canvas.translate(-left, -top);
- }
- mClippedMatrixState.mDrawable.draw(canvas);
- canvas.restoreToCount(saveCount);
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mClippedMatrixState.mDrawable.getIntrinsicWidth();
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mClippedMatrixState.mDrawable.getIntrinsicHeight();
- }
-
- @Override
- public Drawable.ConstantState getConstantState() {
- if (mClippedMatrixState.canConstantState()) {
- mClippedMatrixState.mChangingConfigurations = getChangingConfigurations();
- return mClippedMatrixState;
- }
- return null;
- }
-
- final static class ClippedMatrixState extends Drawable.ConstantState {
- Drawable mDrawable;
- Matrix mMatrix;
- Rect mClipRect;
-
- private boolean mCheckedConstantState;
- private boolean mCanConstantState;
- int mChangingConfigurations;
-
- ClippedMatrixState(ClippedMatrixState orig, MatrixClippedDrawable owner, Resources res) {
- if (orig != null) {
- if (res != null) {
- mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
- } else {
- mDrawable = orig.mDrawable.getConstantState().newDrawable();
- }
- mDrawable.setCallback(owner);
- mCheckedConstantState = mCanConstantState = true;
- if (orig.mMatrix != null) {
- mMatrix = new Matrix(orig.mMatrix);
- }
- if (orig.mClipRect != null) {
- mClipRect = new Rect(orig.mClipRect);
- }
- }
- }
-
- @Override
- public Drawable newDrawable() {
- return new MatrixClippedDrawable(this, null);
- }
-
- @Override
- public Drawable newDrawable(Resources res) {
- return new MatrixClippedDrawable(this, res);
- }
-
- @Override
- public int getChangingConfigurations() {
- return mChangingConfigurations;
- }
-
- boolean canConstantState() {
- if (!mCheckedConstantState) {
- mCanConstantState = mDrawable.getConstantState() != null;
- mCheckedConstantState = true;
- }
-
- return mCanConstantState;
- }
- }
-
- private MatrixClippedDrawable(ClippedMatrixState state, Resources res) {
- mClippedMatrixState = new ClippedMatrixState(state, this, res);
- }
-
-}
diff --git a/core/java/android/transition/MoveImage.java b/core/java/android/transition/MoveImage.java
index 6f1b6f7..48b96ec 100644
--- a/core/java/android/transition/MoveImage.java
+++ b/core/java/android/transition/MoveImage.java
@@ -15,340 +15,17 @@
*/
package android.transition;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.RectEvaluator;
-import android.animation.TypeEvaluator;
-import android.animation.ValueAnimator;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.util.FloatMath;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroupOverlay;
-import android.view.ViewParent;
-import android.widget.ImageView;
-
-import java.util.ArrayList;
-import java.util.Map;
-
/**
- * Transitions ImageViews, including size, scaleType, and matrix. The ImageView drawable
- * must remain the same between both start and end states, but the
- * {@link ImageView#setScaleType(android.widget.ImageView.ScaleType)} may
- * differ.
+ * TO BE REMOVED.
+ * Use ChangeImageTransform + ChangeBounds instead.
+ * @hide
*/
-public class MoveImage extends Transition {
- private static final String TAG = "MoveImage";
- private static final String PROPNAME_MATRIX = "android:moveImage:matrix";
- private static final String PROPNAME_BOUNDS = "android:moveImage:bounds";
- private static final String PROPNAME_CLIP = "android:moveImage:clip";
- private static final String PROPNAME_DRAWABLE = "android:moveImage:drawable";
+public class MoveImage extends TransitionSet {
- private int[] mTempLoc = new int[2];
-
- private static final String[] sTransitionProperties = {
- PROPNAME_MATRIX,
- PROPNAME_BOUNDS,
- PROPNAME_CLIP,
- PROPNAME_DRAWABLE,
- };
-
- private void captureValues(TransitionValues transitionValues) {
- View view = transitionValues.view;
- if (!(view instanceof ImageView) || view.getVisibility() != View.VISIBLE) {
- return;
- }
- ImageView imageView = (ImageView) view;
- Drawable drawable = imageView.getDrawable();
- if (drawable == null) {
- return;
- }
- Map<String, Object> values = transitionValues.values;
- values.put(PROPNAME_DRAWABLE, drawable);
-
- ViewGroup parent = (ViewGroup) view.getParent();
- parent.getLocationInWindow(mTempLoc);
- int paddingLeft = view.getPaddingLeft();
- int paddingTop = view.getPaddingTop();
- int paddingRight = view.getPaddingRight();
- int paddingBottom = view.getPaddingBottom();
- int left = mTempLoc[0] + paddingLeft + view.getLeft() + Math.round(view.getTranslationX());
- int top = mTempLoc[1] + paddingTop + view.getTop() + Math.round(view.getTranslationY());
- int right = left + view.getWidth() - paddingRight - paddingLeft;
- int bottom = top + view.getHeight() - paddingTop - paddingBottom;
-
- Rect bounds = new Rect(left, top, right, bottom);
- values.put(PROPNAME_BOUNDS, bounds);
- Matrix matrix = getMatrix(imageView);
- values.put(PROPNAME_MATRIX, matrix);
- values.put(PROPNAME_CLIP, findClip(imageView));
- }
-
- @Override
- public void captureStartValues(TransitionValues transitionValues) {
- captureValues(transitionValues);
- }
-
- @Override
- public void captureEndValues(TransitionValues transitionValues) {
- captureValues(transitionValues);
- }
-
- @Override
- public String[] getTransitionProperties() {
- return sTransitionProperties;
- }
-
- /**
- * Creates an Animator for ImageViews moving, changing dimensions, and/or changing
- * {@link android.widget.ImageView.ScaleType}.
- * @param sceneRoot The root of the transition hierarchy.
- * @param startValues The values for a specific target in the start scene.
- * @param endValues The values for the target in the end scene.
- * @return An Animator to move an ImageView or null if the View is not an ImageView,
- * the Drawable changed, the View is not VISIBLE, or there was no change.
- */
- @Override
- public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
- if (startValues == null || endValues == null
- || startValues.values.get(PROPNAME_BOUNDS) == null
- || endValues.values.get(PROPNAME_BOUNDS) == null
- || startValues.values.get(PROPNAME_DRAWABLE)
- != endValues.values.get(PROPNAME_DRAWABLE)) {
- return null;
- }
- ArrayList<PropertyValuesHolder> changes = new ArrayList<PropertyValuesHolder>();
-
- Matrix startMatrix = (Matrix) startValues.values.get(PROPNAME_MATRIX);
- Matrix endMatrix = (Matrix) endValues.values.get(PROPNAME_MATRIX);
-
- if (startMatrix != null && !startMatrix.equals(endMatrix)) {
- changes.add(PropertyValuesHolder.ofObject(MatrixClippedDrawable.MATRIX_PROPERTY,
- new MatrixEvaluator(), startMatrix, endMatrix));
- }
-
- sceneRoot.getLocationInWindow(mTempLoc);
- int rootX = mTempLoc[0];
- int rootY = mTempLoc[1];
- final ImageView imageView = (ImageView) endValues.view;
-
- Drawable drawable = imageView.getDrawable();
-
- Rect startBounds = new Rect((Rect) startValues.values.get(PROPNAME_BOUNDS));
- Rect endBounds = new Rect((Rect) endValues.values.get(PROPNAME_BOUNDS));
- startBounds.offset(-rootX, -rootY);
- endBounds.offset(-rootX, -rootY);
-
- if (!startBounds.equals(endBounds)) {
- changes.add(PropertyValuesHolder.ofObject("bounds", new RectEvaluator(new Rect()),
- startBounds, endBounds));
- }
-
- Rect startClip = (Rect) startValues.values.get(PROPNAME_CLIP);
- Rect endClip = (Rect) endValues.values.get(PROPNAME_CLIP);
- if (startClip != null || endClip != null) {
- startClip = nonNullClip(startClip, sceneRoot, rootX, rootY);
- endClip = nonNullClip(endClip, sceneRoot, rootX, rootY);
-
- expandClip(startBounds, startMatrix, startClip, endClip);
- expandClip(endBounds, endMatrix, endClip, startClip);
- boolean clipped = !startClip.contains(startBounds) || !endClip.contains(endBounds);
- if (!clipped) {
- startClip = null;
- } else if (!startClip.equals(endClip)) {
- changes.add(PropertyValuesHolder.ofObject(MatrixClippedDrawable.CLIP_PROPERTY,
- new RectEvaluator(), startClip, endClip));
- }
- }
-
- if (changes.isEmpty()) {
- return null;
- }
-
- drawable = drawable.getConstantState().newDrawable();
- final MatrixClippedDrawable matrixClippedDrawable = new MatrixClippedDrawable(drawable);
- final ImageView overlayImage = new ImageView(imageView.getContext());
- final ViewGroupOverlay overlay = sceneRoot.getOverlay();
- overlay.add(overlayImage);
- overlayImage.setLeft(0);
- overlayImage.setTop(0);
- overlayImage.setRight(sceneRoot.getWidth());
- overlayImage.setBottom(sceneRoot.getBottom());
- overlayImage.setScaleType(ImageView.ScaleType.MATRIX);
- overlayImage.setImageDrawable(matrixClippedDrawable);
- matrixClippedDrawable.setMatrix(startMatrix);
- matrixClippedDrawable.setBounds(startBounds);
- matrixClippedDrawable.setClipRect(startClip);
-
- imageView.setVisibility(View.INVISIBLE);
- ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(matrixClippedDrawable,
- changes.toArray(new PropertyValuesHolder[changes.size()]));
-
- AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- imageView.setVisibility(View.VISIBLE);
- overlay.remove(overlayImage);
- }
-
- @Override
- public void onAnimationPause(Animator animation) {
- imageView.setVisibility(View.VISIBLE);
- overlayImage.setVisibility(View.INVISIBLE);
- }
-
- @Override
- public void onAnimationResume(Animator animation) {
- imageView.setVisibility(View.INVISIBLE);
- overlayImage.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- onAnimationEnd(animation);
- }
- };
-
- animator.addListener(listener);
- animator.addPauseListener(listener);
-
- return animator;
- }
-
- private static Rect nonNullClip(Rect clip, ViewGroup sceneRoot, int rootX, int rootY) {
- if (clip != null) {
- clip = new Rect(clip);
- clip.offset(-rootX, -rootY);
- } else {
- clip = new Rect(0, 0, sceneRoot.getWidth(), sceneRoot.getHeight());
- }
- return clip;
- }
-
- private static void expandClip(Rect bounds, Matrix matrix, Rect clip, Rect otherClip) {
- RectF boundsF = new RectF(bounds);
- if (matrix != null) {
- matrix.mapRect(boundsF);
- }
- clip.left = expandMinDimension(boundsF.left, clip.left, otherClip.left);
- clip.top = expandMinDimension(boundsF.top, clip.top, otherClip.top);
- clip.right = expandMaxDimension(boundsF.right, clip.right, otherClip.right);
- clip.bottom = expandMaxDimension(boundsF.bottom, clip.bottom, otherClip.bottom);
- }
-
- private static int expandMinDimension(float boundsDimension, int clipDimension,
- int otherClipDimension) {
- if (clipDimension > boundsDimension) {
- // Already clipped in that dimension, return the clipped value
- return clipDimension;
- }
- return Math.min(clipDimension, otherClipDimension);
- }
-
- private static int expandMaxDimension(float boundsDimension, int clipDimension,
- int otherClipDimension) {
- return -expandMinDimension(-boundsDimension, -clipDimension, -otherClipDimension);
- }
-
- private static Matrix getMatrix(ImageView imageView) {
- Drawable drawable = imageView.getDrawable();
- int drawableWidth = drawable.getIntrinsicWidth();
- int drawableHeight = drawable.getIntrinsicHeight();
- ImageView.ScaleType scaleType = imageView.getScaleType();
- Matrix matrix;
- if (drawableWidth <= 0 || drawableHeight <= 0) {
- matrix = null;
- } else if (scaleType == ImageView.ScaleType.FIT_XY) {
- matrix = new Matrix();
- float scaleX = imageView.getWidth();
- scaleX /= drawableWidth;
- float scaleY = imageView.getHeight();
- scaleY /= drawableHeight;
- matrix.setScale(scaleX, scaleY);
- } else {
- matrix = new Matrix(imageView.getImageMatrix());
- }
- return matrix;
- }
-
- private Rect findClip(ImageView imageView) {
- if (imageView.getCropToPadding()) {
- Rect clip = getClip(imageView);
- clip.left += imageView.getPaddingLeft();
- clip.right -= imageView.getPaddingRight();
- clip.top += imageView.getPaddingTop();
- clip.bottom -= imageView.getPaddingBottom();
- return clip;
- } else {
- View view = imageView;
- ViewParent viewParent;
- while ((viewParent = view.getParent()) instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) viewParent;
- if (viewGroup.getClipChildren()) {
- Rect clip = getClip(view);
- return clip;
- }
- view = viewGroup;
- }
- }
- return null;
- }
-
- private Rect getClip(View clipView) {
- Rect clipBounds = clipView.getClipBounds();
- if (clipBounds == null) {
- clipBounds = new Rect(clipView.getLeft(), clipView.getTop(),
- clipView.getRight(), clipView.getBottom());
- }
-
- ViewParent parent = clipView.getParent();
- if (parent instanceof ViewGroup) {
- ViewGroup parentViewGroup = (ViewGroup) parent;
- parentViewGroup.getLocationInWindow(mTempLoc);
- clipBounds.offset(mTempLoc[0], mTempLoc[1]);
- }
-
- return clipBounds;
- }
-
- @Override
- public Transition clone() {
- MoveImage clone = (MoveImage) super.clone();
- clone.mTempLoc = new int[2];
- return clone;
- }
-
- private static class MatrixEvaluator implements TypeEvaluator<Matrix> {
- static final Matrix sIdentity = new Matrix();
- float[] mTempStartValues = new float[9];
- float[] mTempEndValues = new float[9];
- Matrix mTempMatrix = new Matrix();
-
- @Override
- public Matrix evaluate(float fraction, Matrix startValue, Matrix endValue) {
- if (startValue == null && endValue == null) {
- return null;
- }
- if (startValue == null) {
- startValue = sIdentity;
- } else if (endValue == null) {
- endValue = sIdentity;
- }
- startValue.getValues(mTempStartValues);
- endValue.getValues(mTempEndValues);
- for (int i = 0; i < 9; i++) {
- float diff = mTempEndValues[i] - mTempStartValues[i];
- mTempEndValues[i] = mTempStartValues[i] + (fraction * diff);
- }
- mTempMatrix.setValues(mTempEndValues);
- return mTempMatrix;
- }
+ public MoveImage() {
+ addTransition(new ChangeBounds());
+ addTransition(new ChangeClipBounds());
+ addTransition(new ChangeTransform());
+ addTransition(new ChangeImageTransform());
}
}
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 8818128..52e6691 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -68,8 +68,8 @@
*
* <p>This TransitionSet contains {@link android.transition.Explode} for visibility,
* {@link android.transition.ChangeBounds}, {@link android.transition.ChangeTransform},
- * and {@link android.transition.ChangeClipBounds} for non-<code>ImageView</code>s and
- * {@link android.transition.MoveImage} for <code>ImageView</code>s:</p>
+ * and {@link android.transition.ChangeClipBounds} and
+ * {@link android.transition.ChangeImageTransform}:</p>
*
* {@sample development/samples/ApiDemos/res/transition/explode_move_together.xml MultipleTransform}
*
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 58d743c..e0c3cae 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -158,6 +158,9 @@
} else if ("moveImage".equals(name)) {
transition = new MoveImage();
newTransition = true;
+ } else if ("changeImageTransform".equals(name)) {
+ transition = new ChangeImageTransform();
+ newTransition = true;
} else if ("changeTransform".equals(name)) {
transition = new ChangeTransform();
newTransition = true;
@@ -349,6 +352,16 @@
transition.setMatchOrder(parseMatchOrder(matchOrder));
}
a.recycle();
+ if (transition instanceof Visibility) {
+ a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.VisibilityTransition);
+ int mode = a.getInt(
+ com.android.internal.R.styleable.VisibilityTransition_visibilityMode, 0);
+ a.recycle();
+ if (mode != 0) {
+ ((Visibility)transition).setMode(mode);
+ }
+ }
return transition;
}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 947e1a7..aa9f04e 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -43,6 +43,20 @@
private static final String PROPNAME_PARENT = "android:visibility:parent";
private static final String PROPNAME_SCREEN_LOCATION = "android:visibility:screenLocation";
+ /**
+ * Mode used in {@link #setMode(int)} to make the transition
+ * operate on targets that are appearing. Maybe be combined with
+ * {@link #OUT} to target Visibility changes both in and out.
+ */
+ public static final int IN = 0x1;
+
+ /**
+ * Mode used in {@link #setMode(int)} to make the transition
+ * operate on targets that are disappearing. Maybe be combined with
+ * {@link #IN} to target Visibility changes both in and out.
+ */
+ public static final int OUT = 0x2;
+
private static final String[] sTransitionProperties = {
PROPNAME_VISIBILITY,
PROPNAME_PARENT,
@@ -58,6 +72,22 @@
ViewGroup endParent;
}
+ private int mMode = IN | OUT;
+
+ /**
+ * Changes the transition to support appearing and/or disappearing Views, depending
+ * on <code>mode</code>.
+ *
+ * @param mode The behavior supported by this transition, a combination of
+ * {@link #IN} and {@link #OUT}.
+ */
+ public void setMode(int mode) {
+ if ((mode & ~(IN | OUT)) != 0) {
+ throw new IllegalArgumentException("Only IN and OUT flags are allowed");
+ }
+ mMode = mode;
+ }
+
@Override
public String[] getTransitionProperties() {
return sTransitionProperties;
@@ -200,6 +230,9 @@
public Animator onAppear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
+ if ((mMode & IN) != IN || endValues == null) {
+ return null;
+ }
return onAppear(sceneRoot, endValues.view, startValues, endValues);
}
@@ -260,6 +293,10 @@
public Animator onDisappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
+ if ((mMode & OUT) != OUT) {
+ return null;
+ }
+
View startView = (startValues != null) ? startValues.view : null;
View endView = (endValues != null) ? endValues.view : null;
View overlayView = null;
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index d86b699..ddc185c 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -21,9 +21,6 @@
import android.graphics.Outline;
import android.graphics.Paint;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* <p>A display list records a series of graphics related operations and can replay
* them later. Display lists are usually built by recording operations on a
@@ -180,12 +177,6 @@
private boolean mValid;
private final long mNativeRenderNode;
- // We need to keep a strong reference to all running animators to ensure that
- // they can call removeAnimator when they have finished, as the native-side
- // object can only hold a WeakReference<> to avoid leaking memory due to
- // cyclic references.
- private List<RenderNodeAnimator> mActiveAnimators;
-
private RenderNode(String name) {
mNativeRenderNode = nCreate(name);
}
@@ -866,18 +857,9 @@
///////////////////////////////////////////////////////////////////////////
public void addAnimator(RenderNodeAnimator animator) {
- if (mActiveAnimators == null) {
- mActiveAnimators = new ArrayList<RenderNodeAnimator>();
- }
- mActiveAnimators.add(animator);
nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
}
- public void removeAnimator(RenderNodeAnimator animator) {
- nRemoveAnimator(mNativeRenderNode, animator.getNativeAnimator());
- mActiveAnimators.remove(animator);
- }
-
///////////////////////////////////////////////////////////////////////////
// Native methods
///////////////////////////////////////////////////////////////////////////
@@ -960,7 +942,6 @@
///////////////////////////////////////////////////////////////////////////
private static native void nAddAnimator(long renderNode, long animatorPtr);
- private static native void nRemoveAnimator(long renderNode, long animatorPtr);
///////////////////////////////////////////////////////////////////////////
// Finalization
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 4979059..1363a5c 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -172,12 +172,14 @@
@Override
public void cancel() {
- mTarget.removeAnimator(this);
+ if (!mFinished) {
+ nCancel(mNativePtr.get());
- final ArrayList<AnimatorListener> listeners = getListeners();
- final int numListeners = listeners == null ? 0 : listeners.size();
- for (int i = 0; i < numListeners; i++) {
- listeners.get(i).onAnimationCancel(this);
+ final ArrayList<AnimatorListener> listeners = getListeners();
+ final int numListeners = listeners == null ? 0 : listeners.size();
+ for (int i = 0; i < numListeners; i++) {
+ listeners.get(i).onAnimationCancel(this);
+ }
}
}
@@ -219,10 +221,6 @@
return mTarget;
}
- /**
- * WARNING: May only be called once!!!
- * TODO: Fix above -_-
- */
public void setStartValue(float startValue) {
checkMutable();
nSetStartValue(mNativePtr.get(), startValue);
@@ -231,6 +229,9 @@
@Override
public void setStartDelay(long startDelay) {
checkMutable();
+ if (startDelay < 0) {
+ throw new IllegalArgumentException("startDelay must be positive; " + startDelay);
+ }
nSetStartDelay(mNativePtr.get(), startDelay);
}
@@ -242,6 +243,9 @@
@Override
public RenderNodeAnimator setDuration(long duration) {
checkMutable();
+ if (duration < 0) {
+ throw new IllegalArgumentException("duration must be positive; " + duration);
+ }
nSetDuration(mNativePtr.get(), duration);
return this;
}
@@ -269,7 +273,6 @@
private void onFinished() {
mFinished = true;
- mTarget.removeAnimator(this);
final ArrayList<AnimatorListener> listeners = getListeners();
final int numListeners = listeners == null ? 0 : listeners.size();
@@ -296,10 +299,13 @@
long canvasProperty, float finalValue);
private static native long nCreateCanvasPropertyPaintAnimator(WeakReference<RenderNodeAnimator> weakThis,
long canvasProperty, int paintField, float finalValue);
+
private static native void nSetStartValue(long nativePtr, float startValue);
private static native void nSetDuration(long nativePtr, long duration);
private static native long nGetDuration(long nativePtr);
private static native void nSetStartDelay(long nativePtr, long startDelay);
private static native long nGetStartDelay(long nativePtr);
private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
+
+ private static native void nCancel(long animPtr);
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 0120875..0a44d23 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1435,7 +1435,7 @@
/**
* Sets the Transition that will be used for shared elements transferred into the content
* Scene. Typical Transitions will affect size and location, such as
- * {@link android.transition.MoveImage} and {@link android.transition.ChangeBounds}. A null
+ * {@link android.transition.ChangeBounds}. A null
* value will cause transferred shared elements to blink to the final position.
* Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
* @param transition The Transition to use for shared elements transferred into the content
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index 66f5f6c..d3d5fff 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -21,6 +21,8 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Layout;
+import android.text.SpannedString;
+import android.text.TextUtils;
import android.view.inputmethod.SparseRectFArray.SparseRectFArrayBuilder;
import java.util.Objects;
@@ -40,7 +42,7 @@
/**
* The text, tracked as a composing region.
*/
- private final String mComposingText;
+ private final CharSequence mComposingText;
/**
* Horizontal position of the insertion marker, in the local coordinates that will be
@@ -88,7 +90,7 @@
mSelectionStart = source.readInt();
mSelectionEnd = source.readInt();
mComposingTextStart = source.readInt();
- mComposingText = source.readString();
+ mComposingText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
mInsertionMarkerHorizontal = source.readFloat();
mInsertionMarkerTop = source.readFloat();
mInsertionMarkerBaseline = source.readFloat();
@@ -109,7 +111,7 @@
dest.writeInt(mSelectionStart);
dest.writeInt(mSelectionEnd);
dest.writeInt(mComposingTextStart);
- dest.writeString(mComposingText);
+ TextUtils.writeToParcel(mComposingText, dest, flags);
dest.writeFloat(mInsertionMarkerHorizontal);
dest.writeFloat(mInsertionMarkerTop);
dest.writeFloat(mInsertionMarkerBaseline);
@@ -210,12 +212,13 @@
if (composingText == null) {
mComposingText = null;
} else {
- mComposingText = composingText.toString();
+ // Make a snapshot of the given char sequence.
+ mComposingText = new SpannedString(composingText);
}
return this;
}
private int mComposingTextStart = -1;
- private String mComposingText = null;
+ private CharSequence mComposingText = null;
/**
* Sets the location of the text insertion point (zero width cursor) as a rectangle in
@@ -362,7 +365,7 @@
* Returns the entire composing text.
* @return null if there is no composition.
*/
- public String getComposingText() {
+ public CharSequence getComposingText() {
return mComposingText;
}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 321d9d3..2564ff0 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -68,7 +68,36 @@
throw new MustOverrideException();
}
- /**
+ /**
+ * Sets whether the {@link WebView} should allow third party cookies to be set.
+ * Allowing third party cookies is a per WebView policy and can be set
+ * differently on different WebView instances.
+ * <p>
+ * Apps that target {@link android.os.Build.VERSION_CODES#KITKAT} or below
+ * default to allowing third party cookies. Apps targeting
+ * {@link android.os.Build.VERSION_CODES#L} or later default to disallowing
+ * third party cookies.
+ *
+ * @param webview the {@link WebView} instance to set the cookie policy on
+ * @param accept whether the {@link WebView} instance should accept
+ * third party cookies
+ */
+ public synchronized void setAcceptThirdPartyCookies(WebView webview,
+ boolean accept) {
+ throw new MustOverrideException();
+ }
+
+ /**
+ * Gets whether the {@link WebView} should allow third party cookies to be set.
+ *
+ * @param webview the {@link WebView} instance to get the cookie policy for
+ * @return true if the {@link WebView} accepts third party cookies
+ */
+ public synchronized boolean acceptThirdPartyCookies(WebView webview) {
+ throw new MustOverrideException();
+ }
+
+ /**
* Sets a cookie for the given URL. Any existing cookie with the same host,
* path and name will be replaced with the new cookie. The cookie being set
* will be ignored if it is expired.
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index d14c19b..44301c3 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -500,6 +500,24 @@
}
/**
+ * Sets policy for third party cookies.
+ * Developers should access this via {@link CookieManager#setShouldAcceptThirdPartyCookies}.
+ * @hide Internal API.
+ */
+ public void setAcceptThirdPartyCookies(boolean accept) {
+ throw new MustOverrideException();
+ }
+
+ /**
+ * Gets policy for third party cookies.
+ * Developers should access this via {@link CookieManager#getShouldAcceptThirdPartyCookies}.
+ * @hide Internal API
+ */
+ public boolean getAcceptThirdPartyCookies() {
+ throw new MustOverrideException();
+ }
+
+ /**
* Sets the text size of the page. The default is {@link TextSize#NORMAL}.
*
* @param t the text size as a {@link TextSize} value
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 5d578ca..e97177d 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -1117,6 +1117,20 @@
}
}
+ /** @hide */
+ public void animateTransform(Matrix matrix) {
+ if (matrix == null) {
+ mDrawable.setBounds(0, 0, getWidth(), getHeight());
+ } else {
+ mDrawable.setBounds(0, 0, mDrawableWidth, mDrawableHeight);
+ if (mDrawMatrix == null) {
+ mDrawMatrix = new Matrix();
+ }
+ mDrawMatrix.set(matrix);
+ }
+ invalidate();
+ }
+
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d470586..8567bed 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7992,43 +7992,39 @@
}
/**
- * Returns the TextView_textColor attribute from the
- * TypedArray, if set, or the TextAppearance_textColor
- * from the TextView_textAppearance attribute, if TextView_textColor
- * was not set directly.
+ * Returns the TextView_textColor attribute from the TypedArray, if set, or
+ * the TextAppearance_textColor from the TextView_textAppearance attribute,
+ * if TextView_textColor was not set directly.
*/
public static ColorStateList getTextColors(Context context, TypedArray attrs) {
- ColorStateList colors;
- colors = attrs.getColorStateList(com.android.internal.R.styleable.
- TextView_textColor);
-
+ // It's not safe to use this method from apps. The parameter 'attrs'
+ // must have been obtained using the TextView filter array which is not
+ // available to the SDK. As such, we grab a default TypedArray with the
+ // right filter instead here.
+ final TypedArray a = context.obtainStyledAttributes(R.styleable.TextView);
+ ColorStateList colors = a.getColorStateList(R.styleable.TextView_textColor);
if (colors == null) {
- int ap = attrs.getResourceId(com.android.internal.R.styleable.
- TextView_textAppearance, -1);
- if (ap != -1) {
- TypedArray appearance;
- appearance = context.obtainStyledAttributes(ap,
- com.android.internal.R.styleable.TextAppearance);
- colors = appearance.getColorStateList(com.android.internal.R.styleable.
- TextAppearance_textColor);
+ final int ap = a.getResourceId(R.styleable.TextView_textAppearance, 0);
+ if (ap != 0) {
+ final TypedArray appearance = context.obtainStyledAttributes(
+ ap, R.styleable.TextAppearance);
+ colors = appearance.getColorStateList(R.styleable.TextAppearance_textColor);
appearance.recycle();
}
}
+ a.recycle();
return colors;
}
/**
- * Returns the default color from the TextView_textColor attribute
- * from the AttributeSet, if set, or the default color from the
- * TextAppearance_textColor from the TextView_textAppearance attribute,
- * if TextView_textColor was not set directly.
+ * Returns the default color from the TextView_textColor attribute from the
+ * AttributeSet, if set, or the default color from the
+ * TextAppearance_textColor from the TextView_textAppearance attribute, if
+ * TextView_textColor was not set directly.
*/
- public static int getTextColor(Context context,
- TypedArray attrs,
- int def) {
- ColorStateList colors = getTextColors(context, attrs);
-
+ public static int getTextColor(Context context, TypedArray attrs, int def) {
+ final ColorStateList colors = getTextColors(context, attrs);
if (colors == null) {
return def;
} else {
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 621534e..eea16f1 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -227,7 +227,7 @@
}
}
-static void SurfaceTexture_init(JNIEnv* env, jobject thiz,
+static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,
jint texName, jboolean singleBufferMode, jobject weakThiz)
{
sp<IGraphicBufferProducer> producer;
@@ -239,8 +239,15 @@
consumer->setDefaultMaxBufferCount(1);
}
- sp<GLConsumer> surfaceTexture(new GLConsumer(consumer, texName,
- GL_TEXTURE_EXTERNAL_OES, true, true));
+ sp<GLConsumer> surfaceTexture;
+ if (isDetached) {
+ surfaceTexture = new GLConsumer(consumer, GL_TEXTURE_EXTERNAL_OES,
+ true, true);
+ } else {
+ surfaceTexture = new GLConsumer(consumer, texName,
+ GL_TEXTURE_EXTERNAL_OES, true, true);
+ }
+
if (surfaceTexture == 0) {
jniThrowException(env, OutOfResourcesException,
"Unable to create native SurfaceTexture");
@@ -338,7 +345,7 @@
static JNINativeMethod gSurfaceTextureMethods[] = {
{"nativeClassInit", "()V", (void*)SurfaceTexture_classInit },
- {"nativeInit", "(IZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init },
+ {"nativeInit", "(ZIZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init },
{"nativeFinalize", "()V", (void*)SurfaceTexture_finalize },
{"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
{"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage },
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index bc5e1b3..6f89800 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -214,7 +214,8 @@
return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
}
-static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
+static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname,
+ jobject info)
{
return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
}
@@ -252,14 +253,14 @@
}
}
-static void android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
+static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
{
- setNetworkForProcess(netId);
+ return (jboolean) !setNetworkForProcess(netId);
}
-static void android_net_utils_unbindProcessToNetwork(JNIEnv *env, jobject thiz)
+static jboolean android_net_utils_unbindProcessToNetwork(JNIEnv *env, jobject thiz)
{
- setNetworkForProcess(NETID_UNSET);
+ return (jboolean) !setNetworkForProcess(NETID_UNSET);
}
static jint android_net_utils_getNetworkBoundToProcess(JNIEnv *env, jobject thiz)
@@ -267,19 +268,21 @@
return getNetworkForProcess();
}
-static void android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz, jint netId)
+static jboolean android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz,
+ jint netId)
{
- setNetworkForResolv(netId);
+ return (jboolean) !setNetworkForResolv(netId);
}
-static void android_net_utils_unbindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz)
+static jboolean android_net_utils_unbindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz)
{
- setNetworkForResolv(NETID_UNSET);
+ return (jboolean) !setNetworkForResolv(NETID_UNSET);
}
-static void android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jint socket, jint netId)
+static jboolean android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jint socket,
+ jint netId)
{
- setNetworkForSocket(netId, socket);
+ return (jboolean) !setNetworkForSocket(netId, socket);
}
// ----------------------------------------------------------------------------
@@ -299,12 +302,12 @@
{ "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
{ "markSocket", "(II)V", (void*) android_net_utils_markSocket },
- { "bindProcessToNetwork", "(I)V", (void*) android_net_utils_bindProcessToNetwork },
+ { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork },
{ "getNetworkBoundToProcess", "()I", (void*) android_net_utils_getNetworkBoundToProcess },
- { "unbindProcessToNetwork", "()V", (void*) android_net_utils_unbindProcessToNetwork },
- { "bindProcessToNetworkForHostResolution", "(I)V", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
- { "unbindProcessToNetworkForHostResolution", "()V", (void*) android_net_utils_unbindProcessToNetworkForHostResolution },
- { "bindSocketToNetwork", "(II)V", (void*) android_net_utils_bindSocketToNetwork },
+ { "unbindProcessToNetwork", "()Z", (void*) android_net_utils_unbindProcessToNetwork },
+ { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
+ { "unbindProcessToNetworkForHostResolution", "()Z", (void*) android_net_utils_unbindProcessToNetworkForHostResolution },
+ { "bindSocketToNetwork", "(II)Z", (void*) android_net_utils_bindSocketToNetwork },
};
int register_android_net_NetworkUtils(JNIEnv* env)
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 3ffde2d..6ba22bf 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -456,16 +456,9 @@
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr);
renderNode->addAnimator(animator);
+ animator->start();
}
-static void android_view_RenderNode_removeAnimator(JNIEnv* env, jobject clazz,
- jlong renderNodePtr, jlong animatorPtr) {
- RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
- RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr);
- renderNode->removeAnimator(animator);
-}
-
-
#endif // USE_OPENGL_RENDERER
// ----------------------------------------------------------------------------
@@ -546,7 +539,6 @@
{ "nGetPivotY", "(J)F", (void*) android_view_RenderNode_getPivotY },
{ "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator },
- { "nRemoveAnimator", "(JJ)V", (void*) android_view_RenderNode_removeAnimator },
#endif
};
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index d689864..de3dd16 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -149,6 +149,11 @@
animator->setInterpolator(interpolator);
}
+static void cancel(JNIEnv* env, jobject clazz, jlong animatorPtr) {
+ BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
+ animator->cancel();
+}
+
#endif
// ----------------------------------------------------------------------------
@@ -168,6 +173,7 @@
{ "nSetStartDelay", "(JJ)V", (void*) setStartDelay },
{ "nGetStartDelay", "(J)J", (void*) getStartDelay },
{ "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
+ { "nCancel", "(J)V", (void*) cancel },
#endif
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ca897d5..7db478d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2719,6 +2719,13 @@
android:description="@string/permdesc_bindConditionProviderService"
android:protectionLevel="signature" />
+ <!-- Must be required by an {@link android.service.dreams.DreamService},
+ to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_DREAM_SERVICE"
+ android:label="@string/permlab_bindDreamService"
+ android:description="@string/permdesc_bindDreamService"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi Allows an application to call into a carrier setup flow. It is up to the
carrier setup application to enforce that this permission is required
@hide This is not a third-party API (intended for OEMs and system apps). -->
diff --git a/core/res/res/transition/move.xml b/core/res/res/transition/move.xml
index d4863ee..56e1938 100644
--- a/core/res/res/transition/move.xml
+++ b/core/res/res/transition/move.xml
@@ -14,17 +14,8 @@
limitations under the License.
-->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
- <transitionSet>
- <changeBounds/>
- <changeTransform/>
- <changeClipBounds/>
- <targets>
- <target android:excludeClass="android.widget.ImageView"/>
- </targets>
- </transitionSet>
- <moveImage>
- <targets>
- <target android:targetClass="android.widget.ImageView"/>
- </targets>
- </moveImage>
+ <changeBounds/>
+ <changeTransform/>
+ <changeClipBounds/>
+ <changeImageTransform/>
</transitionSet>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 60fa084..7cf4e78 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Vliegtuigmodus is AAN"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Vliegtuigmodus is AF"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Instellings"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Sluit nou"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-stelsel"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Laat die program toe om die kalibrasieparameters van die raakskerm te wysig. Dit behoort nooit vir normale programme nodig te wees nie."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"gaan in by DRM-sertifikate"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Laat \'n program toe om DRM-sertifikate op te stel en te gebruik. Behoort nooit vir normale programme nodig te wees nie."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Ontvang oordraguitsendings."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Laat toe dat oordragstatusinligting ontvang word."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Beheer lengte en watter karakters wat in die skermontsluit-wagwoorde gebruik word."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitor pogings om skerm te ontsluit"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Laat die program toe om die blaaier se geskiedenis of boekmerke wat op jou foon gestoor is, te verander. Dit kan moontlik die program toelaat om blaaierdata uit te vee of te verander. Let wel: hierdie toestemming mag dalk nie deur derdeparty-blaaiers of ander programme met webblaaivermoëns afgedwing word nie."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"stel \'n wekker"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Laat die program toe om \'n alarm in \'n geïnstalleerde wekkerprogram te stel. Sommige wekkerprogramme werk dalk nie met hierdie funksie nie."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"verwyder stemposse"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Laat die program toe om boodskappe uit jou stemposinkassie te verwyder."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"voeg stemboodskap by"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Laat die program toe om boodskappe by te voeg by jou stempos-inkassie."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"lees alle stempos"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 7a08236..14ad538 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"የአውሮፕላንሁነታ በርቷል"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"የአውሮፕላንሁነታ ጠፍቷል"</string>
<string name="global_action_settings" msgid="1756531602592545966">"ቅንብሮች"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"አሁን ቆልፍ"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"የሚያስተማምን ሁነታ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android ስርዓት"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"መተግበሪያው የማያ ንካ የማስተካከያ ልኬቶቹን እንዲቀይር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"የDRM የምስክር ወረቀቶች ላይ ይድረሱ"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"አንድ መተግበሪያ የDRM የምስክር ወረቀቶችን እንዲሰጥና እንዲጠቀም ያስችላል። ለመደበኛ መተግበሪያዎች በፍጹም አስፈላጊ አይሆንም።"</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"የርክክብ ትልልፍ ስርጭቶችን ተቀበል።"</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"የርክክብ ትልልፍ ሁኔታ መረጃ እንዲቀበል ያስችላል።"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"መተግበሪያው ስልክህ ላይ የተከማቹ የአሳሹን ታሪክ ወይም ዕልባቶችን እንዲቀይር ይፈቅድለታል። ይህ መተግበሪያው የአሳሽ ውሂብ እንዲያጠፋ ወይም እንዲያስተካክል ሊፈቅድለት ይችላል። ማስታወሻ፦ ይህ ፈቃድ በሶስተኛ ወገን አሳሾች ወይም በሌላ የድር አሳሽነት አቅም ባላቸው መተግበሪያዎች ላይፈጸም ይችላል።"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ማንቂያ አስቀምጥ"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"በተጫነው የማንቂያ ሰዓት መተግበሪያ ውስጥ ማንቅያን ለማደራጀት ለመተግበሪያው ይፈቅዳሉ፡፡አንዳንድ የማንቂያ ሰዓት መተግበሪያዎች ይሄንን ባህሪ ላይፈፅሙ ይችላሉ፡፡"</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"የድምጽ መልዕክቶችን ያስወግዳል"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"መተግበሪያው መልዕክቶችን ከገቢ የድምጽ መልዕክት ሳጥዎ እንዲያስወግድ ያስችለዋል።"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"የድምፅ መልዕክት አክል"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ወደ ድምፅ መልዕክት የገቢ መልዕክትህ መልዕክቶች ለማከል ለመተግበሪያው ይፈቅዳሉ።"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"ሁሉንም የድምጽ መልዕክት ያነብባል"</string>
@@ -1726,16 +1731,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ተመርጧል"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ተሰርዟል"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ስራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"መተግበሪያ-ላይ-ቆልፍን ይጠቀሙ?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"መተግበሪያ-ላይ-ቆልፍ ማሳያውን በአንዲት መተግበሪያ ውስጥ ይቆልፋል።\n\nለመውጣት የቅርብ ጊዜ መተግበሪያዎች አዝራር $ን ተጭነው ይያዙት"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"አይ"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"ጀምር"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"መተግበሪያ-ላይ-ቆልፍን ጀምር"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"ከመተግበሪያ-ላይ-ቆልፍ ውጣ"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d53daba..77a2fad 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"وضع الطائرة قيد التشغيل"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"وضع الطائرة متوقف"</string>
<string name="global_action_settings" msgid="1756531602592545966">"الإعدادات"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"قفل الآن"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"نظام Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"يتيح للتطبيق إمكانية تعديل معلمات المعايرة في شاشة اللمس. يجب عدم اللجوء إليه مع التطبيقات العادية."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"الدخول إلى شهادات DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"للسماح لأحد التطبيقات بتقديم شهادات DRM واستخدامها. لا يجب أن يكون ذلك لازمًا مطلقًا مع التطبيقات العادية."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"استلام عمليات البث المتعلقة بنقل إمكانية التحكم."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"للسماح باستلام معلومات حالة نقل إمكانية التحكم."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"للسماح للتطبيق بتعديل سجل المتصفح أو الإشارات المرجعية المخزنة على هاتفك. وقد يتيح هذا للتطبيق محو بيانات المتصفح أو تعديلها. ملاحظة: لا يجوز فرض هذا الإذن من قِبل متصفحات جهات خارجية أو تطبيقات أخرى بها إمكانيات تصفح الويب."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"تعيين منبه"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"للسماح للتطبيق بضبط المنبه في تطبيق المنبه المثبّت. ربما لا تنفذ بعض تطبيقات المنبه هذه الميزة."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"إزالة رسائل البريد الصوتي"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"للسماح للتطبيق بإزالة الرسائل من صندوق البريد الصوتي."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"إضافة بريد صوتي"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"للسماح للتطبيق بإضافة رسائل إلى صندوق البريد الصوتي."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"قراءة جميع رسائل البريد الصوتي"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d77971c..bd518ad 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Самолетният режим е ВКЛЮЧЕН"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Самолетният режим е ИЗКЛЮЧЕН"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Настройки"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Системно от Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Разрешава на приложението да променя параметрите на калибриране на сензорния екран. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"достъп до сертификатите за управление на цифровите права (DRM)"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Разрешава на приложението да обезпечава и използва сертификатите за управление на цифровите права (DRM). Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Разрешава на приложението да променя историята или отметките на браузъра, съхранени на телефона ви. Това може да му позволи да изтрива или променя данните на браузъра. Забележка: Възможно е браузъри на трети страни или други приложения с възможности за сърфиране в мрежата да не могат да наложат ограниченията на разрешението."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"навиване на будилника"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Разрешава на приложението да навие инсталирано приложение будилник. Някои будилници може да не изпълнят тази функция."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"добавяне на гласова поща"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Разрешава на приложението да добавя съобщения към входящата ви гласова поща."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"четене на цялата гласова поща"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"Избрахте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"Изтрихте <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> за работа"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Да се използва ли „Заключване в приложението“?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Със „Заключване в приложението“ екранът се заключва в едно приложение.\n\nЗа изход натиснете и задръжте бутона за скорошни приложения $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"НЕ"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"СТАРТИРАНЕ"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Стартиране на „Заключване в приложението“"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Изход от „Заключване в приложението“"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 46eeae8..f5e0166 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mode d\'avió activat"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mode d\'avió desactivat"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Configuració"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Bloqueja ara"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permet que l\'aplicació modifiqui els paràmetres de calibratge de la pantalla tàctil. No ha de ser mai necessari per a aplicacions normals."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"accedir als certificats de DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permet que una aplicació proporcioni i utilitzi certificats de gestió de drets digitals (DRM, Digital Rights Management). No ha de ser mai necessari per a aplicacions normals."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"rebre difusions de transferència d\'entrega"</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Permet rebre informació sobre l\'estat de la transferència d\'entrega."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir les normes de contrasenya"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controla la longitud i els caràcters permesos a les contrasenyes de desbloqueig de pantalla."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Controlar els intents de desbloqueig de pantalla"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permet que l\'aplicació modifiqui l\'historial del navegador o els marcadors del telèfon. Això pot permetre que l\'aplicació esborri o modifiqui les dades del navegador. Nota: És possible que aquest permís no s\'apliqui a navegadors de tercers o a altres aplicacions amb capacitats de navegació web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"configuració d\'una alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permet que l\'aplicació defineixi una alarma en una aplicació de despertador instal·lada. És possible que algunes aplicacions de despertador no incorporin aquesta funció."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"suprimir correus de veu"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Permet que l\'aplicació suprimeixi missatges de la safata d\'entrada de la bústia de veu."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"afegeix bústia de veu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permet que l\'aplicació afegeixi missatges a la safata d\'entrada de la bústia de veu."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"accedir a tots els correus de veu"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index eb28a23..07dbeec 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim V letadle je ZAPNUTÝ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim V letadle je VYPNUTÝ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Nastavení"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Zamknout"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Umožňuje aplikaci měnit parametry kalibrace dotykové obrazovky. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"přístup k certifikátům DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Umožňuje aplikaci vydávat a používat certifikáty DRM. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Příjem vysílání pro předání spojení"</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Povoluje příjem informací o stavu předání spojení."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Umožňuje aplikaci upravit historii prohlížeče nebo záložky uložené v telefonu. Aplikace s tímto oprávněním může vymazat či pozměnit data prohlížeče. Poznámka: Pro prohlížeče třetí strany a jiné aplikace umožňující procházení webu toto oprávnění platit nemusí."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"nastavení budíku"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Umožňuje aplikaci nastavit budík v nainstalované aplikaci budík. Některé aplikace budík tuto funkci nemusí obsahovat."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"odstraňování hlasových zpráv"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Povoluje aplikaci odstraňovat zprávy z hlasové schránky."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"přidat hlasovou zprávu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Umožňuje aplikaci přidávat zprávy do hlasové schránky."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"číst všechny hlasové zprávy"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9ddbf87..b7805d4 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flytilstand er TIL"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flytilstand er slået FRA"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Indstillinger"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Tillader, at appen ændrer kalibreringsparametrene for berøringsskærmen. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"få adgang til DRM-certifikater"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Tillader, at en applikation leverer og anvender DRM-certfikater. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Indstil regler for adgangskode"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller længden samt tilladte tegn i adgangskoder til oplåsning af skærmen."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Tillader, at appen kan ændre browserens historik eller de bogmærker, der er gemt på din telefon. Dette kan give appen tilladelse til at slette eller ændre browserdata. Bemærk! Denne tilladelse håndhæves muligvis ikke af tredjepartsbrowsere eller andre applikationer med websøgningsfunktioner."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"indstille en alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Tillader, at appen kan indstille en alarm i en installeret alarmapp. Nogle alarmapps har muligvis ikke denne funktion."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"tilføje telefonsvarer"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Tillader, at appen kan tilføje beskeder på din telefonsvarer."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"læs alle talebeskeder"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 6f08ba2..05bd32e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flugmodus ist AN."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flugmodus ist AUS."</string>
<string name="global_action_settings" msgid="1756531602592545966">"Einstellungen"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Jetzt sperren"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-System"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ermöglicht der App, die Kalibrierungsparameter des Touchscreens zu ändern. Für normale Apps sollte dies nie erforderlich sein."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"Auf DRM-Zertifikate zugreifen"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ermöglicht einer App die Bereitstellung und Nutzung von DRM-Zertifikaten. Sollte für normale Apps nie benötigt werden."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Handover-Übertragungen empfangen"</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Ermöglicht das Empfangen von Informationen zum Handover-Übertragungsstatus"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Zulässige Länge und Zeichen für Passwörter zum Entsperren des Bildschirms festlegen"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Versuche zum Entsperren des Displays überwachen"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"Wecker stellen"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Ermöglicht der App, einen Alarm in einer installierten Wecker-App einzurichten. Einige Wecker-Apps implementieren diese Funktion möglicherweise nicht."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"Mailboxnachrichten entfernen"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Ermöglicht der App das Entfernen von Nachrichten aus Ihrer Mailbox"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"Mailbox-Nachrichten hinzufügen"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ermöglicht der App, Nachrichten zu Ihrem Mailbox-Posteingang hinzuzufügen"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"Alle Mailboxnachrichten abrufen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 0539bc9..ea52d18 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Η λειτουργία πτήσης είναι ενεργοποιημένη."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Λειτ. πτήσης είναι ανενεργή"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Ρυθμίσεις"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Κλείδωμα τώρα"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string>
<string name="android_system_label" msgid="6577375335728551336">"Σύστημα Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Επιτρέπει στην εφαρμογή να τροποποιεί τις παραμέτρους βαθμονόμησης της οθόνης αφής. Δεν απαιτείται για τις κανονικές εφαρμογές."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"πρόσβαση σε πιστοποιητικά DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Επιτρέπει σε μια εφαρμογή να παρέχει και να χρησιμοποιεί πιστοποιητικά DRM. Δεν θα χρειαστεί ποτέ για κανονικές εφαρμογές."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Λήψη εκπομπών μεταφοράς παράδοσης."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Επιτρέπει τη λήψη πληροφοριών κατάστασης μεταφοράς παράδοσης."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Επιτρέπει στην εφαρμογή την τροποποίηση του ιστορικού του προγράμματος περιήγησης ή των σελιδοδεικτών που έχουν αποθηκευτεί στο τηλέφωνό σας. Αυτό μπορεί να δίνει τη δυνατότητα στην εφαρμογή να διαγράφει ή να τροποποιεί δεδομένα του προγράμματος περιήγησης. Σημείωση: αυτή η άδεια ίσως να μην μπορεί να εφαρμοστεί από τρίτα προγράμματα περιήγησης ή άλλες εφαρμογές με δυνατότητες περιήγησης ιστού."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ρύθμιση ξυπνητηριού"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Επιτρέπει στην εφαρμογή τη ρύθμιση μιας ειδοποίησης σε μια εγκατεστημένη εφαρμογή ξυπνητηριού. Ορισμένες εφαρμογές ξυπνητηριού ενδέχεται να μην μπορούν να ενσωματώσουν αυτήν τη λειτουργία."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"κατάργηση μηνυμάτων αυτόματου τηλεφωνητή"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Επιτρέπει στην εφαρμογή να καταργεί μηνύματα από τα εισερχόμενα του αυτόματου τηλεφωνητή σας."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"προσθήκη τηλεφωνητή"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Επιτρέπει στην εφαρμογή να προσθέτει μηνύματα στα εισερχόμενα του αυτόματου τηλεφωνητή σας."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"ανάγνωση όλων των μηνυμάτων του αυτόματου τηλεφωνητή"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 18e11df..0f3513d 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aeroplane mode is ON"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Aeroplane mode is OFF"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Settings"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"access DRM certificates"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Allows an application to provision and use DRM certficates. Should never be needed for normal apps."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Receive handover transfer broadcasts."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Allows receiving handover transfer status information."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Allows the app to modify the Browser\'s history or bookmarks stored on your phone. This may allow the app to delete or modify Browser data. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"set an alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Allows the app to set an alarm in an installed alarm clock app. Some alarm clock apps may not implement this feature."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"remove voicemails"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Allows the app to remove messages from your voicemail inbox."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"add voicemail"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Allows the app to add messages to your voicemail inbox."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"read all voicemail"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 18e11df..0f3513d 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aeroplane mode is ON"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Aeroplane mode is OFF"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Settings"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"access DRM certificates"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Allows an application to provision and use DRM certficates. Should never be needed for normal apps."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Receive handover transfer broadcasts."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Allows receiving handover transfer status information."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Allows the app to modify the Browser\'s history or bookmarks stored on your phone. This may allow the app to delete or modify Browser data. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"set an alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Allows the app to set an alarm in an installed alarm clock app. Some alarm clock apps may not implement this feature."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"remove voicemails"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Allows the app to remove messages from your voicemail inbox."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"add voicemail"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Allows the app to add messages to your voicemail inbox."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"read all voicemail"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 2451d62..2d88ca0 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"El modo avión está Activado"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"El modo avión está Desactivado"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Configuración"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"Acceder a certificados DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que una aplicación proporcione y utilice certificados DRM. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que la aplicación modifique el historial o los marcadores del navegador almacenados en el dispositivo. La aplicación puede utilizar este permiso para borrar o modificar los datos del navegador. Nota: Este permiso no puede ser utilizado por navegadores externos ni otras aplicaciones que tengan funciones de navegación por Internet."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"programar una alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que la aplicación establezca una alarma en una aplicación de alarma instalada. Es posible que algunas aplicaciones de alarma no incluyan esta función."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"agregar correo de voz"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que la aplicación agregue mensajes a la bandeja de entrada de tu buzón de voz."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"Consultar todos los mensajes del buzón de voz"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> borrado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"¿Usar bloqueo de aplicación?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"El bloqueo de aplicación bloquea la pantalla en una sola aplicación.\n\nMantén presionado el botón de aplicaciones recientes $ para salir."</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NO"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"INICIAR"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Iniciar bloqueo de aplicación"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Salir de bloqueo de aplicación"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0bc3a92..f5f1428 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo avión activado. Desactivar"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo avión desactivado. Activar"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Ajustes"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"> 999"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"acceder a certificados DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que una aplicación proporcione y utilice certificados DRM. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Recibe emisiones de la transferencia de la conexión."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Permite recibir información sobre el estado de la transferencia de la conexión."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que la aplicación modifique el historial o los marcadores del navegador almacenados en el teléfono. La aplicación puede utilizar este permiso para borrar o modificar datos del navegador. Nota: este permiso no pueden utilizarlo navegadores externos ni otras aplicaciones que tengan funciones de navegación por Internet."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"establecer una alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que la aplicación establezca una alarma en una aplicación de reloj instalada. Es posible que algunas aplicaciones de reloj no incluyan esta función."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"eliminar mensajes de voz"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Permite que la aplicación elimine mensajes de la bandeja de entrada del buzón de voz."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"añadir buzón de voz"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que la aplicación añada mensajes a la bandeja de entrada del buzón de voz."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"consultar todos los mensajes de voz"</string>
@@ -1731,5 +1736,5 @@
<string name="lock_to_app_negative" msgid="8522854387366288195">"NO"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"INICIAR"</string>
<string name="lock_to_app_start" msgid="8889002974248178076">"Iniciar bloqueo de aplicación"</string>
- <string name="lock_to_app_exit" msgid="7033017307788432861">"Salir de bloqueo de aplicación"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Salir del bloqueo de aplicación"</string>
</resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 4012f09..c73eef8 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lennurežiim on SEES"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lennurežiim on VÄLJAS"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Seaded"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Lukusta kohe"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-süsteem"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lubab rakendusel muuta puuteekraani kalibreerimisparameetreid. Ei tohiks kunagi olla vajalik tavaliste rakenduste puhul."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"juurdepääs DRM-i sertifikaatidele"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Lubab rakendusel ette valmistada ja kasutada DRM-i sertifikaate. Tavarakenduste puhul ei tohiks see vajalik olla."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Üleandmise edastuste vastuvõtmine"</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Võimaldab vastu võtta üleandmise olekuteavet."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Võimaldab rakendusel muuta telefoni salvestatud brauseri ajalugu või järjehoidjaid. See võimaldab rakendusel kustutada või muuta brauseri andmeid. Märkus: see luba ei pruugi jõustuda kolmanda osapoole brauserites või teistes veebisirvimisvõimega rakendustes."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"määrake äratus"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Võimaldab rakendusel seada installitud äratuskellarakenduses äratuse. Mõned äratuskellarakendused ei pruugi seda funktsiooni juurutada."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"kõnepostisõnumite eemaldamine"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Võimaldab rakendusel teie kõneposti postkastist sõnumeid eemaldada."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"lisa kõneposti"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Võimaldab rakendusel lisada sõnumeid teie kõneposti postkasti."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"kogu kõneposti lugemine"</string>
@@ -1725,8 +1730,7 @@
<string name="select_year" msgid="7952052866994196170">"Aasta valimine"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valitud"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> on kustutatud"</string>
- <!-- no translation found for managed_profile_label_badge (2355652472854327647) -->
- <skip />
+ <string name="managed_profile_label_badge" msgid="2355652472854327647">"Töö <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"Kas soovite kasutada rakendusele lukustamist?"</string>
<string name="lock_to_app_description" msgid="8597199033462406175">"Rakendusele lukustamise funktsioon lukustab kuva ühele rakendusele.\n\nVäljumiseks hoidke hiljutiste rakenduste nuppu $"</string>
<string name="lock_to_app_negative" msgid="8522854387366288195">"EI"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 30136e76..da802cf 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"حالت هواپیما روشن است"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"حالت هواپیما خاموش است"</string>
<string name="global_action_settings" msgid="1756531602592545966">"تنظیمات"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string>
<string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"سیستم Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"به برنامه امکان میدهد پارامترهای کالیبراسیون صفحه لمسی را تغییر دهد. هرگز نباید برای برنامههای عادی مورد نیاز باشد."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"دسترسی به گواهیهای DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"به یک برنامه کاربردی اجازه ارائه مجوز و استفاده از گواهیهای DRM را میدهد. هرگز برای برنامههای عادی مورد نیاز نیست."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"دریافت پخشهای انتقال تحویلی."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"دریافت اطلاعات وضعیت انتقالی را ممکن میسازد."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"طول و نویسههای مجاز در گذرواژههای بازکردن قفل صفحه را کنترل کنید."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاشهای قفل گشایی صفحه"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"به برنامه اجازه میدهد سابقه مرورگر یا نشانکهای ذخیره شده در تلفن شما را اصلاح کند. این ویژگی ممکن است به برنامه اجازه دهد دادههای مرورگر را حذف یا اصلاح کند. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامههای دارای قابلیت مرور وب قابل اجرا نباشد."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"تنظیم یک هشدار"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"به برنامه اجازه میدهد تا هشداری را در برنامه ساعت زنگدار نصب شده تنظیم کند. برخی از برنامههای ساعت زنگدار نمیتوانند این ویژگی را اعمال کنند."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"حذف پستهای صوتی"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"به برنامه امکان میدهد پیامها را از صندوق ورودی پست صوتی شما حذف کند."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"افزودن پست صوتی"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"به برنامه اجازه میدهد تا پیامها را به صندوق دریافت پست صوتی شما اضافه کند."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"خواندن کل پست صوتی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f833733..9e6cafd 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lentokonetila on KÄYTÖSSÄ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lentokonetila on POIS KÄYTÖSTÄ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Asetukset"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Lukitse nyt"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-järjestelmä"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Antaa sovelluksen muokata kosketusnäytön kalibrointiparametreja. Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM-varmenteiden käyttö"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Antaa sovelluksen käyttää DRM-varmenteita ja hallita niiden käyttäjiä. Ei tavallisten sovellusten käyttöön."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Vastaanota handover-siirtolähetyksiä."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Sallii handover-siirtotietojen vastaanottamisen."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Aseta salasanasäännöt"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Hallinnoi ruudun lukituksenpoistosalasanoissa sallittuja merkkejä ja salasanan pituutta."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Tarkkaile ruudun lukituksen poistoyrityksiä"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Antaa sovelluksen muokata selaimen historiaa ja puhelimeen tallennettuja kirjanmerkkejä. Sovellus voi poistaa tai muokata selaimen tietoja. Huomaa: kolmannen osapuolen selaimet tai muut sovellukset, jotka pystyvät selaamaan verkkoa, eivät saa käyttää tätä lupaa."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"aseta herätys"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Antaa sovelluksen asettaa hälytyksen sisäiseen herätyskellosovellukseen. Jotkin herätyskellosovellukset eivät välttämättä käytä tätä ominaisuutta."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"vastaajaviestien poistaminen"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Antaa sovelluksen poistaa viestejä saapuneista vastaajaviesteistä."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"lisää vastaajaviesti"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Antaa sovelluksen lisätä viestejä saapuneisiin vastaajaviesteihin."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"kaikkien vastaajaviestien luku"</string>
@@ -1726,16 +1731,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valittu"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> poistettiin"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (työ)"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Käytetäänkö sovellukseen lukitusta?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Sovellukseen lukitus lukitsee näytön yhteen sovellukseen.\n\nPoistu pitämällä viimeaikaisten sovellusten painiketta $ painettuna."</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"EI"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"ALOITA"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Aloita sovellukseen lukitus"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Lopeta sovellukseen lukitus"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 5ffa2e7..c23d9aa 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Le mode Avion est activé."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Le mode Avion est désactivé."</string>
<string name="global_action_settings" msgid="1756531602592545966">"Paramètres"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
<string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permet à l\'application de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applications standards."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"accéder aux certificats GDN"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permet à une application de fournir et d\'utiliser les certificats de GDN. Cela ne devrait jamais être nécessaire pour les applications normales."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permet à l\'application de modifier l\'historique du navigateur ou les favoris enregistrés sur votre téléphone. Cette autorisation peut lui permettre d\'effacer ou de modifier les données du navigateur. Remarque : il est possible que cette autorisation ne soit pas appliquée par les navigateurs tiers ni par d\'autres applications permettant de naviguer sur le Web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"définir une alarme"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permet à l\'application de régler la sonnerie d\'une fonction de réveil installée sur votre appareil. Cette fonctionnalité n\'est pas compatible avec toutes les applications de réveils."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ajouter des messages vocaux"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permet à l\'application d\'ajouter des messages à votre messagerie vocale."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"accéder à tous les messages vocaux"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"« <xliff:g id="ITEM">%1$s</xliff:g> » a été sélectionné"</string>
<string name="deleted_key" msgid="7659477886625566590">"« <xliff:g id="KEY">%1$s</xliff:g> » a été supprimé"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Utiliser la fonctionnalité de verrouillage sur l\'application?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"La fonctionnalité « Verrouiller sur l\'application » verrouille l\'écran sur une seule application.\n\nPour quitter ce mode, maintenez le doigt sur le bouton Applications récentes $."</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NON"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"COMMENCER"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Lancer Verrouiller sur l\'application"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Quitter Verrouiller sur l\'application"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e2c7196..5544a45 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Le mode Avion est activé."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Le mode Avion est désactivé."</string>
<string name="global_action_settings" msgid="1756531602592545966">"Paramètres"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
<string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permettre à l\'application de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applications standards."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"accéder aux certificats de GDN"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permettre à une application de fournir et d\'utiliser des certificats de GDN. Ne devrait jamais être nécessaire pour les applications standards."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permet à l\'application de modifier l\'historique du navigateur ou les favoris enregistrés sur votre téléphone. Cette autorisation peut lui permettre d\'effacer ou de modifier les données du navigateur. Remarque : il est possible que cette autorisation ne soit pas appliquée par les navigateurs tiers ni par d\'autres applications permettant de naviguer sur le Web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"définir une alarme"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permet à l\'application de régler la sonnerie d\'un réveil installé. Cette fonctionnalité n\'est pas disponible sur tous les réveils."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ajouter un message vocal"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permet à l\'application d\'ajouter des messages à votre messagerie vocale."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"accéder à tous les messages vocaux"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"\"<xliff:g id="ITEM">%1$s</xliff:g>\" sélectionné"</string>
<string name="deleted_key" msgid="7659477886625566590">"\"<xliff:g id="KEY">%1$s</xliff:g>\" supprimé"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Utiliser la fonctionnalité Verrouiller sur l\'application ?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"La fonctionnalité Verrouiller sur l\'application verrouille l\'écran sur une seule application.\n\nPour quitter ce mode, appuyez de manière prolongée sur le bouton Applications récentes $."</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NON"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"ACTIVER"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Activer Verrouiller sur l\'application"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Quitter Verrouiller sur l\'application"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 8cbb095..379a318 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"हवाई जहाज मोड चालू है"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"हवाई जहाज मोड बंद है"</string>
<string name="global_action_settings" msgid="1756531602592545966">"सेटिंग"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"अभी लॉक करें"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ऐप्स को टच स्क्रीन के कैलिब्रेशन पैरामीटर को बदलने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्र एक्सेस करें"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"एप्लिकेशन को DRM प्रमाणपत्रों का प्रावधान और उपयोग करने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यकता नहीं होना चाहिए."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"हस्तांतरण स्थानान्तरण प्राप्त करें."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"हस्तांतरण स्थानान्तरण स्थिति की जानकारी प्राप्त करने देती है."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"स्क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ऐप्स को आपके फ़ोन में संग्रहीत ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे ऐप्स ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्य ऐप्स द्वारा लागू नहीं की जा सकती."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"अलार्म सेट करें"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"ऐप्स को इंस्टॉल किए गए अलार्म घड़ी ऐप्स में अलार्म सेट करने देता है. हो सकता है कुछ अलार्म घड़ी ऐप्स में यह सुविधा न हो."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"ध्वनिमेल निकालें"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"ऐप्स को आपके ध्वनिमेल इनबॉक्स में से संदेशों को निकालने देती है."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ध्वनिमेल जोड़ें"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ऐप्स को आपके ध्वनिमेल इनबॉक्स में संदेश जोड़ने देता है."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"सभी ध्वनिमेल पढ़ें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index a427eb3..a906ab5 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uključen je način rada u zrakoplovu"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Isključen je način rada u zrakoplovu"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Postavke"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Omogućuje aplikaciji izmjenu parametara kalibracije dodirnog zaslona. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"pristup DRM certifikatima"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Aplikaciji omogućuje pružanje i korištenje DRM certifikata. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Upravljajte duljinom zaporki za otključavanje zaslona i dopuštenim znakovima u tim zaporkama."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledaj pokušaje otključavanja zaslona"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Aplikaciji omogućuje izmjenu povijesti i oznaka Preglednika pohranjenih na telefonu. To aplikaciji može omogućiti brisanje ili izmjenu podataka Preglednika. Napomena: tu dozvolu ne mogu primijeniti preglednici treće strane ili druge aplikacije s mogućnostima pregledavanja weba."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"postavljanje alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Omogućuje aplikaciji postavljanje alarma na instaliranoj aplikaciji budilici. Neke aplikacije budilice možda neće primijeniti tu značajku."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"dodaj govornu poštu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Omogućuje aplikaciji da doda poruke u vašu govornu poštu."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"čitanje svih poruka u govornoj pošti"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"Odabrana je stavka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"Izbrisan je broj <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> za posao"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Želite li upotrijebiti zaključavanje na aplikaciju?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Značajkom zaključavanja na aplikaciju zaključava se prikaz na pojedinačnu aplikaciju.\n\nDa biste je zatvorili, pritisnite i držite gumb za nedavne aplikacije $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NE"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"POKRENI"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Pokretanje zaključavanja na aplikaciju"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Zatvaranje zaključavanja na aplikaciju"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 1fbfdef..931b1f5 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Repülőgép üzemmód bekapcsolva"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Repülőgép üzemmód kikapcsolva"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Beállítások"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Zárolás most"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lehetővé teszi, hogy az alkalmazás módosítsa az érintőképernyő kalibrációs paramétereit. A normál alkalmazásoknál erre elvileg soha nincs szükség."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM-tanúsítványokhoz való hozzáférés"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Engedélyezi egy alkalmazás számára a DRM-tanúsítványokhoz való hozzáférést és azok használatát. Átlagos alkalmazásoknak erre nem lehet szükségük."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Az átadás átviteli adásainak fogadása."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Lehetővé teszi az átadás átviteli állapotinformációinak fogadását."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"A képernyőzár-feloldási jelszavakban engedélyezett karakterek és hosszúság vezérlése."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Képernyőzár-feloldási kísérletek figyelése"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a böngésző előzményeit vagy a telefonon tárolt könyvjelzőket. Az engedéllyel rendelkező alkalmazás törölheti vagy módosíthatja a böngésző adatait. Megjegyzés: előfordulhat, hogy ezt az engedélyt harmadik felek által üzemeltetett böngészők vagy egyéb böngészésre képes alkalmazások nem léptetik életbe."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ébresztés beállítása"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Lehetővé teszi az alkalmazás számára, hogy ébresztőt állítson be egy telepített ébresztőóra alkalmazásban. Egyes ilyen alkalmazásokban lehet, hogy nem működik ez a funkció."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"hangpostaüzenetek eltávolítása"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Lehetővé teszi az alkalmazás számára, hogy üzeneteket távolítson el a bejövő hangpostafiókból."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"hangposta hozzáadása"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Lehetővé teszi az alkalmazás számára, hogy üzeneteket adjon hozzá bejövő hangpostájához."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"az összes hangüzenet olvasása"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 27a65a3..8e36c85 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Ինքնաթիռային ռեժիմը միացված է"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Ինքնաթիռային ռեժիմը անջատված է"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Կարգավորումներ"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Թույլ է տալիս ծրագրին փոփոխել հպէկրանի չափաբերման կարգավորումները: Սովորական ծրագրերի համար երբեք պետք չի գալու:"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM հավաստագրերի մատչում"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ծրագրին թույլ է տալիս տրամադրել և օգտագործել DRM վկայագրեր: Սովորական ծրագրերի համար երբեք պետք չի գալիս:"</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Թույլ է տալիս հավելվածին փոփոխել դիտարկչի պատմությունը կամ ձեր հեռախոսում պահված էջանիշերը: Այն կարող է թույլ տալ հավելվածին ջնջել կամ փոփոխել դիտարկչի տվյալները: Նշում. այս թույլտվությունը չի կարող գործածվել կողմնակի դիտարկիչների կամ վեբ զննարկման հնարավորություններով այլ հավելվածների կողմից:"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"դնել ազդանշան"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Թույլ է տալիս հավելվածին սահմանել զարթուցիչի ծրագրում տեղադրված ազդանշանը: Զարթուցիչի որոշ հավելվածներ չեն կարող կիրառել այս հատկությունը:"</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ավելացնել ձայնային փոստ"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Թույլ է տալիս հավելվածին ավելացնել հաղորդագրություններ ձեր ձայնային փոստի արկղում:"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"կարդալ ձայնային հաղորդագրությունները"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"Ընտրված է <xliff:g id="ITEM">%1$s</xliff:g> տարրը"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> թիվը ջնջված է"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Աշխատանքային <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Օգտագործե՞լ lock-to-app գործառույթը:"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Lock-to-app գործառույթը արգելափակում է ցուցադրումը առանձին ծրագրերում:\n\nԳործառույթն անջատելու համար սեղմեք և պահեք վերջին ծրագրերի կոճակը $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"Ոչ"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"Այո"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Միացնել Lock-to-app գործառույթը"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Անջատել Lock-to-app գործառույթը"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 666d585..fd164cc 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mode pesawat AKTIF"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mode pesawat MATI"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Setelan"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Memungkinkan aplikasi mengubah parameter kalibrasi layar sentuh. Tidak diperlukan oleh aplikasi normal."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"mengakses sertifikat DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Memungkinkan aplikasi menyediakan dan menggunakan sertifikat DRM. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Terima siaran transfer penyerahan."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Memungkinkan penerimaan informasi status transfer penyerahan."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrol panjang dan karakter yang diizinkan dalam sandi pembuka layar."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Upaya pembukaan kunci layar monitor"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Memungkinkan aplikasi mengubah riwayat atau bookmark Browser yang tersimpan dalam ponsel Anda. Izin ini memungkinkan aplikasi menghapus atau mengubah data Browser. Catatan: izin ini tidak dapat diberlakukan oleh browser pihak ketiga atau aplikasi lain dengan kemampuan menjelajahi web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"setel alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Mengizinkan apl menyetel alarm di apl jam alarm yang terpasang. Beberapa apl jam alarm mungkin tidak menerapkan fitur ini."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"buang pesan suara"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Memungkinkan aplikasi membuang pesan dari kotak masuk pesan suara."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"tambahkan kotak pesan"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Mengizinkan apl menambahkan pesan ke kotak masuk untuk pesan suara Anda."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"baca semua kotak pesan"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3397834..81d6290 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modalità aereo attiva"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modalità aereo non attiva"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Impostazioni"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Blocca ora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Consente all\'app di modificare i parametri di calibrazione del touch screen. Questa opzione non deve essere utilizzata per le app normali."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"accesso a certificati DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Consente a un\'app di fornire e utilizzare ceritificati DRM. Questa opzione non deve essere utilizzata per app normali."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Ricevi trasmissioni del trasferimento."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Consente di ricevere informazioni sullo stato del trasferimento."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Impostazione regole password"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlla la lunghezza e i caratteri ammessi nelle password di sblocco dello schermo."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Controllo tentativi di sblocco dello schermo"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Consente all\'applicazione di modificare la cronologia o i segnalibri del Browser memorizzati sul telefono. Ciò potrebbe consentire all\'applicazione di cancellare o modificare i dati del Browser. Nota. È possibile che questa autorizzazione non sia applicabile da browser di terze parti o altre applicazioni con funzionalità di navigazione web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"impostazione allarme"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Consente all\'applicazione di impostare un allarme in un\'applicazione sveglia installata. È possibile che alcune applicazioni sveglia non possano implementare questa funzione."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"rimuovi messaggi vocali"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Consente all\'app di rimuovere messaggi dalla segreteria."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"aggiunta di un messaggio vocale"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Consente all\'applicazione di aggiungere messaggi alla casella della segreteria."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"accesso alla segreteria"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index f67ae0c..d8c6675d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"מצב טיסה מופעל"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"מצב טיסה כבוי"</string>
<string name="global_action_settings" msgid="1756531602592545966">"הגדרות"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"נעל עכשיו"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string>
<string name="android_system_label" msgid="6577375335728551336">"מערכת Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"מאפשרת לאפליקציה לשנות את פרמטרי הכיול של מסך המגע. לעולם לא אמורה להיות נחוצה לאפליקציות רגילות."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"גישה אל אישורי DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"מאפשרת לאפליקציה לנהל תצורה של אישורי DRM ולהשתמש בהם. לעולם לא אמורה להיות נחוצה עבור אפליקציה רגילה."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"קבל שידורים על העברת שליטה."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"מאפשר קבלה של מידע על סטטוס העברת שליטה."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"מאפשר לאפליקציה לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטלפון. הדבר עשוי לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"הגדרת התראה"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"מאפשר לאפליקציה להגדיר התראה באפליקציה מותקנת של שעון מעורר. אפליקציות מסוימות של שעון מעורר אינן מיישמות תכונה זו."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"הסרה של הודעות דואר קולי"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"מאפשרת לאפליקציה להסיר הודעות מתיבת הדואר הנכנס של דואר קולי."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"הוסף דואר קולי"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"מאפשר לאפליקציה להוסיף הודעות לתיבת הדואר הקולי."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"קריאת כל הדואר הקולי"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 1bd8906..1ad0573 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"機内モードON"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"機内モードOFF"</string>
<string name="global_action_settings" msgid="1756531602592545966">"設定"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"セーフモード"</string>
<string name="android_system_label" msgid="6577375335728551336">"Androidシステム"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"タッチスクリーンの調整パラメータの変更をアプリに許可します。通常のアプリでは必要ありません。"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM証明書へのアクセス権"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM証明書のプロビジョニングと使用をアプリに許可します。通常のアプリでは不要です。"</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"携帯端末に保存されているブラウザの履歴やブックマークの変更をアプリに許可します。これにより、アプリがブラウザデータを消去または変更できるようになる可能性があります。注: この許可は、サードパーティブラウザまたはウェブブラウジング機能を備えたその他のアプリでは適用されない場合があります。"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"アラームの設定"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"インストール済みアラームアプリのアラームを設定することをアプリに許可します。この機能が実装されていないアラームアプリもあります。"</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ボイスメールの追加"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ボイスメール受信トレイにメッセージを追加することをアプリに許可します。"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"すべてのボイスメールの読み取り"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>を選択しました"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g>を削除しました"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"仕事の<xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Lock-to-appの使用"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Lock-to-appでは1つのアプリの表示をロックします。\n\n終了するには[最近使ったアプリ]ボタン($)を押し続けます"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"開始しない"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"開始する"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Lock-to-appを開始"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Lock-to-appを終了"</string>
</resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index a7601d2..bd6dea96 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"თვითმფრინავის რეჟიმი ჩართულია."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"თვითმფრინავის რეჟიმი გამორთულია."</string>
<string name="global_action_settings" msgid="1756531602592545966">"პარამეტრები"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-ის სისტემა"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"საშუალებას აძლევს აპს შეცვალოს სენსორული ეკრანის კალიბრაციის პარამეტრები. ჩვეულებრივ აპებს წესით არ უნდა დაჭირდეს."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM სერთიფიკატებზე წვდომა"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"საშუალებას აძლევს აპლიკაციას დანერგოს და გამოიყენოს DRM სერთიფიკატები. ეს უფლება ჩვეულებრივ აპებს არ ჭირდება."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"აპს შეეძლება, შეცვალოს ბრაუზერის ისტორია და თქვენ ტელეფონში შენახული სანიშნეები. ამან შეიძლება უფლება მისცეს აპს, წაშალოს ან შეცვალოს ბრაუზერის მონაცემები. შენიშვნა: ეს ნებართვა არ შეიძლება შესრულდეს მესამე მხარის ბრაუზერების ან ვებ დათვალიერების შესაძლებლობის მქონე სხვა აპლიკაციების მიერ."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"მაღვიძარას დაყენება"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"აპს შეეძლება მაღვიძარას დაყენება დაინსტალირებული მაღვიძარას აპლიკაციაში. ამ ფუნქციას მაღვიძარას ზოგიერთი აპი არ იყენებს."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ხმოვანი ფოსტის დამატება"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"აპს შეეძლება დაამატოს შეტყობინებები თქვენი ხმოვანი ფოსტის შემოსულებში."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"მთელი ხმოვანი ფოსტის წაკითხვა"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"არჩეულია <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> წაიშალა"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"გსურთ „აპში ჩაკეტვის“ გამოყენება?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"„აპში ჩაკეტვა“ კეტავს ეკრანს ერთ აპში.\n\nგასასვლელად დააჭირეთ და არ აუშვათ ღილაკს „ბოლო აპები“ $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"არა"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"დაწყება"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"„აპში ჩაკეტვის“ დაწყება"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"„აპში ჩაკეტვიდან“ გასვლა"</string>
</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index d8bf2ff..f54b36e 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -68,7 +68,7 @@
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
- <string name="ClipMmi" msgid="6952821216480289285">"លេខសម្គាល់អ្នកហៅចូល"</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"លេខសម្គាល់អ្នកហៅចូល"</string>
<string name="ClirMmi" msgid="7784673673446833091">"លេខសម្គាល់អ្នកហៅចេញ"</string>
<string name="CfMmi" msgid="5123218989141573515">"បញ្ជូនការហៅបន្ត"</string>
<string name="CwMmi" msgid="9129678056795016867">"រង់ចាំការហៅ"</string>
@@ -125,7 +125,7 @@
<string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> ៖ មិនបានបញ្ជូនបន្ត"</string>
<string name="fcComplete" msgid="3118848230966886575">"កូដលក្ខណៈពេញលេញ។"</string>
<string name="fcError" msgid="3327560126588500777">"បញ្ហាការតភ្ជាប់ ឬកូដលក្ខណៈមិនត្រឹមត្រូវ។"</string>
- <string name="httpErrorOk" msgid="1191919378083472204">"យល់ព្រម"</string>
+ <string name="httpErrorOk" msgid="1191919378083472204">"យល់ព្រម"</string>
<string name="httpError" msgid="7956392511146698522">"មានកំហុសបណ្ដាញ។"</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"រកមិនឃើញ URL ។"</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"គ្រោងការណ៍ផ្ទៀងផ្ទាត់តំបន់បណ្ដាញមិនត្រូវបានគាំទ្រ។"</string>
@@ -183,8 +183,10 @@
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"បើកសំឡេង"</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"ពេលជិះយន្តហោះ"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"បានបើករបៀបពេលជិះយន្តហោះ"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បានបិទរបៀបពេលជិះយន្តហោះ"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បានបិទរបៀបពេលជិះយន្តហោះ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"ការកំណត់"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"របៀបសុវត្ថិភាព"</string>
<string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ Android"</string>
@@ -195,7 +197,7 @@
<string name="permgrouplab_messages" msgid="7521249148445456662">"សាររបស់អ្នក"</string>
<string name="permgroupdesc_messages" msgid="7821999071003699236">"អាន និងសរសេរសារ SMS, អ៊ីមែល និងសារផ្សេងៗទៀតរបស់អ្នក។"</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ព័ត៌មានផ្ទាល់ខ្លួនរបស់អ្នក"</string>
- <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីអ្នក ដែលបានរក្សាទុកក្នុងកាតទំនាក់ទំនងរបស់អ្នក។"</string>
+ <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីអ្នក ដែលបានរក្សាទុកក្នុងកាតទំនាក់ទំនងរបស់អ្នក។"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មានសង្គមរបស់អ្នក"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីទំនាក់ទំនង និងការភ្ជាប់សង្គមរបស់អ្នក។"</string>
<string name="permgrouplab_location" msgid="635149742436692049">"ទីតាំងរបស់អ្នក"</string>
@@ -384,7 +386,7 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"ឲ្យកម្មវិធីមើលគ្រាប់ចុចដែលអ្នកចុចពេលមានអន្តរកម្មជាមួយកម្មវិធីផ្សេង (ដូចជា បញ្ចូលពាក្យសម្ងាត់)។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"ចងទៅវិធីសាស្ត្របញ្ចូល"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃវិធីសាស្ត្របញ្ចូល។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចងសេវាកម្មភាពមធ្យោបាយងាយស្រួល"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចងសេវាកម្មភាពមធ្យោបាយងាយស្រួល"</string>
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មភាពងាយស្រួល។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"ចងសេវាកម្មបោះពុម្ព"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -404,7 +406,7 @@
<string name="permdesc_manageVoiceKeyphrases" msgid="8476560722907530008">"អនុញ្ញាតឲ្យម្ចាស់គ្រប់គ្រងឃ្លាសម្រាប់ការរកឃើញពាក្យជាសំឡេង។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"ភ្ជាប់ទៅការបង្ហាញពីចម្ងាយ"</string>
<string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលនៃការបង្ហាញពីចម្ងាយ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចងសេវាកម្មធាតុក្រាហ្វិក"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចងសេវាកម្មធាតុក្រាហ្វិក"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ភ្ជាប់ទៅសេវាកម្មក្រុមហ៊ុនផ្ដល់ច្រក"</string>
<string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅក្រុមហ៊ុនផ្ដល់ច្រកដែលបានចុះឈ្មោះ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -412,7 +414,7 @@
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យម្ចាស់ផ្ញើគោលបំណងទៅអ្នកគ្រប់គ្រងឧបករណ៍។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindTvInput" msgid="5601264742478168987">"ភ្ជាប់ទៅការបញ្ចូលទូរទស្សន៍"</string>
<string name="permdesc_bindTvInput" msgid="2371008331852001924">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតខ្ពស់នៃការបញ្ចូលទូរទស្សន៍។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍"</string>
+ <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍"</string>
<string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"អនុញ្ញាតឲ្យម្ចាស់បន្ថែម ឬលុបកម្មវិធីគ្រប់គ្រងឧបករណ៍សកម្មចេញ។ មិនគួរប្រើសម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"ប្ដូរទិសអេក្រង់"</string>
<string name="permdesc_setOrientation" msgid="3046126619316671476">"ឲ្យកម្មវិធីប្ដូរការបង្វិលអេក្រង់នៅពេលណាមួយ។ មិនចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
@@ -424,9 +426,9 @@
<string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ឲ្យកម្មវិធីស្នើសញ្ញាដែលបានផ្ដល់ត្រូវផ្ញើទៅដំណើរការស្ថិតស្ថេរទាំងអស់។"</string>
<string name="permlab_persistentActivity" msgid="8841113627955563938">"ធ្វើឲ្យកម្មវិធីដំណើរការជានិច្ច"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ឲ្យកម្មវិធីធ្វើជាផ្នែកស្ថិតស្ថេរដោយខ្លួនឯងក្នុងអង្គចងចាំ។ វាអាចកំណត់អង្គចងចាំដែលអាចប្រើបានចំពោះកម្មវិធីផ្សេងៗ ដោយធ្វើឲ្យកុំព្យូទ័របន្ទះយឺត។"</string>
- <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យកម្មវិធី ធ្វើជាផ្នែកអចិន្ត្រៃយ៍នៃខ្លួនក្នុងអង្គចងចាំ។ វាអាចកម្រិតអង្គចងចាំអាចប្រើបាន ដើម្បីធ្វើឲ្យកម្មវិធីផ្សេងធ្វើឲ្យទូរស័ព្ទរបស់អ្នកយឺត។"</string>
+ <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យកម្មវិធី ធ្វើជាផ្នែកអចិន្ត្រៃយ៍នៃខ្លួនក្នុងអង្គចងចាំ។ វាអាចកម្រិតអង្គចងចាំអាចប្រើបាន ដើម្បីធ្វើឲ្យកម្មវិធីផ្សេងធ្វើឲ្យទូរស័ព្ទរបស់អ្នកយឺត។"</string>
<string name="permlab_deletePackages" msgid="184385129537705938">"លុបកម្មវិធី"</string>
- <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យកម្មវិធីលុបកញ្ចប់ Android ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុបកម្មវិធីសំខាន់ៗ។ "</string>
+ <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យកម្មវិធីលុបកញ្ចប់ Android ។ កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុបកម្មវិធីសំខាន់ៗ។"</string>
<string name="permlab_clearAppUserData" msgid="274109191845842756">"លុបទិន្នន័យរបស់កម្មវិធីផ្សេង"</string>
<string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ឲ្យកម្មវិធីសម្អាតទិន្នន័យអ្នកប្រើ។"</string>
<string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"លុបឃ្លាំងសម្ងាត់កម្មវិធីផ្សេងៗ"</string>
@@ -477,7 +479,7 @@
<string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងកុំព្យូទ័របន្ទះ រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនងជាក់លាក់។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនងរបស់អ្នក។"</string>
<string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"ឲ្យកម្មវិធីកែទិន្នន័យអំពីទំនាក់ទំនងរបស់អ្នកដែលបានរក្សាទុកក្នុងទូរស័ព្ទរបស់អ្នក រួមមានប្រេកង់ដែលអ្នកបានហៅ អ៊ីមែល ឬបានទាក់ទងតាមវិធីផ្សេងៗជាមួយទំនាក់ទំនាក់ជាក់លាក់។ សិទ្ធិនេះឲ្យកម្មវិធីលុបទិន្នន័យទំនាក់ទំនង។"</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"អានកំណត់ហេតុហៅ"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យកម្មវិធីអានបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យកម្មវិធីអានបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
<string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ឲ្យកម្មវិធីអានបញ្ជីហៅទូរស័ព្ទរបស់អ្នក រួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។ សិទ្ធិនេះអនុញ្ញាតឲ្យកម្មវិធីរក្សាទុកទិន្នន័យបញ្ជីហៅរបស់អ្នក ហើយកម្មវិធីព្យាបាទអាចចែករំលែកទិន្នន័យបញ្ជីហៅដោយមិនឲ្យអ្នកដឹង។"</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"សរសេរបញ្ជីហៅ"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ឲ្យកម្មវិធីកែបញ្ជីហៅកុំព្យូទ័របន្ទះរបស់អ្នករួមមានទិន្នន័យអំពីការហៅចូល និងចេញ។កម្មវិធីព្យាបាទអាចប្រើវា ដើម្បីលុប ឬកែបញ្ជីហៅរបស់អ្នក។"</string>
@@ -613,7 +615,7 @@
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"ឲ្យកម្មវិធីកំណត់ជំនួយទំហំផ្ទាំងរូបភាពប្រព័ន្ធ។"</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"កំណត់ប្រព័ន្ធទៅលំនាំដើមរោងចក្រឡើងវិញ"</string>
<string name="permdesc_masterClear" msgid="3665380492633910226">"ឲ្យកម្មវិធីកំណត់ប្រព័ន្ធដូចការកំណត់ចេញពីរោងចក្រឡើងវិញពេញលេញ ដោយលុបទិន្នន័យ ការកំណត់រចនាសម្ព័ន្ធ និងកម្មវិធីបានដំឡើង។"</string>
- <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់ម៉ោង"</string>
+ <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់ម៉ោង"</string>
<string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ឲ្យកម្មវិធីប្ដូរម៉ោងកុំព្យូទ័របន្ទះ។"</string>
<string name="permdesc_setTime" product="default" msgid="1855702730738020">"ឲ្យកម្មវិធីប្ដូរម៉ោងទូរស័ព្ទ។"</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"កំណត់តំបន់ពេលវេលា"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ឲ្យកម្មវិធីកែប៉ារ៉ាម៉ែត្រកែចំណុចនៃការប៉ះអេក្រង់។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"ចូលមើលវិញ្ញាបនបត្រ DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ឲ្យកម្មវិធីផ្ដល់ និងប្រើវិញ្ញាបនបត្រ DRM ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់ក្បួនពាក្យសម្ងាត់"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យប្រវែង និងតួអក្សរដែលបានអនុញ្ញាតក្នុងពាក្យសម្ងាត់ចាក់សោអេក្រង់។"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យការព្យាយាមដោះសោអេក្រង់"</string>
@@ -779,7 +785,7 @@
<string-array name="organizationTypes">
<item msgid="7546335612189115615">"កន្លែងធ្វើការ"</item>
<item msgid="4378074129049520373">"ផ្សេងៗ"</item>
- <item msgid="3455047468583965104">"តាមតម្រូវការ"</item>
+ <item msgid="3455047468583965104">"តាមតម្រូវការ"</item>
</string-array>
<string-array name="imProtocols">
<item msgid="8595261363518459565">"AIM"</item>
@@ -795,7 +801,7 @@
<string name="phoneTypeHome" msgid="2570923463033985887">"ផ្ទះ"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"ចល័ត"</string>
<string name="phoneTypeWork" msgid="8863939667059911633">"កន្លែងធ្វើការ"</string>
- <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារកន្លែងធ្វើការ"</string>
+ <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារកន្លែងធ្វើការ"</string>
<string name="phoneTypeFaxHome" msgid="2067265972322971467">"ទូរសារផ្ទះ"</string>
<string name="phoneTypePager" msgid="7582359955394921732">"ភេយ័រ"</string>
<string name="phoneTypeOther" msgid="1544425847868765990">"ផ្សេងៗ"</string>
@@ -920,7 +926,7 @@
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"ដើម្បីដោះសោ ចូលគណនី Google របស់អ្នក។"</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"ឈ្មោះអ្នកប្រើ (អ៊ីមែល)"</string>
- <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់"</string>
+ <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"ពាក្យសម្ងាត់"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ចូល"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -965,7 +971,7 @@
<string name="factorytest_failed" msgid="5410270329114212041">"បានបរាជ័យក្នុងការសាកល្បងរោងចក្រ"</string>
<string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវបានគាំទ្រសម្រាប់តែកញ្ចប់បានដំឡើងក្នុង /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"រកមិនឃើញកញ្ចប់ដែលផ្ដល់សកម្មភាព FACTORY_TEST ។"</string>
- <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់ផ្ដើមឡើងវិញ"</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់ផ្ដើមឡើងវិញ"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"ទំព័រមានចំណងជើង \"<xliff:g id="TITLE">%s</xliff:g>\" សរសេរ៖"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"បញ្ជាក់ការរុករក"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ឲ្យកម្មវិធីកែប្រវត្តិ ឬចំណាំរបស់កម្មវិធីអ៊ីនធឺណិតដែលបានរក្សាទុកក្នុងទូរស័ព្ទរបស់អ្នក។ កម្មវិធីព្យាបាទអាចប្រើវាដើម្បីលុប ឬកែទិន្នន័យនៃកម្មវិធីអ៊ីនធឺណិតរបស់អ្នក។ ចំណាំ៖ សិទ្ធិនេះអាចត្រូវបានបង្ខំដោយកម្មវិធីអ៊ីនធឺណិតភាគីទីបី ឬកម្មវិធីផ្សេងដែលមានសមត្ថភាពរុករកបណ្ដាញ។ស"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"កំណត់សំឡេងរោទ៍"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"ឲ្យកម្មវិធីកំណត់សំឡេងរោទ៍ក្នុងកម្មវិធីនាឡិការោទ៍បានដំឡើង។ កម្មវិធីនាឡិការោទ៍មួយចំនួនអាចមិនអនុវត្តលក្ខណៈនេះ។"</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"បន្ថែមសារជាសំឡេង"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ឲ្យកម្មវិធីបន្ថែមសារទៅប្រអប់ទទួលសារជាសំឡេងរបស់អ្នក។"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"អានសារជាសំឡេងទាំងអស់"</string>
@@ -1025,7 +1035,7 @@
<string name="prepend_shortcut_label" msgid="2572214461676015642">"ម៉ឺនុយ +"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"ដកឃ្លា"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
- <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប"</string>
+ <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"លុប"</string>
<string name="search_go" msgid="8298016669822141719">"ស្វែងរក"</string>
<string name="searchview_description_search" msgid="6749826639098512120">"ស្វែងរក"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"ស្វែងរកសំណួរ"</string>
@@ -1109,18 +1119,18 @@
<string name="preposition_for_date" msgid="9093949757757445117">"នៅ <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="preposition_for_time" msgid="5506831244263083793">"នៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"ក្នុងឆ្នាំ <xliff:g id="YEAR">%s</xliff:g>"</string>
- <string name="day" msgid="8144195776058119424">"ថ្ងៃ"</string>
+ <string name="day" msgid="8144195776058119424">"ថ្ងៃ"</string>
<string name="days" msgid="4774547661021344602">"ថ្ងៃ"</string>
<string name="hour" msgid="2126771916426189481">"ម៉ោង"</string>
<string name="hours" msgid="894424005266852993">"ម៉ោង"</string>
- <string name="minute" msgid="9148878657703769868">"នាទី"</string>
+ <string name="minute" msgid="9148878657703769868">"នាទី"</string>
<string name="minutes" msgid="5646001005827034509">"នាទី"</string>
- <string name="second" msgid="3184235808021478">"វិនាទី"</string>
+ <string name="second" msgid="3184235808021478">"វិនាទី"</string>
<string name="seconds" msgid="3161515347216589235">"វិនាទី"</string>
- <string name="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
- <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
- <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
- <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
+ <string name="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
+ <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
+ <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
+ <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
<plurals name="duration_seconds">
<item quantity="one" msgid="6962015528372969481">"1 វិនាទី"</item>
<item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
@@ -1136,12 +1146,12 @@
<string name="VideoView_error_title" msgid="3534509135438353077">"បញ្ហាវីដេអូ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"វីដេអូនេះមិនត្រឹមត្រូវសម្រាប់ចរន្តចូលឧបករណ៍នេះ។"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"មិនអាចចាក់វីដេអូនេះ។"</string>
- <string name="VideoView_error_button" msgid="2822238215100679592">"យល់ព្រម"</string>
+ <string name="VideoView_error_button" msgid="2822238215100679592">"យល់ព្រម"</string>
<string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="noon" msgid="7245353528818587908">"រសៀល"</string>
<string name="Noon" msgid="3342127745230013127">"រសៀល"</string>
<string name="midnight" msgid="7166259508850457595">"កណ្ដាលអធ្រាត្រ"</string>
- <string name="Midnight" msgid="5630806906897892201">"កណ្ដាលអធ្រាត្រ"</string>
+ <string name="Midnight" msgid="5630806906897892201">"កណ្ដាលអធ្រាត្រ"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="6876518925844129331">"ជ្រើសទាំងអស់"</string>
@@ -1158,13 +1168,13 @@
<string name="inputMethod" msgid="1653630062304567879">"វិធីសាស្ត្របញ្ចូល"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាពអត្ថបទ"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់ទំហំផ្ទុក"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារប្រព័ន្ធមួយចំនួនអាចមិនដំណើរការ"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារប្រព័ន្ធមួយចំនួនអាចមិនដំណើរការ"</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងដំណើរការ"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"ប៉ះ ដើម្បីមើលព័ត៌មានបន្ថែម ឬបញ្ឈប់កម្មវិធី។"</string>
- <string name="ok" msgid="5970060430562524910">"យល់ព្រម"</string>
- <string name="cancel" msgid="6442560571259935130">"បោះបង់"</string>
- <string name="yes" msgid="5362982303337969312">"យល់ព្រម"</string>
- <string name="no" msgid="5141531044935541497">"បោះបង់"</string>
+ <string name="ok" msgid="5970060430562524910">"យល់ព្រម"</string>
+ <string name="cancel" msgid="6442560571259935130">"បោះបង់"</string>
+ <string name="yes" msgid="5362982303337969312">"យល់ព្រម"</string>
+ <string name="no" msgid="5141531044935541497">"បោះបង់"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"ប្រយ័ត្ន"</string>
<string name="loading" msgid="7933681260296021180">"កំពុងផ្ទុក..."</string>
<string name="capital_on" msgid="1544682755514494298">"បើក"</string>
@@ -1173,7 +1183,7 @@
<string name="whichHomeApplication" msgid="4616420172727326782">"ជ្រើសកម្មវិធីដើម"</string>
<string name="alwaysUse" msgid="4583018368000610438">"ប្រើតាមលំនាំដើមសម្រាប់សកម្មភាពនេះ។"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"សម្អាតលំនាំដើមក្នុងការកំណត់ប្រព័ន្ធ > កម្មវិធី > ទាញយក។"</string>
- <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើសសកម្មភាព"</string>
+ <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើសសកម្មភាព"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"ជ្រើសកម្មវិធីសម្រាប់ឧបករណ៍យូអេសប៊ី"</string>
<string name="noApplications" msgid="2991814273936504689">"គ្មានកម្មវិធីអាចអនុវត្តសកម្មភាពនេះ។"</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
@@ -1184,7 +1194,7 @@
<string name="anr_activity_process" msgid="5776209883299089767">"សកម្មភាព <xliff:g id="ACTIVITY">%1$s</xliff:g> មិនឆ្លើយតប។\n\nតើអ្នកចង់បិទវា?"</string>
<string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> មិនឆ្លើយតប។ តើអ្នកចង់បិទវា?"</string>
<string name="anr_process" msgid="6513209874880517125">"ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> មិនឆ្លើយតប។ \n\nតើអ្នកចង់បិទវាឬ?"</string>
- <string name="force_close" msgid="8346072094521265605">"យល់ព្រម"</string>
+ <string name="force_close" msgid="8346072094521265605">"យល់ព្រម"</string>
<string name="report" msgid="4060218260984795706">"រាយការណ៍"</string>
<string name="wait" msgid="7147118217226317732">"រង់ចាំ"</string>
<string name="webpage_unresponsive" msgid="3272758351138122503">"ទំព័រក្លាយជាមិនឆ្លើយតប។\n\nតើអ្នកចង់បិទវា?"</string>
@@ -1266,19 +1276,19 @@
<string name="sms_short_code_details" msgid="3492025719868078457"><font fgcolor="#ffffb060">"នេះអាចកាត់លុយ"</font>" លើគណនីចល័តរបស់អ្នក។"</string>
<string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"វានឹងគិតថ្លៃសេវាកម្មលើគណនីចល័តរបស់អ្នក។"</font></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ផ្ញើ"</string>
- <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះបង់"</string>
+ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"បោះបង់"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ចងចាំជម្រើសរបស់ខ្ញុំ"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"អ្នកអាចប្ដូរវាពេលក្រោយក្នុងការកំណត់ > កម្មវិធី"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"អនុញ្ញាតជានិច្ច"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"កុំអនុញ្ញាត"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"បានដកស៊ីមកាតចេញ"</string>
- <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញចល័តនឹងប្រើលែងបានរហូតដល់អ្នកចាប់ផ្ដើមជាមួយស៊ីមកាតដែលបាបញ្ចូលត្រឹមត្រូវ។"</string>
+ <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញចល័តនឹងប្រើលែងបានរហូតដល់អ្នកចាប់ផ្ដើមជាមួយស៊ីមកាតដែលបាបញ្ចូលត្រឹមត្រូវ។"</string>
<string name="sim_done_button" msgid="827949989369963775">"រួចរាល់"</string>
<string name="sim_added_title" msgid="3719670512889674693">"បានបន្ថែមស៊ីមកាត"</string>
<string name="sim_added_message" msgid="6599945301141050216">"ចាប់ផ្ដើមឧបករណ៍របស់អ្នកឡើងវិញ ដើម្បីចូលដំណើរការបណ្ដាញចល័ត។"</string>
<string name="sim_restart_button" msgid="4722407842815232347">"ចាប់ផ្ដើមឡើងវិញ"</string>
- <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់ម៉ោង"</string>
- <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់កាលបរិច្ឆេទ"</string>
+ <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់ម៉ោង"</string>
+ <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់កាលបរិច្ឆេទ"</string>
<string name="date_time_set" msgid="5777075614321087758">"កំណត់"</string>
<string name="date_time_done" msgid="2507683751759308828">"រួចរាល់"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"ថ្មី៖ "</font></string>
@@ -1356,7 +1366,7 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ឲ្យកម្មវិធីដកសេវាកម្មនៃកម្មវិធីផ្ទុកលំនាំដើម ដើម្បីចម្លងមាតិកា។ មិនសម្រាប់ប្រើដោយកម្មវិធីលំនាំដើម។"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"នាំផ្លូវលទ្ធផលមេឌៀ"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"ឲ្យកម្មវិធីនាំផ្លូវលទ្ធផលមេឌៀទៅឧបករណ៍ខាងក្រៅផ្សេង។"</string>
- <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូលដំណើរការឧបករណ៍ផ្ទុកសុវត្ថិភាព"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូលដំណើរការឧបករណ៍ផ្ទុកសុវត្ថិភាព"</string>
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ឲ្យកម្មវិធីចូលការផ្ទុកមានសុវត្ថិភាព keguard ។"</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"ពិនិត្យការបង្ហាញ និងលាក់ការការពារ"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"ឲ្យកម្មវិធីគ្រប់គ្រង keguard ។"</string>
@@ -1375,7 +1385,7 @@
<string name="ime_action_go" msgid="8320845651737369027">"ទៅ"</string>
<string name="ime_action_search" msgid="658110271822807811">"ស្វែងរក"</string>
<string name="ime_action_send" msgid="2316166556349314424">"ផ្ញើ"</string>
- <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់"</string>
+ <string name="ime_action_next" msgid="3138843904009813834">"បន្ទាប់"</string>
<string name="ime_action_done" msgid="8971516117910934605">"រួចរាល់"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"មុន"</string>
<string name="ime_action_default" msgid="2840921885558045721">"អនុវត្ត"</string>
@@ -1384,7 +1394,7 @@
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"កម្មវិធីមួយ ឬច្រើនដូចខាងក្រោមស្នើសិទ្ធិ ដើម្បីចូលគណនីរបស់អ្នកឥឡូវ និងពេលអនាគត។"</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"តើអ្នកចង់អនុញ្ញាតសំណើនេះ?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"ស្នើចូល"</string>
- <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
+ <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string>
<string name="deny" msgid="2081879885755434506">"បដិសេធ"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"បានស្នើសិទ្ធិ"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"បានស្នើសិទ្ធិ\nសម្រាប់គណនី <xliff:g id="ACCOUNT">%s</xliff:g> ។"</string>
@@ -1407,12 +1417,12 @@
<string name="no_file_chosen" msgid="6363648562170759465">"គ្មានឯកសារបានជ្រើស"</string>
<string name="reset" msgid="2448168080964209908">"កំណត់ឡើងវិញ"</string>
<string name="submit" msgid="1602335572089911941">"ដាក់ស្នើ"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បានបើករបៀបរថយន្ត"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បានបើករបៀបរថយន្ត"</string>
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"ប៉ះ ដើម្បីចេញពីរបៀបរថយន្ត។"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬហតស្ពតសកម្ម"</string>
<string name="tethered_notification_message" msgid="6857031760103062982">"ប៉ះ ដើម្បីរៀបចំ។"</string>
<string name="back_button_label" msgid="2300470004503343439">"ថយក្រោយ"</string>
- <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string>
+ <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string>
<string name="skip_button_label" msgid="1275362299471631819">"រំលង"</string>
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"ការប្រើទិន្នន័យចល័តខ្ពស់"</string>
<string name="throttle_warning_notification_message" msgid="3340822228599337743">"ប៉ះ ដើម្បីស្វែងយល់បន្ថែមអំពីការប្រើទិន្នន័យចល័ត។"</string>
@@ -1438,7 +1448,7 @@
<string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ឧបករណ៍ផ្ទុកយូអេសប៊ីបច្ចុប្បន្នកំពុងប្រើដោយកុំព្យូទ័រ។"</string>
<string name="media_shared" product="default" msgid="5706130568133540435">"បច្ចុប្បន្នកាតអេសឌីកំពុងប្រើដោយកុំព្យូទ័រ"</string>
<string name="media_unknown_state" msgid="729192782197290385">"មិនស្គាល់ស្ថានភាពមេឌៀខាងក្រៅ។"</string>
- <string name="share" msgid="1778686618230011964">"ចែករំលែក"</string>
+ <string name="share" msgid="1778686618230011964">"ចែករំលែក"</string>
<string name="find" msgid="4808270900322985960">"រក"</string>
<string name="websearch" msgid="4337157977400211589">"ស្វែងរកតាមបណ្ដាញ"</string>
<string name="find_next" msgid="5742124618942193978">"រកបន្ទាប់"</string>
@@ -1454,7 +1464,7 @@
<string name="sync_undo_deletes" msgid="2941317360600338602">"មិនធ្វើការលុបវិញ"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"មិនធ្វើអ្វីទេឥឡូវ"</string>
<string name="choose_account_label" msgid="5655203089746423927">"ជ្រើសគណនី"</string>
- <string name="add_account_label" msgid="2935267344849993553">"បន្ថែមគណនីថ្មី"</string>
+ <string name="add_account_label" msgid="2935267344849993553">"បន្ថែមគណនីថ្មី"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"បន្ថែមគណនី"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"បង្កើន"</string>
<string name="number_picker_decrement_button" msgid="476050778386779067">"បន្ថយ"</string>
@@ -1473,15 +1483,15 @@
<string name="date_picker_increment_year_button" msgid="6318697384310808899">"បង្កើនឆ្នាំ"</string>
<string name="date_picker_decrement_year_button" msgid="4482021813491121717">"បន្ថយឆ្នាំ"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូររបៀប"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
- <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើសកម្មវិធី"</string>
+ <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើសកម្មវិធី"</string>
<string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"មិនអាចចាប់ផ្ដើម <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែកជាមួយ"</string>
+ <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែកជាមួយ"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ចែករំលែកជាមួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"គ្រប់គ្រងការរុញ។ ប៉ះ & សង្កត់។"</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស ដើម្បីដោះសោ។"</string>
@@ -1495,7 +1505,7 @@
<string name="storage_internal" msgid="4891916833657929263">"ឧបករណ៍ផ្ទុកខាងក្នុង"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"កាតអេសឌី"</string>
<string name="storage_usb" msgid="3017954059538517278">"ឧបករណ៍ផ្ទុកយូអេសប៊ី"</string>
- <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
+ <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"ការព្រមានប្រើទិន្នន័យ"</string>
<string name="data_usage_warning_body" msgid="2814673551471969954">"ប៉ះ ដើម្បីមើលការប្រើ និងការកំណត់។"</string>
<string name="data_usage_3g_limit_title" msgid="7093334419518706686">"បានបិទទិន្នន័យ 2G-3G"</string>
@@ -1552,7 +1562,7 @@
<string name="media_route_status_available" msgid="6983258067194649391">"ទំនេរ"</string>
<string name="media_route_status_not_available" msgid="6739899962681886401">"មិនទំនេរ"</string>
<string name="media_route_status_in_use" msgid="4533786031090198063">"កំពុងប្រើ"</string>
- <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់ជាប់"</string>
+ <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"អេក្រង់ជាប់"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"អេក្រង់ HDMI"</string>
<string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ត្រួតគ្នា"</string>
<string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
@@ -1584,7 +1594,7 @@
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បីដោះសោ ចូលក្នុងគណនី Google ។"</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីម៉ែល)"</string>
- <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
@@ -1693,7 +1703,7 @@
<string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
<string name="mediasize_unknown_portrait" msgid="3088043641616409762">"មិនស្គាល់បញ្ឈរ"</string>
<string name="mediasize_unknown_landscape" msgid="4876995327029361552">"មិនស្គាល់ទេសភាព"</string>
- <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បានបោះបង់"</string>
+ <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បានបោះបង់"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុសក្នុងការសរសេរមាតិកា"</string>
<string name="reason_unknown" msgid="6048913880184628119">"មិនស្គាល់"</string>
<string name="reason_service_unavailable" msgid="7824008732243903268">"មិនបានបើកសេវាកម្មបោះពុម្ព"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d2fd2b0..39ac525 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"비행기 모드 사용중"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"비행기 모드 사용중이 아님"</string>
<string name="global_action_settings" msgid="1756531602592545966">"설정"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"안전 모드"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 시스템"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"앱이 터치 스크린의 보정 매개변수를 수정할 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM 인증서에 액세스"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"애플리케이션이 DRM 인증서를 프로비저닝하고 사용하도록 허용합니다. 일반 앱에서는 필요하지 않습니다."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"앱이 휴대전화에 저장된 브라우저 기록 또는 북마크를 수정할 수 있도록 허용합니다. 이 경우 앱이 브라우저 데이터를 삭제 또는 수정할 수 있습니다. 참고: 이 권한은 타사 브라우저 또는 브라우저 기능을 가진 기타 애플리케이션에 적용되지 않습니다."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"알람 설정"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"앱이 설치된 알람 시계 앱에서 알람을 설정할 수 있도록 허용합니다. 일부 알람 시계 앱에는 이 기능이 구현되지 않을 수 있습니다."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"음성사서함 추가"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"앱이 음성사서함에 메시지를 추가할 수 있도록 허용합니다."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"모든 음성사서함 읽기"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>이(가) 선택됨"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 삭제됨"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"앱 잠금 기능을 사용하시겠습니까?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"앱 잠금 기능은 단일 앱의 화면을 잠급니다.\n\n종료하려면 최근 앱 버튼 $를 길게 누릅니다."</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"아니요"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"시작"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"앱 잠금 기능 시작"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"앱 잠금 기능 종료"</string>
</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 8de71f9..0561613 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"ເປີດໂໝດຢູ່ໃນຍົນແລ້ວ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"ປິດໂໝດໃນຍົນແລ້ວ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"ການຕັ້ງຄ່າ"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"ລັອກດຽວນີ້"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂຄ່າການວັດແທ້ໜ້າຈໍສຳຜັດ. ແອັບຯທຳມະດາບໍ່ຄວນໃຊ້."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"ເຂົ້າເຖິງໃບຮັບຮອງ DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຈັດຫາ ແລະນຳໃຊ້ໃບຮັບຮອງ DRM. ແອັບຯທຳມະດາບໍ່ຄວນຕ້ອງການໃຊ້."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"ຮັບການກະຈາຍຂໍ້ມູນການໂອນຍ້າຍການສົ່ງຕໍ່."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"ອະນຸຍາດການຮັບຂໍ້ມູນສະຖານະການສົ່ງຕໍ່."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂປະຫວັດໂປຣແກຣມທ່ອງເວັບ ຫຼືບຸກມາກທີ່ເກັບໄວ້ໃນໂທລະສັບຂອງທ່ານ. ນີ້ອາດອະນຸຍາດໃຫ້ແອັບຯລຶບ ຫຼືແກ້ໄຂຂໍ້ມູນໂປຣແກຣມທ່ອງເວັບ. ໝາຍເຫດ: ການກຳນົດສິດນີ້ ອາດບໍ່ໄດ້ຖືກບັງຄັບໃຊ້ໃນໂປຣແກຣມທ່ອງເວັບພາກສ່ວນທີສາມ ຫຼືແອັບພລິເຄຊັນອື່ນທີ່ມີຄວາມສາມາດທ່ອງເວັບ."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ຕັ້ງການແຈ້ງເຕືອນ"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງໂມງປຸກໃນແອັບຯໂມງປຸກທີ່ຕິດຕັ້ງໄວ້. ບາງແອັບຯໂມງປຸກອາດບໍ່ມີຄຸນສົມບັດແບບນີ້ເທື່ອ."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"ລຶບຂໍ້ຄວາມສຽງອອກ"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"ອະນຸຍາດໃຫ້ແອັບຯລຶບຂໍ້ຄວາມຈາກອິນບັອກຂໍ້ຄວາມສຽງຂອງທ່ານໄດ້."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ເພີ່ມຂໍ້ຄວາມສຽງ"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"ອະນຸຍາດໃຫ້ແອັບຯ ສາມາດເພີ່ມຂໍ້ຄວາມໃສ່ອິນບັອກຂໍ້ຄວາມສຽງຂອງທ່ານໄດ້."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"ອ່ານຂໍ້ຄວາມສຽງທັງໝົດ"</string>
@@ -1705,7 +1710,7 @@
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ປະຈຸບັນ"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
<string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ຢືນຢັນລະຫັດ PIN ໃໝ່"</string>
- <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາລັບການປັບປຸງຂໍ້ຈໍາກັດ"</string>
+ <string name="restr_pin_create_pin" msgid="8017600000263450337">"ສ້າງ PIN ສໍາລັບການປັບປຸງຂໍ້ຈໍາກັດ"</string>
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN ບໍ່ກົງກັນ. ລອງໃໝ່ອີກຄັ້ງ."</string>
<string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ສັ້ນເກີນໄປ. ຕ້ອງມີຢ່າງໜ້ອຍ 4 ຫຼັກ."</string>
<plurals name="restr_pin_countdown">
@@ -1726,16 +1731,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ຖືກເລືອກແລ້ວ"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ຖືກລຶບແລ້ວ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ບ່ອນເຮັດວຽກ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"ນຳໃຊ້ lock-to-app ບໍ່?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Lock-to-app ຈະລັອກໜ້າຈໍໄວ້ຢູ່ກັບແອັບດຽວ.\n\nເພື່ອອອກຈາກມັນ ກະລຸນາກົດປຸ່ມແອັບທີ່ຫາກໍໃຊ້ຄ້າງໄວ້ $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"ບໍ່"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"ເລີ່ມ"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"ເລີ່ມຕົ້ນ Lock-to-app"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"ອອກຈາກ Lock-to-app"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index dcac639..3988cee 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"ĮJUNGTAS lėktuvo režimas"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"lėktuvo režimas IŠJUNGTAS"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Nustatymai"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string>
<string name="android_system_label" msgid="6577375335728551336">"„Android“ sistema"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Leidžiama programai keisti jutiklinio ekrano kalibravimo parametrus. Neturėtų prireikti naudojant įprastas programas."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"gali pasiekti DRM sertifikatus"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Programai leidžiama pasiekti ir naudoti DRM sertifikatus. Neturėtų prireikti naudojant įprastas programas."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Valdyti leidžiamą ekrano atrakinimo slaptažodžių ilgį ir leidžiamus naudoti simbolius."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Stebėti bandymus atrakinti ekraną"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Leidžiama programai keisti naršyklės istoriją ar žymes, išsaugotas telefone. Dėl to programai gali būti leidžiama ištrinti ar keisti naršyklės duomenis. Pastaba: šis leidimas nesuteikiamas trečiosios šalies naršyklėms ar kitoms programoms, kuriomis galima naršyti žiniatinklį."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"nustatyti pavojaus signalą"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Leidžiama programai nustatyti signalą įdiegtoje žadintuvo programoje. Kai kuriose žadintuvo programose ši funkcija gali nebūti nevykdoma."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"pridėti balso pašto pranešimų"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Leidžia programai pridėti pranešimų prie jūsų balso pašto gautųjų."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"skaityti visus balso pašto pranešimus"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index a9a9984..d1686b2 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lidojuma režīms ir IESLĒGTS."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lidojuma režīms ir IZSLĒGTS."</string>
<string name="global_action_settings" msgid="1756531602592545966">"Iestatījumi"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
<string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistēma"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ļauj lietotnei pārveidot skārienekrāna kalibrēšanas parametrus. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"Piekļuve digitālā satura tiesību pārvaldības sertifikātiem"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ļauj lietojumprogrammai nodrošināt un izmantot digitālā satura tiesību pārvaldības sertifikātus. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolē ekrāna atbloķēšanas parolē atļautās rakstzīmes un garumu."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ļauj lietotnei mainīt tālrunī saglabāto pārlūkprogrammas vēsturi vai grāmatzīmes. Tas var ļaut lietotnei dzēst vai pārveidot pārlūkprogrammas datus. Piezīme: šo atļauju nevar piemērot trešo pušu pārlūkprogrammas vai citas lietojumprogrammas ar tīmekļa pārlūkošanas iespējām."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"iestatīt modinātāju"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Ļauj lietotnei iestatīt signālu instalētajā modinātājpulksteņa lietotnē. Dažās modinātājpulksteņu lietotnēs šo funkciju, iespējams, nevar ieviest."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"pievienot balss pastu"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ļauj lietotnei pievienot ziņojumus jūsu balss pasta iesūtnei."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"lasīt visus balss pasta ziņojumus"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index c55bbcd..d2d15c8 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Нислэгийн горим асав"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Нислэгийн горим унтарсан"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Тохиргоо"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Мэдрэгчтэй дэлгэцний калибрешн параметрийг өөрчлөхийг апп-д зөвшөөрнө. Энгийн апп-д шаардлагагүй."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"хандалтын DRM сертификат"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Аппликешнд DRM сертификатыг ашиглах болон нийлүүлэхийг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Апп нь таны утсан дээр хадгалагдсан Хөтчийн түүх эсвэл хавчуургыг өөрчлөх боломжтой. Энэ нь апп-д Хөтчийн датаг арилгах эсвэл өөрчлөх боломжийг олгоно. Анхаар: Энэ зөвшөөрөл нь гуравдагч талын хөтөч эсвэл вебээр хөтөчлөх чадвартай аппликешнд ажиллахгүй байх боломжтой."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"сэрүүлэг тохируулах"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Апп нь суулгагдсан сэрүүлэгний апп дээр сэрүүлэг тохируулах боломжтой. Зарим сэрүүлэгний апп нь энэ функцийг дэмжихгүй байж болзошгүй."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"дуут шуудан нэмэх"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Таны дуут шуудангийн ирсэн мэйлд зурвас нэмэхийг апп-д зөвшөөрөх."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"бүх дуут шууданг унших"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 7c35ec5..6182e42 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mod Pesawat DIHIDUPKAN"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mod Pesawat DIMATIKAN"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Tetapan"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Membenarkan apl mengubah suai parameter penentukuran skrin sentuh. Ini tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"akses sijil DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Membenarkan aplikasi memperuntuk dan menggunakan sijil DRM. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Membenarkan apl mengubah suai sejarah atau penanda halaman Penyemak Imbas yang tersimpan pada telefon anda. Ini boleh membenarkan apl untuk memadam atau mengubah suai data Penyemak Imbas. Nota: kebenaran ini tidak boleh dikuatkuasakan oleh penyemak imbas pihak ketiga atau aplikasi lain dengan keupayaan menyemak imbas web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"tetapkan penggera"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Membenarkan apl untuk menetapkan penggera dalam apl penggera jam yang dipasang. Sesetengah applikasi jam penggera tidak boleh melaksanakan ciri ini."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"tambah mel suara"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Membenarkan apl untuk menambahkan mesej pada peti masuk mel suara anda."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"baca semua mel suara"</string>
@@ -1725,18 +1735,11 @@
<string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dipadamkan"</string>
- <!-- no translation found for managed_profile_label_badge (2355652472854327647) -->
- <skip />
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="managed_profile_label_badge" msgid="2355652472854327647">"Kerja <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Gunakan kunci ke apl?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Kunci ke apl mengunci paparan dalam apl tunggal.\n\nUntuk keluar tekan dan tahan butang apl terbaru $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"TIDAK"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"MULA"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Mulakan Kunci ke apl"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Keluar kunci ke apl"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index fb3f90e..594d3cb 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flymodus er på"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flymodus er av"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Innstillinger"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lar appen endre kalibrasjonsparametrene for berøringsskjermen. Denne tillatelsen bør aldri være nødvendig for vanlige apper."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"tilgang til DRM-sertifikater"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Tillater at en app klargjøre og bruke DRM-sertifikater. Denne tillatelsen bør aldri være nødvendig for vanlige apper."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller tillatt lengde og tillatte tegn i passord for opplåsing av skjerm."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Overvåk forsøk på opplåsing av skjerm"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"stille alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Lar appen stille inn alarmen for en installert alarmklokke-app. Enkelte alarmklokke-apper implementerer kanskje ikke denne funksjonen."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"legge til talepost"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Lar appen legge til meldinger i talepostkassen din."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"lese alle meldingene i talepostkassen"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b60d8c0..b332e76 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Vliegmodus is AAN"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Vliegmodus is UIT"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Instellingen"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Nu vergrendelen"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-systeem"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Hiermee kan de app de kalibratieparameters van het aanraakscherm aanpassen. Nooit vereist voor normale apps."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"toegang tot DRM-certificaten"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Toestaan dat een app DRM-certificaten registreert en gebruikt. Nooit vereist voor normale apps."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Handover-overdrachtsuitzendingen ontvangen."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Hiermee kan informatie over de handover-overdrachtsstatus worden ontvangen."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Hiermee kan de app de webgeschiedenis wijzigen in de systeemeigen browser en de bladwijzers die zijn opgeslagen op uw telefoon. Deze toestemming kan niet worden geforceerd door andere browsers of andere apps met internetmogelijkheden."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"een alarm instellen"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Hiermee kan de app een alarm instellen in een geïnstalleerde wekkerapp. Deze functie wordt door sommige wekkerapps niet geïmplementeerd."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"voicemails verwijderen"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Hiermee kan de app berichten verwijderen uit de inbox van uw voicemail."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"voicemail toevoegen"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van uw voicemail."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"alle voicemails lezen"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f71c8a8..c2be792 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Tryb samolotowy jest włączony"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Tryb samolotowy jest wyłączony"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Ustawienia"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Zablokuj teraz"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string>
<string name="android_system_label" msgid="6577375335728551336">"System Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Zezwala aplikacji na modyfikowanie parametrów kalibracji ekranu dotykowego. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"dostęp do certyfikatów DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Zezwala aplikacji na dodanie i używanie certyfikatów DRM. Nieprzeznaczone dla zwykłych aplikacji."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Otrzymywanie informacji o transferze."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Pozwala na odbieranie informacji o stanie transferu."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolowanie długości haseł odblokowania ekranu i dozwolonych w nich znaków"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitoruj próby odblokowania ekranu"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Pozwala aplikacji na modyfikowanie historii i zakładek przeglądarki zapisanych na telefonie. Aplikacja będzie mogła usunąć lub zmodyfikować dane przeglądarki. Uwaga: to uprawnienie może nie być egzekwowane przez przeglądarki innych firm oraz inne aplikacje z możliwością przeglądania internetu."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ustawianie alarmu"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Pozwala aplikacji na ustawienie alarmu w zainstalowanej aplikacji budzika. Funkcja ta może nie być zaimplementowana w niektórych aplikacjach tego typu."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"usuwaj wiadomości głosowe"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Pozwala aplikacji na usuwanie wiadomości z Twojej skrzynki głosowej."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"dodawanie poczty głosowej"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Pozwala aplikacji na dodawanie wiadomości do skrzynki odbiorczej poczty głosowej."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"odczyt całej poczty głosowej"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 4c5140f..ca0c028 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"O modo de voo está ativado"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"O modo de voo está desativado"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Definições"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite à aplicação modificar os parâmetros de calibragem do ecrã tátil. Esta funcionalidade nunca deverá ser necessária para aplicações normais."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"Aceder a certificados DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que uma aplicação forneça e utilize certificados DRM. Nunca deverá ser necessário para aplicações normais."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Receber transmissões de transferência da entrega."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Permite a receção de informações do estado de transferência da entrega."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o comprimento e os caracteres permitidos nas palavras-passe de desbloqueio do ecrã."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizar tentativas de desbloqueio do ecrã"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que a aplicação modifique o histórico do Navegador ou marcadores guardados no telemóvel. Isto pode permitir que a aplicação apague ou modifique dados do Navegador. Nota: esta autorização pode não ser aplicada por navegadores de terceiros ou outras aplicações com capacidades de navegação na Web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"definir um alarme"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que a aplicação defina um alarme numa aplicação de despertador instalada. Algumas aplicações de despertador podem não integrar esta funcionalidade."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"remover mensagens de correio de voz"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Permite que a aplicação remova mensagens da sua caixa de entrada de correio de voz."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"adicionar correio de voz"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que a aplicação adicione mensagens à sua caixa de entrada de correio de voz."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"ler todo o correio de voz"</string>
@@ -1726,16 +1731,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Utilizar o Lock-to-app?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"A funcionalidade Lock-to-app bloqueia o ecrã numa única aplicação.\n\nPara sair, prima sem soltar o botão $ das aplicações recentes"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NÃO"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"INICIAR"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Iniciar o Lock-to-app"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Sair do Lock-to-app"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index e677fb7..e5fb0ed 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo avião ATIVADO"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo avião DESATIVADO"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Configurações"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que o aplicativo modifique os parâmetros de calibragem da tela sensível ao toque. Não deve ser necessário para aplicativos normais."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"acessar certificados de DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que o aplicativo provisione e use certificados de DRM. Não deve ser necessário para aplicativos comuns."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que o aplicativo modifique o histórico ou os favoritos do navegador armazenados no telefone. Pode permitir que o aplicativo apague ou modifique os dados do navegador. Observação: pode não ser aplicável a navegadores de terceiros e outros aplicativos com capacidade de navegação na web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"definir um alarme"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que o aplicativo defina um alarme em um aplicativo despertador instalado. Alguns aplicativos despertador podem não implementar este recurso."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"adicionar correio de voz"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que o aplicativo adicione mensagens a sua caixa de entrada do correio de voz."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"ler todo o correio de voz"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Usar fixar em aplicativo?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"\"Fixar em aplicativo\" congela a exibição em um único aplicativo.\n\nPara sair, pressione e segure o botão de aplicativos recentes $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NÃO"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"INICIAR"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Iniciar Fixar em aplicativo"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Sair de Fixar em aplicativo"</string>
</resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 880a05d..58fe4af 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -242,6 +242,8 @@
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Il modus d\'aviun è deactivà."</string>
<!-- no translation found for global_action_settings (1756531602592545966) -->
<skip />
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<!-- no translation found for status_bar_notification_info_overflow (5301981741705354993) -->
<skip />
<string name="safeMode" msgid="2788228061547930246">"Modus segirà"</string>
@@ -1244,6 +1246,10 @@
<skip />
<!-- no translation found for permdesc_accessDrmCertificates (8073288354426159089) -->
<skip />
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<!-- no translation found for policylab_limitPassword (4497420728857585791) -->
<skip />
<!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
@@ -1662,6 +1668,10 @@
<skip />
<!-- no translation found for permdesc_setAlarm (316392039157473848) -->
<skip />
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<!-- no translation found for permlab_addVoicemail (5525660026090959044) -->
<skip />
<!-- no translation found for permdesc_addVoicemail (6604508651428252437) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b734b22..0424909 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modul Avion este ACTIVAT"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modul avion este DEZACTIVAT"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Setări"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string>
<string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistemul Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite aplicației să modifice parametrii de calibrare a ecranului tactil. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"accesează certificatele DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite unei aplicații să furnizeze și să utilizeze certificate DRM. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite aplicaţiei să modifice istoricul Browserului sau marcajele stocate pe telefon. În acest fel, aplicaţia poate şterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicaţii cu capacităţi de navigare pe web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"setează o alarmă"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite aplicaţiei să seteze o alarmă într-o aplicaţie de ceas cu alarmă instalată. Este posibil ca unele aplicaţii de ceas cu alarmă să nu implementeze această funcţie."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"adăugare mesagerie vocală"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite aplicaţiei să adauge mesaje în Mesaje primite în mesageria vocală."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"acces la toate mesajele vocale"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selectat"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> a fost șters"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de serviciu"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Utilizați Blocarea aplicației?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Blocarea aplicației blochează ecranul într-o singură aplicație.\n\nPentru a ieși, apăsați lung pe butonul pentru aplicații recente $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NU"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"PORNIȚI"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Porniți Blocarea aplicației"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Ieșiți din Blocarea aplicației"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index f727364..f6e6d5a 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Выключить"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Включить"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Настройки"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Приложение сможет изменять параметры калибровки сенсорного экрана. Это разрешение обычно используется только специальными приложениями."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"Доступ к сертификатам DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Приложение сможет синхронизировать и использовать сертификаты DRM (разрешение актуально только для специальных приложений)."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Приложение сможет изменять историю или закладки браузера, сохраненные на телефоне, а также удалять и изменять данные браузера. Обратите внимание: браузеры независимых поставщиков или другие приложения для просмотра веб-страниц могут не применять это разрешение."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"Установка будильника"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Приложение сможет настраивать будильник. Функция поддерживается не во всех программах."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"Добавление голосовых сообщений"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Приложение сможет добавлять голосовые сообщения в папку \"Входящие\"."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"Доступ к голосовой почте"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"Выбран элемент <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"Цифра <xliff:g id="KEY">%1$s</xliff:g> удалена"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Рабочий <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Использовать блокировку в приложении?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Функция блокирует переход в другие приложения.\n\nЧтобы выключить блокировку, нажмите и удерживайте кнопку \"Недавние приложения\" $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"НЕТ"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"ДА"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Запуск блокировки в приложении"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Выключить блокировку"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 0d4ee13..2ae3a8e 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim V lietadle je ZAPNUTÝ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim V lietadle je VYPNUTÝ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Nastavenia"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Umožňuje aplikácii upraviť parametre kalibrácie dotykovej obrazovky. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"prístup k certifikátom DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Umožňuje aplikácii vydávať a používať certifikáty DRM. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Ovládanie dĺžky hesiel na odomknutie obrazovky a v nich používané znaky."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Sledovať pokusy o odomknutie obrazovky"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Umožňuje aplikácii upraviť históriu prehliadača alebo záložky uložené v telefóne. Aplikácia s týmto povolením môže vymazať alebo upraviť údaje prehliadača. Poznámka: Toto povolenie nemôžu vynucovať prehliadače tretích strán ani žiadne ďalšie aplikácie umožňujúce prehliadanie webu."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"nastaviť budík"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Umožňuje aplikácii nastaviť budík v nainštalovanej aplikácii budík. Niektoré aplikácie budíka nemusia túto funkciu implementovať."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"pridať hlasovú schránku"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Umožní aplikácii pridávať správy do doručenej pošty hlasovej schránky."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"čítanie všetkých hlasových schránok"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"Bola vybratá položka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"Číslo <xliff:g id="KEY">%1$s</xliff:g> bolo odstránené"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Práca – <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Použiť uzamknutie na aplikáciu?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Funkcia Uzamknutie na aplikáciu uzamkne displej na zobrazovanie jednej aplikácie.\n\nTúto funkciu ukončíte stlačením a podržaním tlačidla nedávnych aplikácií $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"NIE"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"SPUSTIŤ"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Spustiť funkciu Uzamknutie na aplikáciu"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Ukončiť funkciu Uzamknutie na aplikáciu"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 44c523c..873dae8 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Način za letalo je VKLOPLJEN"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Način za letalo je IZKLOPLJEN"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Nastavitve"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Varni način"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Aplikaciji dovoli spreminjanje parametrov za umerjanje zaslona na dotik. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"dostop do potrdil za upravljanje digitalnih pravic"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Aplikaciji omogoča pripravo in uporabo potrdil za upravljanje digitalnih pravic. To naj ne bi bilo nikoli potrebno za običajne aplikacije."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih za odklepanje zaslona."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"nadzor nad poskusi odklepanja zaslona"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Aplikaciji omogoča spreminjanje zgodovine ali zaznamkov brskalnika v telefonu. S tem lahko aplikacija izbriše ali spremeni podatke v brskalniku. Opomba: Tega dovoljenja ne morejo uveljavljati drugi brskalniki ali aplikacije, s katerimi je mogoče brskati po spletu."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"nastavitev alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Programu omogoča nastavitev alarma v nameščenem programu budilke. Nekateri programi budilke morda nimajo te funkcije."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"dodajanje odzivnika"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Programu omogoča dodajanje sporočil prejetim sporočilom odzivnika."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"branje vseh sporočil v odzivniku"</string>
@@ -1726,10 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"Izbrano: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"Številka <xliff:g id="KEY">%1$s</xliff:g> je izbrisana"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> za delo"</string>
- <string name="lock_to_app_title" msgid="5895142291937470019">"Želite uporabiti zaklepanje v aplikaciji?"</string>
- <string name="lock_to_app_description" msgid="8597199033462406175">"Zaklepanje v aplikaciji zaklene zaslon v eni aplikaciji.\n\nČe želite zapustiti ta način, pritisnite in pridržite gumb za nedavne aplikacije $"</string>
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Želite uporabiti zaklepanje v aplikacijo?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Zaklepanje v aplikacijo zaklene zaslon v eni aplikaciji.\n\nČe želite zapustiti ta način, pritisnite in pridržite gumb za nedavne aplikacije $"</string>
<string name="lock_to_app_negative" msgid="8522854387366288195">"NE"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"ZAŽENI"</string>
- <string name="lock_to_app_start" msgid="8889002974248178076">"Zagon zaklepanja v aplikaciji"</string>
- <string name="lock_to_app_exit" msgid="7033017307788432861">"Izhod iz zaklepanja v aplikaciji"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Zagon zaklepanja v aplikacijo"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Izhod iz zaklepanja v aplikacijo"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a07b7fa4..4a5b2de 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Режим рада у авиону је УКЉУЧЕН"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Режим рада у авиону је ИСКЉУЧЕН"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Подешавања"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android систем"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Дозвољава апликацији да модификује параметре калибрације додирног екрана. Не би требало да буде потребно за нормалне апликације."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"приступ DRM сертификатима"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Дозвољава апликацији да додељује и користи DRM сертификате. Никада не би требало да се користи за уобичајене апликације."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Дозвољава апликацији да мења историју Прегледача или обележиваче ускладиштене на телефону. Ово може да омогући апликацији да брише или мења податке Прегледача. Напомена: Ова дозвола се можда на примењује на прегледаче треће стране и друге апликације са могућношћу веб прегледања."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"подешавање аларма"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Дозвољава апликацији да подеси аларм у инсталираној апликацији будилника. Неке апликације будилника можда не примењују ову функцију."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"додавање говорне поште"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дозвољава апликацији да додаје поруке у пријемно сандуче говорне поште."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"читај сву говорну пошту"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"Изабрали сте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"Избрисали сте <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> на послу"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Желите ли да користите закључавање у апликацији?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Закључавање у апликацији закључава екран у само једној апликацији.\n\nДа бисте изашли притисните и држите дугме за недавне апликације $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"НЕ"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"ПОКРЕНИ"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Покрени закључавање у апликацији"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Излазак из Закључавања у апликацији"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4db7351..bf1271a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flygplansläge är AKTIVERAT"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flygplansläge är INAKTIVERAT"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Inställningar"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Tillåter att appen ändrar kalibreringsparametrarna för pekskärmen. Detta behövs aldrig för vanliga appar."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"tillgång till DRM-certifikat"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Tillåter att en app tillhandahåller och använder DRM-certifikat. Behövs inte för vanliga appar."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Ta emot överföringssändningar."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Tillåter att information om överföringsstatus tas emot."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Bestäm hur många och vilka tecken som är tillåtna i skärmlåsets lösenord."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Tillåter att appen ändrar historiken för besökta sidor i webbläsaren eller bokmärken som sparats på telefonen. Det kan innebära att appen kan ta bort eller ändra webbläsarinformation. Observera att den här behörigheten kanske inte är tillämplig för webbläsare från tredje part eller andra appar med surffunktion."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ställa in ett alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Tillåter att appen ställer in ett alarm i en befintlig alarmapp. Vissa alarmappar har inte den här funktionen."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"ta bort röstmeddelanden"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Tillåter att appen tar bort meddelanden från röstbrevlådans inkorg."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"lägg till röstbrevlåda"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Gör att appen lägger till meddelanden i röstbrevlådans inkorg."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"läsa alla röstmeddelanden"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index df51691..914c0b3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Hali ya ndege IMEWASHWA"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Hali ya ndege IMEZIMWA"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Mipangilio"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Funga sasa"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
<string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Huruhusu programu kubadilisha vigezo vya urekebishaji vya skrini ya kugusa. Havipaswi kuhitajika kamwe kwa programu za kawaida."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"fikia vyeti vya DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Huruhusu programu kwa utoaji na matumizi ya vyeti vya DRM. Havifahi kuhitajika kwa ajili ya programu za kawaida."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Pokea matangazo ya makabidhiano ya uhamisho."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Huruhusu upokeaji wa maelezo ya hali ya makabidhiano ya uhamisho."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kudhibiti urefu na herufi zinazoruhusiwa katika manenosiri ya kufungua skrini."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Kuhesabu mara ambazo skrini inajaribu kufunguliwa"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Inaruhusu programu kurekebisha historia ya Kivinjari au alamisho zilizohifadhiwa kwenye simu yako. Hii huenda ikaruhusu programu kufuta au kurekebisha data ya Kivinjari. Kumbuka: huenda idhini hii isitekelezwe na vivinjari vingine au programu nyingine zenye uwezo wa kuvinjari wavuti."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"weka kengele"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Inaruhusu programu kuweka kengele katika programu iliyosakinishwa ya kengele. Programu zingine za kengele zinawezakosa kutekeleza kipengee hiki."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"ondoa ujumbe wa sauti"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Huruhusu programu kuondoa ujumbe kwenye kikasha chako cha ujumbe wa sauti."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"ongeza barua ya sauti"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Huruhusu programu kuongeza mawasiliano kwenye kikasha cha ujumbe wa sauti."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"soma ujumbe wote wa sauti"</string>
@@ -1725,9 +1730,9 @@
<string name="select_year" msgid="7952052866994196170">"Chagua mwaka"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> kimechaguliwa"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> kimefutwa"</string>
- <string name="managed_profile_label_badge" msgid="2355652472854327647">"Kazi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="managed_profile_label_badge" msgid="2355652472854327647">"Ya kazini <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"Ungependa kutumia lazimisha kutumia programu?"</string>
- <string name="lock_to_app_description" msgid="8597199033462406175">"Lazimisha kutumia programu huonyeshwa katika programu moja. \n\n Ili uondoke bonyeza na ushikilie kitufe cha programu za hivi majuzi $"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Lazimisha kutumia programu katika programu moja. \n\n Ili uondoke bonyeza na ushikilie kitufe cha programu za hivi majuzi $"</string>
<string name="lock_to_app_negative" msgid="8522854387366288195">"HAPANA"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"ANZA"</string>
<string name="lock_to_app_start" msgid="8889002974248178076">"Anzisha Lazimisha kutumia programu"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a0f0bb5..5904777 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"เปิดโหมดใช้งานบนเครื่องบิน"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"โหมดใช้งานบนเครื่องบินปิดทำงานอยู่"</string>
<string name="global_action_settings" msgid="1756531602592545966">"การตั้งค่า"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
<string name="android_system_label" msgid="6577375335728551336">"ระบบแอนดรอยด์"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"อนุญาตให้แอปสามารถปรับพารามิเตอร์การเทียบมาตรฐานของหน้าจอสัมผัส ไม่ควรใช้สำหรับแอปทั่วไป"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"เข้าถึงใบรับรอง DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ช่วยให้แอปพลิเคชันสามารถจัดสรรและใช้ใบรับรอง DRM ได้ ไม่จำเป็นสำหรับแอปปกติทั่วไป"</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงประวัติหรือบุ๊กมาร์กของเบราว์เซอร์ที่จัดเก็บไว้ในโทรศัพท์ ซึ่งทำให้แอปพลิเคชันสามารถลบหรือเปลี่ยนข้อมูลเบราว์เซอร์ได้ หมายเหตุ: การอนุญาตนี้อาจไม่สามารถใช้งานได้กับเบราว์เซอร์ของบุคคลที่สามหรือแอปพลิเคชันอื่นๆ ที่มีความสามารถในการเรียกดูบนเว็บ"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ตั้งปลุก"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"อนุญาตให้แอปพลิเคชันตั้งเวลาปลุกในแอปพลิเคชันนาฬิกาปลุกที่ติดตั้ง แอปพลิเคชันนาฬิกาปลุกบางรายการอาจไม่ใช้คุณลักษณะนี้"</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"เพิ่มข้อวามเสียง"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"อนุญาตให้แอปพลิเคชันเพิ่มข้อความลงในกล่องข้อความเสียงของคุณ"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"อ่านข้อความเสียงทั้งหมด"</string>
@@ -1727,7 +1737,7 @@
<string name="deleted_key" msgid="7659477886625566590">"ลบ <xliff:g id="KEY">%1$s</xliff:g> แล้ว"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g>ที่ทำงาน"</string>
<string name="lock_to_app_title" msgid="5895142291937470019">"ใช้การล็อกแอปไหม"</string>
- <string name="lock_to_app_description" msgid="8597199033462406175">"การล็อกแอปจะล็อกการแสดงไว้ในแอปเดียว\n\nหากต้องการออก ให้กดปุ่มแอปล่าสุด $ ค้างไว้"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"การล็อกแอปจะล็อกการแสดงไว้ในแอปเดียว\n\nหากต้องการออก ให้กดปุ่มแอปล่าสุด$ค้างไว้"</string>
<string name="lock_to_app_negative" msgid="8522854387366288195">"ไม่"</string>
<string name="lock_to_app_positive" msgid="7085139175671313864">"เริ่มต้น"</string>
<string name="lock_to_app_start" msgid="8889002974248178076">"เริ่มใช้การล็อกแอป"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 2b0eb8c..1206b66 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Naka-ON ang airplane mode"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Naka-OFF ang airplane mode"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Mga Setting"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Pinapayagan ang app na baguhin ang mga parameter sa pag-calibrate ng touch screen. Hindi dapat kailanganin sa normal na apps."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"access sa Mga DRM certificate"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Nagbibigay-daan sa isang application na makapagbigay at gumamit ng mga DRM certficate. Hindi dapat kailanman kailanganin para sa mga normal na app."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolin ang haba at mga character na pinapayagan sa mga password sa pag-unlock ng screen."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Pinapayagan ang app na baguhin ang kasaysayan o mga bookmark ng Browser na naka-imbak sa iyong telepono. Maaari nitong payagan ang app na burahin o baguhin ang data ng Browser. Tandaan: hindi maaaring ipatupad ang pahintulot na ito ng mga third-party na browser o iba pang mga application na may mga kakayahan sa pagba-browse sa web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"magtakda ng alarm"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Pinapayagan ang app na magtakda ng alarm sa isang naka-install na app ng alarm clock. Maaaring hindi ipatupad ng ilang apps ng alarm clock ang tampok na ito."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"magdagdag ng voicemail"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Pinapayagan ang app na magdagdag ng mga mensahe sa iyong inbox ng voicemail."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"basahin ang lahat ng voicemail"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 6c3ec18..c2bc68b 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uçak modu AÇIK"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Uçak modu KAPALI"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Ayarlar"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android Sistemi"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Uygulamaya, dokunmatik ekranın kalibrasyon parametrelerini değiştirme izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM sertifikalarına eriş"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Bir uygulamanın DRM sertifikaları için temel hazırlık yapmasına ve bunları kullanmasına izin verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açma şifrelerinde izin verilen uzunluğu ve karakterleri denetleme."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidini açma denemelerini izle"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Uygulamaya Tarayıcı geçmişini ve telefonunuzda depolanan yer işaretlerini değiştirme izni verir. Bu izin, uygulamanın Tarayıcı geçmişini silmesine ve değiştirmesine olanak sağlar. Not: Bu izin, üçüncü taraf cihazlar veya Web\'e göz atma işlevine sahip diğer uygulamalar tarafından kullanılmayabilir."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"alarm ayarla"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Uygulamaya, çalar saat uygulamasının alarmını ayarlama izni verir. Bazı çalar saat uygulamaları bu özelliği uygulayamayabilir."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"sesli mesaj ekle"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Uygulamaya, sesli mesaj gelen kutunuza mesaj ekleme izni verir."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"tüm sesli mesajları oku"</string>
@@ -1726,16 +1736,10 @@
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seçildi"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> silindi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (İş)"</string>
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="lock_to_app_title" msgid="5895142291937470019">"Uygulamaya kilitleme özelliği kullanılsın mı?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"Uygulamaya kilitleme özelliği, ekranı tek bir uygulamaya kilitler.\n\nÇıkmak için son uygulamalar düğmesine ($) uzun basın"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"HAYIR"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"BAŞLAT"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"Uygulamaya kilitleme özelliğini başlat"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"Uygulamaya kilitleme özelliğinden çık"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index f439595..e86e533 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Режим польоту ВВІМК."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Режим польоту ВИМК."</string>
<string name="global_action_settings" msgid="1756531602592545966">"Налаштування"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Блокувати зараз"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Програма може змінювати параметри калібрування сенсорного екрана. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"отримувати доступ до сертифікатів DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Дозволяє додатку надавати та використовувати сертифікати DRM. Ніколи не застосовується для звичайних додатків."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Отримувати широкомовні повідомлення про естафетне передавання."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Можна отримувати інформацію про статус естафетного передавання."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Дозволяє програмі змінювати історію чи закладки веб-переглядача, збережені у вашому телефоні. Це може дозволити програмі стирати чи змінювати дані веб-переглядача. Зауважте: цей дозвіл не може застосовуватися веб-переглядачами третіх сторін або іншими програмами з можливостями веб-перегляду."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"установлювати будильник"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Дозволяє програмі налаштовувати сигнал у встановленій програмі будильника. У деяких програмах будильника ця функція може не застосовуватися."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"видаляти голосові повідомлення"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Додаток може видаляти голосові повідомлення з папки \"Вхідні\"."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"додавати голосову пошту"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дозволяє програмі додавати повідомлення в папку \"Вхідні\" голосової пошти."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"читати всі голосові повідомлення"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 9d8905a..56fd457 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Chế độ trên máy bay BẬT"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Chế độ trên máy bay TẮT"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Cài đặt"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
<string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Cho phép ứng dụng sửa đổi các thông số hiệu chỉnh của màn hình cảm ứng. Không cần cho ứng dụng thông thường."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"truy cập chứng chỉ DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Cho phép ứng dụng cung cấp và sử dụng chứng chỉ DRM. Không cần thiết cho các ứng dụng thông thường."</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Kiểm soát độ dài và ký tự được phép trong mật khẩu mở khóa màn hình."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Giám sát những lần thử mở khóa màn hình"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Cho phép ứng dụng sửa đổi lịch sử hoặc dấu trang của Trình duyệt được lưu trữ trên điện thoại của bạn. Việc này có thể cho phép ứng dụng xóa hoặc sửa đổi dữ liệu của Trình duyệt. Lưu ý: quyền này có thể không được thực thi bởi các trình duyệt của bên thứ ba hoặc các ứng dụng khác có khả năng duyệt web."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"đặt báo thức"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Cho phép ứng dụng đặt báo thức trong ứng dụng đồng hồ báo thức được cài đặt. Một số ứng dụng đồng hồ báo thức có thể không thực thi tính năng này."</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"thêm thư thoại"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Cho phép ứng dụng thêm thông báo vào hộp thư thoại đến của bạn."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"đọc tất cả các thư thoại"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index eb1cb3b..ba2cdb7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"已开启飞行模式"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"未开启飞行模式"</string>
<string name="global_action_settings" msgid="1756531602592545966">"设置"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系统"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允许应用修改触摸屏的校准参数。普通应用绝不需要此权限。"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"访问DRM证书"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"允许应用配置和使用DRM证书。普通应用绝不需要此权限。"</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"允许该应用修改您手机上存储的浏览器历史记录或浏览器书签。此权限可让该应用清除或修改浏览器数据。请注意:此权限可能不适用于第三方浏览器或具备网页浏览功能的其他应用。"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"设置闹钟"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"允许应用在已安装的闹钟应用中设置闹钟。有些闹钟应用可能无法实现此功能。"</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"添加语音邮件"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"允许应用向您的语音信箱收件箱添加邮件。"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"读取所有语音邮件"</string>
@@ -1725,18 +1735,11 @@
<string name="select_year" msgid="7952052866994196170">"选择年份"</string>
<string name="item_is_selected" msgid="949687401682476608">"已选择<xliff:g id="ITEM">%1$s</xliff:g>"</string>
<string name="deleted_key" msgid="7659477886625566590">"已删除<xliff:g id="KEY">%1$s</xliff:g>"</string>
- <!-- no translation found for managed_profile_label_badge (2355652472854327647) -->
- <skip />
- <!-- no translation found for lock_to_app_title (5895142291937470019) -->
- <skip />
- <!-- no translation found for lock_to_app_description (8597199033462406175) -->
- <skip />
- <!-- no translation found for lock_to_app_negative (8522854387366288195) -->
- <skip />
- <!-- no translation found for lock_to_app_positive (7085139175671313864) -->
- <skip />
- <!-- no translation found for lock_to_app_start (8889002974248178076) -->
- <skip />
- <!-- no translation found for lock_to_app_exit (7033017307788432861) -->
- <skip />
+ <string name="managed_profile_label_badge" msgid="2355652472854327647">"工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="lock_to_app_title" msgid="5895142291937470019">"要使用“锁定到应用”吗?"</string>
+ <string name="lock_to_app_description" msgid="8597199033462406175">"“锁定到应用”功能会锁定屏幕,使其只显示一个应用。\n\n要退出,请按住“最近用过的应用”按钮 $"</string>
+ <string name="lock_to_app_negative" msgid="8522854387366288195">"算了"</string>
+ <string name="lock_to_app_positive" msgid="7085139175671313864">"启动"</string>
+ <string name="lock_to_app_start" msgid="8889002974248178076">"启动“锁定到应用”"</string>
+ <string name="lock_to_app_exit" msgid="7033017307788432861">"退出“锁定到应用”"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 2db1ba6..a0e83cf 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"飛航模式為 [開啟]"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"飛行模式為 [關閉]"</string>
<string name="global_action_settings" msgid="1756531602592545966">"設定"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允許應用程式修改觸控式螢幕的校正參數,而一般應用程式並不需要作出類似修改。"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"存取 DRM 憑證"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"允許應用程式準備和使用 DRM 憑證,但一般應用程式並不需要使用。"</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解鎖密碼所允許的長度和字元。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"監控屏幕解鎖嘗試次數"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"允許應用程式修改手機上儲存的瀏覽器記錄或書籤。如此一來,應用程式或可清除或修改瀏覽器資料。注意:這項權限可能不適用於第三方瀏覽器或其他具備網頁瀏覽功能的應用程式。"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"設定鬧鐘"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"允許應用程式在安裝的鬧鐘應用程式中設定鬧鐘,某些鬧鐘應用程式可能沒有這項功能。"</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"新增留言"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"允許應用程式將訊息加到您的留言信箱收件箱。"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"讀取所有語音留言"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d362084..659ffe3 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -185,6 +185,8 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"飛航模式為 [開啟]"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"飛航模式為 [關閉]"</string>
<string name="global_action_settings" msgid="1756531602592545966">"設定"</string>
+ <!-- no translation found for global_action_lockdown (8751542514724332873) -->
+ <skip />
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
@@ -726,6 +728,10 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允許應用程式修改觸控螢幕的校正參數 (一般應用程式並不需要)。"</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"存取 DRM 憑證"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"允許應用程式佈建及使用 DRM 憑證 (一般應用程式並不需要)。"</string>
+ <!-- no translation found for permlab_handoverStatus (4558616203830448763) -->
+ <skip />
+ <!-- no translation found for permdesc_handoverStatus (5738446261941364055) -->
+ <skip />
<string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
@@ -999,6 +1005,10 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"允許應用程式修改手機上儲存的瀏覽紀錄或書籤。這項設定會讓應用程式具有清除或修改瀏覽資料的權限。注意:這項權限不適用於第三方瀏覽器或其他具備網頁瀏覽功能的應用程式。"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"設定鬧鐘"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"允許應用程式在安裝的鬧鐘應用程式中設定鬧鐘,某些鬧鐘應用程式可能無法執行這項功能。"</string>
+ <!-- no translation found for permlab_removeVoicemail (6328485960478155867) -->
+ <skip />
+ <!-- no translation found for permdesc_removeVoicemail (8113704917331103065) -->
+ <skip />
<string name="permlab_addVoicemail" msgid="5525660026090959044">"新增語音留言"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"允許應用程式將訊息新增至您的語音信箱收件匣。"</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"讀取所有語音留言"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 23d2966..27a4331 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -185,6 +185,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Imodi yendiza IVULIWE"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Imodi yendiza IVALIWE"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Izilungiselelo"</string>
+ <string name="global_action_lockdown" msgid="8751542514724332873">"Khiya manje"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Imodi ephephile"</string>
<string name="android_system_label" msgid="6577375335728551336">"Uhlelo lwe-Android"</string>
@@ -726,6 +727,8 @@
<string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ivumela uhlelo lokusebenza ukuthi lushintshe imingcele yokulinganisa yesikrini esithintwayo. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
<string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"finyelela izitifiketi ze-DRM"</string>
<string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Ivumela uhlelo lokusebenza ekunikezweni nokusetshenziswa kwezitifiketi ze-DRM. Akufanele kudingeke kuzinhlelo zokusebenza ezivamile."</string>
+ <string name="permlab_handoverStatus" msgid="4558616203830448763">"Thola ukusakaza kokuthuthukisela kokunikeza."</string>
+ <string name="permdesc_handoverStatus" msgid="5738446261941364055">"Ivumela ukuthola ulwazi lwesimo sokuthutha olunikezwayo."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi okuvula isikrini"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Gaka imizamo yokuvula isikrini"</string>
@@ -999,6 +1002,8 @@
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ivumela uhlelo lokusebenza ukushintsha umlando wamabhukhimakhi noma wesiphequluli alondolozwe efonini yakho. Lokhu kungavumela uhlelo lokusebenza ukususa noma ukushintsha idatha yesiphequluli. Qaphela: le mvume kungenzeka ingaphoqelelwa iziphequluli ezivela eceleni noma ezinye izinhlelo zokusebenza ezinamandla okuphequlula iwebhu."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"setha i-alamu"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Ivumela uhlelo lokusebenza ukuthi isethe i-alamu ensizeni efkiwe ye-alamu. Ezinye izinhlelo zokusebenza ze-alamu kungenzeka zingakusebenzisi lokho."</string>
+ <string name="permlab_removeVoicemail" msgid="6328485960478155867">"susa amavoyisimeyili"</string>
+ <string name="permdesc_removeVoicemail" msgid="8113704917331103065">"Ivumela uhlelo lokusebenza ukususa imilayezo kusuka kubhokisi lokungenayo levoyisimeyili."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"engeza imeyili yezwi"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ivumela uhlelo lokusebenza ukwengeza imiyalezo kwibhokisi lakho lemeyili yezwi."</string>
<string name="permlab_readAllVoicemail" msgid="5834057671176753416">"funda wonke amavoyisimeyili"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a8a4d7a..e7e750d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5338,6 +5338,8 @@
resource are available in addition to the specific attributes of Fade
described here. -->
<declare-styleable name="Fade">
+ <!-- Equivalent to <code>visibilityMode</code>, fadingMode works only
+ with the Fade transition. -->
<attr name="fadingMode">
<!-- Fade will only fade appearing items in. -->
<enum name="fade_in" value="1" />
@@ -5366,6 +5368,21 @@
</attr>
</declare-styleable>
+ <!-- Use with {@link android.transition.Visibility} transitions, such as
+ <code>slide</code>, <code>explode</code>, and <code>fade</code> to mark which
+ views are supported. -->
+ <declare-styleable name="VisibilityTransition">
+ <!-- Changes whether the transition supports appearing and/or disappearing Views.
+ Corresponds to {@link android.transition.Visibility#setMode(int)}. -->
+ <attr name="visibilityMode">
+ <!-- Only appearing Views will be supported. -->
+ <enum name="mode_in" value="1" />
+ <!-- Only disappearing Views will be supported. -->
+ <enum name="mode_out" value="2" />
+ <!-- Both appearing and disappearing views will be supported. -->
+ <enum name="mode_in_out" value="3" />
+ </attr>
+ </declare-styleable>
<!-- Use <code>target</code> as the root tag of the XML resource that
describes a {@link android.transition.Transition#addTarget(int)
targetId} of a transition. There can be one or more targets inside
@@ -5430,9 +5447,9 @@
greater than 0 or infinite. The default value is restart. -->
<attr name="repeatMode"/>
<!-- Value the animation starts from. -->
- <attr name="valueFrom" format="float|integer|color|dimension"/>
+ <attr name="valueFrom" format="float|integer|color|dimension|string"/>
<!-- Value the animation animates to. -->
- <attr name="valueTo" format="float|integer|color|dimension"/>
+ <attr name="valueTo" format="float|integer|color|dimension|string"/>
<!-- The type of valueFrom and valueTo. -->
<attr name="valueType">
<!-- valueFrom and valueTo are floats. This is the default value is valueType is
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 727d286..3206457 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2215,6 +2215,7 @@
<public type="attr" name="actionModeShareDrawable" />
<public type="attr" name="actionModeFindDrawable" />
<public type="attr" name="actionModeWebSearchDrawable" />
+ <public type="attr" name="visibilityMode" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6e92b07..a3262ed 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -463,7 +463,7 @@
<string name="user_owner_label">Personal apps</string>
<!-- Label for a corporate profile in the intent forwarding app. -->
- <string name="managed_profile_label">Android Work</string>
+ <string name="managed_profile_label">Work</string>
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_costMoney">Services that cost you money</string>
@@ -2122,6 +2122,11 @@
<string name="permdesc_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindDreamService">bind to a dream service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindDreamService">Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_invokeCarrierSetup">invoke the carrier-provided configuration app</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_invokeCarrierSetup">Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps.</string>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index b52b3a0..5d9fc66 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -156,7 +156,7 @@
<item name="windowTitleStyle">@style/WindowTitle.Material</item>
<item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
<item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
- <item name="windowContentTransitions">false</item>
+ <item name="windowContentTransitions">true</item>
<item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
<item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
<item name="windowActionBar">true</item>
@@ -521,6 +521,7 @@
<item name="windowEnterTransition">@transition/fade</item>
<item name="windowSharedElementEnterTransition">@transition/move</item>
<item name="windowSharedElementExitTransition">@transition/move</item>
+ <item name="windowContentTransitions">true</item>
<!-- Dialog attributes -->
<item name="dialogTheme">@style/Theme.Material.Light.Dialog</item>
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index cac6b93..ff2c8f0 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -20,8 +20,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.net.NetworkScorerAppManager.NetworkScorerAppData;
import android.test.InstrumentationTestCase;
import com.google.android.collect.Lists;
@@ -63,11 +65,11 @@
setScorers(package1, package2, package3);
- Iterator<String> result =
+ Iterator<NetworkScorerAppData> result =
NetworkScorerAppManager.getAllValidScorers(mMockContext).iterator();
assertTrue(result.hasNext());
- assertEquals("package1", result.next());
+ assertEquals("package1", result.next().mPackageName);
assertFalse(result.hasNext());
}
@@ -93,6 +95,7 @@
ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.activityInfo = new ActivityInfo();
resolveInfo.activityInfo.packageName = packageName;
+ resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
if (hasReceiverPermission) {
resolveInfo.activityInfo.permission = permission.BROADCAST_SCORE_NETWORKS;
}
diff --git a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
index d850c7c..9252270 100644
--- a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
+++ b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
@@ -20,6 +20,7 @@
import android.graphics.RectF;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.CursorAnchorInfo.Builder;
@@ -81,7 +82,7 @@
assertEquals(SELECTION_START, info.getSelectionStart());
assertEquals(SELECTION_END, info.getSelectionEnd());
assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart());
- assertEquals(COMPOSING_TEXT, info.getComposingText());
+ assertTrue(TextUtils.equals(COMPOSING_TEXT, info.getComposingText()));
assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal());
assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop());
assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline());
@@ -97,7 +98,7 @@
assertEquals(SELECTION_START, info2.getSelectionStart());
assertEquals(SELECTION_END, info2.getSelectionEnd());
assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart());
- assertEquals(COMPOSING_TEXT, info2.getComposingText());
+ assertTrue(TextUtils.equals(COMPOSING_TEXT, info2.getComposingText()));
assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal());
assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop());
assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline());
@@ -110,12 +111,12 @@
assertEquals(info, info2);
assertEquals(info.hashCode(), info2.hashCode());
- // Make sure that object can be marshalled via {@link Parsel}.
+ // Make sure that object can be marshaled via {@link Parsel}.
final CursorAnchorInfo info3 = cloneViaParcel(info2);
assertEquals(SELECTION_START, info3.getSelectionStart());
assertEquals(SELECTION_END, info3.getSelectionEnd());
assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart());
- assertEquals(COMPOSING_TEXT, info3.getComposingText());
+ assertTrue(TextUtils.equals(COMPOSING_TEXT, info3.getComposingText()));
assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal());
assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop());
assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline());
diff --git a/docs/html/design/devices.jd b/docs/html/design/devices.jd
index 9554e9b..c67e585 100644
--- a/docs/html/design/devices.jd
+++ b/docs/html/design/devices.jd
@@ -13,7 +13,7 @@
#text-overlay {
position: absolute;
left: 0;
- top: 380px;
+ top: 410px;
width: 340px;
}
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index 278617b..eec4e8d 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -90,19 +90,19 @@
</div>
<div class="layout-content-col span-4">
<a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear Toolkit AI']);"
- href="{@docRoot}downloads/design/Android_Design_Stencils_Sources_20131106.zip">Adobe® Illustrator® Toolkit</a>
+ href="{@docRoot}downloads/design/Android_Wear_Toolkit_20140626.ai">Adobe® Illustrator® Toolkit</a>
<a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear Toolkit PDF']);"
- href="{@docRoot}downloads/design/Android_Design_Stencils_Sources_20131106.zip">PDF Toolkit</a>
+ href="{@docRoot}downloads/design/Android_Wear_Toolkit_20140626.pdf">PDF Toolkit</a>
</div>
</div>
+
<div class="layout-content-row">
<div class="layout-content-col span-5">
- <h4>Sample app user flows</h4>
-<p>Examples of how to chain together simple Android Wear UI components into common user flows, from simple notifications to complex interactions involving full screen activities.
+ <h4>Sample user flow patterns</h4>
+<p>Examples of how to chain together simple Android Wear UI components into common user flow patterns, from simple notifications to complex interactions involving full screen activities.
</p>
-
</div>
<div class="layout-content-col span-4">
@@ -110,13 +110,14 @@
</div>
<div class="layout-content-col span-4">
- <a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear Sample Flows AI']);"
- href="{@docRoot}downloads/design/Android_Design_Stencils_Sources_20131106.zip">Adobe® Illustrator® App Flows</a>
- <a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear Sample Flows PDF']);"
- href="{@docRoot}downloads/design/Android_Design_Stencils_Sources_20131106.zip">PDF App Flows</a>
+ <a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear App Patterns AI']);"
+ href="{@docRoot}downloads/design/Android_Wear_Patterns_20140626.ai">Adobe® Illustrator® App Patterns</a>
+ <a class="download-button" onClick="_gaq.push(['_trackEvent', 'Design', 'Download', 'Wear App Patterns PDF']);"
+ href="{@docRoot}downloads/design/Android_Wear_Patterns_20140626.pdf">PDF App Patterns</a>
</div>
</div>
+
<div class="layout-content-row">
<div class="layout-content-col span-5">
<h4>Sample app design mocks</h4>
diff --git a/docs/html/design/media/device_family.png b/docs/html/design/media/device_family.png
index c4863fc..96b31d3 100644
--- a/docs/html/design/media/device_family.png
+++ b/docs/html/design/media/device_family.png
Binary files differ
diff --git a/docs/html/design/media/wear/fitness.png b/docs/html/design/media/wear/fitness.png
new file mode 100644
index 0000000..18ae969
--- /dev/null
+++ b/docs/html/design/media/wear/fitness.png
Binary files differ
diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd
index f992bf9..2e99194 100644
--- a/docs/html/preview/api-overview.jd
+++ b/docs/html/preview/api-overview.jd
@@ -110,7 +110,7 @@
href="{@docRoot}">developer.android.com</a>. These API elements are
formatted in {@code code style} in this document (without hyperlinks). For the
preliminary API documentation for these elements, download the <a
-href="{@docRoot}preview/l-developer-preview-reference.zip">preview
+href="http://storage.googleapis.com/androiddevelopers/preview/l-developer-preview-reference.zip">preview
reference</a>.</p>
<h2 id="Behaviors">Important Behavior Changes</h2>
diff --git a/docs/html/preview/google-play-services-wear.html b/docs/html/preview/google-play-services-wear.html
index ff43757..84647b7 100644
--- a/docs/html/preview/google-play-services-wear.html
+++ b/docs/html/preview/google-play-services-wear.html
@@ -38,30 +38,29 @@
<p>If you attended Google I/O, your registered Google account is automatically whitelisted for
these preview resources. You're done! Head to Step 2.</p>
-<p><stong><em>If you didn't attend Google I/O</em></strong> or want to use a different account,
-click following link to
-<a href="https://groups.google.com/group/io14androidweardev/subscribe" target="_blank">join
-the Google Group</a> and get whitelisted.</p>
+<p><strong><em>If you didn't attend Google I/O</em></strong> or want to use a different account,
+click following link to and get whitelisted.</p>
+
+<a style="font-size:24px" href="https://groups.google.com/group/io14androidweardev/subscribe" target="_blank">
+Join the Preview Group</a>
<h2 style="margin-bottom: 0px;">2. Download Required Apps</h2><hr>
-<p>You'll need the following apps to get the most out of Android Wear:</p>
+<p>You'll need the following apps to get the most out of Android Wear. You must be whitelisted
+in the Preview Group above and you must install these apps in this exact order:</p>
-<ul>
+<ol>
<li><a href="https://play.google.com/apps/testing/com.google.android.gms">Google Play services</a>:
Allows your Android Wear device to communicate with your handheld device. This is required to
use the Android Wear app and other apps listed below.</li>
+ <li><a href="https://play.google.com/apps/testing/com.google.android.googlequicksearchbox">Google
+ Search</a>: Enables searches from Android Wear</li>
<li><a href="https://play.google.com/apps/testing/com.google.android.wearable.app">Android Wear
Companion</a>: The app for pairing a handheld to a wearable and providing syncing of
notifications and data
</li>
- <li><a href="https://play.google.com/apps/testing/com.google.android.googlequicksearchbox">Google
- Search</a>: Enables searches from Android Wear</li>
- <li><a href="https://play.google.com/apps/testing/com.google.android.keep">Google Keep</a>:
- Supports the "Take a note" command</li>
- <li><a href="https://play.google.com/apps/testing/com.google.samples.apps.iosched">Google I/O
- 2014</a>:
- Supports session feedback from Android Wear</li>
- </ul>
+ <p class="note"><b>Note:</b> After becoming a tester, it can take up to 1 hour to get access to
+ the preview versions of these apps.</p>
+ </ol>
<p>To obtain these apps from Google Play, click each app link above and follow these instructions,
preferably from your mobile browser:</p>
@@ -72,9 +71,22 @@
<li>Click the <b>Download <app name> from the Play Store</b> link to go to Google Play
Store download page to get the app. The
following screenshot shows how the opt-in process looks like:
-<img style="margin-top:40px" src="/preview/images/opt-in.png"></li>
+<img style="margin-top:40px" src="/preview/images/opt-in.png" /></li>
</ol>
-<h2 style="margin-bottom: 0px;">3. Start Building</h2><hr>
+
+<h2>3. Download Optional Apps</h2>
+<p>Please join the Test Group and install the following apps to enhance your Android Wear experience:
+</p>
+
+<ol>
+ <li><a href="https://play.google.com/apps/testing/com.google.android.keep">Google Keep</a>:
+ Supports the "Take a note" command</li>
+ <li><a href="https://play.google.com/apps/testing/com.google.samples.apps.iosched">Google I/O
+ 2014</a>:
+ Supports session feedback from Android Wear</li>
+ </ol>
+
+<h2 style="margin-bottom: 0px;">4. Start Building</h2><hr>
<p>The Google Play services SDK is required if you want to sync and send data between wearable
and handheld devices. To get the new SDK that is compatible with the Google Play services
@@ -82,7 +94,8 @@
<p class="note"><b>Note:</b> Android Studio is required for Wear development.</p>
<ol>
- <li>Start AVD Manager.</li>
+ <li><a href="/sdk/installing/studio.html">Download and install Android Studio</a></li>
+ <li>Start SDK Manager.</li>
<li>Update the Android SDK Tools and Platform-tools to versions 23 and 20 respectively.</li>
<li>Click <b>Tools > Manage Add-on Sites > User Defined Sites</b>.</li>
<li>Click <b>New</b>, enter
@@ -91,14 +104,13 @@
<li>Click Close. You should now see new emulator images that support this preview
release of Google Play services and the Google Play services client libraries you need to
start developing.</li>
- <li><a href="{@docRoot}preview/google-play-services-preview.zip">Download</a> the Google Play
+ <li><a href="http://storage.googleapis.com/androiddevelopers/preview/google-play-services-preview.zip">Download</a> the Google Play
services reference documentation for this preview release.</li>.
</ol>
-<p>When you're done here, check out the <a href="{@docRoot}training/building-wearables">Building Apps for Wearables</a>
+<p>When you're done here, check out the <a href="/training/building-wearables.html">Building Apps for Wearables</a>
training classes for information on how to build for Wear.</p>
- </div>
</div> <!-- end jd-content -->
</div><!-- end doc-content -->
</div> <!-- end body-content -->
diff --git a/docs/html/preview/images/notifications/LockScreen.png b/docs/html/preview/images/notifications/LockScreen.png
index 083e646..c204a81 100644
--- a/docs/html/preview/images/notifications/LockScreen.png
+++ b/docs/html/preview/images/notifications/LockScreen.png
Binary files differ
diff --git a/docs/html/preview/images/notifications/notifications_pattern_priority.png b/docs/html/preview/images/notifications/notifications_pattern_priority.png
index 137a83f..af2d725 100644
--- a/docs/html/preview/images/notifications/notifications_pattern_priority.png
+++ b/docs/html/preview/images/notifications/notifications_pattern_priority.png
Binary files differ
diff --git a/docs/html/preview/images/opt-in.png b/docs/html/preview/images/opt-in.png
index 0f309c2..7151253 100644
--- a/docs/html/preview/images/opt-in.png
+++ b/docs/html/preview/images/opt-in.png
Binary files differ
diff --git a/docs/html/preview/index.html b/docs/html/preview/index.html
index 4f3f150..4c42d99 100644
--- a/docs/html/preview/index.html
+++ b/docs/html/preview/index.html
@@ -257,7 +257,7 @@
Join the community of Android developers testing out the L Developer Preview and
share your thoughts and experiences.
</p><p class="landing-small">
- <a href="https://plus.google.com/communities/113159138894928487684">
+ <a href="http://g.co/androidldevpreview">
Discuss on Google+</a>
</p>
</div>
diff --git a/docs/html/preview/material/images/list_mail.png b/docs/html/preview/material/images/list_mail.png
index bd107ff..e70291c 100644
--- a/docs/html/preview/material/images/list_mail.png
+++ b/docs/html/preview/material/images/list_mail.png
Binary files differ
diff --git a/docs/html/preview/notifications.jd b/docs/html/preview/notifications.jd
index 2b75651..e0fb7be 100644
--- a/docs/html/preview/notifications.jd
+++ b/docs/html/preview/notifications.jd
@@ -2,7 +2,6 @@
page.tags="notifications","design","L"
@jd:body
-
<p>The notification system allows users to keep informed about relevant and timely
events in your app, such as new chat messages from a friend or a calendar event.
Think of notifications as a news channel that alerts the user to important events as
@@ -31,8 +30,10 @@
<h2 id="Anatomy">Anatomy of a notification</h2>
+<p>This section goes over basic parts of a notification and how they can
+appear on different types of devices.</p>
-<h4 id="BaseLayout"><strong>Base Layout</strong></h4>
+<h3 id="BaseLayout">Base Layout</h3>
<p>At a minimum, all notifications consist of a base layout, including:</p>
@@ -41,63 +42,72 @@
<li> A notification <strong>title</strong> and additional <strong>text</strong></li>
<li> A <strong>timestamp</strong></li>
</ul>
-<div class="figure" style="width:376px">
- <img src="{@docRoot}preview/images/notifications/Basic.png"
- alt="" width="376" height="281" id="figure1" />
- <p class="img-caption">
- <strong>Figure 1.</strong> Base layout of a handset notification
- </p>
+
+<p>Notifications created with <code>Notification.Builder</code> for versions of Android earlier than L will look and work the same in L, with only minor stylistic changes that the system handles for you.</p>
+
+<div style="margin-top:20px" >
+ <div class="col-7">
+ <img src="{@docRoot}preview/images/notifications/Basic.png"
+ alt=""/>
+ </div>
+ <div class="col-4" style="padding-top:60px; text-align:center" >
+ <img src="{@docRoot}preview/images/notifications/WearBasic.png"
+ alt="" width="162" height="162" />
+ </div>
</div>
-<div class="figure" style="width:164px">
- <img src="{@docRoot}preview/images/notifications/WearBasic.png"
- alt="" width="164" height="164" id="figure2" />
- <p class="img-caption">
- <strong>Figure 2.</strong> The same notification on Wear, with a user photo and a
- notification icon
- </p>
+<div style="clear:both;">
+ <p class="img-caption">
+ Base layout of a handheld notification and the same notification on Wear,
+ with a user photo and a notification icon
+ </p>
+ </div>
</div>
-<p>Notifications created with {@code Notification.Builder} for versions of Android earlier than L will look and work the same in L, with only minor stylistic changes that the system handles for you.</p>
+
+<h3 id="ExpandedLayouts">Expanded layouts</h3>
+<p>You have the option to provide more details on notifications. You can use this to show the first few lines of a message or show a larger image preview. This provides the user with additional context, and - in some cases - may allow the user to read a message in its entirety. The user can pinch-zoom or perform a single-finger glide in order to toggle between compact and expanded layouts. For single event notifications, Android provides three expanded layout templates (text, inbox, and image) for you to re-use in your application. The following images show you how they look on handhelds and wearables.</p>
-<h4 id="ExpandedLayouts">Expanded layouts</h4>
-
-<p>You have the option to provide more details on notifications. You can use this to show the first few lines of a message or show a larger image preview. This provides the user with additional context, and - in some cases - may allow the user to read a message in its entirety. The user can pinch-zoom or perform a single-finger glide in order to toggle between compact and expanded layouts. For single event notifications, Android provides three expanded layout templates (text, inbox, and image) for you to re-use in your application.</p>
-
-<div class="figure" style="width:201px">
+<div class="col-5" style="margin-top:20px">
<img src="{@docRoot}preview/images/notifications/ExpandedText.png"
- alt="" width="201" height="182" id="figure3" />
+ alt="" />
+ <img style="margin-top:30px" src="{@docRoot}preview/images/notifications/Stack.png"
+ alt=""/>
+ <img style="margin-top:30px" src="{@docRoot}preview/images/notifications/ExpandedImage.png"
+ alt="" />
</div>
-<div class="figure" style="width:272px">
- <img src="{@docRoot}preview/images/notifications/Expanded.png"
- alt="" width="272" height="121" id="figure4" />
+<div class="col-6" style="margin-top:20px">
+ <img style="margin-top:60px" src="{@docRoot}preview/images/notifications/Expanded.png"
+ alt="" />
+
+ <img style="margin-top:140px" src="{@docRoot}preview/images/notifications/figure6.png"
+ alt="" />
</div>
-<div class="figure" style="width:202px">
- <img src="{@docRoot}preview/images/notifications/Stack.png"
- alt="" width="202" height="169" id="figure5" />
-</div>
-
-<div class="figure" style="width:285px">
- <img src="{@docRoot}preview/images/notifications/figure6.png"
- alt="" width="285" height="124" id="figure6" />
-</div>
-
-<div class="figure" style="width:196px">
- <img src="{@docRoot}preview/images/notifications/ExpandedImage.png"
- alt="" width="196" height="277" id="figure7" />
- <p class="img-caption">
- <strong>Figure 3.</strong> A text-focused notification, an inbox notification, and a photo-centric notification, shown expanded and contracted, and with Wear equivalents for the first two.
- </p>
-</div>
-
-<h4 id="actions"><strong>Actions</strong></h4>
+<h3 id="actions" style="clear:both">Actions</h3>
<p>Android has supported optional actions that are displayed at the bottom of the notification, as far back as Jelly Bean. With actions, users can handle the most common tasks for a particular notification from within the notification shade without having to open the originating application. This speeds up interaction and, in conjunction with "swipe-to-dismiss", helps users to streamline their notification triaging experience.</p>
-<p>Be judicious with how many actions you include with a notification. The more actions you include, the more cognitive complexity you create. Limit yourself to the fewest number of actions possible by only including the most imminently important and meaningful ones.</p>
+
+<div class="col-6" style="margin-top:20px">
+ <img src="{@docRoot}preview/images/notifications/Action.png"
+ alt="" />
+ <p class="img-caption">
+ Calendar reminder notification with two actions
+ </p>
+</div>
+<div class="col-5" style="margin-top:20px">
+ <img src="{@docRoot}preview/images/notifications/ReplyAction.png" width="156px" height="156px"
+ alt="" />
+ <p class="img-caption">
+ Gmail new message notification - the actions appear to the right of the main card on Wear devices
+ </p>
+</div>
+
+
+<p style="clear:both">Be judicious with how many actions you include with a notification. The more actions you include, the more cognitive complexity you create. Limit yourself to the fewest number of actions possible by only including the most imminently important and meaningful ones.</p>
<p>Good candidates for actions on notifications are actions that:</p>
@@ -113,111 +123,110 @@
<li> Duplicative of the default action of the notification (such as "Read" or "Open")
</ul>
-<div class="figure" style="width:340px">
- <img src="{@docRoot}preview/images/notifications/Action.png"
- alt="" width="340" height="169" id="figure8" />
- <p class="img-caption">
- <strong>Figure 4.</strong> Calendar reminder notification with two actions
- </p>
-</div>
-<div class="figure" style="width:154px">
- <img src="{@docRoot}preview/images/notifications/ReplyAction.png"
- alt="" width="154" height="154" id="figure8_1" />
- <p class="img-caption">
- <strong>Figure 5.</strong> Gmail new message notification - the actions appear to the right of the main card on Wear devices
- </p>
-</div>
<p>You can specify a maximum of three actions, each consisting of an action icon and an action name. Adding actions to a simple base layout will make the notification expandable, even if the notification doesn't have an expanded layout. Since actions are only shown for expanded notifications and are otherwise hidden, you must make sure that any action a user can invoke from a notification is available from within the associated application as well.</p>
-<h4 id="notifications_on_android_wear"><strong>Notifications on Android Wear</strong></h4>
+<h2 id="notifications_on_android_wear">Notifications on Android Wear</h2>
<p>Additionally, notifications and their actions are bridged over to Wear devices by default. Developers have control to control which notifications from bridging from the phone to the watch and vice versa. And developers can control which actions bridge as well. If your app includes actions that can't be accomplished with a single tap, either hide these actions on your Wear notification or consider hooking them up to a Wear app to allow the user to finish the action on their watch.</p>
-<p><strong>Bridging notifications</strong></p>
+<div class="col-7">
+<h4>Bridging notifications</h4>
<p><strong>Notifications that should be bridged</strong></p>
<ul>
- <li> New instant messages
+ <li> New instant messages</li>
</ul>
<p><strong>Don't bridge</strong></p>
<ul>
- <li> If a podcasting app has new episodes available for download, keep this notification on the phone.
+ <li> If a podcasting app has new episodes available for download,
+ keep this notification on the phone.</li>
</ul>
+</div>
-<p><strong>Bridging actions </strong></p>
+<div class="col-4" style="margin-top:20px">
+ <img src="{@docRoot}preview/images/notifications/WearBasic.png" width="156px" height="156px"
+ alt="" />
+</div>
+
+
+<div style="clear:left" class="col-7">
+<h4>Bridging actions</h4></p>
<p><strong>Actions to bridge</strong></p>
<ul>
- <li> Single tap actions such as +1, Like, Heart
+ <li> Single tap actions such as +1, Like, Heart</li>
</ul>
<p><strong>Actions not to bridge</strong></p>
<ul>
- <li> Actions that map to features that aren't possible on the watch
+ <li> Actions that map to features that aren't possible on the watch</li>
</ul>
-<p><strong>Unique actions to define for Wear</strong></p>
+<p><b>Unique actions to define for Wear</b></p>
<ul>
- <li> Quick lists of canned responses such as "Be right back"
- <li> Open on phone
- <li> A "Comment" or "Reply" action that brings up the speech input screen
- <li> Actions that can launch Wear-specific apps
+ <li> Quick lists of canned responses such as "Be right back"</li>
+ <li> Open on phone</li>
+ <li> A "Comment" or "Reply" action that brings up the speech input screen</li>
+ <li> Actions that can launch Wear-specific apps</li>
</ul>
+</div>
-<p>[Asset needed: show one or more sample Wear notifications]</p>
+<div class="col-4" style="margin-top:220px">
+ <img src="{@docRoot}preview/images/notifications/ReplyAction.png" width="156px" height="156px"
+ alt="" />
+</div>
-<p><strong>Heads-up Notification</strong></p>
-
-<p>When notifications with priority set to High (see below) arrives, it is presented to users for a short period of time on the device with an expanded layout with its actions exposed. After this period of time, it retreats back to the Notification shade. If a notification is flagged as High or Max or a full-screen takeover, it gets a HUN in L.</p>
-
-
+<h2 style="clear:left">Heads-up Notification</h2>
<div class="figure" style="width:262px">
<img src="{@docRoot}preview/images/notifications/Headsup.png"
- alt="" width="262" height="513" id="figure9" />
+ alt="" width="220" id="figure9" />
<p class="img-caption">
<strong>Figure 6.</strong> Example of a Heads-up notification (incoming phone call, high priority) coming in on top of an immersive app
</p>
</div>
-<p><strong>Good examples of Heads-up notifications</strong></p>
+<p>When notifications with priority set to High (see right) arrives, it is presented to users for a short period of time on the device with an expanded layout with its actions exposed.</p>
+<p> After this period of time, it retreats back to the Notification shade. If a notification is flagged as High or Max or a full-screen takeover, it gets a HUN in L.</p>
+
+<p><b>Good examples of Heads-up notifications</b></p>
<ul>
- <li> Incoming phone call when using device
- <li> Alarm when using device
- <li> New SMS message
- <li> Low battery
+ <li> Incoming phone call when using device</li>
+ <li> Alarm when using device</li>
+ <li> New SMS message</li>
+ <li> Low battery</li>
</ul>
-<h2 id="guidelines">Guidelines</h2>
+<h2 style="clear:both" id="guidelines">Guidelines</h2>
-<div class="figure" style="width:366px">
+<div class="figure" style="width:366px; margin-top:40px">
<img src="{@docRoot}preview/images/notifications/Triggered.png"
- alt="" width="366" height="142" id="figure10" />
+ alt="" width="366" height="142" />
<p class="img-caption">
- <strong>Figure 7.</strong> Notification that shows the person who triggered it and the content they are sending you
+ Notification that shows the person who triggered it and the content they are sending you
</p>
</div>
-<h4 id="make_it_personal"><strong>Make it personal</strong></h4>
+<h3 id="MakeItPersonal">Make it personal</h3>
<p>For notifications of items sent by another person (such as a message or status update), include that person's image using setLargeIcon. Also attach information about the person to the notification's metadata (see EXTRA_PEOPLE).</p>
<p>Your notification's main icon will still be shown, so the user can associate it with the icon visible in the status bar.</p>
-<h4 id="navigate_to_the_right_place"><strong>Navigate to the right place</strong></h4>
+<h3 id="navigate_to_the_right_place">Navigate to the right place</h3>
-<p>When the user touches the body of a notification (outside of the action buttons), open your app to the place where the user can view and act upon the data referenced in the notification. In most cases this will be the detail view of a single data item such as a message, but it might also be a summary view if the notification is stacked (see <em>Stacked notifications</em> below) and references multiple items. If in any of those cases the user is taken to a hierarchy level below your app's top-level, insert navigation into your app's back stack to allow them to navigate to your app's top level using the system back button. For more information, see the chapter on <em>System-to-app navigation</em> in the <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> design pattern.</p>
+<p>When the user touches the body of a notification (outside of the action buttons), open your app to the place where the user can view and act upon the data referenced in the notification. In most cases this will be the detail view of a single data item such as a message, but it might also be a summary view if the notification is stacked (see <em>Stacked notifications</em> below) and references multiple items. If in any of those cases the user is taken to a hierarchy level below your app's top-level, insert navigation into your app's back stack to allow them to navigate to your app's top level using the system back button. For more information, see the chapter on <em>System-to-app navigation</em> in the <a href="/design/patterns/navigation.html">Navigation</a> design pattern.</p>
-<h4 id="correctly_set_and_manage_notification_priority"><strong>Correctly set and manage notification priority</strong></h4>
+<h3 id="correctly_set_and_manage_notification_priority">Correctly set and manage notification priority</h3>
<p>Starting with Jelly Bean, Android supported a priority flag for notifications. It allows you to influence where your notification will appear in comparison to other notifications and help to make sure that users always see their most important notifications first. You can choose from the following priority levels when posting a notification:</p>
<table>
@@ -231,7 +240,7 @@
</tr>
<tr>
<td class="tab1">
-<p>{@code MAX}</p>
+<p><code>MAX</code></p>
</td>
<td class="tab1">
<p>Use for critical and urgent notifications that alert the user to a condition that is time-critical or needs to be resolved before they can continue with a particular task.</p>
@@ -239,7 +248,7 @@
</tr>
<tr>
<td class="tab1">
-<p>{@code HIGH}</p>
+<p><code>HIGH</code></p>
</td>
<td class="tab1">
<p>Use high priority notifications primarily for important communication, such as message or chat events with content that is particularly interesting for the user. High priority notifications will get the Heads-Up Notification display starting in L.</p>
@@ -247,7 +256,7 @@
</tr>
<tr>
<td class="tab1">
-<p>{@code DEFAULT}</p>
+<p><code>DEFAULT</code></p>
</td>
<td class="tab1">
<p>The default priority. Keep all notifications that don't fall into any of the other categories at this priority level.</p>
@@ -255,7 +264,7 @@
</tr>
<tr>
<td class="tab1">
-<p>{@code LOW}</p>
+<p><code>LOW</code></p>
</td>
<td class="tab1">
<p>Use for notifications that you still want the user to be informed about, but that rate low in urgency. LOW notifications will tend to show up at the bottom of the list, which makes them a good choice for things like pubic/undirected social updates: the user has asked to be notified about them, but they should never take precedence over urgent or direct communication.</p>
@@ -263,7 +272,7 @@
</tr>
<tr>
<td class="tab1">
-<p>{@code MIN}</p>
+<p><code>MIN</code></p>
</td>
<td class="tab1">
<p>Contextual/background information (e.g. weather information, contextual location information). Minimum priority notifications will not show in the status bar. The user will only discover them when they expand the notification shade.</p>
@@ -272,36 +281,37 @@
</table>
-<h4 id="how_to_choose_an_appropriate_priority"><strong>How to choose an appropriate priority</strong></h4>
+<h4 id="how_to_choose_an_appropriate_priority"><strong>How to choose an appropriate
+priority</strong></h4>
<p>Default, High, and Max priority are interruptive priority levels and risk interrupting the user from what they are doing. This should not not be taken lightly, so these levels should be reserved for notifications that:</p>
<ul>
- <li> Involve another person
- <li> Are time-sensitive
- <li> Might immediately change the user's behavior in the real world
+ <li> Involve another person</li>
+ <li> Are time-sensitive</li>
+ <li> Might immediately change the user's behavior in the real world</li>
</ul>
<p>Notifications set to Low and Min can still be very valuable for the user. Many if not most notifications just don't need to command the user's immediate attention, or vibrate the user's wrist, yet contain information that they will find valuable when they choose to look for notifications. Criteria for Low and Min priority notifications:</p>
<ul>
- <li> Don't involve other people
- <li> Aren't time sensitive
- <li> Is content the user might be interested in but could choose to browse at their leisure
+ <li> Don't involve other people</li>
+ <li> Aren't time sensitive</li>
+ <li> Is content the user might be interested in but could choose to browse at their leisure</li>
</ul>
-<div class="figure" style="width:624px">
- <img src="{@docRoot}preview/images/notifications/notifications_pattern_priority.png"
- alt="" width="624" height="210" id="figure11">
-</div>
-<h4 id="set_a_notification_category"><strong>Set a notification category</strong></h4>
+ <img src="{@docRoot}preview/images/notifications/notifications_pattern_priority.png"
+ alt="" width="700"/>
+
+
+<h3 style="clear:both" id="set_a_notification_category">Set a notification category</h3>
<p>If your notification falls into one of the predefined categories (see below), assign it accordingly. Aspects of the system UI such as the notification shade (or any other notification listener) may use this information to make ranking and filtering decisions.</p>
<table>
<tr>
<td>
-<p>{@code Notification.CATEGORY_CALL}</p>
+<p><code>Notification.CATEGORY_CALL</code></p>
</td>
<td>
<p>Incoming call (voice or video) or similar synchronous communication request</p>
@@ -309,7 +319,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_MESSAGE}</p>
+<p><code>Notification.CATEGORY_MESSAGE</code></p>
</td>
<td>
<p>Incoming direct message (SMS, instant message, etc.)</p>
@@ -317,7 +327,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_EMAIL}</p>
+<p><code>Notification.CATEGORY_EMAIL</code></p>
</td>
<td>
<p>Asynchronous bulk message (email)</p>
@@ -325,7 +335,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_EVENT}</p>
+<p><code>Notification.CATEGORY_EVENT</code></p>
</td>
<td>
<p>Calendar event</p>
@@ -333,7 +343,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_PROMO}</p>
+<p><code>Notification.CATEGORY_PROMO</code></p>
</td>
<td>
<p>Promotion or advertisement</p>
@@ -341,7 +351,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_ALARM}</p>
+<p><code>Notification.CATEGORY_ALARM</code></p>
</td>
<td>
<p>Alarm or timer</p>
@@ -349,7 +359,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_PROGRESS}</p>
+<p><code>Notification.CATEGORY_PROGRESS</code></p>
</td>
<td>
<p>Progress of a long-running background operation</p>
@@ -357,7 +367,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_SOCIAL}</p>
+<p><code>Notification.CATEGORY_SOCIAL</code></p>
</td>
<td>
<p>Social network or sharing update</p>
@@ -365,7 +375,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_ERROR}</p>
+<p><code>Notification.CATEGORY_ERROR</code></p>
</td>
<td>
<p>Error in background operation or authentication status</p>
@@ -373,7 +383,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_TRANSPORT}</p>
+<p><code>Notification.CATEGORY_TRANSPORT</code></p>
</td>
<td>
<p>Media transport control for playback</p>
@@ -381,7 +391,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_SYSTEM}</p>
+<p><code>Notification.CATEGORY_SYSTEM</code></p>
</td>
<td>
<p>System or device status update. Reserved for system use.</p>
@@ -389,7 +399,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_SERVICE}</p>
+<p><code>Notification.CATEGORY_SERVICE</code></p>
</td>
<td>
<p>Indication of running background service</p>
@@ -397,7 +407,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_RECOMMENDATION}</p>
+<p><code>Notification.CATEGORY_RECOMMENDATION</code></p>
</td>
<td>
<p>A specific, timely recommendation for a single thing. For example, a news app might want to recommend a news story it believes the user will want to read next.</p>
@@ -405,7 +415,7 @@
</tr>
<tr>
<td>
-<p>{@code Notification.CATEGORY_STATUS}</p>
+<p><code>Notification.CATEGORY_STATUS</code></p>
</td>
<td>
<p>Ongoing information about device or contextual status</p>
@@ -416,104 +426,104 @@
<p> </p>
-<h4 id="summarize_your_notifications"><strong>Summarize your notifications</strong></h4>
+<h3 id="summarize_your_notifications">Summarize your notifications</h3>
<p>If your app creates a notification while another of the same type is still pending, avoid creating an altogether new notification object. Instead, turn it into a summary notification for the app.</p>
<p>A summary notification builds a summary description and allows the user to understand how many notifications of a particular kind are pending.</p>
-<p><strong>Don't</strong>:</p>
-
-<div class="figure" style="width:325px">
- <img src="{@docRoot}preview/images/notifications/Summarise_Dont.png"
- alt="" width="325" height="361" id="figure12" />
-</div>
-
-<p><strong>Do</strong>:</p>
-
-<div class="figure" style="width:318px">
- <img src="{@docRoot}preview/images/notifications/Summarise_Do.png"
- alt="" width="318" height="293" id="figure13" />
-</div>
-
-<p>You can provide more detail about the individual notifications that make up a summary by using the expanded digest layout. This allows users to gain a better sense of which notifications are pending and if they are interesting enough to be read in detail within the associated app.</p>
-
-<div class="figure" style="width:370px">
- <img src="{@docRoot}preview/images/notifications/ExpandedText.png"
- alt="" width="370" height="309" id="figure14" />
- <p class="img-caption">
- <strong>Figure 8.</strong> Expanded and contracted notification that is a summary (using InboxStyle)
- </p>
-</div>
-
-<h4 id="make_notifications_optional"><strong>Make notifications optional</strong></h4>
-
-<p>Users should always be in control of notifications. Allow the user to disable your app's notifications or change their alert properties, such as alert sound and whether to use vibration, by adding a notification settings item to your application settings.</p>
-
-<h4 id="use_distinct_icons"><strong>Use distinct icons</strong></h4>
-
-<p>By glancing at the notification area, the user should be able to discern what kinds of notifications are currently pending.</p>
-
-<p><strong>Do</strong></p>
-
-<p>Look at the notification icons Android apps already provide and create notification icons for your app that are sufficiently distinct in appearance.</p>
-
-<p>[asset: include some sample visuals of notification icons]</p>
-
-<div class="figure" style="width:405px">
- <img src="{@docRoot}preview/images/notifications/figure15.png"
- alt="" width="405" height="80" id="figure15" />
-</div>
-
-<p><strong>Do</strong></p>
-
-<p>Use the proper <a href="{@docRoot}design/style/iconography.html#notification">notification icon style</a> for small icons, and the Material Light <a href="{@docRoot}design/style/iconography.html#action-bar">action bar icon style</a> for your action icons. Do not place any additional alpha (dimming or fading) into your small icons and action icons; they can have anti-aliased edges, but because L uses these icons as masks (that is, only the alpha channel is used), the image should generally be drawn at full opacity.</p>
-
-<p>[asset: show a zoomed example of how this should look]</p>
-
-<div class="figure" style="width:348px">
- <img src="{@docRoot}preview/images/notifications/figure16.png"
- alt="" width="348" height="300" id="figure16" />
-</div>
-
-<p><strong>Do</strong></p>
-
-<p>Keep your icons visually simple and avoid excessive detail that is hard to discern.</p>
-
+<div class="col-6">
<p><strong>Don't</strong></p>
+ <img src="{@docRoot}preview/images/notifications/Summarise_Dont.png"
+ alt="" width="300" />
+
+</div>
+
+<div class="col-5">
+<p><strong>Do</strong></p>
+
+ <img src="{@docRoot}preview/images/notifications/Summarise_Do.png"
+ alt="" width="300"/>
+</div>
+</div>
+
+
+<p style="clear:left">You can provide more detail about the individual notifications that make up a summary by using the expanded digest layout. This allows users to gain a better sense of which notifications are pending and if they are interesting enough to be read in detail within the associated app.</p>
+
+ <img src="{@docRoot}preview/images/notifications/Stack.png" style="margin-bottom:30px"
+ alt="" width="370" />
+ <p class="img-caption">
+ Expanded and contracted notification that is a summary (using InboxStyle)
+ </p>
+
+
+<h3 style="clear:right" id="make_notifications_optional">Make notifications optional</h3>
+
+<p>Users should always be in control of notifications. Allow the user to diszable your app's
+notifications or change their alert properties, such as alert sound and whether to use vibration,
+by adding a notification settings item to your application settings.</p>
+
+<h3 id="use_distinct_icons">Use distinct icons</h3>
+<p>By glancing at the notification area, the user should be able to discern what kinds of
+notifications are currently pending.</p>
+
+<div class="figure">
+ <img src="{@docRoot}preview/images/notifications/ProductIcons.png"
+ alt="" width="420" />
+</div>
+
+ <div><p><strong>Do</strong></p>
+ <p>Look at the notification icons Android apps already provide and create notification icons for
+ your app that are sufficiently distinct in appearance.</p>
+
+ <p><strong>Do</strong></p>
+ <p>Use the proper <a href="/design/style/iconography.html#notification">notification icon
+ style</a> for small icons, and the Material Light
+ <a href="/design/style/iconography.html#action-bar">action bar icon style</a> for your action
+ icons. Do not place any additional alpha (dimming or fading) into your small icons and action
+ icons; they can have anti-aliased edges, but because L uses these icons as masks (that is, only
+ the alpha channel is used), the image should generally be drawn at full opacity.</p>
+<p ><strong>Do</strong></p>
+<p >Keep your icons visually simple and avoid excessive detail that is hard to discern.</p>
+
+</div>
+<p style="clear:both"><strong>Don't</strong></p>
+
<p>Use color to distinguish your app from others. Notification icons should only be a white-on-transparent background image.</p>
-<h4 id=pulse_the_notification_led_appropriately><strong>Pulse the notification LED appropriately</strong></h4>
+
+<h3 id="pulse_the_notification_led_appropriately">Pulse the notification LED appropriately</h3>
<p>Many Android devices contain a notification LED, which is used to keep the user informed about events while the screen is off. Notifications with a priority level of MAX, HIGH, or DEFAULT should cause the LED to glow, while those with lower priority (LOW and MIN) should not.</p>
<p>The user's control over notifications should extend to the LED. When you use DEFAULT_LIGHTS, the LED will glow with a white color. Your notifications shouldn't use a different color unless the user has explicitly customized it.</p>
-<h2 id=building_notifications_that_users_care_about>Building notifications that users care about</h2>
+<h2 id="building_notifications_that_users_care_about">Building notifications that users care about</h2>
<p>To create an app that users love, it is important to design your notifications carefully. Notifications embody your app's voice, and contribute to your app's personality. Unwanted or unimportant notifications can annoy the user or make them resent how much attention the app wants from them, so use notifications judiciously.</p>
-<h4 id=when_to_display_a_notification><strong>When to display a notification</strong></h4>
-
+<h3 id="when_to_display_a_notification">When to display a notification</h3>
+<div class="figure">
+ <img src="{@docRoot}preview/images/notifications/TimeSensitive.png"
+ alt="" width="360" />
+ <p class="img-caption">
+ Time sensitive notification examples
+ </p>
+</div>
<p>To create an application that people enjoy using, it's important to recognize that the user's attention and focus is a resource that must be protected. While Android's notification system has been designed to minimize the impact of notifications on the user's attention, it is nonetheless still important to be aware of the fact that notifications are interrupting the user's task flow. As you plan your notifications, ask yourself if they are important enough to warrant an interruption. If you are unsure, allow the user to opt into a notification using your apps notification settings or adjust the notifications priority flag to Low or Min to avoid distracting the user while they are doing something else.</p>
<p>While well behaved apps generally only speak when spoken to, there are some limited cases where an app actually should interrupt the user with an unprompted notification.</p>
<p>Notifications should be used primarily for <strong>time sensitive events</strong>, and especially if these synchronous events <strong>involve other people</strong>. For instance, an incoming chat is a real time and synchronous form of communication: there is another user actively waiting on you to respond. Calendar events are another good example of when to use a notification and grab the user's attention, because the event is imminent, and calendar events often involve other people.</p>
-<div class="figure" style="width:624px">
- <img src="{@docRoot}preview/images/notifications/figure17.png"
- alt="" width="624" height="232" id="figure17" />
- <p class="img-caption">
- <strong>Figure 8.</strong> Time sensitive notification examples
- </p>
+<h3 style="clear:both" id="when_not_to_display_a_notification">When not to display a notification</h3>
+
+<div class="figure" style="margin-top:60px">
+ <img src="{@docRoot}preview/images/notifications/AntiSample1.png"
+ alt="" width="280px" />
</div>
-<p> </p>
-
-<h4 id=when_not_to_display_a_notification><strong>When not to display a notification</strong></h4>
-
<p>There are however many other cases where notifications should not be used:</p>
<ul>
@@ -525,44 +535,30 @@
<li> Don't create superfluous notifications just to get your brand in front of users. Such notifications will only frustrate and likely alienate your audience. The best way to provide the user with a small amount of updated information and to keep them engaged with your application is to develop a widget that they can choose to place on their home screen.
</ul>
-<div class="figure" style="width:373px">
- <img src="{@docRoot}preview/images/notifications/figure18.png"
- alt="" width="373" height="734" id="figure18" />
- <p class="img-caption">
- <strong>Figure 9.</strong> Anti-examples of notifications
- </p>
-</div>
-
-<h2 id=interacting_with_notifications>Interacting With Notifications</h2>
-
-<div class="figure" style="width:444px">
- <img src="{@docRoot}preview/images/notifications/AntiSample1.png"
- alt="" width="444" height="188" id="figure19" />
-</div>
+<h2 style="clear:left" id="interacting_with_notifications">Interacting With Notifications</h2>
<p>Notifications are indicated by icons in the status bar and can be accessed by opening the notification drawer.</p>
<p>Touching a notification opens the associated app to detailed content matching the notification. Swiping left or right on a notification removes it from the list.</p>
-<h4 id=ongoing_notifications><strong>Ongoing notifications</strong></h4>
-
-<p>Ongoing notifications keep users informed about an ongoing process in the background. For example, music players announce the currently playing track in the notification system and continue to do so until the user stops the playback. They can also be used to show the user feedback for longer tasks like downloading a file, or encoding a video. Ongoing notifications cannot be manually removed from the notification drawer.</p>
-
+<h3 id="ongoing_notifications">Ongoing notifications</h3>
<div class="figure" style="width:337px">
<img src="{@docRoot}preview/images/notifications/MusicPlayback.png"
- alt="" width="337" height="196" id="figure20" />
+ alt="" width="337" />
<p class="img-caption">
- <strong>Figure 10.</strong> Ongoing notification due to music playback
+ Ongoing notification due to music playback
</p>
</div>
+<p>Ongoing notifications keep users informed about an ongoing process in the background. For example, music players announce the currently playing track in the notification system and continue to do so until the user stops the playback. They can also be used to show the user feedback for longer tasks like downloading a file, or encoding a video. Ongoing notifications cannot be manually removed from the notification drawer.</p>
<p>The L lockscreen doesn't show transport controls for RCC (RemoteControlClient)s anymore. But the lockscreen <em>does</em> show notifications, so each app's playback notification is now the primary way for users to control playback from a locked state. This gives apps more control over which buttons to show and in what way, while providing a consistent experience for the user whether on the lockscreen or unlocked.</p>
-<h4 id=dialogs_and_toasts_are_for_feedback_not_notification><strong>Dialogs and toasts are for feedback not notification</strong></h4>
+<h3 style="clear:both" id="dialogs_and_toasts_are_for_feedback_not_notification">Dialogs
+and toasts are for feedback not notifications</h3>
-<p>Your app should not create a dialog or toast if it is not currently on screen. Dialogs and Toasts should only be displayed as the immediate response to the user taking an action inside of your app. For further guidance on the use of dialogs and toasts, refer to <a href="{@docRoot}design/patterns/confirming-acknowledging.html">Confirming & Acknowledging</a>.</p>
+<p>Your app should not create a dialog or toast if it is not currently on screen. Dialogs and Toasts should only be displayed as the immediate response to the user taking an action inside of your app. For further guidance on the use of dialogs and toasts, refer to <a href="/design/patterns/confirming-acknowledging.html">Confirming & Acknowledging</a>.</p>
-<p><strong>Ranking and ordering</strong></p>
+<h3>Ranking and Ordering</h3>
<p>Notifications are "news" and so they are essentially shown in reverse-chronological order, with special consideration given to the app's stated notification priority.</p>
@@ -573,24 +569,19 @@
<ul>
<li> The timestamp and application's stated priority, as before.
<li> Whether the notification has recently disturbed the user with sound or vibration. (That is, if the phone just made noise, and the user wants to know "what just happened?" the lockscreen should answer that at a glance.)
- <li> Any people that are attached to the notification using {@code EXTRA_PEOPLE}, and in particular whether those are starred contacts.
+ <li> Any people that are attached to the notification using <code>EXTRA_PEOPLE</code>, and in particular whether those are starred contacts.
</ul>
<p>To best take advantage of this sorting, developers should focus on the user experience they want to create rather than aiming for any particular spot on the list.</p>
-<p>An example:</p>
-
-<div class="figure" style="width:624px">
<img src="{@docRoot}preview/images/notifications/AntiSample3.png"
- alt="" width="624" height="334" id="figure21" />
- <p class="img-caption">
- <strong>Figure 11.</strong> Gmail notifications are default priority, so they normally sort below messages from an instant messaging app like Hangouts, but Gmail will get a temporary bump when new messages come in.
+ alt="" width="700px" />
+
+ <p class="img-caption" style="margin-top:20px">Gmail notifications are default priority, so they normally sort below messages from an instant messaging app like Hangouts, but Gmail will get a temporary bump when new messages come in.
</p>
-</div>
-<p>Give the user choices: about whether to have notifications at all, whether they should vibrate or make sound.</p>
-<p><strong>On the lockscreen</strong></p>
+<h3>On the lockscreen</h3>
<p>Starting in L, notifications are visible on the lockscreen, and so we must consider the user's privacy. Notifications often contain sensitive information, and we must take care when showing it to anyone who picks up the device and turns on the display.</p>
@@ -599,28 +590,28 @@
<li> When a device has a secure lockscreen (PIN, pattern, or password), however, it divides the interface into two spheres: "public", the things that are displayed atop a secure lockscreen and can therefore be seen by anyone; and "private", the world behind that lockscreen, which can only be accessed by supplying the correct authentication.
</ul>
+
+
+<h3>The user decides what shows on the secure lockscreen</h3>
<div class="figure" style="width:249px">
<img src="{@docRoot}preview/images/notifications/LockScreen.png"
alt="" width="249" height="482" id="figure22" />
<p class="img-caption">
- <strong>Figure 12.</strong> Notifications on the lockscreen followed by the Pattern Unlock when the user attempts to unlock the phone.
+ Notifications on the lockscreen followed by the Pattern Unlock when the user attempts to unlock the phone.
</p>
</div>
-<p><strong>The user decides what shows on the secure lockscreen</strong></p>
-
<p>When setting up a secure lockscreen, the user can choose to conceal sensitive details from atop the secure lockscreen. In this case the SystemUI considers the notification's <em>visibility level</em> to figure out what can safely be shown.</p>
-<p>To control the visibility level, call {@code android.app.Notification.Builder.setVisibility()} and specify one of these values:</p>
+<p>To control the visibility level, call <code>android.app.Notification.Builder.setVisibility()</code> and specify one of these values:</p>
<ul>
- <li>{@code android.app.Notification.VISIBILITY_PUBLIC}. Shows the notification's full content. This is the system default if visibility is left unspecified.
- <li>{@code android.app.Notification.VISIBILITY_PRIVATE}. The lockscreen will reveal basic information about the existence of this notification, including its icon and the name of the app that posted it. The rest of the notification's details, however, are not displayed.
+ <li><code>android.app.Notification.VISIBILITY_PUBLIC</code>. Shows the notification's full content. This is the system default if visibility is left unspecified.
+ <li><code>android.app.Notification.VISIBILITY_PRIVATE</code>. The lockscreen will reveal basic information about the existence of this notification, including its icon and the name of the app that posted it. The rest of the notification's details, however, are not displayed.
<ul>
- <li> If you want to provide a different public version of your notification for the system to display on a secure lockscreen, supply a replacement Notification object in the {@code android.app.Notification.publicVersion} field.
+ <li> If you want to provide a different public version of your notification for the system to display on a secure lockscreen, supply a replacement Notification object in the <code>android.app.Notification.publicVersion</code> field.
<li> This is an app's opportunity to create a redacted version of the content that is still useful but does not reveal personal information.
- <li> <strong>Example: </strong>An SMS app whose notifications include the text of the SMS and the sender's name and contact icon. This notification should be {@code VISIBILITY_PRIVATE}, but the {@code publicVersion} could still contain useful information like "3 new messages" without any other identifying details.
+ <li> <strong>Example: </strong>An SMS app whose notifications include the text of the SMS and the sender's name and contact icon. This notification should be <code>VISIBILITY_PRIVATE</code>, but the <code>publicVersion</code> could still contain useful information like "3 new messages" without any other identifying details.
</ul>
- <li>{@code android.app.Notification.VISIBILITY_SECRET}. Shows only the most minimal information, excluding even the notification's icon.
-</ul>
-
+ <li><code>android.app.Notification.VISIBILITY_SECRET</code>. Shows only the most minimal information, excluding even the notification's icon.
+</ul>
\ No newline at end of file
diff --git a/docs/html/preview/reference.jd b/docs/html/preview/reference.jd
index f70f7a2..b70e4e5 100644
--- a/docs/html/preview/reference.jd
+++ b/docs/html/preview/reference.jd
@@ -2,12 +2,10 @@
@jd:body
-<p>The reference documentation and API difference report are available as downloadable packages.
+<p>The reference documentation and API difference report are available in this downloadable package.
</p>
<ul>
- <li><a href="{@docRoot}preview/l-developer-preview-reference.zip">L
+ <li><a href="http://storage.googleapis.com/androiddevelopers/preview/l-developer-preview-reference.zip">L
Developer Preview reference</a></li>
- <li><a href="{@docRoot}preview/l-developer-preview-api-diff.zip">L
- Developer Preview difference report</a></li>
</ul>
\ No newline at end of file
diff --git a/docs/html/preview/support.jd b/docs/html/preview/support.jd
index 8efc4bc..9d7844b 100644
--- a/docs/html/preview/support.jd
+++ b/docs/html/preview/support.jd
@@ -7,7 +7,7 @@
our issue tracker.</p>
<p>For more support,
-<a href="https://plus.google.com/communities/113159138894928487684">join
+<a href="https://plus.google.com/communities/101985907812750684586">join
the L Developer Preview Google+ community</a> to discuss your development experiences.
diff --git a/docs/html/training/wearables/apps/creating.jd b/docs/html/training/wearables/apps/creating.jd
index 841f24a..a5107d7 100644
--- a/docs/html/training/wearables/apps/creating.jd
+++ b/docs/html/training/wearables/apps/creating.jd
@@ -126,7 +126,7 @@
<p class="note"><b>Note:</b> The <b>wear</b> module also contains a "Hello World" activity that uses a
<code>WatchViewStub</code> that inflates a layout based on whether the device's screen
is round or square. The <code>WatchViewStub</code> class is one of the UI widgets that's provided
- by the <a href="{@docRoot}training/wearables/apps/layouts#UiLibrary">wearable support library</a>.</p>
+ by the <a href="{@docRoot}training/wearables/apps/layouts.html#UiLibrary">wearable support library</a>.</p>
</li>
<h2 id="Install">Install the Wearable app</h2>
diff --git a/docs/html/training/wearables/apps/index.jd b/docs/html/training/wearables/apps/index.jd
index 3a4eb70..a0d02fb 100644
--- a/docs/html/training/wearables/apps/index.jd
+++ b/docs/html/training/wearables/apps/index.jd
@@ -59,7 +59,7 @@
<dd>Learn how to create an Android Studio project that
contains both the wearable and handheld app modules and how to run the app on a device
or emulator.</dd>
- <dt><a href="{@docRoot}training/wearables/apps/activity.html">Creating Custom Layouts</a></dt>
+ <dt><a href="{@docRoot}training/wearables/apps/layouts.html">Creating Custom Layouts</a></dt>
<dd>Learn how to create and display custom layouts for notifications and
activities.</dd>
<dt><a href="{@docRoot}training/wearables/apps/voice.html">Adding Voice Capabilities</a></dt>
diff --git a/docs/html/wear/index.jd b/docs/html/wear/index.jd
index c9b8ba85..5dd7690 100644
--- a/docs/html/wear/index.jd
+++ b/docs/html/wear/index.jd
@@ -152,7 +152,7 @@
for a hands-free experience.
</p>
<p class="landing-small">
- <a href="{@docRoot}training/wearables/apps/voice-actions.html">Integrate voice actions</a>
+ <a href="{@docRoot}training/wearables/apps/voice.html">Integrate voice actions</a>
</p>
</div>
<div class="col-4">
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 0862cdd..17795f3 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -126,7 +126,34 @@
*/
public SurfaceTexture(int texName, boolean singleBufferMode) {
mCreatorLooper = Looper.myLooper();
- nativeInit(texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
+ nativeInit(false, texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
+ }
+
+ /**
+ * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
+ *
+ * In single buffered mode the application is responsible for serializing access to the image
+ * content buffer. Each time the image content is to be updated, the
+ * {@link #releaseTexImage()} method must be called before the image content producer takes
+ * ownership of the buffer. For example, when producing image content with the NDK
+ * ANativeWindow_lock and ANativeWindow_unlockAndPost functions, {@link #releaseTexImage()}
+ * must be called before each ANativeWindow_lock, or that call will fail. When producing
+ * image content with OpenGL ES, {@link #releaseTexImage()} must be called before the first
+ * OpenGL ES function call each frame.
+ *
+ * Unlike {@link #SurfaceTexture(int, boolean)}, which takes an OpenGL texture object name,
+ * this constructor creates the SurfaceTexture in detached mode. A texture name must be passed
+ * in using {@link #attachToGLContext} before calling {@link #releaseTexImage()} and producing
+ * image content using OpenGL ES.
+ *
+ * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
+ *
+ * @throws Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
+ * @hide
+ */
+ public SurfaceTexture(boolean singleBufferMode) {
+ mCreatorLooper = Looper.myLooper();
+ nativeInit(true, 0, singleBufferMode, new WeakReference<SurfaceTexture>(this));
}
/**
@@ -339,8 +366,8 @@
}
}
- private native void nativeInit(int texName, boolean singleBufferMode,
- WeakReference<SurfaceTexture> weakSelf)
+ private native void nativeInit(boolean isDetached, int texName,
+ boolean singleBufferMode, WeakReference<SurfaceTexture> weakSelf)
throws Surface.OutOfResourcesException;
private native void nativeFinalize();
private native void nativeGetTransformMatrix(float[] mtx);
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 0740761..cef3377 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -80,20 +80,41 @@
*/
public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
private final AnimationState mAnimationState;
+
+ /** The current frame, may be -1 when not animating. */
private int mCurFrame = -1;
+
+ /** Whether the drawable has an animation callback posted. */
+ private boolean mRunning;
+
+ /** Whether the drawable should animate when visible. */
private boolean mAnimating;
+
private boolean mMutated;
public AnimationDrawable() {
this(null, null);
}
+ /**
+ * Sets whether this AnimationDrawable is visible.
+ * <p>
+ * When the drawable becomes invisible, it will pause its animation. A
+ * subsequent change to visible with <code>restart</code> set to true will
+ * restart the animation from the first frame. If <code>restart</code> is
+ * false, the animation will resume from the most recent frame.
+ *
+ * @param visible true if visible, false otherwise
+ * @param restart when visible, true to force the animation to restart
+ * from the first frame
+ * @return true if the new visibility is different than its previous state
+ */
@Override
public boolean setVisible(boolean visible, boolean restart) {
final boolean changed = super.setVisible(visible, restart);
if (visible) {
- if (changed || restart) {
- setFrame(0, true, mAnimating);
+ if (restart || changed) {
+ setFrame(restart ? 0 : mCurFrame, true, mAnimating);
}
} else {
unscheduleSelf(this);
@@ -115,6 +136,8 @@
*/
@Override
public void start() {
+ mAnimating = true;
+
if (!isRunning()) {
run();
}
@@ -129,6 +152,8 @@
*/
@Override
public void stop() {
+ mAnimating = false;
+
if (isRunning()) {
unscheduleSelf(this);
}
@@ -141,7 +166,7 @@
*/
@Override
public boolean isRunning() {
- return mAnimating;
+ return mRunning;
}
/**
@@ -158,7 +183,7 @@
@Override
public void unscheduleSelf(Runnable what) {
mCurFrame = -1;
- mAnimating = false;
+ mRunning = false;
super.unscheduleSelf(what);
}
@@ -219,6 +244,7 @@
if (next >= N) {
next = 0;
}
+
setFrame(next, unschedule, !mAnimationState.mOneShot || next < (N - 1));
}
@@ -226,6 +252,7 @@
if (frame >= mAnimationState.getChildCount()) {
return;
}
+ mAnimating = animate;
mCurFrame = frame;
selectDrawable(frame);
if (unschedule || animate) {
@@ -234,7 +261,7 @@
if (animate) {
// Unscheduling may have clobbered these values; restore them
mCurFrame = frame;
- mAnimating = true;
+ mRunning = true;
scheduleSelf(this, SystemClock.uptimeMillis() + mAnimationState.mDurations[frame]);
}
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index f2e75a5..9bf7c43 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -16,6 +16,8 @@
package android.graphics.drawable;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -52,7 +54,7 @@
* <code><!-- A red ripple masked against an opaque rectangle. --/>
* <ripple android:color="#ffff0000">
* <item android:id="@android:id/mask"
- * android:drawable="#ffffffff" />
+ * android:drawable="@android:color/white" />
* <ripple /></code>
* </pre>
* <p>
@@ -62,9 +64,9 @@
* If no mask layer is set, the ripple effect is masked against the composite
* of the child layers.
* <pre>
- * <code><!-- A blue ripple drawn atop a green rectangle. --/>
+ * <code><!-- A blue ripple drawn atop a black rectangle. --/>
* <ripple android:color="#ff00ff00">
- * <item android:drawable="#ff0000ff" />
+ * <item android:drawable="@android:color/black" />
* <ripple />
*
* <!-- A red ripple drawn atop a drawable resource. --/>
@@ -147,11 +149,7 @@
}
/**
- * Creates a new ripple drawable with the specified content and mask
- * drawables.
- *
- * @param content The content drawable, may be {@code null}
- * @param mask The mask drawable, may be {@code null}
+ * @hide TO BE REMOVED FOR L-RELEASE
*/
public RippleDrawable(Drawable content, Drawable mask) {
this(new RippleState(null, null, null), null, null);
@@ -165,6 +163,36 @@
}
ensurePadding();
+
+ Log.e(LOG_TAG, "This constructor is being removed", new RuntimeException());
+ }
+
+ /**
+ * Creates a new ripple drawable with the specified ripple color and
+ * optional content and mask drawables.
+ *
+ * @param color The ripple color
+ * @param content The content drawable, may be {@code null}
+ * @param mask The mask drawable, may be {@code null}
+ */
+ public RippleDrawable(@NonNull ColorStateList color, @Nullable Drawable content,
+ @Nullable Drawable mask) {
+ this(new RippleState(null, null, null), null, null);
+
+ if (color == null) {
+ throw new IllegalArgumentException("RippleDrawable requires a non-null color");
+ }
+
+ if (content != null) {
+ addLayer(content, null, 0, 0, 0, 0, 0);
+ }
+
+ if (mask != null) {
+ addLayer(content, null, android.R.id.mask, 0, 0, 0, 0);
+ }
+
+ setColor(color);
+ ensurePadding();
}
@Override
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index a704e19..1a96b2f 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -13,6 +13,7 @@
font/Font.cpp \
AmbientShadow.cpp \
Animator.cpp \
+ AnimatorManager.cpp \
AssetAtlas.cpp \
DamageAccumulator.cpp \
FontRenderer.cpp \
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index dc6d852..4a8c122 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -18,6 +18,7 @@
#include "Animator.h"
+#include <inttypes.h>
#include <set>
#include "RenderNode.h"
@@ -35,72 +36,105 @@
, mDeltaValue(0)
, mFromValue(0)
, mInterpolator(0)
- , mPlayState(NEEDS_START)
+ , mStagingPlayState(NOT_STARTED)
+ , mPlayState(NOT_STARTED)
+ , mHasStartValue(false)
, mStartTime(0)
- , mDelayUntil(0)
, mDuration(300)
, mStartDelay(0) {
-
}
BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
- setInterpolator(NULL);
+ delete mInterpolator;
+}
+
+void BaseRenderNodeAnimator::checkMutable() {
+ // Should be impossible to hit as the Java-side also has guards for this
+ LOG_ALWAYS_FATAL_IF(mStagingPlayState != NOT_STARTED,
+ "Animator has already been started!");
}
void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
+ checkMutable();
delete mInterpolator;
mInterpolator = interpolator;
}
void BaseRenderNodeAnimator::setStartValue(float value) {
- LOG_ALWAYS_FATAL_IF(mPlayState != NEEDS_START,
- "Cannot set the start value after the animator has started!");
- mFromValue = value;
- mDeltaValue = (mFinalValue - mFromValue);
- mPlayState = PENDING;
+ checkMutable();
+ doSetStartValue(value);
}
-void BaseRenderNodeAnimator::setupStartValueIfNecessary(RenderNode* target, TreeInfo& info) {
- if (mPlayState == NEEDS_START) {
- setStartValue(getValue(target));
- }
+void BaseRenderNodeAnimator::doSetStartValue(float value) {
+ mFromValue = value;
+ mDeltaValue = (mFinalValue - mFromValue);
+ mHasStartValue = true;
}
void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
+ checkMutable();
mDuration = duration;
}
void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
+ checkMutable();
mStartDelay = startDelay;
}
-bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
- if (mPlayState == PENDING && mStartDelay > 0 && mDelayUntil == 0) {
- mDelayUntil = info.frameTimeMs + mStartDelay;
- return false;
+void BaseRenderNodeAnimator::pushStaging(RenderNode* target, TreeInfo& info) {
+ if (!mHasStartValue) {
+ doSetStartValue(getValue(target));
}
-
- if (mDelayUntil > info.frameTimeMs) {
- return false;
- }
-
- if (mPlayState == PENDING) {
- mPlayState = RUNNING;
- mStartTime = info.frameTimeMs;
- // No interpolator was set, use the default
- if (!mInterpolator) {
- setInterpolator(Interpolator::createDefaultInterpolator());
+ if (mStagingPlayState > mPlayState) {
+ mPlayState = mStagingPlayState;
+ // Oh boy, we're starting! Man the battle stations!
+ if (mPlayState == RUNNING) {
+ transitionToRunning(info);
}
}
+}
+
+void BaseRenderNodeAnimator::transitionToRunning(TreeInfo& info) {
+ LOG_ALWAYS_FATAL_IF(info.frameTimeMs <= 0, "%" PRId64 " isn't a real frame time!", info.frameTimeMs);
+ if (mStartDelay < 0 || mStartDelay > 50000) {
+ ALOGW("Your start delay is strange and confusing: %" PRId64, mStartDelay);
+ }
+ mStartTime = info.frameTimeMs + mStartDelay;
+ if (mStartTime < 0) {
+ ALOGW("Ended up with a really weird start time of %" PRId64
+ " with frame time %" PRId64 " and start delay %" PRId64,
+ mStartTime, info.frameTimeMs, mStartDelay);
+ // Set to 0 so that the animate() basically instantly finishes
+ mStartTime = 0;
+ }
+ // No interpolator was set, use the default
+ if (!mInterpolator) {
+ setInterpolator(Interpolator::createDefaultInterpolator());
+ }
+ if (mDuration < 0 || mDuration > 50000) {
+ ALOGW("Your duration is strange and confusing: %" PRId64, mDuration);
+ }
+}
+
+bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
+ if (mPlayState < RUNNING) {
+ return false;
+ }
+
+ if (mStartTime > info.frameTimeMs) {
+ info.out.hasAnimations |= true;
+ return false;
+ }
float fraction = 1.0f;
- if (mPlayState == RUNNING) {
- fraction = mDuration > 0 ? (float)(info.frameTimeMs - mStartTime) / mDuration : 1.0f;
- if (fraction >= 1.0f) {
- fraction = 1.0f;
- mPlayState = FINISHED;
- }
+ if (mPlayState == RUNNING && mDuration > 0) {
+ fraction = (float)(info.frameTimeMs - mStartTime) / mDuration;
}
+ if (fraction >= 1.0f) {
+ fraction = 1.0f;
+ mPlayState = FINISHED;
+ }
+
fraction = mInterpolator->interpolate(fraction);
setValue(target, mFromValue + (mDeltaValue * fraction));
@@ -108,6 +142,8 @@
callOnFinishedListener(info);
return true;
}
+
+ info.out.hasAnimations |= true;
return false;
}
@@ -153,7 +189,7 @@
}
void RenderPropertyAnimator::onAttached(RenderNode* target) {
- if (mPlayState == NEEDS_START
+ if (!mHasStartValue
&& target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
setStartValue((target->stagingProperties().*mPropertyAccess->getter)());
}
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 6cb72c4c..a981b5a 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -50,12 +50,11 @@
ANDROID_API void setListener(AnimationListener* listener) {
mListener = listener;
}
+ ANDROID_API void start() { mStagingPlayState = RUNNING; }
+ ANDROID_API void cancel() { mStagingPlayState = FINISHED; }
- ANDROID_API virtual void onAttached(RenderNode* target) {}
-
- // Guaranteed to happen before the staging push
- void setupStartValueIfNecessary(RenderNode* target, TreeInfo& info);
-
+ virtual void onAttached(RenderNode* target) {}
+ virtual void pushStaging(RenderNode* target, TreeInfo& info);
bool animate(RenderNode* target, TreeInfo& info);
bool isFinished() { return mPlayState == FINISHED; }
@@ -73,8 +72,7 @@
void callOnFinishedListener(TreeInfo& info);
enum PlayState {
- NEEDS_START,
- PENDING,
+ NOT_STARTED,
RUNNING,
FINISHED,
};
@@ -84,13 +82,19 @@
float mFromValue;
Interpolator* mInterpolator;
+ PlayState mStagingPlayState;
PlayState mPlayState;
+ bool mHasStartValue;
nsecs_t mStartTime;
- nsecs_t mDelayUntil;
nsecs_t mDuration;
nsecs_t mStartDelay;
sp<AnimationListener> mListener;
+
+private:
+ void doSetStartValue(float value);
+ inline void checkMutable();
+ void transitionToRunning(TreeInfo& info);
};
class RenderPropertyAnimator : public BaseRenderNodeAnimator {
@@ -112,7 +116,7 @@
ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue);
- ANDROID_API virtual void onAttached(RenderNode* target);
+ virtual void onAttached(RenderNode* target);
ANDROID_API virtual uint32_t dirtyMask();
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
new file mode 100644
index 0000000..6a10cf8
--- /dev/null
+++ b/libs/hwui/AnimatorManager.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "AnimatorManager.h"
+
+#include <algorithm>
+
+#include "RenderNode.h"
+
+namespace android {
+namespace uirenderer {
+
+using namespace std;
+
+static void unref(BaseRenderNodeAnimator* animator) {
+ animator->decStrong(0);
+}
+
+AnimatorManager::AnimatorManager(RenderNode& parent)
+ : mParent(parent) {
+}
+
+AnimatorManager::~AnimatorManager() {
+ for_each(mNewAnimators.begin(), mNewAnimators.end(), unref);
+ for_each(mAnimators.begin(), mAnimators.end(), unref);
+}
+
+void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+ animator->incStrong(0);
+ animator->onAttached(&mParent);
+ mNewAnimators.push_back(animator.get());
+}
+
+template<typename T>
+static void move_all(T& source, T& dest) {
+ dest.reserve(source.size() + dest.size());
+ for (typename T::iterator it = source.begin(); it != source.end(); it++) {
+ dest.push_back(*it);
+ }
+ source.clear();
+}
+
+void AnimatorManager::pushStaging(TreeInfo& info) {
+ if (mNewAnimators.size()) {
+ // Since this is a straight move, we don't need to inc/dec the ref count
+ move_all(mNewAnimators, mAnimators);
+ }
+ for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) {
+ (*it)->pushStaging(&mParent, info);
+ }
+}
+
+class AnimateFunctor {
+public:
+ AnimateFunctor(RenderNode& target, TreeInfo& info)
+ : mTarget(target), mInfo(info) {}
+
+ bool operator() (BaseRenderNodeAnimator* animator) {
+ bool remove = animator->animate(&mTarget, mInfo);
+ if (remove) {
+ animator->decStrong(0);
+ }
+ return remove;
+ }
+private:
+ RenderNode& mTarget;
+ TreeInfo& mInfo;
+};
+
+void AnimatorManager::animate(TreeInfo& info) {
+ if (!mAnimators.size()) return;
+
+ // TODO: Can we target this better? For now treat it like any other staging
+ // property push and just damage self before and after animators are run
+
+ mParent.damageSelf(info);
+ info.damageAccumulator->popTransform();
+
+ AnimateFunctor functor(mParent, info);
+ std::vector< BaseRenderNodeAnimator* >::iterator newEnd;
+ newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
+ mAnimators.erase(newEnd, mAnimators.end());
+
+ mParent.mProperties.updateMatrix();
+ info.damageAccumulator->pushTransform(&mParent);
+ mParent.damageSelf(info);
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h
new file mode 100644
index 0000000..2568121
--- /dev/null
+++ b/libs/hwui/AnimatorManager.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANIMATORMANAGER_H
+#define ANIMATORMANAGER_H
+
+#include <vector>
+
+#include <cutils/compiler.h>
+#include <utils/StrongPointer.h>
+
+#include "TreeInfo.h"
+#include "utils/Macros.h"
+
+namespace android {
+namespace uirenderer {
+
+class BaseRenderNodeAnimator;
+class RenderNode;
+
+// Responsible for managing the animators for a single RenderNode
+class AnimatorManager {
+ PREVENT_COPY_AND_ASSIGN(AnimatorManager);
+public:
+ AnimatorManager(RenderNode& parent);
+ ~AnimatorManager();
+
+ void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
+
+ void pushStaging(TreeInfo& info);
+ void animate(TreeInfo& info);
+
+private:
+ RenderNode& mParent;
+
+ // To improve the efficiency of resizing & removing from the vector
+ // use manual ref counting instead of sp<>.
+ std::vector<BaseRenderNodeAnimator*> mNewAnimators;
+ std::vector<BaseRenderNodeAnimator*> mAnimators;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* ANIMATORMANAGER_H */
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 8e99b9a..02b0372 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -58,7 +58,7 @@
SkRefCnt_SafeAssign(mColorFilter, colorFilter);
}
-bool DeferredLayerUpdater::apply(TreeInfo& info) {
+bool DeferredLayerUpdater::apply() {
bool success = true;
// These properties are applied the same to both layer types
mLayer->setColorFilter(mColorFilter);
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index c76bd5e..5905b95 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -75,7 +75,7 @@
ANDROID_API void setPaint(const SkPaint* paint);
- ANDROID_API bool apply(TreeInfo& info);
+ ANDROID_API bool apply();
ANDROID_API Layer* backingLayer() {
return mLayer;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 5ed04a0..9fb972b 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -253,7 +253,7 @@
// default empty constructor for bounds, to be overridden in child constructor body
DrawBoundedOp(const SkPaint* paint): DrawOp(paint) { }
- bool getLocalBounds(Rect& localBounds) {
+ virtual bool getLocalBounds(Rect& localBounds) {
localBounds.set(mLocalBounds);
OpenGLRenderer::TextShadow textShadow;
if (OpenGLRenderer::getTextShadow(mPaint, &textShadow)) {
@@ -1029,7 +1029,7 @@
DrawStrokableOp(float left, float top, float right, float bottom, const SkPaint* paint)
: DrawBoundedOp(left, top, right, bottom, paint) {};
- bool getLocalBounds(Rect& localBounds) {
+ virtual bool getLocalBounds(Rect& localBounds) {
localBounds.set(mLocalBounds);
if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
localBounds.outset(strokeWidthOutset());
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 4ff5780..8a1aebc 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -184,12 +184,6 @@
virtual status_t drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, const SkPaint* paint);
virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
- virtual status_t drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
- CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
- // TODO: Remove once android_view_GLES20Canvas uses DisplayListRenderer
- // directly
- return drawCircle(x->value, y->value, radius->value, &paint->value);
- }
virtual status_t drawOval(float left, float top, float right, float bottom,
const SkPaint* paint);
virtual status_t drawArc(float left, float top, float right, float bottom,
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 131384a..e803ec3 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -62,7 +62,7 @@
, mNeedsDisplayListDataSync(false)
, mDisplayListData(0)
, mStagingDisplayListData(0)
- , mNeedsAnimatorsSync(false)
+ , mAnimatorManager(*this)
, mLayer(0) {
}
@@ -117,6 +117,10 @@
prepareTreeImpl(info);
}
+void RenderNode::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+ mAnimatorManager.addAnimator(animator);
+}
+
void RenderNode::damageSelf(TreeInfo& info) {
if (isRenderable()) {
if (properties().getClipDamageToBounds()) {
@@ -193,11 +197,11 @@
info.damageAccumulator->pushTransform(this);
if (info.mode == TreeInfo::MODE_FULL) {
pushStagingPropertiesChanges(info);
- evaluateAnimations(info);
+ mAnimatorManager.animate(info);
} else if (info.mode == TreeInfo::MODE_MAYBE_DETACHING) {
pushStagingPropertiesChanges(info);
} else if (info.mode == TreeInfo::MODE_RT_ONLY) {
- evaluateAnimations(info);
+ mAnimatorManager.animate(info);
}
prepareLayer(info);
@@ -210,33 +214,11 @@
info.damageAccumulator->popTransform();
}
-class PushAnimatorsFunctor {
-public:
- PushAnimatorsFunctor(RenderNode* target, TreeInfo& info)
- : mTarget(target), mInfo(info) {}
-
- bool operator() (const sp<BaseRenderNodeAnimator>& animator) {
- animator->setupStartValueIfNecessary(mTarget, mInfo);
- return animator->isFinished();
- }
-private:
- RenderNode* mTarget;
- TreeInfo& mInfo;
-};
-
void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
// Push the animators first so that setupStartValueIfNecessary() is called
// before properties() is trampled by stagingProperties(), as they are
// required by some animators.
- if (mNeedsAnimatorsSync) {
- mAnimators.resize(mStagingAnimators.size());
- std::vector< sp<BaseRenderNodeAnimator> >::iterator it;
- PushAnimatorsFunctor functor(this, info);
- // hint: this means copy_if_not()
- it = std::remove_copy_if(mStagingAnimators.begin(), mStagingAnimators.end(),
- mAnimators.begin(), functor);
- mAnimators.resize(std::distance(mAnimators.begin(), it));
- }
+ mAnimatorManager.pushStaging(info);
if (mDirtyPropertyFields) {
mDirtyPropertyFields = 0;
damageSelf(info);
@@ -267,8 +249,7 @@
mNeedsDisplayListDataSync = false;
// Do a push pass on the old tree to handle freeing DisplayListData
// that are no longer used
- TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info.renderState);
- oldTreeInfo.damageAccumulator = info.damageAccumulator;
+ TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info);
prepareSubTree(oldTreeInfo, mDisplayListData);
delete mDisplayListData;
mDisplayListData = mStagingDisplayListData;
@@ -277,39 +258,6 @@
}
}
-class AnimateFunctor {
-public:
- AnimateFunctor(RenderNode* target, TreeInfo& info)
- : mTarget(target), mInfo(info) {}
-
- bool operator() (const sp<BaseRenderNodeAnimator>& animator) {
- return animator->animate(mTarget, mInfo);
- }
-private:
- RenderNode* mTarget;
- TreeInfo& mInfo;
-};
-
-void RenderNode::evaluateAnimations(TreeInfo& info) {
- if (!mAnimators.size()) return;
-
- // TODO: Can we target this better? For now treat it like any other staging
- // property push and just damage self before and after animators are run
-
- damageSelf(info);
- info.damageAccumulator->popTransform();
-
- AnimateFunctor functor(this, info);
- std::vector< sp<BaseRenderNodeAnimator> >::iterator newEnd;
- newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
- mAnimators.erase(newEnd, mAnimators.end());
- mProperties.updateMatrix();
- info.out.hasAnimations |= mAnimators.size();
-
- info.damageAccumulator->pushTransform(this);
- damageSelf(info);
-}
-
void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
if (subtree) {
TextureCache& cache = Caches::getInstance().textureCache;
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 3980dad..7d42b59 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -20,18 +20,11 @@
#define LOG_TAG "OpenGLRenderer"
#endif
-#include <set>
-#include <vector>
-
#include <SkCamera.h>
#include <SkMatrix.h>
-#include <private/hwui/DrawGlInfo.h>
-
-#include <utils/KeyedVector.h>
#include <utils/LinearAllocator.h>
#include <utils/RefBase.h>
-#include <utils/SortedVector.h>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -39,6 +32,7 @@
#include <androidfw/ResourceTypes.h>
+#include "AnimatorManager.h"
#include "DamageAccumulator.h"
#include "Debug.h"
#include "Matrix.h"
@@ -176,19 +170,7 @@
ANDROID_API virtual void prepareTree(TreeInfo& info);
// UI thread only!
- ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
- animator->onAttached(this);
- mStagingAnimators.insert(animator);
- mNeedsAnimatorsSync = true;
- }
-
- // UI thread only!
- ANDROID_API void removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
- mStagingAnimators.erase(animator);
- // Force a sync of the staging property value
- mDirtyPropertyFields |= animator->dirtyMask();
- mNeedsAnimatorsSync = true;
- }
+ ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
protected:
virtual void damageSelf(TreeInfo& info);
@@ -262,7 +244,6 @@
void prepareTreeImpl(TreeInfo& info);
void pushStagingPropertiesChanges(TreeInfo& info);
void pushStagingDisplayListChanges(TreeInfo& info);
- void evaluateAnimations(TreeInfo& info);
void prepareSubTree(TreeInfo& info, DisplayListData* subtree);
void applyLayerPropertiesToLayer(TreeInfo& info);
void prepareLayer(TreeInfo& info);
@@ -278,9 +259,8 @@
DisplayListData* mDisplayListData;
DisplayListData* mStagingDisplayListData;
- bool mNeedsAnimatorsSync;
- std::set< sp<BaseRenderNodeAnimator> > mStagingAnimators;
- std::vector< sp<BaseRenderNodeAnimator> > mAnimators;
+ friend class AnimatorManager;
+ AnimatorManager mAnimatorManager;
// Owned by RT. Lifecycle is managed by prepareTree(), with the exception
// being in ~RenderNode() which may happen on any thread.
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index 249e525..083100e 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -79,6 +79,17 @@
, errorHandler(NULL)
{}
+ explicit TreeInfo(TraversalMode mode, const TreeInfo& clone)
+ : mode(mode)
+ , frameTimeMs(clone.frameTimeMs)
+ , animationHook(clone.animationHook)
+ , prepareTextures(mode == MODE_FULL)
+ , damageAccumulator(clone.damageAccumulator)
+ , renderState(clone.renderState)
+ , renderer(clone.renderer)
+ , errorHandler(clone.errorHandler)
+ {}
+
const TraversalMode mode;
nsecs_t frameTimeMs;
AnimationHook* animationHook;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 281a8e1..9c3cf44 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -123,8 +123,8 @@
mHaveNewSurface |= mEglManager.makeCurrent(mEglSurface);
}
-void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info) {
- bool success = layerUpdater->apply(info);
+void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) {
+ bool success = layerUpdater->apply();
LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!");
if (layerUpdater->backingLayer()->deferredUpdateScheduled) {
mCanvas->pushLayerUpdate(layerUpdater->backingLayer());
@@ -237,8 +237,7 @@
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
requireGlContext();
- TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState());
- layer->apply(info);
+ layer->apply();
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index d2ce1a6..dbfb3d2 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -56,7 +56,7 @@
void setup(int width, int height, const Vector3& lightCenter, float lightRadius);
void setOpaque(bool opaque);
void makeCurrent();
- void processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info);
+ void processLayerUpdate(DeferredLayerUpdater* layerUpdater);
void prepareTree(TreeInfo& info);
void draw();
void destroyCanvasAndSurface();
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index fddffd5..dd34e09 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -127,7 +127,7 @@
Caches::getInstance().textureCache.resetMarkInUse();
for (size_t i = 0; i < mLayers.size(); i++) {
- mContext->processLayerUpdate(mLayers[i].get(), info);
+ mContext->processLayerUpdate(mLayers[i].get());
}
mLayers.clear();
mContext->prepareTree(info);
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 8dd2721..d882bc8 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -444,8 +444,7 @@
// Devices for which the volume is fixed and VolumePanel slider should be disabled
final int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_HDMI |
AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET |
- AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET |
- AudioSystem.DEVICE_OUT_ALL_USB;
+ AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET;
// TODO merge orientation and rotation
private final boolean mMonitorOrientation;
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 2831d9e..a913e59c 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -33,6 +33,7 @@
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
+import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
@@ -339,6 +340,11 @@
public void setVisibility(int visibility) {
super.setVisibility(visibility);
mSurfaceView.setVisibility(visibility);
+ if (visibility == View.VISIBLE) {
+ createSessionOverlayView();
+ } else {
+ removeSessionOverlayView();
+ }
}
private void release() {
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index 8c9030d..e8944ec 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -20,14 +20,14 @@
<string name="title_open" msgid="4353228937663917801">"បើកពី"</string>
<string name="title_save" msgid="2433679664882857999">"រក្សាទុកទៅ"</string>
<string name="menu_create_dir" msgid="5947289605844398389">"បង្កើតថត"</string>
- <string name="menu_grid" msgid="6878021334497835259">"ទិដ្ឋភាពក្រឡា"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"ទិដ្ឋភាពក្រឡា"</string>
<string name="menu_list" msgid="7279285939892417279">"ទិដ្ឋភាពបញ្ជី"</string>
<string name="menu_sort" msgid="7677740407158414452">"តម្រៀបតាម"</string>
<string name="menu_search" msgid="3816712084502856974">"ស្វែងរក"</string>
<string name="menu_settings" msgid="6008033148948428823">"ការកំណត់"</string>
<string name="menu_open" msgid="432922957274920903">"បើក"</string>
<string name="menu_save" msgid="2394743337684426338">"រក្សាទុក"</string>
- <string name="menu_share" msgid="3075149983979628146">"ចែករំលែក"</string>
+ <string name="menu_share" msgid="3075149983979628146">"ចែករំលែក"</string>
<string name="menu_delete" msgid="8138799623850614177">"លុប"</string>
<string name="menu_select" msgid="8711270657353563424">"ជ្រើស \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
<string name="mode_selected_count" msgid="459111894725594625">"បានជ្រើស <xliff:g id="COUNT">%1$d</xliff:g>"</string>
@@ -48,7 +48,7 @@
<string name="pref_advanced_devices" msgid="903257239609301276">"បង្ហាញឧបករណ៍កម្រិតខ្ពស់"</string>
<string name="pref_file_size" msgid="2826879315743961459">"បង្ហាញទំហំឯកសារ"</string>
<string name="pref_device_size" msgid="3542106883278997222">"បង្ហាញទំហំឧបករណ៍"</string>
- <string name="empty" msgid="7858882803708117596">"គ្មានធាតុ"</string>
+ <string name="empty" msgid="7858882803708117596">"គ្មានធាតុ"</string>
<string name="toast_no_application" msgid="1339885974067891667">"មិនអាចបើកឯកសារ"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"មិនអាចលុបឯកសារមួយចំនួន"</string>
<string name="share_via" msgid="8966594246261344259">"ចែករំលែកតាម"</string>
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
index c26b1b4..ecdad8c 100644
--- a/packages/Keyguard/res/values-km-rKH/strings.xml
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -83,7 +83,7 @@
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"បោះបង់"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"លុប"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"រួចរាល់"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ប្ដូររបៀប"</string>
@@ -120,7 +120,7 @@
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បីដោះសោ ចូលក្នុងគណនី Google ។"</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីម៉ែល)"</string>
- <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ភ្លេចឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់របស់អ្នក?\nមើល "<b>"google.com/accounts/recovery"</b>" ។"</string>
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
index cdcb21f..0146ab75 100644
--- a/packages/PrintSpooler/res/values-km-rKH/strings.xml
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -60,7 +60,7 @@
</plurals>
<string name="cancel" msgid="4373674107267141885">"បោះបង់"</string>
<string name="restart" msgid="2472034227037808749">"ចាប់ផ្ដើមឡើងវិញ"</string>
- <string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មានការភ្ជាប់ទៅម៉ាស៊ីនបោះពុម្ព"</string>
+ <string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មានការភ្ជាប់ទៅម៉ាស៊ីនបោះពុម្ព"</string>
<string name="reason_unknown" msgid="5507940196503246139">"មិនស្គាល់"</string>
<string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – មិនអាចប្រើបាន"</string>
<string-array name="color_mode_labels">
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0df6c74..e12549a 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -267,6 +267,7 @@
android:name=".DessertCaseDream"
android:exported="true"
android:label="@string/dessert_case"
+ android:permission="android.permission.BIND_DREAM_SERVICE"
android:enabled="false"
android:process=":sweetsweetdesserts"
>
@@ -305,6 +306,7 @@
<!-- I dream of notifications -->
<service
android:name=".doze.DozeService"
- android:exported="true" />
+ android:exported="true"
+ android:permission="android.permission.BIND_DREAM_SERVICE" />
</application>
</manifest>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4e38da6..19d72c4 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -38,8 +38,8 @@
<color name="system_secondary_color">#ff384248</color>
<color name="system_accent_color">#ff7fcac3</color>
<color name="system_error_color">#fff0592b</color>
- <color name="qs_tile_divider">#29ffffff</color><!-- 16% white -->
- <color name="qs_tile_text">#FFFFFFFF</color>
+ <color name="qs_tile_divider">#29ffffff</color><!-- 16% white -->
+ <color name="qs_tile_text">#B3FFFFFF</color><!-- 70% white -->
<color name="status_bar_clock_color">#FFFFFFFF</color>
<!-- Tint color for the content on the notification overflow card. -->
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 41b1f75..186b570 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -81,6 +81,8 @@
private long mScreenOffTime;
private int mShowing;
+ private long mBucketDroppedNegativeTimeMs;
+
private boolean mSaver;
private int mSaverTriggerLevel;
private boolean mWarning;
@@ -108,6 +110,11 @@
@Override
public void update(int batteryLevel, int bucket, long screenOffTime) {
mBatteryLevel = batteryLevel;
+ if (bucket >= 0) {
+ mBucketDroppedNegativeTimeMs = 0;
+ } else if (bucket < mBucket) {
+ mBucketDroppedNegativeTimeMs = System.currentTimeMillis();
+ }
mBucket = bucket;
mScreenOffTime = screenOffTime;
mFallbackDialogs.update(batteryLevel, bucket, screenOffTime);
@@ -146,6 +153,7 @@
private void showInvalidChargerNotification() {
final Notification.Builder nb = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.ic_power_low)
+ .setWhen(0)
.setShowWhen(false)
.setOngoing(true)
.setContentTitle(mContext.getString(R.string.invalid_charger_title))
@@ -166,6 +174,8 @@
: R.string.battery_low_percent_format;
final Notification.Builder nb = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.ic_power_low)
+ // Bump the notification when the bucket dropped.
+ .setWhen(mBucketDroppedNegativeTimeMs)
.setShowWhen(false)
.setContentTitle(mContext.getString(R.string.battery_low_title))
.setContentText(mContext.getString(textRes, mBatteryLevel))
@@ -198,6 +208,7 @@
.setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
.setContentText(mContext.getString(R.string.battery_saver_notification_text))
.setOngoing(true)
+ .setWhen(0)
.setShowWhen(false)
.setCategory(Notification.CATEGORY_SYSTEM)
.setVisibility(Notification.VISIBILITY_PUBLIC);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 8dcdcdb..52ccb59 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -510,7 +510,7 @@
} else {
// If there is no thumbnail transition, but is launching from home into recents, then
// use a quick home transition and do the animation from home
- if (hasRecentTasks && Constants.DebugFlags.App.EnableHomeTransition) {
+ if (hasRecentTasks) {
ActivityOptions opts = getHomeTransitionActivityOptions();
startAlternateRecentsActivity(opts, EXTRA_FROM_HOME);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 8995437..4fb1918 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -25,8 +25,6 @@
public static final boolean Verbose = false;
public static class App {
- // Enables the home->Recents transition
- public static final boolean EnableHomeTransition = true;
// Enables the screenshot app->Recents transition
public static final boolean EnableScreenshotAppTransition = false;
// Enables the filtering of tasks according to their grouping
@@ -96,10 +94,6 @@
public static String Key_DebugModeEnabled = "debugModeEnabled";
public static String DebugModeVersion = "A";
}
- public static class Window {
- // The dark background dim is set behind the empty recents view
- public static final float DarkBackgroundDim = 0.5f;
- }
public static class RecentsTaskLoader {
// XXX: This should be calculated on the first load
@@ -109,15 +103,6 @@
public static class TaskStackView {
public static final int TaskStackOverscrollRange = 150;
public static final int FilterStartDelay = 25;
-
- // The overlap height relative to the task height
- public static final float StackOverlapPct = 0.65f;
- // The height of the peek space relative to the stack height
- public static final float StackPeekHeightPct = 0.1f;
- // The min scale of the last card in the peek area
- public static final float StackPeekMinScale = 0.8f;
- // The number of cards we see in the peek space
- public static final int StackPeekNumCards = 3;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index ecdc9dd..4b4cf01 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -85,6 +85,10 @@
mUseCustomFinishTransition = withTransition;
}
+ /**
+ * Creates a finish runnable that starts the specified intent, using the given
+ * ActivityOptions.
+ */
public FinishRecentsRunnable(Intent launchIntent, ActivityOptions opts) {
mLaunchIntent = launchIntent;
mLaunchOpts = opts;
@@ -618,6 +622,11 @@
AlternateRecentsComponent.notifyVisibilityChanged(false);
}
+ @Override
+ public void onLastTaskRemoved() {
+ mFinishLaunchHomeRunnable.run();
+ }
+
/**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index e40d732..b6895d1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -30,6 +30,7 @@
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.TaskStackView;
+import com.android.systemui.recents.views.TaskStackViewLayoutAlgorithm;
import com.android.systemui.recents.views.TaskViewTransform;
import java.lang.ref.WeakReference;
@@ -70,6 +71,7 @@
// Create a dummy task stack & compute the rect for the thumbnail to animate to
TaskStack stack = new TaskStack(context);
TaskStackView tsv = new TaskStackView(context, stack);
+ TaskStackViewLayoutAlgorithm algo = tsv.getStackAlgorithm();
Bundle replyData = new Bundle();
TaskViewTransform transform;
@@ -85,7 +87,7 @@
tsv.computeRects(taskStackBounds.width(), taskStackBounds.height() -
systemInsets.top - systemInsets.bottom, 0, 0);
tsv.setStackScrollToInitialState();
- transform = tsv.getStackTransform(0, tsv.getStackScroll());
+ transform = algo.getStackTransform(0, tsv.getStackScroll());
transform.rect.offset(taskStackBounds.left, taskStackBounds.top);
replyData.putParcelable(AlternateRecentsComponent.KEY_SINGLE_TASK_STACK_RECT,
new Rect(transform.rect));
@@ -95,7 +97,7 @@
tsv.computeRects(taskStackBounds.width(), taskStackBounds.height() -
systemInsets.top - systemInsets.bottom, 0, 0);
tsv.setStackScrollToInitialState();
- transform = tsv.getStackTransform(1, tsv.getStackScroll());
+ transform = algo.getStackTransform(1, tsv.getStackScroll());
transform.rect.offset(taskStackBounds.left, taskStackBounds.top);
replyData.putParcelable(AlternateRecentsComponent.KEY_TWO_TASK_STACK_RECT,
new Rect(transform.rect));
@@ -105,7 +107,7 @@
tsv.computeRects(taskStackBounds.width(), taskStackBounds.height() -
systemInsets.top - systemInsets.bottom, 0, 0);
tsv.setStackScrollToInitialState();
- transform = tsv.getStackTransform(2, tsv.getStackScroll());
+ transform = algo.getStackTransform(2, tsv.getStackScroll());
transform.rect.offset(taskStackBounds.left, taskStackBounds.top);
replyData.putParcelable(AlternateRecentsComponent.KEY_MULTIPLE_TASK_STACK_RECT,
new Rect(transform.rect));
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
index 2c632cfe..6568b1a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -172,10 +173,12 @@
}
// Calculate the bottom clip
- float scale = (float) ctx.taskRect.width() / getMeasuredWidth();
- int translationY = -mConfig.systemInsets.top + ctx.stackRectSansPeek.top +
- ctx.transform.translationY;
- int clipBottom = mConfig.systemInsets.top + (int) (ctx.taskRect.height() / scale);
+ Rect taskRect = ctx.taskRect;
+ float scale = (float) taskRect.width() / getMeasuredWidth();
+ float scaleYOffset = ((1f - scale) * getMeasuredHeight()) / 2;
+ float scaledTopInset = (int) (scale * mConfig.systemInsets.top);
+ int translationY = (int) -scaleYOffset + (int) (mConfig.systemInsets.top - scaledTopInset) + taskRect.top;
+ int clipBottom = mConfig.systemInsets.top + (int) (taskRect.height() / scale);
// Enable the HW Layers on the screenshot view
mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 3856311..e7eac67 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -56,6 +56,7 @@
/** The RecentsView callbacks */
public interface RecentsViewCallbacks {
public void onTaskLaunching();
+ public void onLastTaskRemoved();
public void onExitToHomeAnimationTriggered();
}
@@ -201,14 +202,12 @@
// animations are started.
ctx.postAnimationTrigger.increment();
- if (Constants.DebugFlags.App.EnableHomeTransition) {
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- if (child instanceof TaskStackView) {
- TaskStackView stackView = (TaskStackView) child;
- stackView.startExitToHomeAnimation(ctx);
- }
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ if (child instanceof TaskStackView) {
+ TaskStackView stackView = (TaskStackView) child;
+ stackView.startExitToHomeAnimation(ctx);
}
}
@@ -426,11 +425,13 @@
// and then offset to the expected transform rect, but bound this to just
// outside the display rect (to ensure we don't animate from too far away)
sourceView = stackView;
- transform = stackView.getStackTransform(stack.indexOfTask(task), stackScroll);
+ transform = stackView.getStackAlgorithm().getStackTransform(stack.indexOfTask(task),
+ stackScroll);
offsetX = transform.rect.left;
offsetY = Math.min(transform.rect.top, mConfig.displayRect.height());
} else {
- transform = stackView.getStackTransform(stack.indexOfTask(task), stackScroll);
+ transform = stackView.getStackAlgorithm().getStackTransform(stack.indexOfTask(task),
+ stackScroll);
}
// Compute the thumbnail to scale up from
@@ -533,6 +534,11 @@
}
@Override
+ public void onLastTaskRemoved() {
+ mCb.onLastTaskRemoved();
+ }
+
+ @Override
public void onTaskStackFilterTriggered() {
// Hide the search bar
if (mSearchBar != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 452665a..29eaa9e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -20,7 +20,6 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
-import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Canvas;
@@ -44,7 +43,6 @@
import com.android.systemui.recents.model.TaskStack;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Set;
@@ -58,6 +56,7 @@
public void onTaskLaunched(TaskStackView stackView, TaskView tv, TaskStack stack, Task t);
public void onTaskAppInfoLaunched(Task t);
public void onTaskRemoved(Task t);
+ public void onLastTaskRemoved();
public void onTaskStackFilterTriggered();
public void onTaskStackUnfilterTriggered();
}
@@ -65,18 +64,14 @@
RecentsConfiguration mConfig;
TaskStack mStack;
+ TaskStackViewLayoutAlgorithm mStackAlgorithm;
+ TaskStackViewFilterAlgorithm mFilterAlgorithm;
TaskStackViewTouchHandler mTouchHandler;
TaskStackViewCallbacks mCb;
ViewPool<TaskView, Task> mViewPool;
ArrayList<TaskViewTransform> mTaskTransforms = new ArrayList<TaskViewTransform>();
DozeTrigger mUIDozeTrigger;
- // The various rects that define the stack view
- Rect mRect = new Rect();
- Rect mStackRect = new Rect();
- Rect mStackRectSansPeek = new Rect();
- Rect mTaskRect = new Rect();
-
// The virtual stack scroll that we use for the card layout
int mStackScroll;
int mMinScroll;
@@ -117,6 +112,8 @@
mTouchHandler = new TaskStackViewTouchHandler(context, this);
mViewPool = new ViewPool<TaskView, Task>(context, this);
mInflater = LayoutInflater.from(context);
+ mStackAlgorithm = new TaskStackViewLayoutAlgorithm(mConfig);
+ mFilterAlgorithm = new TaskStackViewFilterAlgorithm(mConfig, this, mViewPool);
mUIDozeTrigger = new DozeTrigger(mConfig.taskBarDismissDozeDelaySeconds, new Runnable() {
@Override
public void run() {
@@ -172,7 +169,7 @@
"[TaskStackView|requestSynchronize]", "" + duration + "ms", Console.AnsiYellow);
}
if (!mStackViewsDirty) {
- invalidate(mStackRect);
+ invalidate(mStackAlgorithm.mStackRect);
}
if (mAwaitingFirstLayout) {
// Skip the animation if we are awaiting first layout
@@ -184,7 +181,7 @@
}
/** Finds the child view given a specific task */
- private TaskView getChildViewForTask(Task t) {
+ TaskView getChildViewForTask(Task t) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView tv = (TaskView) getChildAt(i);
@@ -195,65 +192,9 @@
return null;
}
- /** Update/get the transform (creates a new TaskViewTransform) */
- public TaskViewTransform getStackTransform(int indexInStack, int stackScroll) {
- TaskViewTransform transform = new TaskViewTransform();
- return getStackTransform(indexInStack, stackScroll, transform);
- }
-
- /** Update/get the transform */
- public TaskViewTransform getStackTransform(int indexInStack, int stackScroll,
- TaskViewTransform transformOut) {
- // Return early if we have an invalid index
- if (indexInStack < 0) {
- transformOut.reset();
- return transformOut;
- }
-
- // Map the items to an continuous position relative to the specified scroll
- int numPeekCards = Constants.Values.TaskStackView.StackPeekNumCards;
- float overlapHeight = Constants.Values.TaskStackView.StackOverlapPct * mTaskRect.height();
- float peekHeight = Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height();
- float t = ((indexInStack * overlapHeight) - stackScroll) / overlapHeight;
- float boundedT = Math.max(t, -(numPeekCards + 1));
-
- // Set the scale relative to its position
- int numFrontScaledCards = 3;
- float minScale = Constants.Values.TaskStackView.StackPeekMinScale;
- float scaleRange = 1f - minScale;
- float scaleInc = scaleRange / (numPeekCards + numFrontScaledCards);
- float scale = Math.max(minScale, Math.min(1f, minScale +
- ((boundedT + (numPeekCards + 1)) * scaleInc)));
- float scaleYOffset = ((1f - scale) * mTaskRect.height()) / 2;
- transformOut.scale = scale;
-
- // Set the y translation
- if (boundedT < 0f) {
- transformOut.translationY = (int) ((Math.max(-numPeekCards, boundedT) /
- numPeekCards) * peekHeight - scaleYOffset);
- } else {
- transformOut.translationY = (int) (boundedT * overlapHeight - scaleYOffset);
- }
-
- // Set the z translation
- int minZ = mConfig.taskViewTranslationZMinPx;
- int incZ = mConfig.taskViewTranslationZIncrementPx;
- transformOut.translationZ = (int) Math.max(minZ, minZ + ((boundedT + numPeekCards) * incZ));
-
- // Set the alphas
- transformOut.dismissAlpha = Math.max(-1f, Math.min(0f, t + 1)) + 1f;
-
- // Update the rect and visibility
- transformOut.rect.set(mTaskRect);
- if (t < -(numPeekCards + 1)) {
- transformOut.visible = false;
- } else {
- transformOut.rect.offset(0, transformOut.translationY);
- Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
- transformOut.visible = Rect.intersects(mRect, transformOut.rect);
- }
- transformOut.t = t;
- return transformOut;
+ /** Returns the stack algorithm for this task stack. */
+ public TaskStackViewLayoutAlgorithm getStackAlgorithm() {
+ return mStackAlgorithm;
}
/**
@@ -284,7 +225,8 @@
// Update the stack transforms
for (int i = 0; i < taskCount; i++) {
- TaskViewTransform transform = getStackTransform(i, stackScroll, taskTransforms.get(i));
+ TaskViewTransform transform = mStackAlgorithm.getStackTransform(i, stackScroll,
+ taskTransforms.get(i));
if (transform.visible) {
if (firstVisibleIndex < 0) {
firstVisibleIndex = i;
@@ -293,7 +235,8 @@
}
if (boundTranslationsToRect) {
- transform.translationY = Math.min(transform.translationY, mRect.bottom);
+ transform.translationY = Math.min(transform.translationY,
+ mStackAlgorithm.mRect.bottom);
}
}
if (visibleRangeOut != null) {
@@ -350,7 +293,7 @@
int fromIndex = (transform.t < 0) ? (visibleRange[0] - 1) :
(visibleRange[1] + 1);
tv.updateViewPropertiesToTaskTransform(
- getStackTransform(fromIndex, stackScroll), 0);
+ mStackAlgorithm.getStackTransform(fromIndex, stackScroll), 0);
}
}
} else {
@@ -398,21 +341,14 @@
}
/** Sets the current stack scroll to the initial state when you first enter recents */
public void setStackScrollToInitialState() {
- if (mStack.getTaskCount() > 2) {
- int initialScroll = mMaxScroll - mTaskRect.height() / 2;
- setStackScroll(initialScroll);
- } else {
- setStackScroll(mMaxScroll);
- }
+ setStackScroll(getInitialStackScroll());
}
-
- /**
- * Returns the scroll to such that the task transform at that index will have t=0. (If the scroll
- * is not bounded)
- */
- int getStackScrollForTaskIndex(int i) {
- int taskHeight = mTaskRect.height();
- return (int) (i * Constants.Values.TaskStackView.StackOverlapPct * taskHeight);
+ /** Computes the initial stack scroll for the stack. */
+ int getInitialStackScroll() {
+ if (mStack.getTaskCount() > 2) {
+ return mMaxScroll - mStackAlgorithm.mTaskRect.height() / 2;
+ }
+ return mMaxScroll;
}
/** Gets the current stack scroll */
@@ -526,29 +462,12 @@
return getScrollAmountOutOfBounds(getStackScroll()) != 0;
}
- /** Returns whether the task view is in the stack bounds or not */
- boolean isTaskInStackBounds(TaskView tv) {
- Rect r = new Rect();
- tv.getHitRect(r);
- return r.bottom <= mRect.bottom;
- }
-
/** Updates the min and max virtual scroll bounds */
void updateMinMaxScroll(boolean boundScrollToNewMinMax) {
// Compute the min and max scroll values
- int numTasks = Math.max(1, mStack.getTaskCount());
- int taskHeight = mTaskRect.height();
- int stackHeight = mStackRectSansPeek.height();
- int maxScrollHeight = taskHeight + (int) ((numTasks - 1) *
- Constants.Values.TaskStackView.StackOverlapPct * taskHeight);
-
- if (numTasks <= 1) {
- // If there is only one task, then center the task in the stack rect (sans peek)
- mMinScroll = mMaxScroll = -(stackHeight - taskHeight) / 2;
- } else {
- mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight;
- mMaxScroll = maxScrollHeight - stackHeight;
- }
+ mStackAlgorithm.computeMinMaxScroll(mStack.getTaskCount());
+ mMinScroll = mStackAlgorithm.mMinScroll;
+ mMaxScroll = mStackAlgorithm.mMaxScroll;
// Debug logging
if (Constants.Log.UI.MeasureAndLayout) {
@@ -612,7 +531,7 @@
if (scrollToNewPosition) {
// Scroll the view into position
int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll,
- getStackScrollForTaskIndex(taskIndex)));
+ mStackAlgorithm.getStackScrollForTaskIndex(taskIndex)));
animateScroll(getStackScroll(), newScroll, postScrollRunnable);
} else {
@@ -666,19 +585,6 @@
}
@Override
- public void computeScroll() {
- if (mScroller.computeScrollOffset()) {
- setStackScroll(mScroller.getCurrY());
- invalidate(mStackRect);
-
- // If we just finished scrolling, then disable the hw layers
- if (mScroller.isFinished()) {
- decHwLayersRefCount("finishedFlingScroll");
- }
- }
- }
-
- @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mTouchHandler.onInterceptTouchEvent(ev);
}
@@ -689,6 +595,19 @@
}
@Override
+ public void computeScroll() {
+ if (mScroller.computeScrollOffset()) {
+ setStackScroll(mScroller.getCurrY());
+ invalidate(mStackAlgorithm.mStackRect);
+
+ // If we just finished scrolling, then disable the hw layers
+ if (mScroller.isFinished()) {
+ decHwLayersRefCount("finishedFlingScroll");
+ }
+ }
+ }
+
+ @Override
public void dispatchDraw(Canvas canvas) {
if (Console.Enabled) {
Console.log(Constants.Log.UI.Draw, "[TaskStackView|dispatchDraw]", "",
@@ -741,34 +660,8 @@
/** Computes the stack and task rects */
public void computeRects(int width, int height, int insetLeft, int insetBottom) {
- // Note: We let the stack view be the full height because we want the cards to go under the
- // navigation bar if possible. However, the stack rects which we use to calculate
- // max scroll, etc. need to take the nav bar into account
-
- // Compute the stack rects
- mRect.set(0, 0, width, height);
- mStackRect.set(mRect);
- mStackRect.left += insetLeft;
- mStackRect.bottom -= insetBottom;
-
- int widthPadding = (int) (mConfig.taskStackWidthPaddingPct * mStackRect.width());
- int heightPadding = mConfig.taskStackTopPaddingPx;
- if (Constants.DebugFlags.App.EnableSearchLayout) {
- mStackRect.top += heightPadding;
- mStackRect.left += widthPadding;
- mStackRect.right -= widthPadding;
- mStackRect.bottom -= heightPadding;
- } else {
- mStackRect.inset(widthPadding, heightPadding);
- }
- mStackRectSansPeek.set(mStackRect);
- mStackRectSansPeek.top += Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height();
-
- // Compute the task rect
- int size = mStackRect.width();
- int left = mStackRect.left + (mStackRect.width() - size) / 2;
- mTaskRect.set(left, mStackRectSansPeek.top,
- left + size, mStackRectSansPeek.top + size);
+ // Compute the rects in the stack algorithm
+ mStackAlgorithm.computeRects(width, height, insetLeft, insetBottom);
// Update the scroll bounds
updateMinMaxScroll(false);
@@ -796,10 +689,10 @@
// Debug logging
if (Constants.Log.UI.MeasureAndLayout) {
- Console.log(" [TaskStack|fullRect] " + mRect);
- Console.log(" [TaskStack|stackRect] " + mStackRect);
- Console.log(" [TaskStack|stackRectSansPeek] " + mStackRectSansPeek);
- Console.log(" [TaskStack|taskRect] " + mTaskRect);
+ Console.log(" [TaskStack|fullRect] " + mStackAlgorithm.mRect);
+ Console.log(" [TaskStack|stackRect] " + mStackAlgorithm.mStackRect);
+ Console.log(" [TaskStack|stackRectSansPeek] " + mStackAlgorithm.mStackRectSansPeek);
+ Console.log(" [TaskStack|taskRect] " + mStackAlgorithm.mTaskRect);
}
// If this is the first layout, then scroll to the front of the stack and synchronize the
@@ -814,8 +707,8 @@
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView t = (TaskView) getChildAt(i);
- t.measure(MeasureSpec.makeMeasureSpec(mTaskRect.width(), MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(mTaskRect.height(), MeasureSpec.EXACTLY));
+ t.measure(MeasureSpec.makeMeasureSpec(mStackAlgorithm.mTaskRect.width(), MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(mStackAlgorithm.mTaskRect.height(), MeasureSpec.EXACTLY));
}
setMeasuredDimension(width, height);
@@ -835,18 +728,19 @@
// Debug logging
if (Constants.Log.UI.MeasureAndLayout) {
- Console.log(" [TaskStack|fullRect] " + mRect);
- Console.log(" [TaskStack|stackRect] " + mStackRect);
- Console.log(" [TaskStack|stackRectSansPeek] " + mStackRectSansPeek);
- Console.log(" [TaskStack|taskRect] " + mTaskRect);
+ Console.log(" [TaskStack|fullRect] " + mStackAlgorithm.mRect);
+ Console.log(" [TaskStack|stackRect] " + mStackAlgorithm.mStackRect);
+ Console.log(" [TaskStack|stackRectSansPeek] " + mStackAlgorithm.mStackRectSansPeek);
+ Console.log(" [TaskStack|taskRect] " + mStackAlgorithm.mTaskRect);
}
// Layout each of the children
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView t = (TaskView) getChildAt(i);
- t.layout(mTaskRect.left, mStackRectSansPeek.top,
- mTaskRect.right, mStackRectSansPeek.top + mTaskRect.height());
+ t.layout(mStackAlgorithm.mTaskRect.left, mStackAlgorithm.mStackRectSansPeek.top,
+ mStackAlgorithm.mTaskRect.right, mStackAlgorithm.mStackRectSansPeek.top +
+ mStackAlgorithm.mTaskRect.height());
}
if (mAwaitingFirstLayout) {
@@ -857,12 +751,13 @@
mUIDozeTrigger.startDozing();
// Prepare the first view for its enter animation
- int offsetTopAlign = -mTaskRect.top;
- int offscreenY = mRect.bottom - (mTaskRect.top - mRect.top);
+ int offsetTopAlign = -mStackAlgorithm.mTaskRect.top;
+ int offscreenY = mStackAlgorithm.mRect.bottom -
+ (mStackAlgorithm.mTaskRect.top - mStackAlgorithm.mRect.top);
for (int i = childCount - 1; i >= 0; i--) {
TaskView tv = (TaskView) getChildAt(i);
tv.prepareEnterRecentsAnimation((i == (getChildCount() - 1)), offsetTopAlign,
- offscreenY, mTaskRect);
+ offscreenY, mStackAlgorithm.mTaskRect);
}
// If the enter animation started already and we haven't completed a layout yet, do the
@@ -890,17 +785,18 @@
}
// Animate all the task views into view
- ctx.taskRect = mTaskRect;
- ctx.stackRectSansPeek = mStackRectSansPeek;
+ TaskViewTransform transform = mStackAlgorithm.getStackTransform(mStack.getTaskCount() - 1,
+ getInitialStackScroll());
+ ctx.taskRect = transform.rect;
+ ctx.stackRectSansPeek = mStackAlgorithm.mStackRectSansPeek;
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
TaskView tv = (TaskView) getChildAt(i);
- TaskViewTransform transform = getStackTransform(mStack.indexOfTask(tv.getTask()),
- getStackScroll());
ctx.stackViewIndex = i;
ctx.stackViewCount = childCount;
ctx.isFrontMost = (i == (getChildCount() - 1));
- ctx.transform = transform;
+ ctx.transform = mStackAlgorithm.getStackTransform(
+ mStack.indexOfTask(tv.getTask()), getStackScroll());
tv.startEnterRecentsAnimation(ctx);
}
}
@@ -908,7 +804,8 @@
/** Requests this task stacks to start it's exit-recents animation. */
public void startExitToHomeAnimation(ViewAnimation.TaskViewExitContext ctx) {
// Animate all the task views into view
- ctx.offscreenTranslationY = mRect.bottom - (mTaskRect.top - mRect.top);
+ ctx.offscreenTranslationY = mStackAlgorithm.mRect.bottom -
+ (mStackAlgorithm.mTaskRect.top - mStackAlgorithm.mRect.top);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView tv = (TaskView) getChildAt(i);
@@ -961,7 +858,7 @@
// Update the min/max scroll and animate other task views into their new positions
updateMinMaxScroll(true);
- int movement = (int) (Constants.Values.TaskStackView.StackOverlapPct * mTaskRect.height());
+ int movement = (int) mStackAlgorithm.getTaskOverlapHeight();
requestSynchronizeStackViewsWithModel(Utilities.calculateTranslationAnimationDuration(movement));
// If there are no remaining tasks, then either unfilter the current stack, or just close
@@ -973,148 +870,11 @@
shouldFinishActivity = (mStack.getTaskCount() == 0);
}
if (shouldFinishActivity) {
- Activity activity = (Activity) getContext();
- activity.finish();
+ mCb.onLastTaskRemoved();
}
}
}
- /**
- * Creates the animations for all the children views that need to be removed or to move views
- * to their un/filtered position when we are un/filtering a stack, and returns the duration
- * for these animations.
- */
- int getExitTransformsForFilterAnimation(ArrayList<Task> curTasks,
- ArrayList<TaskViewTransform> curTaskTransforms,
- ArrayList<Task> tasks, ArrayList<TaskViewTransform> taskTransforms,
- HashMap<TaskView, TaskViewTransform> childViewTransformsOut,
- ArrayList<TaskView> childrenToRemoveOut) {
- // Animate all of the existing views out of view (if they are not in the visible range in
- // the new stack) or to their final positions in the new stack
- int offset = 0;
- int movement = 0;
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- TaskView tv = (TaskView) getChildAt(i);
- Task task = tv.getTask();
- int taskIndex = tasks.indexOf(task);
- TaskViewTransform toTransform;
-
- // If the view is no longer visible, then we should just animate it out
- boolean willBeInvisible = taskIndex < 0 || !taskTransforms.get(taskIndex).visible;
- if (willBeInvisible) {
- if (taskIndex < 0) {
- toTransform = curTaskTransforms.get(curTasks.indexOf(task));
- } else {
- toTransform = new TaskViewTransform(taskTransforms.get(taskIndex));
- }
- tv.prepareTaskTransformForFilterTaskVisible(toTransform);
- childrenToRemoveOut.add(tv);
- } else {
- toTransform = taskTransforms.get(taskIndex);
- // Use the movement of the visible views to calculate the duration of the animation
- movement = Math.max(movement, Math.abs(toTransform.translationY -
- (int) tv.getTranslationY()));
- }
-
- toTransform.startDelay = offset * Constants.Values.TaskStackView.FilterStartDelay;
- childViewTransformsOut.put(tv, toTransform);
- offset++;
- }
- return mConfig.filteringCurrentViewsAnimDuration;
- }
-
- /**
- * Creates the animations for all the children views that need to be animated in when we are
- * un/filtering a stack, and returns the duration for these animations.
- */
- int getEnterTransformsForFilterAnimation(ArrayList<Task> tasks,
- ArrayList<TaskViewTransform> taskTransforms,
- HashMap<TaskView, TaskViewTransform> childViewTransformsOut) {
- int offset = 0;
- int movement = 0;
- int taskCount = tasks.size();
- for (int i = taskCount - 1; i >= 0; i--) {
- Task task = tasks.get(i);
- TaskViewTransform toTransform = taskTransforms.get(i);
- if (toTransform.visible) {
- TaskView tv = getChildViewForTask(task);
- if (tv == null) {
- // For views that are not already visible, animate them in
- tv = mViewPool.pickUpViewFromPool(task, task);
-
- // Compose a new transform to fade and slide the new task in
- TaskViewTransform fromTransform = new TaskViewTransform(toTransform);
- tv.prepareTaskTransformForFilterTaskHidden(fromTransform);
- tv.updateViewPropertiesToTaskTransform(fromTransform, 0);
-
- toTransform.startDelay = offset * Constants.Values.TaskStackView.FilterStartDelay;
- childViewTransformsOut.put(tv, toTransform);
-
- // Use the movement of the new views to calculate the duration of the animation
- movement = Math.max(movement,
- Math.abs(toTransform.translationY - fromTransform.translationY));
- offset++;
- }
- }
- }
- return mConfig.filteringNewViewsAnimDuration;
- }
-
- /** Orchestrates the animations of the current child views and any new views. */
- void doFilteringAnimation(ArrayList<Task> curTasks,
- ArrayList<TaskViewTransform> curTaskTransforms,
- final ArrayList<Task> tasks,
- final ArrayList<TaskViewTransform> taskTransforms) {
- // Calculate the transforms to animate out all the existing views if they are not in the
- // new visible range (or to their final positions in the stack if they are)
- final ArrayList<TaskView> childrenToRemove = new ArrayList<TaskView>();
- final HashMap<TaskView, TaskViewTransform> childViewTransforms =
- new HashMap<TaskView, TaskViewTransform>();
- int duration = getExitTransformsForFilterAnimation(curTasks, curTaskTransforms, tasks,
- taskTransforms, childViewTransforms, childrenToRemove);
-
- // If all the current views are in the visible range of the new stack, then don't wait for
- // views to animate out and animate all the new views into their place
- final boolean unifyNewViewAnimation = childrenToRemove.isEmpty();
- if (unifyNewViewAnimation) {
- int inDuration = getEnterTransformsForFilterAnimation(tasks, taskTransforms,
- childViewTransforms);
- duration = Math.max(duration, inDuration);
- }
-
- // Animate all the views to their final transforms
- for (final TaskView tv : childViewTransforms.keySet()) {
- TaskViewTransform t = childViewTransforms.get(tv);
- tv.animate().cancel();
- tv.animate()
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- childViewTransforms.remove(tv);
- if (childViewTransforms.isEmpty()) {
- // Return all the removed children to the view pool
- for (TaskView tv : childrenToRemove) {
- mViewPool.returnViewToPool(tv);
- }
-
- if (!unifyNewViewAnimation) {
- // For views that are not already visible, animate them in
- childViewTransforms.clear();
- int duration = getEnterTransformsForFilterAnimation(tasks,
- taskTransforms, childViewTransforms);
- for (final TaskView tv : childViewTransforms.keySet()) {
- TaskViewTransform t = childViewTransforms.get(tv);
- tv.updateViewPropertiesToTaskTransform(t, duration);
- }
- }
- }
- }
- });
- tv.updateViewPropertiesToTaskTransform(t, duration);
- }
- }
-
@Override
public void onStackFiltered(TaskStack newStack, final ArrayList<Task> curTasks,
Task filteredTask) {
@@ -1127,7 +887,7 @@
// Scroll the item to the top of the stack (sans-peek) rect so that we can see it better
updateMinMaxScroll(false);
- float overlapHeight = Constants.Values.TaskStackView.StackOverlapPct * mTaskRect.height();
+ float overlapHeight = mStackAlgorithm.getTaskOverlapHeight();
setStackScrollRaw((int) (newStack.indexOfTask(filteredTask) * overlapHeight));
boundScrollRaw();
@@ -1137,7 +897,7 @@
getStackTransforms(mStack.getTasks(), getStackScroll(), null, true);
// Animate
- doFilteringAnimation(curTasks, curTaskTransforms, tasks, taskTransforms);
+ mFilterAlgorithm.startFilteringAnimation(curTasks, curTaskTransforms, tasks, taskTransforms);
// Notify any callbacks
mCb.onTaskStackFilterTriggered();
@@ -1160,7 +920,7 @@
getStackTransforms(tasks, getStackScroll(), null, true);
// Animate
- doFilteringAnimation(curTasks, curTaskTransforms, tasks, taskTransforms);
+ mFilterAlgorithm.startFilteringAnimation(curTasks, curTaskTransforms, tasks, taskTransforms);
// Clear the saved vars
mStashedScroll = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewFilterAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewFilterAlgorithm.java
new file mode 100644
index 0000000..9cd5ae4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewFilterAlgorithm.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.model.Task;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/* The layout logic for a TaskStackView */
+public class TaskStackViewFilterAlgorithm {
+
+ RecentsConfiguration mConfig;
+ TaskStackView mStackView;
+ ViewPool<TaskView, Task> mViewPool;
+
+ public TaskStackViewFilterAlgorithm(RecentsConfiguration config, TaskStackView stackView,
+ ViewPool<TaskView, Task> viewPool) {
+ mConfig = config;
+ mStackView = stackView;
+ mViewPool = viewPool;
+ }
+
+ /** Orchestrates the animations of the current child views and any new views. */
+ void startFilteringAnimation(ArrayList<Task> curTasks,
+ ArrayList<TaskViewTransform> curTaskTransforms,
+ final ArrayList<Task> tasks,
+ final ArrayList<TaskViewTransform> taskTransforms) {
+ // Calculate the transforms to animate out all the existing views if they are not in the
+ // new visible range (or to their final positions in the stack if they are)
+ final ArrayList<TaskView> childrenToRemove = new ArrayList<TaskView>();
+ final HashMap<TaskView, TaskViewTransform> childViewTransforms =
+ new HashMap<TaskView, TaskViewTransform>();
+ int duration = getExitTransformsForFilterAnimation(curTasks, curTaskTransforms, tasks,
+ taskTransforms, childViewTransforms, childrenToRemove);
+
+ // If all the current views are in the visible range of the new stack, then don't wait for
+ // views to animate out and animate all the new views into their place
+ final boolean unifyNewViewAnimation = childrenToRemove.isEmpty();
+ if (unifyNewViewAnimation) {
+ int inDuration = getEnterTransformsForFilterAnimation(tasks, taskTransforms,
+ childViewTransforms);
+ duration = Math.max(duration, inDuration);
+ }
+
+ // Animate all the views to their final transforms
+ for (final TaskView tv : childViewTransforms.keySet()) {
+ TaskViewTransform t = childViewTransforms.get(tv);
+ tv.animate().cancel();
+ tv.animate()
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ childViewTransforms.remove(tv);
+ if (childViewTransforms.isEmpty()) {
+ // Return all the removed children to the view pool
+ for (TaskView tv : childrenToRemove) {
+ mViewPool.returnViewToPool(tv);
+ }
+
+ if (!unifyNewViewAnimation) {
+ // For views that are not already visible, animate them in
+ childViewTransforms.clear();
+ int duration = getEnterTransformsForFilterAnimation(tasks,
+ taskTransforms, childViewTransforms);
+ for (final TaskView tv : childViewTransforms.keySet()) {
+ TaskViewTransform t = childViewTransforms.get(tv);
+ tv.updateViewPropertiesToTaskTransform(t, duration);
+ }
+ }
+ }
+ }
+ });
+ tv.updateViewPropertiesToTaskTransform(t, duration);
+ }
+ }
+
+ /**
+ * Creates the animations for all the children views that need to be animated in when we are
+ * un/filtering a stack, and returns the duration for these animations.
+ */
+ int getEnterTransformsForFilterAnimation(ArrayList<Task> tasks,
+ ArrayList<TaskViewTransform> taskTransforms,
+ HashMap<TaskView, TaskViewTransform> childViewTransformsOut) {
+ int offset = 0;
+ int movement = 0;
+ int taskCount = tasks.size();
+ for (int i = taskCount - 1; i >= 0; i--) {
+ Task task = tasks.get(i);
+ TaskViewTransform toTransform = taskTransforms.get(i);
+ if (toTransform.visible) {
+ TaskView tv = mStackView.getChildViewForTask(task);
+ if (tv == null) {
+ // For views that are not already visible, animate them in
+ tv = mViewPool.pickUpViewFromPool(task, task);
+
+ // Compose a new transform to fade and slide the new task in
+ TaskViewTransform fromTransform = new TaskViewTransform(toTransform);
+ tv.prepareTaskTransformForFilterTaskHidden(fromTransform);
+ tv.updateViewPropertiesToTaskTransform(fromTransform, 0);
+
+ toTransform.startDelay = offset * Constants.Values.TaskStackView.FilterStartDelay;
+ childViewTransformsOut.put(tv, toTransform);
+
+ // Use the movement of the new views to calculate the duration of the animation
+ movement = Math.max(movement,
+ Math.abs(toTransform.translationY - fromTransform.translationY));
+ offset++;
+ }
+ }
+ }
+ return mConfig.filteringNewViewsAnimDuration;
+ }
+
+ /**
+ * Creates the animations for all the children views that need to be removed or to move views
+ * to their un/filtered position when we are un/filtering a stack, and returns the duration
+ * for these animations.
+ */
+ int getExitTransformsForFilterAnimation(ArrayList<Task> curTasks,
+ ArrayList<TaskViewTransform> curTaskTransforms,
+ ArrayList<Task> tasks, ArrayList<TaskViewTransform> taskTransforms,
+ HashMap<TaskView, TaskViewTransform> childViewTransformsOut,
+ ArrayList<TaskView> childrenToRemoveOut) {
+ // Animate all of the existing views out of view (if they are not in the visible range in
+ // the new stack) or to their final positions in the new stack
+ int offset = 0;
+ int movement = 0;
+ int childCount = mStackView.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ TaskView tv = (TaskView) mStackView.getChildAt(i);
+ Task task = tv.getTask();
+ int taskIndex = tasks.indexOf(task);
+ TaskViewTransform toTransform;
+
+ // If the view is no longer visible, then we should just animate it out
+ boolean willBeInvisible = taskIndex < 0 || !taskTransforms.get(taskIndex).visible;
+ if (willBeInvisible) {
+ if (taskIndex < 0) {
+ toTransform = curTaskTransforms.get(curTasks.indexOf(task));
+ } else {
+ toTransform = new TaskViewTransform(taskTransforms.get(taskIndex));
+ }
+ tv.prepareTaskTransformForFilterTaskVisible(toTransform);
+ childrenToRemoveOut.add(tv);
+ } else {
+ toTransform = taskTransforms.get(taskIndex);
+ // Use the movement of the visible views to calculate the duration of the animation
+ movement = Math.max(movement, Math.abs(toTransform.translationY -
+ (int) tv.getTranslationY()));
+ }
+
+ toTransform.startDelay = offset * Constants.Values.TaskStackView.FilterStartDelay;
+ childViewTransformsOut.put(tv, toTransform);
+ offset++;
+ }
+ return mConfig.filteringCurrentViewsAnimDuration;
+ }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
new file mode 100644
index 0000000..daa18bc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.graphics.Rect;
+import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.Utilities;
+
+/* The layout logic for a TaskStackView */
+public class TaskStackViewLayoutAlgorithm {
+
+ // These are all going to change
+ static final float StackOverlapPct = 0.65f; // The overlap height relative to the task height
+ static final float StackPeekHeightPct = 0.1f; // The height of the peek space relative to the stack height
+ static final float StackPeekMinScale = 0.8f; // The min scale of the last card in the peek area
+ static final int StackPeekNumCards = 3; // The number of cards we see in the peek space
+
+ RecentsConfiguration mConfig;
+
+ // The various rects that define the stack view
+ Rect mRect = new Rect();
+ Rect mStackRect = new Rect();
+ Rect mStackRectSansPeek = new Rect();
+ Rect mTaskRect = new Rect();
+
+ // The min/max scroll
+ int mMinScroll;
+ int mMaxScroll;
+
+ public TaskStackViewLayoutAlgorithm(RecentsConfiguration config) {
+ mConfig = config;
+ }
+
+ /** Computes the stack and task rects */
+ public void computeRects(int width, int height, int insetLeft, int insetBottom) {
+ // Note: We let the stack view be the full height because we want the cards to go under the
+ // navigation bar if possible. However, the stack rects which we use to calculate
+ // max scroll, etc. need to take the nav bar into account
+
+ // Compute the stack rects
+ mRect.set(0, 0, width, height);
+ mStackRect.set(mRect);
+ mStackRect.left += insetLeft;
+ mStackRect.bottom -= insetBottom;
+
+ int widthPadding = (int) (mConfig.taskStackWidthPaddingPct * mStackRect.width());
+ int heightPadding = mConfig.taskStackTopPaddingPx;
+ if (Constants.DebugFlags.App.EnableSearchLayout) {
+ mStackRect.top += heightPadding;
+ mStackRect.left += widthPadding;
+ mStackRect.right -= widthPadding;
+ mStackRect.bottom -= heightPadding;
+ } else {
+ mStackRect.inset(widthPadding, heightPadding);
+ }
+ mStackRectSansPeek.set(mStackRect);
+ mStackRectSansPeek.top += StackPeekHeightPct * mStackRect.height();
+
+ // Compute the task rect
+ int size = mStackRect.width();
+ int left = mStackRect.left + (mStackRect.width() - size) / 2;
+ mTaskRect.set(left, mStackRectSansPeek.top,
+ left + size, mStackRectSansPeek.top + size);
+ }
+
+ void computeMinMaxScroll(int taskCount) {
+ // Compute the min and max scroll values
+ int numTasks = Math.max(1, taskCount);
+ int taskHeight = mTaskRect.height();
+ int stackHeight = mStackRectSansPeek.height();
+ int maxScrollHeight = taskHeight + getStackScrollForTaskIndex(numTasks - 1);
+
+ if (numTasks <= 1) {
+ // If there is only one task, then center the task in the stack rect (sans peek)
+ mMinScroll = mMaxScroll = -(stackHeight - taskHeight) / 2;
+ } else {
+ mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight;
+ mMaxScroll = maxScrollHeight - stackHeight;
+ }
+ }
+
+ /** Update/get the transform (creates a new TaskViewTransform) */
+ public TaskViewTransform getStackTransform(int indexInStack, int stackScroll) {
+ TaskViewTransform transform = new TaskViewTransform();
+ return getStackTransform(indexInStack, stackScroll, transform);
+ }
+
+ /** Update/get the transform */
+ public TaskViewTransform getStackTransform(int indexInStack, int stackScroll,
+ TaskViewTransform transformOut) {
+ // Return early if we have an invalid index
+ if (indexInStack < 0) {
+ transformOut.reset();
+ return transformOut;
+ }
+
+ // Map the items to an continuous position relative to the specified scroll
+ int numPeekCards = StackPeekNumCards;
+ float overlapHeight = StackOverlapPct * mTaskRect.height();
+ float peekHeight = StackPeekHeightPct * mStackRect.height();
+ float t = ((indexInStack * overlapHeight) - stackScroll) / overlapHeight;
+ float boundedT = Math.max(t, -(numPeekCards + 1));
+
+ // Set the scale relative to its position
+ int numFrontScaledCards = 3;
+ float minScale = StackPeekMinScale;
+ float scaleRange = 1f - minScale;
+ float scaleInc = scaleRange / (numPeekCards + numFrontScaledCards);
+ float scale = Math.max(minScale, Math.min(1f, minScale +
+ ((boundedT + (numPeekCards + 1)) * scaleInc)));
+ float scaleYOffset = ((1f - scale) * mTaskRect.height()) / 2;
+ transformOut.scale = scale;
+
+ // Set the y translation
+ if (boundedT < 0f) {
+ transformOut.translationY = (int) ((Math.max(-numPeekCards, boundedT) /
+ numPeekCards) * peekHeight - scaleYOffset);
+ } else {
+ transformOut.translationY = (int) (boundedT * overlapHeight - scaleYOffset);
+ }
+
+ // Set the z translation
+ int minZ = mConfig.taskViewTranslationZMinPx;
+ int incZ = mConfig.taskViewTranslationZIncrementPx;
+ transformOut.translationZ = (int) Math.max(minZ, minZ + ((boundedT + numPeekCards) * incZ));
+
+ // Set the alphas
+ transformOut.dismissAlpha = Math.max(-1f, Math.min(0f, t + 1)) + 1f;
+
+ // Update the rect and visibility
+ transformOut.rect.set(mTaskRect);
+ if (t < -(numPeekCards + 1)) {
+ transformOut.visible = false;
+ } else {
+ transformOut.rect.offset(0, transformOut.translationY);
+ Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
+ transformOut.visible = Rect.intersects(mRect, transformOut.rect);
+ }
+ transformOut.t = t;
+ return transformOut;
+ }
+
+ /**
+ * Returns the overlap between one task and the next.
+ */
+ float getTaskOverlapHeight() {
+ return StackOverlapPct * mTaskRect.height();
+ }
+
+ /**
+ * Returns the scroll to such that the task transform at that index will have t=0. (If the scroll
+ * is not bounded)
+ */
+ int getStackScrollForTaskIndex(int i) {
+ return (int) (i * getTaskOverlapHeight());
+ }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index f9c5f13..51f994e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -264,7 +264,7 @@
if (overScrollAmount != 0) {
// Bound the overscroll to a fixed amount, and inversely scale the y-movement
// relative to how close we are to the max overscroll
- float maxOverScroll = mSv.mTaskRect.height() / 3f;
+ float maxOverScroll = mSv.mStackAlgorithm.mTaskRect.height() / 3f;
deltaY = Math.round(deltaY * (1f - (Math.min(maxOverScroll, overScrollAmount)
/ maxOverScroll)));
}
@@ -307,7 +307,7 @@
mSv.mMinScroll, mSv.mMaxScroll,
0, overscrollRange);
// Invalidate to kick off computeScroll
- mSv.invalidate(mSv.mStackRect);
+ mSv.invalidate(mSv.mStackAlgorithm.mStackRect);
} else if (mSv.isScrollOutOfBounds()) {
// Animate the scroll back into bounds
// XXX: Make this animation a function of the velocity OR distance
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index f9d5a65..b1fc700 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -485,7 +485,7 @@
/** Compute the dim as a function of the scale of this view. */
int getDimOverlayFromScale() {
- float minScale = Constants.Values.TaskStackView.StackPeekMinScale;
+ float minScale = TaskStackViewLayoutAlgorithm.StackPeekMinScale;
float scaleRange = 1f - minScale;
float dim = (1f - getScaleX()) / scaleRange;
dim = mDimInterpolator.getInterpolation(Math.min(dim, 1f));
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index dc6b6c7..19fff55 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -409,7 +409,8 @@
/**
* used to remove a network request, either a listener or a real request
- * includes a NetworkRequest
+ * arg1 = UID of caller
+ * obj = NetworkRequest
*/
private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
@@ -3333,10 +3334,15 @@
}
}
- private void handleReleaseNetworkRequest(NetworkRequest request) {
- if (DBG) log("releasing NetworkRequest " + request);
- NetworkRequestInfo nri = mNetworkRequests.remove(request);
+ private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
+ NetworkRequestInfo nri = mNetworkRequests.get(request);
if (nri != null) {
+ if (nri.mUid != callingUid) {
+ if (DBG) log("Attempt to release unowned NetworkRequest " + request);
+ return;
+ }
+ if (DBG) log("releasing NetworkRequest " + request);
+ mNetworkRequests.remove(request);
// tell the network currently servicing this that it's no longer interested
NetworkAgentInfo affectedNetwork = mNetworkForRequestId.get(nri.request.requestId);
if (affectedNetwork != null) {
@@ -3482,7 +3488,7 @@
break;
}
case EVENT_RELEASE_NETWORK_REQUEST: {
- handleReleaseNetworkRequest((NetworkRequest) msg.obj);
+ handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1);
break;
}
}
@@ -5460,8 +5466,8 @@
@Override
public void releaseNetworkRequest(NetworkRequest networkRequest) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST,
- networkRequest));
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(),
+ 0, networkRequest));
}
@Override
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 512ebc6..1b71518 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -23,6 +23,7 @@
import android.net.INetworkScoreCache;
import android.net.INetworkScoreService;
import android.net.NetworkScorerAppManager;
+import android.net.NetworkScorerAppManager.NetworkScorerAppData;
import android.net.ScoredNetwork;
import android.os.RemoteException;
import android.text.TextUtils;
@@ -165,12 +166,12 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
- String currentScorer = NetworkScorerAppManager.getActiveScorer(mContext);
+ NetworkScorerAppData currentScorer = NetworkScorerAppManager.getActiveScorer(mContext);
if (currentScorer == null) {
writer.println("Scoring is disabled.");
return;
}
- writer.println("Current scorer: " + currentScorer);
+ writer.println("Current scorer: " + currentScorer.mPackageName);
writer.flush();
for (INetworkScoreCache scoreCache : getScoreCaches()) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9cd5091..c2523be 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7768,7 +7768,8 @@
// Since we lost lock on task, make sure it is still there.
task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
if (task != null) {
- if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
+ if (!isSystemInitiated
+ && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
throw new IllegalArgumentException("Invalid task, not in foreground");
}
mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
@@ -13493,7 +13494,7 @@
// activity manager to announce its creation.
public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
- enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
+ enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
synchronized(this) {
// !!! TODO: currently no check here that we're already bound
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 0825f2e..287ad00 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -79,8 +79,6 @@
private static final String ATTR_LAUNCHEDFROMPACKAGE = "launched_from_package";
private static final String ATTR_RESOLVEDTYPE = "resolved_type";
private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
- private static final String ATTR_TASKDESCRIPTIONLABEL = "task_description_label";
- private static final String ATTR_TASKDESCRIPTIONCOLOR = "task_description_color";
private static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
final ActivityManagerService service; // owner
@@ -1064,20 +1062,10 @@
}
out.attribute(null, ATTR_COMPONENTSPECIFIED, String.valueOf(componentSpecified));
out.attribute(null, ATTR_USERID, String.valueOf(userId));
+
if (taskDescription != null) {
- final String label = taskDescription.getLabel();
- if (label != null) {
- out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, label);
- }
- final int colorPrimary = taskDescription.getPrimaryColor();
- if (colorPrimary != 0) {
- out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(colorPrimary));
- }
- final Bitmap icon = taskDescription.getIcon();
- if (icon != null) {
- TaskPersister.saveImage(icon, String.valueOf(task.taskId) + ACTIVITY_ICON_SUFFIX +
- createTime);
- }
+ TaskPersister.saveTaskDescription(taskDescription, String.valueOf(task.taskId) +
+ ACTIVITY_ICON_SUFFIX + createTime, out);
}
out.startTag(null, TAG_INTENT);
@@ -1100,10 +1088,9 @@
String resolvedType = null;
boolean componentSpecified = false;
int userId = 0;
- String activityLabel = null;
- int activityColor = 0;
long createTime = -1;
final int outerDepth = in.getDepth();
+ TaskDescription taskDescription = new TaskDescription();
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
@@ -1122,10 +1109,9 @@
componentSpecified = Boolean.valueOf(attrValue);
} else if (ATTR_USERID.equals(attrName)) {
userId = Integer.valueOf(attrValue);
- } else if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
- activityLabel = attrValue;
- } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
- activityColor = (int) Long.parseLong(attrValue, 16);
+ } else if (TaskPersister.readTaskDescriptionAttribute(taskDescription, attrName,
+ attrValue)) {
+ // Completed in TaskPersister.readTaskDescriptionAttribute()
} else {
Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
}
@@ -1161,7 +1147,8 @@
final ActivityInfo aInfo = stackSupervisor.resolveActivity(intent, resolvedType, 0, null,
null, userId);
if (aInfo == null) {
- throw new XmlPullParserException("restoreActivity resolver error.");
+ throw new XmlPullParserException("restoreActivity resolver error. Intent=" + intent +
+ " resolvedType=" + resolvedType);
}
final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid,
launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(),
@@ -1169,12 +1156,11 @@
r.persistentState = persistentState;
- Bitmap icon = null;
if (createTime >= 0) {
- icon = TaskPersister.restoreImage(String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX +
- createTime);
+ taskDescription.setIcon(TaskPersister.restoreImage(String.valueOf(taskId) +
+ ACTIVITY_ICON_SUFFIX + createTime));
}
- r.taskDescription = new TaskDescription(activityLabel, icon, activityColor);
+ r.taskDescription = taskDescription;
r.createTime = createTime;
return r;
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index c79b33d..eee7e9e 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import android.app.ActivityManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Debug;
@@ -56,6 +57,9 @@
private static final String TAG_TASK = "task";
+ private static final String ATTR_TASKDESCRIPTIONLABEL = "task_description_label";
+ private static final String ATTR_TASKDESCRIPTIONCOLOR = "task_description_color";
+
private static File sImagesDir;
private static File sTasksDir;
@@ -143,6 +147,53 @@
}
}
+ static void saveTaskDescription(ActivityManager.TaskDescription taskDescription,
+ String iconFilename, XmlSerializer out) throws IOException {
+ if (taskDescription != null) {
+ final String label = taskDescription.getLabel();
+ if (label != null) {
+ out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, label);
+ }
+ final int colorPrimary = taskDescription.getPrimaryColor();
+ if (colorPrimary != 0) {
+ out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(colorPrimary));
+ }
+ final Bitmap icon = taskDescription.getIcon();
+ if (icon != null) {
+ saveImage(icon, iconFilename);
+ }
+ }
+ }
+
+ static boolean readTaskDescriptionAttribute(ActivityManager.TaskDescription taskDescription,
+ String attrName, String attrValue) {
+ if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
+ taskDescription.setLabel(attrValue);
+ return true;
+ } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
+ taskDescription.setPrimaryColor((int) Long.parseLong(attrValue, 16));
+ return true;
+ }
+ return false;
+ }
+
+ private String fileToString(File file) {
+ final String newline = System.lineSeparator();
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(file));
+ StringBuffer sb = new StringBuffer((int) file.length() * 2);
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line + newline);
+ }
+ reader.close();
+ return sb.toString();
+ } catch (IOException ioe) {
+ Slog.e(TAG, "Couldn't read file " + file.getName());
+ return null;
+ }
+ }
+
ArrayList<TaskRecord> restoreTasksLocked() {
final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>();
ArraySet<Integer> recoveredTaskIds = new ArraySet<Integer>();
@@ -172,13 +223,18 @@
if (TAG_TASK.equals(name)) {
final TaskRecord task =
TaskRecord.restoreFromXml(in, mStackSupervisor);
- if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" + task);
+ if (true || DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" +
+ task);
if (task != null) {
task.isPersistable = true;
+ task.needsPersisting = true;
tasks.add(task);
final int taskId = task.taskId;
recoveredTaskIds.add(taskId);
mStackSupervisor.setNextTaskId(taskId);
+ } else {
+ Slog.e(TAG, "Unable to restore taskFile=" + taskFile + ": " +
+ fileToString(taskFile));
}
} else {
Slog.wtf(TAG, "restoreTasksLocked Unknown xml event=" + event +
@@ -189,6 +245,7 @@
}
} catch (Exception e) {
Slog.wtf(TAG, "Unable to parse " + taskFile + ". Error " + e);
+ Slog.e(TAG, "Failing file: " + fileToString(taskFile));
deleteFile = true;
} finally {
if (reader != null) {
@@ -198,7 +255,7 @@
}
}
if (!DEBUG && deleteFile) {
- if (DEBUG) Slog.d(TAG, "Deleting file=" + taskFile.getName());
+ if (true || DEBUG) Slog.d(TAG, "Deleting file=" + taskFile.getName());
taskFile.delete();
}
}
@@ -242,7 +299,8 @@
continue;
}
if (!persistentTaskIds.contains(taskId)) {
- if (DEBUG) Slog.d(TAG, "removeObsoleteFile: deleting file=" + file.getName());
+ if (true || DEBUG) Slog.d(TAG, "removeObsoleteFile: deleting file=" +
+ file.getName());
file.delete();
}
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 57dee2e..0bd7ef9 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -60,6 +60,7 @@
private static final String ATTR_LASTDESCRIPTION = "last_description";
private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity";
+ private static final String LAST_ACTIVITY_ICON_SUFFIX = "_last_activity_icon_";
private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
@@ -138,7 +139,8 @@
String _affinity, ComponentName _realActivity, ComponentName _origActivity,
boolean _rootWasReset, boolean _askedCompatMode, int _taskType, int _userId,
String _lastDescription, ArrayList<ActivityRecord> activities, long _lastActiveTime,
- long lastTimeMoved, boolean neverRelinquishIdentity) {
+ long lastTimeMoved, boolean neverRelinquishIdentity,
+ ActivityManager.TaskDescription _lastTaskDescription) {
mService = service;
taskId = _taskId;
intent = _intent;
@@ -158,8 +160,7 @@
mActivities = activities;
mLastTimeMoved = lastTimeMoved;
mNeverRelinquishIdentity = neverRelinquishIdentity;
- // Recompute the task description for this task
- updateTaskDescription();
+ lastTaskDescription = _lastTaskDescription;
}
void touchActiveTime() {
@@ -714,6 +715,11 @@
out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
}
+ if (lastTaskDescription != null) {
+ TaskPersister.saveTaskDescription(lastTaskDescription, String.valueOf(taskId) +
+ LAST_ACTIVITY_ICON_SUFFIX + lastActiveTime, out);
+ }
+
if (affinityIntent != null) {
out.startTag(null, TAG_AFFINITYINTENT);
affinityIntent.saveToXml(out);
@@ -758,11 +764,12 @@
int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
int userId = 0;
String lastDescription = null;
- long lastActiveTime = 0;
+ long lastActiveTime = -1;
long lastTimeOnTop = 0;
boolean neverRelinquishIdentity = true;
int taskId = -1;
final int outerDepth = in.getDepth();
+ ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription();
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
@@ -793,6 +800,9 @@
lastTimeOnTop = Long.valueOf(attrValue);
} else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
neverRelinquishIdentity = Boolean.valueOf(attrValue);
+ } else if (TaskPersister.readTaskDescriptionAttribute(taskDescription, attrName,
+ attrValue)) {
+ // Completed in TaskPersister.readTaskDescriptionAttribute()
} else {
Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
}
@@ -824,10 +834,15 @@
}
}
+ if (lastActiveTime >= 0) {
+ taskDescription.setIcon(TaskPersister.restoreImage(String.valueOf(taskId) +
+ LAST_ACTIVITY_ICON_SUFFIX + lastActiveTime));
+ }
+
final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
affinityIntent, affinity, realActivity, origActivity, rootHasReset,
askedCompatMode, taskType, userId, lastDescription, activities, lastActiveTime,
- lastTimeOnTop, neverRelinquishIdentity);
+ lastTimeOnTop, neverRelinquishIdentity, taskDescription);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index ed4ccfc..a35e2ba 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -16,6 +16,8 @@
package com.android.server.dreams;
+import static android.Manifest.permission.BIND_DREAM_SERVICE;
+
import com.android.internal.util.DumpUtils;
import com.android.server.FgThread;
import com.android.server.SystemService;
@@ -29,6 +31,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
@@ -193,7 +196,7 @@
private void startDreamInternal(boolean doze) {
final int userId = ActivityManager.getCurrentUser();
- final ComponentName dream = doze ? getDozeComponent() : chooseDreamForUser(userId);
+ final ComponentName dream = chooseDreamForUser(doze, userId);
if (dream != null) {
synchronized (mLock) {
startDreamLocked(dream, false /*isTest*/, doze, userId);
@@ -245,11 +248,31 @@
}
}
- private ComponentName chooseDreamForUser(int userId) {
+ private ComponentName chooseDreamForUser(boolean doze, int userId) {
+ if (doze) {
+ ComponentName dozeComponent = getDozeComponent();
+ return validateDream(dozeComponent) ? dozeComponent : null;
+ }
ComponentName[] dreams = getDreamComponentsForUser(userId);
return dreams != null && dreams.length != 0 ? dreams[0] : null;
}
+ private boolean validateDream(ComponentName component) {
+ if (component == null) return false;
+ final ServiceInfo serviceInfo = getServiceInfo(component);
+ if (serviceInfo == null) {
+ Slog.w(TAG, "Dream " + component + " does not exist");
+ return false;
+ } else if (serviceInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.L
+ && !BIND_DREAM_SERVICE.equals(serviceInfo.permission)) {
+ Slog.w(TAG, "Dream " + component
+ + " is not available because its manifest is missing the " + BIND_DREAM_SERVICE
+ + " permission on the dream service declaration.");
+ return false;
+ }
+ return true;
+ }
+
private ComponentName[] getDreamComponentsForUser(int userId) {
String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.SCREENSAVER_COMPONENTS,
@@ -260,10 +283,8 @@
List<ComponentName> validComponents = new ArrayList<ComponentName>();
if (components != null) {
for (ComponentName component : components) {
- if (serviceExists(component)) {
+ if (validateDream(component)) {
validComponents.add(component);
- } else {
- Slog.w(TAG, "Dream " + component + " does not exist");
}
}
}
@@ -307,11 +328,11 @@
return TextUtils.isEmpty(name) ? null : ComponentName.unflattenFromString(name);
}
- private boolean serviceExists(ComponentName name) {
+ private ServiceInfo getServiceInfo(ComponentName name) {
try {
- return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null;
+ return name != null ? mContext.getPackageManager().getServiceInfo(name, 0) : null;
} catch (NameNotFoundException e) {
- return false;
+ return null;
}
}
diff --git a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java
index 74eaf2a..8de6763 100644
--- a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java
+++ b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java
@@ -27,18 +27,18 @@
/**
* Handles CEC command <Active Source>.
* <p>
- * Used by feature actions that need to handle the command in their flow.
+ * Used by feature actions that need to handle the command in their flow. Only for TV
+ * local device.
*/
final class ActiveSourceHandler {
private static final String TAG = "ActiveSourceHandler";
- private final HdmiCecLocalDevice mSource;
+ private final HdmiCecLocalDeviceTv mSource;
private final HdmiControlService mService;
@Nullable
private final IHdmiControlCallback mCallback;
- static ActiveSourceHandler create(HdmiCecLocalDevice source,
- IHdmiControlCallback callback) {
+ static ActiveSourceHandler create(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) {
if (source == null) {
Slog.e(TAG, "Wrong arguments");
return null;
@@ -46,7 +46,7 @@
return new ActiveSourceHandler(source, callback);
}
- private ActiveSourceHandler(HdmiCecLocalDevice source, IHdmiControlCallback callback) {
+ private ActiveSourceHandler(HdmiCecLocalDeviceTv source, IHdmiControlCallback callback) {
mSource = source;
mService = mSource.getService();
mCallback = callback;
@@ -55,48 +55,46 @@
/**
* Handles the incoming active source command.
*
- * @param deviceLogicalAddress logical address of the device to be the active source
- * @param routingPath routing path of the device to be the active source
+ * @param activeAddress logical address of the device to be the active source
+ * @param activePath routing path of the device to be the active source
*/
- void process(int deviceLogicalAddress, int routingPath) {
- if (getSourcePath() == routingPath && mSource.getActiveSource() == getSourceAddress()) {
+ void process(int activeAddress, int activePath) {
+ // Seq #17
+ HdmiCecLocalDeviceTv tv = mSource;
+ if (getSourcePath() == activePath && tv.getActiveSource() == getSourceAddress()) {
invokeCallback(HdmiCec.RESULT_SUCCESS);
return;
}
- HdmiCecDeviceInfo device = mService.getDeviceInfo(deviceLogicalAddress);
+ HdmiCecDeviceInfo device = mService.getDeviceInfo(activeAddress);
if (device == null) {
// "New device action" initiated by <Active Source> does not require
// "Routing change action".
- mSource.addAndStartAction(new NewDeviceAction(mSource, deviceLogicalAddress,
- routingPath, false));
+ tv.addAndStartAction(new NewDeviceAction(tv, activeAddress, activePath, false));
}
- if (!mSource.isInPresetInstallationMode()) {
- int prevActiveInput = mSource.getActivePortId();
- mSource.updateActiveDevice(deviceLogicalAddress, routingPath);
- if (prevActiveInput != mSource.getActivePortId()) {
- // TODO: change port input here.
+ int currentActive = tv.getActiveSource();
+ int currentPath = tv.getActivePath();
+ if (!tv.isInPresetInstallationMode()) {
+ tv.updateActiveSource(activeAddress, activePath);
+ if (currentActive != activeAddress && currentPath != activePath) {
+ tv.updateActivePortId(mService.pathToPortId(activePath));
}
invokeCallback(HdmiCec.RESULT_SUCCESS);
} else {
// TV is in a mode that should keep its current source/input from
// being changed for its operation. Reclaim the active source
// or switch the port back to the one used for the current mode.
- if (mSource.getActiveSource() == getSourceAddress()) {
+ if (currentActive == getSourceAddress()) {
HdmiCecMessage activeSource =
- HdmiCecMessageBuilder.buildActiveSource(getSourceAddress(),
- getSourcePath());
+ HdmiCecMessageBuilder.buildActiveSource(currentActive, currentPath);
mService.sendCecCommand(activeSource);
- mSource.updateActiveDevice(deviceLogicalAddress, routingPath);
+ tv.updateActiveSource(currentActive, currentPath);
invokeCallback(HdmiCec.RESULT_SUCCESS);
} else {
- int activePath = mSource.getActivePath();
- mService.sendCecCommand(HdmiCecMessageBuilder.buildRoutingChange(getSourceAddress(),
- routingPath, activePath));
- // TODO: Start port select action here
- // PortSelectAction action = new PortSelectAction(mService, getSourceAddress(),
- // activePath, mCallback);
- // mService.addActionAndStart(action);
+ HdmiCecMessage routingChange = HdmiCecMessageBuilder.buildRoutingChange(
+ getSourceAddress(), activePath, currentPath);
+ mService.sendCecCommand(routingChange);
+ tv.addAndStartAction(new RoutingControlAction(tv, currentPath, mCallback));
}
}
}
diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
index dbe3b80..b97350d 100644
--- a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
@@ -77,7 +77,7 @@
* @param target target logical device that will be a new active source
* @param callback callback object
*/
- public DeviceSelectAction(HdmiCecLocalDevice source,
+ public DeviceSelectAction(HdmiCecLocalDeviceTv source,
HdmiCecDeviceInfo target, IHdmiControlCallback callback) {
super(source);
mCallback = callback;
@@ -116,7 +116,7 @@
if (opcode == HdmiCec.MESSAGE_ACTIVE_SOURCE && params.length == 2) {
int activePath = HdmiUtils.twoBytesToInt(params);
ActiveSourceHandler
- .create(localDevice(), mCallback)
+ .create((HdmiCecLocalDeviceTv) localDevice(), mCallback)
.process(cmd.getSource(), activePath);
finish();
return true;
@@ -164,8 +164,10 @@
}
private void turnOnDevice() {
- sendRemoteKeyCommand(HdmiConstants.UI_COMMAND_POWER);
- sendRemoteKeyCommand(HdmiConstants.UI_COMMAND_POWER_ON_FUNCTION);
+ sendUserControlPressedAndReleased(mTarget.getLogicalAddress(),
+ HdmiConstants.UI_COMMAND_POWER);
+ sendUserControlPressedAndReleased(mTarget.getLogicalAddress(),
+ HdmiConstants.UI_COMMAND_POWER_ON_FUNCTION);
mState = STATE_WAIT_FOR_DEVICE_POWER_ON;
addTimer(mState, TIMEOUT_POWER_ON_MS);
}
@@ -177,13 +179,6 @@
addTimer(mState, TIMEOUT_ACTIVE_SOURCE_MS);
}
- private void sendRemoteKeyCommand(int keyCode) {
- sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(),
- mTarget.getLogicalAddress(), keyCode));
- sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(getSourceAddress(),
- mTarget.getLogicalAddress()));
- }
-
@Override
public void handleTimerEvent(int timeoutState) {
if (mState != timeoutState) {
diff --git a/services/core/java/com/android/server/hdmi/FeatureAction.java b/services/core/java/com/android/server/hdmi/FeatureAction.java
index 0ec17f6..cf28f05 100644
--- a/services/core/java/com/android/server/hdmi/FeatureAction.java
+++ b/services/core/java/com/android/server/hdmi/FeatureAction.java
@@ -248,4 +248,11 @@
protected final int getSourcePath() {
return mSource.getDeviceInfo().getPhysicalAddress();
}
+
+ protected void sendUserControlPressedAndReleased(int targetAddress, int uiCommand) {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(
+ getSourceAddress(), targetAddress, uiCommand));
+ sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(
+ getSourceAddress(), targetAddress));
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 6f7f5c2..bf7e57b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -125,6 +125,12 @@
return true;
}
switch (message.getOpcode()) {
+ case HdmiCec.MESSAGE_ACTIVE_SOURCE:
+ return handleActiveSource(message);
+ case HdmiCec.MESSAGE_INACTIVE_SOURCE:
+ return handleInactiveSource(message);
+ case HdmiCec.MESSAGE_REQUEST_ACTIVE_SOURCE:
+ return handleRequestActiveSource(message);
case HdmiCec.MESSAGE_GET_MENU_LANGUAGE:
return handleGetMenuLanguage(message);
case HdmiCec.MESSAGE_GIVE_PHYSICAL_ADDRESS:
@@ -145,6 +151,8 @@
return handleSetSystemAudioMode(message);
case HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_STATUS:
return handleSystemAudioModeStatus(message);
+ case HdmiCec.MESSAGE_REPORT_AUDIO_STATUS:
+ return handleReportAudioStatus(message);
default:
return false;
}
@@ -193,6 +201,21 @@
}
@ServiceThreadOnly
+ protected boolean handleActiveSource(HdmiCecMessage message) {
+ return false;
+ }
+
+ @ServiceThreadOnly
+ protected boolean handleInactiveSource(HdmiCecMessage message) {
+ return false;
+ }
+
+ @ServiceThreadOnly
+ protected boolean handleRequestActiveSource(HdmiCecMessage message) {
+ return false;
+ }
+
+ @ServiceThreadOnly
protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
assertRunOnServiceThread();
Slog.w(TAG, "Only TV can handle <Get Menu Language>:" + message.toString());
@@ -242,6 +265,10 @@
return false;
}
+ protected boolean handleReportAudioStatus(HdmiCecMessage message) {
+ return false;
+ }
+
@ServiceThreadOnly
final void handleAddressAllocated(int logicalAddress) {
assertRunOnServiceThread();
@@ -383,15 +410,24 @@
}
}
- /**
- * Returns the active routing path.
- */
+ void setActiveSource(int source) {
+ synchronized (mLock) {
+ mActiveSource = source;
+ }
+ }
+
int getActivePath() {
synchronized (mLock) {
return mActiveRoutingPath;
}
}
+ void setActivePath(int path) {
+ synchronized (mLock) {
+ mActiveRoutingPath = path;
+ }
+ }
+
/**
* Returns the ID of the active HDMI port. The active port is the one that has the active
* routing path connected to it directly or indirectly under the device hierarchy.
@@ -429,6 +465,13 @@
}
boolean isInPresetInstallationMode() {
+ // TODO: Change this to check the right flag.
+ synchronized (mLock) {
+ return !mInputChangeEnabled;
+ }
+ }
+
+ boolean isHdmiControlEnabled() {
synchronized (mLock) {
return !mInputChangeEnabled;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 0333dbf..718072a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -48,6 +48,20 @@
@GuardedBy("mLock")
private boolean mSystemAudioMode;
+ // The previous port id (input) before switching to the new one. This is remembered in order to
+ // be able to switch to it upon receiving <Inactive Source> from currently active source.
+ // This remains valid only when the active source was switched via one touch play operation
+ // (either by TV or source device). Manual port switching invalidates this value to
+ // HdmiConstants.PORT_INVALID, for which case <Inactive Source> does not do anything.
+ @GuardedBy("mLock")
+ private int mPrevPortId;
+
+ @GuardedBy("mLock")
+ private int mSystemAudioVolume = HdmiConstants.UNKNOWN_VOLUME;
+
+ @GuardedBy("mLock")
+ private boolean mSystemAudioMute = false;
+
// Copy of mDeviceInfos to guarantee thread-safety.
@GuardedBy("mLock")
private List<HdmiCecDeviceInfo> mSafeAllDeviceInfos = Collections.emptyList();
@@ -62,7 +76,7 @@
HdmiCecLocalDeviceTv(HdmiControlService service) {
super(service, HdmiCec.DEVICE_TV);
-
+ mPrevPortId = HdmiConstants.INVALID_PORT_ID;
// TODO: load system audio mode and set it to mSystemAudioMode.
}
@@ -90,6 +104,10 @@
@ServiceThreadOnly
void deviceSelect(int targetAddress, IHdmiControlCallback callback) {
assertRunOnServiceThread();
+ if (targetAddress == HdmiCec.ADDR_INTERNAL) {
+ handleSelectInternalSource(callback);
+ return;
+ }
HdmiCecDeviceInfo targetDevice = getDeviceInfo(targetAddress);
if (targetDevice == null) {
invokeCallback(callback, HdmiCec.RESULT_TARGET_NOT_AVAILABLE);
@@ -99,30 +117,85 @@
addAndStartAction(new DeviceSelectAction(this, targetDevice, callback));
}
- /**
- * Performs the action routing control.
- *
- * @param portId new HDMI port to route to
- * @param callback callback object to report the result with
- */
@ServiceThreadOnly
- void portSelect(int portId, IHdmiControlCallback callback) {
+ private void handleSelectInternalSource(IHdmiControlCallback callback) {
assertRunOnServiceThread();
- if (isInPresetInstallationMode()) {
+ // Seq #18
+ if (isHdmiControlEnabled() && getActiveSource() != mAddress) {
+ updateActiveSource(mAddress, mService.getPhysicalAddress());
+ // TODO: Check if this comes from <Text/Image View On> - if true, do nothing.
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ mAddress, mService.getPhysicalAddress());
+ mService.sendCecCommand(activeSource);
+ }
+ }
+
+ @ServiceThreadOnly
+ void updateActiveSource(int activeSource, int activePath) {
+ assertRunOnServiceThread();
+ // Seq #14
+ if (activeSource == getActiveSource() && activePath == getActivePath()) {
+ return;
+ }
+ setActiveSource(activeSource);
+ setActivePath(activePath);
+ if (getDeviceInfo(activeSource) != null && activeSource != mAddress) {
+ if (mService.pathToPortId(activePath) == getActivePortId()) {
+ setPrevPortId(getActivePortId());
+ }
+ // TODO: Show the OSD banner related to the new active source device.
+ } else {
+ // TODO: If displayed, remove the OSD banner related to the previous
+ // active source device.
+ }
+ }
+
+ /**
+ * Returns the previous port id kept to handle input switching on <Inactive Source>.
+ */
+ int getPrevPortId() {
+ synchronized (mLock) {
+ return mPrevPortId;
+ }
+ }
+
+ /**
+ * Sets the previous port id. INVALID_PORT_ID invalidates it, hence no actions will be
+ * taken for <Inactive Source>.
+ */
+ void setPrevPortId(int portId) {
+ synchronized (mLock) {
+ mPrevPortId = portId;
+ }
+ }
+
+ @ServiceThreadOnly
+ void updateActivePortId(int portId) {
+ assertRunOnServiceThread();
+ // Seq #15
+ if (portId == getActivePortId()) {
+ return;
+ }
+ setPrevPortId(portId);
+ // TODO: Actually switch the physical port here. Handle PAP/PIP as well.
+ // Show OSD port change banner
+ }
+
+ @ServiceThreadOnly
+ void doManualPortSwitching(int portId, IHdmiControlCallback callback) {
+ assertRunOnServiceThread();
+ // Seq #20
+ if (!isHdmiControlEnabled() || portId == getActivePortId()) {
invokeCallback(callback, HdmiCec.RESULT_INCORRECT_MODE);
return;
}
- // Make sure this call does not stem from <Active Source> message reception, in
- // which case the two ports will be the same.
- if (portId == getActivePortId()) {
- invokeCallback(callback, HdmiCec.RESULT_SUCCESS);
- return;
- }
- setActivePortId(portId);
+ // TODO: Make sure this call does not stem from <Active Source> message reception.
+ setActivePortId(portId);
// TODO: Return immediately if the operation is triggered by <Text/Image View On>
+ // and this is the first notification about the active input after power-on.
// TODO: Handle invalid port id / active input which should be treated as an
- // internal tuner.
+ // internal tuner.
removeAction(RoutingControlAction.class);
@@ -168,6 +241,61 @@
@Override
@ServiceThreadOnly
+ protected boolean handleActiveSource(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+ int activePath = HdmiUtils.twoBytesToInt(message.getParams());
+ ActiveSourceHandler.create(this, null).process(message.getSource(), activePath);
+ return true;
+ }
+
+ @Override
+ @ServiceThreadOnly
+ protected boolean handleInactiveSource(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+ // Seq #10
+
+ // Ignore <Inactive Source> from non-active source device.
+ if (getActiveSource() != message.getSource()) {
+ return true;
+ }
+ if (isInPresetInstallationMode()) {
+ return true;
+ }
+ int portId = getPrevPortId();
+ if (portId != HdmiConstants.INVALID_PORT_ID) {
+ // TODO: Do this only if TV is not showing multiview like PIP/PAP.
+
+ HdmiCecDeviceInfo inactiveSource = getDeviceInfo(message.getSource());
+ if (inactiveSource == null) {
+ return true;
+ }
+ if (mService.pathToPortId(inactiveSource.getPhysicalAddress()) == portId) {
+ return true;
+ }
+ // TODO: Switch the TV freeze mode off
+
+ setActivePortId(portId);
+ doManualPortSwitching(portId, null);
+ setPrevPortId(HdmiConstants.INVALID_PORT_ID);
+ }
+ return true;
+ }
+
+ @Override
+ @ServiceThreadOnly
+ protected boolean handleRequestActiveSource(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+ // Seq #19
+ int address = getDeviceInfo().getLogicalAddress();
+ if (address == getActiveSource()) {
+ mService.sendCecCommand(
+ HdmiCecMessageBuilder.buildActiveSource(address, getActivePath()));
+ }
+ return true;
+ }
+
+ @Override
+ @ServiceThreadOnly
protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
assertRunOnServiceThread();
HdmiCecMessage command = HdmiCecMessageBuilder.buildSetMenuLanguageCommand(
@@ -231,6 +359,22 @@
return true;
}
+ @Override
+ @ServiceThreadOnly
+ protected boolean handleReportAudioStatus(HdmiCecMessage message) {
+ assertRunOnServiceThread();
+
+ byte params[] = message.getParams();
+ if (params.length < 1) {
+ Slog.w(TAG, "Invalide <Report Audio Status> message:" + message);
+ return true;
+ }
+ int mute = params[0] & 0x80;
+ int volume = params[0] & 0x7F;
+ setAudioStatus(mute == 0x80, volume);
+ return true;
+ }
+
@ServiceThreadOnly
private void launchDeviceDiscovery() {
assertRunOnServiceThread();
@@ -336,9 +480,64 @@
}
}
- @ServiceThreadOnly
void setAudioStatus(boolean mute, int volume) {
- mService.setAudioStatus(mute, volume);
+ synchronized (mLock) {
+ mSystemAudioMute = mute;
+ mSystemAudioVolume = volume;
+ // TODO: pass volume to service (audio service) after scale it to local volume level.
+ mService.setAudioStatus(mute, volume);
+ }
+ }
+
+ @ServiceThreadOnly
+ void changeVolume(int curVolume, int delta, int maxVolume) {
+ assertRunOnServiceThread();
+ if (delta == 0 || !isSystemAudioOn()) {
+ return;
+ }
+
+ int targetVolume = curVolume + delta;
+ int cecVolume = VolumeControlAction.scaleToCecVolume(targetVolume, maxVolume);
+ synchronized (mLock) {
+ // If new volume is the same as current system audio volume, just ignore it.
+ // Note that UNKNOWN_VOLUME is not in range of cec volume scale.
+ if (cecVolume == mSystemAudioVolume) {
+ // Update tv volume with system volume value.
+ mService.setAudioStatus(false,
+ VolumeControlAction.scaleToCustomVolume(mSystemAudioVolume, maxVolume));
+ return;
+ }
+ }
+
+ // Remove existing volume action.
+ removeAction(VolumeControlAction.class);
+
+ HdmiCecDeviceInfo avr = getAvrDeviceInfo();
+ addAndStartAction(VolumeControlAction.ofVolumeChange(this, avr.getLogicalAddress(),
+ cecVolume, delta > 0));
+ }
+
+ @ServiceThreadOnly
+ void changeMute(boolean mute) {
+ assertRunOnServiceThread();
+ if (!isSystemAudioOn()) {
+ return;
+ }
+
+ // Remove existing volume action.
+ removeAction(VolumeControlAction.class);
+ HdmiCecDeviceInfo avr = getAvrDeviceInfo();
+ addAndStartAction(VolumeControlAction.ofMute(this, avr.getLogicalAddress(), mute));
+ }
+
+ private boolean isSystemAudioOn() {
+ if (getAvrDeviceInfo() == null) {
+ return false;
+ }
+
+ synchronized (mLock) {
+ return mSystemAudioMode;
+ }
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiConstants.java b/services/core/java/com/android/server/hdmi/HdmiConstants.java
index 5294506..ab5b8d8 100644
--- a/services/core/java/com/android/server/hdmi/HdmiConstants.java
+++ b/services/core/java/com/android/server/hdmi/HdmiConstants.java
@@ -97,5 +97,12 @@
static final int UNKNOWN_VOLUME = -1;
+ // IRT(Initiator Repetition Time) in millisecond as recommended in the standard.
+ // Outgoing UCP commands, when in 'Press and Hold' mode, should be this much apart
+ // from the adjacent one so as not to place unnecessarily heavy load on the CEC line.
+ // TODO: This value might need tweaking per product basis. Consider putting it
+ // in config.xml to allow customization.
+ static final int IRT_MS = 300;
+
private HdmiConstants() { /* cannot be instantiated */ }
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 53cb81d..ad95181 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -582,7 +582,7 @@
invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE);
return;
}
- tv.portSelect(portId, callback);
+ tv.doManualPortSwitching(portId, callback);
}
});
}
diff --git a/services/core/java/com/android/server/hdmi/SendKeyAction.java b/services/core/java/com/android/server/hdmi/SendKeyAction.java
index c3078a2..5d81251 100644
--- a/services/core/java/com/android/server/hdmi/SendKeyAction.java
+++ b/services/core/java/com/android/server/hdmi/SendKeyAction.java
@@ -15,6 +15,8 @@
*/
package com.android.server.hdmi;
+import static com.android.server.hdmi.HdmiConstants.IRT_MS;
+
import android.hardware.hdmi.HdmiCecMessage;
import android.util.Slog;
import android.view.KeyEvent;
@@ -38,13 +40,6 @@
// persists throughout the process till it is set back to {@code STATE_NONE} at the end.
private static final int STATE_PROCESSING_KEYCODE = 1;
- // IRT(Initiator Repetition Time) in millisecond as recommended in the standard.
- // Outgoing UCP commands, when in 'Press and Hold' mode, should be this much apart
- // from the adjacent one so as not to place unnecessarily heavy load on the CEC line.
- // TODO: This value might need tweaking per product basis. Consider putting it
- // in config.xml to allow customization.
- private static final int IRT_MS = 450;
-
// Logical address of the device to which the UCP/UCP commands are sent.
private final int mTargetAddress;
@@ -77,7 +72,6 @@
*
* @param keyCode key code of {@link KeyEvent} object
* @param isPressed true if the key event is of {@link KeyEvent#ACTION_DOWN}
- * @param param additional parameter that comes with the key event
*/
void processKeyEvent(int keyCode, boolean isPressed) {
if (mState != STATE_PROCESSING_KEYCODE) {
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
index 89206a7..ecb158b 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
@@ -72,19 +72,12 @@
int uiCommand = tv().getSystemAudioMode()
? HdmiConstants.UI_COMMAND_RESTORE_VOLUME_FUNCTION // SystemAudioMode: ON
: HdmiConstants.UI_COMMAND_MUTE_FUNCTION; // SystemAudioMode: OFF
- sendUserControlPressedAndReleased(uiCommand);
+ sendUserControlPressedAndReleased(mAvrAddress, uiCommand);
// Still return SUCCESS to callback.
finishWithCallback(HdmiCec.RESULT_SUCCESS);
}
- private void sendUserControlPressedAndReleased(int uiCommand) {
- sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(
- getSourceAddress(), mAvrAddress, uiCommand));
- sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(
- getSourceAddress(), mAvrAddress));
- }
-
@Override
boolean processCommand(HdmiCecMessage cmd) {
if (mState != STATE_WAIT_FOR_REPORT_AUDIO_STATUS) {
@@ -109,7 +102,7 @@
if ((tv().getSystemAudioMode() && mute) || (!tv().getSystemAudioMode() && !mute)) {
// Toggle AVR's mute status to match with the system audio status.
- sendUserControlPressedAndReleased(HdmiConstants.UI_COMMAND_MUTE);
+ sendUserControlPressedAndReleased(mAvrAddress, HdmiConstants.UI_COMMAND_MUTE);
}
finishWithCallback(HdmiCec.RESULT_SUCCESS);
} else {
diff --git a/services/core/java/com/android/server/hdmi/VolumeControlAction.java b/services/core/java/com/android/server/hdmi/VolumeControlAction.java
new file mode 100644
index 0000000..07c72f7
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/VolumeControlAction.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import static com.android.server.hdmi.HdmiConstants.IRT_MS;
+
+import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecMessage;
+import android.util.Slog;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Feature action that transmits volume change to Audio Receiver.
+ * <p>
+ * This action is created when a user pressed volume up/down. However, Since Android only provides a
+ * listener for delta of some volume change, we will set a target volume, and check reported volume
+ * from Audio Receiver(AVR). If TV receives no <Report Audio Status> from AVR, this action
+ * will be finished in {@link #IRT_MS} * {@link #VOLUME_CHANGE_TIMEOUT_MAX_COUNT} (ms).
+ */
+final class VolumeControlAction extends FeatureAction {
+ private static final String TAG = "VolumeControlAction";
+
+ private static final int VOLUME_MUTE = 101;
+ private static final int VOLUME_RESTORE = 102;
+ private static final int MAX_VOLUME = 100;
+ private static final int MIN_VOLUME = 0;
+
+ // State where to wait for <Report Audio Status>
+ private static final int STATE_WAIT_FOR_REPORT_VOLUME_STATUS = 1;
+
+ // Maximum count of time out used to finish volume action.
+ private static final int VOLUME_CHANGE_TIMEOUT_MAX_COUNT = 2;
+
+ private final int mAvrAddress;
+ private final int mTargetVolume;
+ private final boolean mIsVolumeUp;
+ private int mTimeoutCount;
+
+ /**
+ * Create a {@link VolumeControlAction} for mute/restore change
+ *
+ * @param source source device sending volume change
+ * @param avrAddress address of audio receiver
+ * @param mute whether to mute sound or not. {@code true} for mute on; {@code false} for mute
+ * off, i.e restore volume
+ * @return newly created {@link VolumeControlAction}
+ */
+ public static VolumeControlAction ofMute(HdmiCecLocalDevice source, int avrAddress,
+ boolean mute) {
+ return new VolumeControlAction(source, avrAddress, mute ? VOLUME_MUTE : VOLUME_RESTORE,
+ false);
+ }
+
+ /**
+ * Create a {@link VolumeControlAction} for volume up/down change
+ *
+ * @param source source device sending volume change
+ * @param avrAddress address of audio receiver
+ * @param targetVolume target volume to be set to AVR. It should be in range of [0-100]
+ * @param isVolumeUp whether to volume up or not. {@code true} for volume up; {@code false} for
+ * volume down
+ * @return newly created {@link VolumeControlAction}
+ */
+ public static VolumeControlAction ofVolumeChange(HdmiCecLocalDevice source, int avrAddress,
+ int targetVolume, boolean isVolumeUp) {
+ Preconditions.checkArgumentInRange(targetVolume, MIN_VOLUME, MAX_VOLUME, "volume");
+ return new VolumeControlAction(source, avrAddress, targetVolume, isVolumeUp);
+ }
+
+ /**
+ * Scale a custom volume value to cec volume scale.
+ *
+ * @param volume volume value in custom scale
+ * @param scale scale of volume (max volume)
+ * @return a volume scaled to cec volume range
+ */
+ public static int scaleToCecVolume(int volume, int scale) {
+ return (volume * MAX_VOLUME) / scale;
+ }
+
+ /**
+ * Scale a cec volume which is in range of 0 to 100 to custom volume level.
+ *
+ * @param cecVolume volume value in cec volume scale. It should be in a range of [0-100]
+ * @param scale scale of custom volume (max volume)
+ * @return a volume value scaled to custom volume range
+ */
+ public static int scaleToCustomVolume(int cecVolume, int scale) {
+ return (cecVolume * scale) / MAX_VOLUME;
+ }
+
+ private VolumeControlAction(HdmiCecLocalDevice source, int avrAddress, int targetVolume,
+ boolean isVolumeUp) {
+ super(source);
+
+ mAvrAddress = avrAddress;
+ mTargetVolume = targetVolume;
+ mIsVolumeUp = isVolumeUp;
+ }
+
+ @Override
+ boolean start() {
+ if (isForMute()) {
+ sendMuteChange(mTargetVolume == VOLUME_MUTE);
+ finish();
+ return true;
+ }
+
+ startVolumeChange();
+ return true;
+ }
+
+
+ private boolean isForMute() {
+ return mTargetVolume == VOLUME_MUTE || mTargetVolume == VOLUME_RESTORE;
+ }
+
+
+ private void startVolumeChange() {
+ mTimeoutCount = 0;
+ sendVolumeChange(mIsVolumeUp);
+ mState = STATE_WAIT_FOR_REPORT_VOLUME_STATUS;
+ addTimer(mState, IRT_MS);
+ }
+
+ private void sendVolumeChange(boolean up) {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(getSourceAddress(), mAvrAddress,
+ up ? HdmiCecKeycode.CEC_KEYCODE_VOLUME_UP
+ : HdmiCecKeycode.CEC_KEYCODE_VOLUME_DOWN));
+ }
+
+ private void sendMuteChange(boolean mute) {
+ sendUserControlPressedAndReleased(mAvrAddress,
+ mute ? HdmiConstants.UI_COMMAND_MUTE_FUNCTION :
+ HdmiConstants.UI_COMMAND_RESTORE_VOLUME_FUNCTION);
+ }
+
+ @Override
+ boolean processCommand(HdmiCecMessage cmd) {
+ if (mState != STATE_WAIT_FOR_REPORT_VOLUME_STATUS) {
+ return false;
+ }
+
+ switch (cmd.getOpcode()) {
+ case HdmiCec.MESSAGE_REPORT_AUDIO_STATUS:
+ handleReportAudioStatus(cmd);
+ return true;
+ case HdmiCec.MESSAGE_FEATURE_ABORT:
+ // TODO: handle feature abort.
+ finish();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private void handleReportAudioStatus(HdmiCecMessage cmd) {
+ byte[] params = cmd.getParams();
+ if (params.length != 1) {
+ Slog.e(TAG, "Invalid <Report Audio Status> message:" + cmd);
+ return;
+ }
+
+ int volume = params[0] & 0x7F;
+ // Update volume with new value.
+ // Note that it will affect system volume change.
+ tv().setAudioStatus(false, volume);
+ if (mIsVolumeUp) {
+ if (mTargetVolume <= volume) {
+ finishWithVolumeChangeRelease();
+ return;
+ }
+ } else {
+ if (mTargetVolume >= volume) {
+ finishWithVolumeChangeRelease();
+ return;
+ }
+ }
+
+ // Clear action status and send another volume change command.
+ clear();
+ startVolumeChange();
+ }
+
+ private void finishWithVolumeChangeRelease() {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(
+ getSourceAddress(), mAvrAddress));
+ finish();
+ }
+
+ @Override
+ void handleTimerEvent(int state) {
+ if (mState != STATE_WAIT_FOR_REPORT_VOLUME_STATUS) {
+ return;
+ }
+
+ // If no report volume action after IRT * VOLUME_CHANGE_TIMEOUT_MAX_COUNT just stop volume
+ // action.
+ if (++mTimeoutCount == VOLUME_CHANGE_TIMEOUT_MAX_COUNT) {
+ finishWithVolumeChangeRelease();
+ return;
+ }
+
+ sendVolumeChange(mIsVolumeUp);
+ addTimer(mState, IRT_MS);
+ }
+}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 6f1eb8f..aeade50 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -38,6 +38,7 @@
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
+import android.os.Binder;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler;
@@ -280,6 +281,9 @@
* @param delta The amount to adjust the volume by.
*/
public void adjustVolumeBy(int delta, int flags) {
+ if (isPlaybackActive(false)) {
+ flags &= ~AudioManager.FLAG_PLAY_SOUND;
+ }
if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) {
if (delta == 0) {
mAudioManager.adjustStreamVolume(mAudioStream, delta, flags);
@@ -1119,12 +1123,22 @@
@Override
public void adjustVolumeBy(int delta, int flags) {
- MediaSessionRecord.this.adjustVolumeBy(delta, flags);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ MediaSessionRecord.this.adjustVolumeBy(delta, flags);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
public void setVolumeTo(int value, int flags) {
- MediaSessionRecord.this.setVolumeTo(value, flags);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ MediaSessionRecord.this.setVolumeTo(value, flags);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 15f0ebf..f8ac2e4 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -36,6 +36,7 @@
import android.util.Slog;
import com.android.internal.R;
+import com.android.server.notification.NotificationManagerService.DumpFilter;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -74,16 +75,19 @@
}
@Override
- public void dump(PrintWriter pw) {
- super.dump(pw);
+ public void dump(PrintWriter pw, DumpFilter filter) {
+ super.dump(pw, filter);
synchronized(mMutex) {
- pw.print(" mListeners("); pw.print(mListeners.size()); pw.println("):");
- for (int i = 0; i < mListeners.size(); i++) {
- pw.print(" "); pw.println(mListeners.keyAt(i));
+ if (filter == null) {
+ pw.print(" mListeners("); pw.print(mListeners.size()); pw.println("):");
+ for (int i = 0; i < mListeners.size(); i++) {
+ pw.print(" "); pw.println(mListeners.keyAt(i));
+ }
}
pw.print(" mRecords("); pw.print(mRecords.size()); pw.println("):");
for (int i = 0; i < mRecords.size(); i++) {
final ConditionRecord r = mRecords.get(i);
+ if (filter != null && !filter.matches(r.component)) continue;
pw.print(" "); pw.println(r);
final String countdownDesc = CountdownConditionProvider.tryParseDescription(r.id);
if (countdownDesc != null) {
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 1b1fc8b..36be21f 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -44,6 +44,8 @@
import android.util.Slog;
import android.util.SparseArray;
+import com.android.server.notification.NotificationManagerService.DumpFilter;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -116,15 +118,17 @@
mSettingsObserver.observe();
}
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, DumpFilter filter) {
pw.println(" All " + getCaption() + "s (" + mEnabledServicesForCurrentProfiles.size()
+ ") enabled for current profiles:");
for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
+ if (filter != null && !filter.matches(cmpt)) continue;
pw.println(" " + cmpt);
}
pw.println(" Live " + getCaption() + "s (" + mServices.size() + "):");
for (ManagedServiceInfo info : mServices) {
+ if (filter != null && !filter.matches(info.component)) continue;
pw.println(" " + info.component
+ " (user " + info.userid + "): " + info.service
+ (info.isSystem?" SYSTEM":""));
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c7adb688..bc14888 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -440,7 +440,8 @@
this.duration = duration;
}
- void dump(PrintWriter pw, String prefix) {
+ void dump(PrintWriter pw, String prefix, DumpFilter filter) {
+ if (filter != null && !filter.matches(pkg)) return;
pw.println(prefix + this);
}
@@ -1313,7 +1314,7 @@
return;
}
- dumpImpl(pw);
+ dumpImpl(pw, DumpFilter.parseFromArguments(args));
}
};
@@ -1334,9 +1335,12 @@
return keys.toArray(new String[keys.size()]);
}
- void dumpImpl(PrintWriter pw) {
- pw.println("Current Notification Manager state:");
-
+ void dumpImpl(PrintWriter pw, DumpFilter filter) {
+ pw.print("Current Notification Manager state");
+ if (filter != null) {
+ pw.print(" (filtered to '"); pw.print(filter.pkgFilter); pw.print("')");
+ }
+ pw.println(':');
int N;
synchronized (mToastQueue) {
@@ -1344,11 +1348,10 @@
if (N > 0) {
pw.println(" Toast Queue:");
for (int i=0; i<N; i++) {
- mToastQueue.get(i).dump(pw, " ");
+ mToastQueue.get(i).dump(pw, " ", filter);
}
pw.println(" ");
}
-
}
synchronized (mNotificationList) {
@@ -1356,29 +1359,35 @@
if (N > 0) {
pw.println(" Notification List:");
for (int i=0; i<N; i++) {
- mNotificationList.get(i).dump(pw, " ", getContext());
+ final NotificationRecord nr = mNotificationList.get(i);
+ if (filter != null && !filter.matches(nr.sbn)) continue;
+ nr.dump(pw, " ", getContext());
}
pw.println(" ");
}
- N = mLights.size();
- if (N > 0) {
- pw.println(" Lights List:");
- for (int i=0; i<N; i++) {
- pw.println(" " + mLights.get(i));
+ if (filter == null) {
+ N = mLights.size();
+ if (N > 0) {
+ pw.println(" Lights List:");
+ for (int i=0; i<N; i++) {
+ pw.println(" " + mLights.get(i));
+ }
+ pw.println(" ");
}
- pw.println(" ");
- }
- pw.println(" mSoundNotification=" + mSoundNotification);
- pw.println(" mVibrateNotification=" + mVibrateNotification);
- pw.println(" mDisableNotificationAlerts=" + mDisableNotificationAlerts);
- pw.println(" mSystemReady=" + mSystemReady);
+ pw.println(" mSoundNotification=" + mSoundNotification);
+ pw.println(" mVibrateNotification=" + mVibrateNotification);
+ pw.println(" mDisableNotificationAlerts=" + mDisableNotificationAlerts);
+ pw.println(" mSystemReady=" + mSystemReady);
+ }
pw.println(" mArchive=" + mArchive.toString());
Iterator<StatusBarNotification> iter = mArchive.descendingIterator();
int i=0;
while (iter.hasNext()) {
- pw.println(" " + iter.next());
+ final StatusBarNotification sbn = iter.next();
+ if (filter != null && !filter.matches(sbn)) continue;
+ pw.println(" " + sbn);
if (++i >= 5) {
if (iter.hasNext()) pw.println(" ...");
break;
@@ -1386,16 +1395,18 @@
}
pw.println("\n Usage Stats:");
- mUsageStats.dump(pw, " ");
+ mUsageStats.dump(pw, " ", filter);
- pw.println("\n Zen Mode:");
- mZenModeHelper.dump(pw, " ");
+ if (filter == null) {
+ pw.println("\n Zen Mode:");
+ mZenModeHelper.dump(pw, " ");
+ }
pw.println("\n Notification listeners:");
- mListeners.dump(pw);
+ mListeners.dump(pw, filter);
pw.println("\n Condition providers:");
- mConditionProviders.dump(pw);
+ mConditionProviders.dump(pw, filter);
}
}
@@ -2447,4 +2458,30 @@
}
}
}
+
+ public static final class DumpFilter {
+ public String pkgFilter;
+
+ public static DumpFilter parseFromArguments(String[] args) {
+ if (args == null || args.length != 2 || !"p".equals(args[0])
+ || args[1] == null || args[1].trim().isEmpty()) {
+ return null;
+ }
+ final DumpFilter filter = new DumpFilter();
+ filter.pkgFilter = args[1].trim().toLowerCase();
+ return filter;
+ }
+
+ public boolean matches(StatusBarNotification sbn) {
+ return sbn != null && (matches(sbn.getPackageName()) || matches(sbn.getOpPkg()));
+ }
+
+ public boolean matches(ComponentName component) {
+ return component != null && matches(component.getPackageName());
+ }
+
+ public boolean matches(String pkg) {
+ return pkg != null && pkg.toLowerCase().contains(pkgFilter);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 5081bf7..adf9516 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -28,6 +28,8 @@
import android.service.notification.StatusBarNotification;
import android.util.Log;
+import com.android.server.notification.NotificationManagerService.DumpFilter;
+
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@@ -168,12 +170,13 @@
return result;
}
- public synchronized void dump(PrintWriter pw, String indent) {
+ public synchronized void dump(PrintWriter pw, String indent, DumpFilter filter) {
for (AggregatedStats as : mStats.values()) {
+ if (filter != null && !filter.matches(as.key)) continue;
as.dump(pw, indent);
}
if (ENABLE_SQLITE_LOG) {
- mSQLiteLog.dump(pw, indent);
+ mSQLiteLog.dump(pw, indent, filter);
}
}
@@ -511,7 +514,7 @@
mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_DISMISS, notification));
}
- public void printPostFrequencies(PrintWriter pw, String indent) {
+ public void printPostFrequencies(PrintWriter pw, String indent, DumpFilter filter) {
SQLiteDatabase db = mHelper.getReadableDatabase();
long nowMs = System.currentTimeMillis();
String q = "SELECT " +
@@ -530,6 +533,7 @@
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
int userId = cursor.getInt(0);
String pkg = cursor.getString(1);
+ if (filter != null && !filter.matches(pkg)) continue;
int day = cursor.getInt(2);
int count = cursor.getInt(3);
pw.println(indent + "post_frequency{user_id=" + userId + ",pkg=" + pkg +
@@ -598,8 +602,8 @@
outCv.put(COL_AIRTIME_MS, r.stats.getCurrentAirtimeMs());
}
- public void dump(PrintWriter pw, String indent) {
- printPostFrequencies(pw, indent);
+ public void dump(PrintWriter pw, String indent, DumpFilter filter) {
+ printPostFrequencies(pw, indent, filter);
}
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a0cb098..832a3b6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1047,6 +1047,11 @@
}
private UserInfo createUserInternal(String name, int flags, int parentId) {
+ if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
+ UserManager.DISALLOW_ADD_USER, false)) {
+ Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
+ return null;
+ }
final long ident = Binder.clearCallingIdentity();
UserInfo userInfo = null;
try {
diff --git a/telecomm/java/android/telecomm/CallCameraCapabilities.aidl b/telecomm/java/android/telecomm/CallCameraCapabilities.aidl
new file mode 100644
index 0000000..25b6106
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallCameraCapabilities.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+
+package android.telecomm;
+
+parcelable CallCameraCapabilities;
diff --git a/telecomm/java/android/telecomm/CallCameraCapabilities.java b/telecomm/java/android/telecomm/CallCameraCapabilities.java
new file mode 100644
index 0000000..87a411a
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallCameraCapabilities.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecomm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents the camera capabilities important to a Video Telephony provider.
+ * TODO: Add camera capabilities as required.
+ */
+public final class CallCameraCapabilities implements Parcelable {
+
+ /**
+ * Whether the camera supports zoom.
+ */
+ private final boolean mZoomSupported;
+
+ /**
+ * The maximum zoom supported by the camera.
+ */
+ private final float mMaxZoom;
+
+ /**
+ * Create a call camera capabilities instance.
+ *
+ * @param zoomSupported True when camera supports zoom.
+ * @param maxZoom Maximum zoom supported by camera.
+ */
+ public CallCameraCapabilities(boolean zoomSupported, float maxZoom) {
+ mZoomSupported = zoomSupported;
+ mMaxZoom = maxZoom;
+ }
+
+ /**
+ * Responsible for creating CallCameraCapabilities objects from deserialized Parcels.
+ **/
+ public static final Parcelable.Creator<CallCameraCapabilities> CREATOR =
+ new Parcelable.Creator<CallCameraCapabilities> () {
+ /**
+ * Creates a CallCameraCapabilities instances from a parcel.
+ *
+ * @param source The parcel.
+ * @return The CallCameraCapabilities.
+ */
+ @Override
+ public CallCameraCapabilities createFromParcel(Parcel source) {
+ boolean supportsZoom = source.readByte() != 0;
+ float maxZoom = source.readFloat();
+
+ return new CallCameraCapabilities(supportsZoom, maxZoom);
+ }
+
+ @Override
+ public CallCameraCapabilities[] newArray(int size) {
+ return new CallCameraCapabilities[size];
+ }
+ };
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return a bitmask indicating the set of special object types marshalled
+ * by the Parcelable.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByte((byte) (isZoomSupported() ? 1 : 0));
+ dest.writeFloat(getMaxZoom());
+
+ }
+
+ /**
+ * Whether the camera supports zoom.
+ */
+ public boolean isZoomSupported() {
+ return mZoomSupported;
+ }
+
+ /**
+ * The maximum zoom supported by the camera.
+ */
+ public float getMaxZoom() {
+ return mMaxZoom;
+ }
+}
diff --git a/telecomm/java/android/telecomm/CallInfo.java b/telecomm/java/android/telecomm/CallInfo.java
index 4de9373..17efed5 100644
--- a/telecomm/java/android/telecomm/CallInfo.java
+++ b/telecomm/java/android/telecomm/CallInfo.java
@@ -24,7 +24,7 @@
import java.util.Date;
/**
- * A parcelable holder class of Call information data. This class is intended for transfering call
+ * A parcelable holder class of Call information data. This class is intended for transferring call
* information from Telecomm to call services and thus is read-only.
* TODO(santoscordon): Need final public-facing comments in this file.
*/
@@ -52,6 +52,11 @@
private final GatewayInfo mGatewayInfo;
/**
+ * Subscription information for the call.
+ */
+ private final Subscription mSubscription;
+
+ /**
* Additional information that can be persisted.
*/
private final Bundle mExtras;
@@ -60,7 +65,7 @@
private final CallServiceDescriptor mCurrentCallServiceDescriptor;
public CallInfo(String id, CallState state, Uri handle) {
- this(id, state, handle, null, Bundle.EMPTY, null);
+ this(id, state, handle, null, null, Bundle.EMPTY, null);
}
/**
@@ -70,6 +75,7 @@
* @param state The state of the call.
* @param handle The handle to the other party in this call.
* @param gatewayInfo Gateway information pertaining to this call.
+ * @param subscription Subscription information pertaining to this call.
* @param extras Additional information that can be persisted.
* @param currentCallServiceDescriptor The descriptor for the call service currently routing
* this call.
@@ -81,12 +87,14 @@
CallState state,
Uri handle,
GatewayInfo gatewayInfo,
+ Subscription subscription,
Bundle extras,
CallServiceDescriptor currentCallServiceDescriptor) {
mId = id;
mState = state;
mHandle = handle;
mGatewayInfo = gatewayInfo;
+ mSubscription = subscription;
mExtras = extras;
mCurrentCallServiceDescriptor = currentCallServiceDescriptor;
}
@@ -119,6 +127,10 @@
return mGatewayInfo;
}
+ public Subscription getSubscription() {
+ return mSubscription;
+ }
+
public Bundle getExtras() {
return mExtras;
}
@@ -137,16 +149,13 @@
CallState state = CallState.valueOf(source.readString());
Uri handle = Uri.CREATOR.createFromParcel(source);
- boolean gatewayInfoPresent = source.readByte() != 0;
- GatewayInfo gatewayInfo = null;
- if (gatewayInfoPresent) {
- gatewayInfo = GatewayInfo.CREATOR.createFromParcel(source);
- }
+ GatewayInfo gatewayInfo = readProviderInfoIfExists(source, GatewayInfo.CREATOR);
+ Subscription subscription = readProviderInfoIfExists(source, Subscription.CREATOR);
ClassLoader classLoader = CallInfo.class.getClassLoader();
Bundle extras = source.readParcelable(classLoader);
CallServiceDescriptor descriptor = source.readParcelable(classLoader);
- return new CallInfo(id, state, handle, gatewayInfo, extras, descriptor);
+ return new CallInfo(id, state, handle, gatewayInfo, subscription, extras, descriptor);
}
@Override
@@ -172,14 +181,35 @@
destination.writeString(mState.name());
mHandle.writeToParcel(destination, 0);
- if (mGatewayInfo != null) {
- destination.writeByte((byte) 1);
- mGatewayInfo.writeToParcel(destination, 0);
- } else {
- destination.writeByte((byte) 0);
- }
+ writeProviderInfoIfExists(destination, mGatewayInfo);
+ writeProviderInfoIfExists(destination, mSubscription);
destination.writeParcelable(mExtras, 0);
destination.writeParcelable(mCurrentCallServiceDescriptor, 0);
}
+
+ /**
+ * Helper function to write provider information (either GatewayInfo or Subscription) to
+ * parcel. Will write a false byte if the information does not exist.
+ */
+ private void writeProviderInfoIfExists(Parcel destination, Parcelable provider) {
+ if (provider != null) {
+ destination.writeByte((byte) 1);
+ provider.writeToParcel(destination, 0);
+ } else {
+ destination.writeByte((byte) 0);
+ }
+ }
+
+ /**
+ * Helper function to read provider information (either GatewayInfo or Subscription) from
+ * parcel.
+ */
+ private static <T> T readProviderInfoIfExists(Parcel source,
+ Parcelable.Creator<T> creator) {
+ if (source.readByte() != 0) {
+ return creator.createFromParcel(source);
+ }
+ return null;
+ }
}
diff --git a/telecomm/java/android/telecomm/CallServiceAdapter.java b/telecomm/java/android/telecomm/CallServiceAdapter.java
index 31e37c4..8412e80 100644
--- a/telecomm/java/android/telecomm/CallServiceAdapter.java
+++ b/telecomm/java/android/telecomm/CallServiceAdapter.java
@@ -23,6 +23,7 @@
import com.android.internal.telecomm.ICallService;
import com.android.internal.telecomm.ICallServiceAdapter;
+import com.android.internal.telecomm.ICallVideoProvider;
import com.android.internal.telecomm.RemoteServiceCallback;
import java.util.ArrayList;
@@ -338,4 +339,19 @@
}
}
}
+
+ /**
+ * Sets the call video provider for a call.
+ *
+ * @param callId The unique ID of the call to set with the given call video provider.
+ * @param callVideoProvider The call video provider instance to set on the call.
+ */
+ public void setCallVideoProvider(String callId, CallVideoProvider callVideoProvider) {
+ for (ICallServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.setCallVideoProvider(callId, callVideoProvider.getInterface());
+ } catch (RemoteException e) {
+ }
+ }
+ }
}
diff --git a/telecomm/java/android/telecomm/CallVideoClient.java b/telecomm/java/android/telecomm/CallVideoClient.java
new file mode 100644
index 0000000..4b37136
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallVideoClient.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecomm;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecomm.ICallVideoClient;
+
+/**
+ * Base implementation of a CallVideoClient which communicates changes to video properties of a call
+ * from the framework to the current InCall-UI.
+ */
+public abstract class CallVideoClient {
+
+ /**
+ * Video is not being received (no protocol pause was issued).
+ */
+ public static final int SESSION_EVENT_RX_PAUSE = 1;
+
+ /**
+ * Video reception has resumed after a SESSION_EVENT_RX_PAUSE.
+ */
+ public static final int SESSION_EVENT_RX_RESUME = 2;
+
+ /**
+ * Video transmission has begun. This occurs after a negotiated start of video transmission
+ * when the underlying protocol has actually begun transmitting video to the remote party.
+ */
+ public static final int SESSION_EVENT_TX_START = 3;
+
+ /**
+ * Video transmission has stopped. This occur after a negotiated stop of video transmission when
+ * the underlying protocol has actually stopped transmitting video to the remote party.
+ */
+ public static final int SESSION_EVENT_TX_STOP = 4;
+
+ /**
+ * Session modify request was successful.
+ */
+ public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1;
+
+ /**
+ * Session modify request failed.
+ */
+ public static final int SESSION_MODIFY_REQUEST_FAIL = 2;
+
+ /**
+ * Session modify request ignored due to invalid parameters.
+ */
+ public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
+
+ private static final int MSG_ON_RECEIVE_SESSION_MODIFY_REQUEST = 1;
+ private static final int MSG_ON_RECEIVE_SESSION_MODIFY_RESPONSE = 2;
+ private static final int MSG_ON_CALL_SESSION_EVENT = 3;
+ private static final int MSG_ON_UPDATED_PEER_DIMENSIONS = 4;
+ private static final int MSG_ON_UPDATE_CALL_DATA_USAGE = 5;
+ private static final int MSG_ON_CAMERA_CAPABILITIES_CHANGE = 6;
+
+ /** Default Handler used to consolidate binder method calls onto a single thread. */
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ON_RECEIVE_SESSION_MODIFY_REQUEST:
+ onReceiveSessionModifyRequest((VideoCallProfile) msg.obj);
+ break;
+ case MSG_ON_RECEIVE_SESSION_MODIFY_RESPONSE: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ int status = (int) args.arg1;
+ VideoCallProfile requestedProfile = (VideoCallProfile) args.arg2;
+ VideoCallProfile responseProfile = (VideoCallProfile) args.arg3;
+
+ onReceiveSessionModifyResponse(status, requestedProfile,
+ responseProfile);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_ON_CALL_SESSION_EVENT:
+ onCallSessionEvent((int) msg.obj);
+ break;
+ case MSG_ON_UPDATED_PEER_DIMENSIONS: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ int width = (int) args.arg1;
+ int height = (int) args.arg2;
+ onUpdatedPeerDimensions(width, height);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_ON_UPDATE_CALL_DATA_USAGE:
+ onUpdateCallDataUsage(msg.arg1);
+ break;
+ case MSG_ON_CAMERA_CAPABILITIES_CHANGE:
+ onCameraCapabilitiesChange((CallCameraCapabilities) msg.obj);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ /**
+ * Default ICallVideoClient implementation.
+ */
+ private final class CallVideoClientBinder extends ICallVideoClient.Stub {
+ @Override
+ public void onReceiveSessionModifyRequest(VideoCallProfile videoCallProfile) {
+ mHandler.obtainMessage(MSG_ON_RECEIVE_SESSION_MODIFY_REQUEST,
+ videoCallProfile).sendToTarget();
+ }
+
+ @Override
+ public void onReceiveSessionModifyResponse(int status,
+ VideoCallProfile requestedProfile, VideoCallProfile responseProfile) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = status;
+ args.arg2 = requestedProfile;
+ args.arg3 = responseProfile;
+ mHandler.obtainMessage(MSG_ON_RECEIVE_SESSION_MODIFY_RESPONSE, args).sendToTarget();
+ }
+
+ @Override
+ public void onCallSessionEvent(int event) {
+ mHandler.obtainMessage(MSG_ON_CALL_SESSION_EVENT, event).sendToTarget();
+ }
+
+ @Override
+ public void onUpdatedPeerDimensions(int width, int height) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = width;
+ args.arg2 = height;
+ mHandler.obtainMessage(MSG_ON_UPDATED_PEER_DIMENSIONS, args).sendToTarget();
+ }
+
+ @Override
+ public void onUpdateCallDataUsage(int dataUsage) {
+ mHandler.obtainMessage(MSG_ON_UPDATE_CALL_DATA_USAGE, dataUsage).sendToTarget();
+ }
+
+ @Override
+ public void onCameraCapabilitiesChange(CallCameraCapabilities cameraCapabilities) {
+ mHandler.obtainMessage(MSG_ON_CAMERA_CAPABILITIES_CHANGE,
+ cameraCapabilities).sendToTarget();
+ }
+ }
+
+ private final CallVideoClientBinder mBinder;
+
+ protected CallVideoClient() {
+ mBinder = new CallVideoClientBinder();
+ }
+
+ /**
+ * Retrieves the binder.
+ *
+ * @return The binder.
+ * @hide
+ */
+ public final CallVideoClientBinder getBinder() {
+ return mBinder;
+ }
+
+ /**
+ * Called when an incoming request is received from a remote device to modify the current
+ * video call profile. This could be, for example, a remote request to upgrade from an
+ * audio-only call to a video call.
+ *
+ * @param videoCallProfile The requested video call profile.
+ */
+ public abstract void onReceiveSessionModifyRequest(VideoCallProfile videoCallProfile);
+
+ /**
+ * Called when a response is received to a previously sent request to modify the video call
+ * profile. For example, if a request was previously sent to the other party to upgrade from an
+ * audio-only call to a video call, the other party responds to indicate which profile
+ * changes were accepted.
+ *
+ * @param status Status of the session modify request. Valid values are
+ * {@link CallVideoClient#SESSION_MODIFY_REQUEST_SUCCESS},
+ * {@link CallVideoClient#SESSION_MODIFY_REQUEST_FAIL},
+ * {@link CallVideoClient#SESSION_MODIFY_REQUEST_INVALID}
+ * @param requestedProfile The original request which was sent to the remote device.
+ * @param responseProfile The actual profile changes made by the remote device.
+ */
+ public abstract void onReceiveSessionModifyResponse(int status,
+ VideoCallProfile requestedProfile, VideoCallProfile responseProfile);
+
+ /**
+ * Handles events related to the current session which the client may wish to handle. These
+ * are separate from requested changes to the session due to the underlying protocol or
+ * connection.
+ * Valid values are: {@link CallVideoClient#SESSION_EVENT_RX_PAUSE},
+ * {@link CallVideoClient#SESSION_EVENT_RX_RESUME},
+ * {@link CallVideoClient#SESSION_EVENT_TX_START}, {@link CallVideoClient#SESSION_EVENT_TX_STOP}
+ *
+ * @param event The event.
+ */
+ public abstract void onCallSessionEvent(int event);
+
+ /**
+ * Handles a change to the video dimensions from the remote caller (peer). This could happen
+ * if, for example, the peer changes orientation of their device.
+ *
+ * @param width The updated peer video width.
+ * @param height The updated peer video height.
+ */
+ public abstract void onUpdatedPeerDimensions(int width, int height);
+
+ /**
+ * Handles an update to the total data used for the current session.
+ *
+ * @param dataUsage The updated data usage.
+ */
+ public abstract void onUpdateCallDataUsage(int dataUsage);
+
+ /**
+ * Handles a change in camera capabilities.
+ *
+ * @param callCameraCapabilities The changed camera capabilities.
+ */
+ public abstract void onCameraCapabilitiesChange(CallCameraCapabilities callCameraCapabilities);
+}
+
diff --git a/telecomm/java/android/telecomm/CallVideoProvider.java b/telecomm/java/android/telecomm/CallVideoProvider.java
index 6126fca..4f593b9 100644
--- a/telecomm/java/android/telecomm/CallVideoProvider.java
+++ b/telecomm/java/android/telecomm/CallVideoProvider.java
@@ -25,7 +25,6 @@
import com.android.internal.telecomm.ICallVideoProvider;
-/** @hide */
public abstract class CallVideoProvider {
private static final int MSG_SET_CAMERA = 1;
@@ -61,6 +60,14 @@
}
/**
+ * Returns binder object which can be used across IPC methods.
+ * @hide
+ */
+ public final ICallVideoProvider getInterface() {
+ return mBinder;
+ }
+
+ /**
* Sets the camera to be used for video recording in a video call.
*
* @param cameraId The id of the camera.
diff --git a/telecomm/java/android/telecomm/CallVideoProviderWrapper.java b/telecomm/java/android/telecomm/CallVideoProviderWrapper.java
new file mode 100644
index 0000000..862adff
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallVideoProviderWrapper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecomm;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.internal.telecomm.ICallVideoProvider;
+
+
+public class CallVideoProviderWrapper implements IBinder.DeathRecipient {
+ private final ICallVideoProvider mCallVideoProvider;
+
+ CallVideoProviderWrapper(ICallVideoProvider callVideoProvider) throws RemoteException {
+ mCallVideoProvider = callVideoProvider;
+ mCallVideoProvider.asBinder().linkToDeath(this, 0);
+ }
+
+ @Override
+ public void binderDied() {
+ mCallVideoProvider.asBinder().unlinkToDeath(this, 0);
+ }
+
+ /**
+ * Sets the camera to be used for video recording in a video call, using the binder.
+ *
+ * @param cameraId The id of the camera.
+ */
+ public void setCamera(String cameraId) throws RemoteException {
+ mCallVideoProvider.setCamera(cameraId);
+ };
+}
\ No newline at end of file
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 1783327..cf4e29a 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -18,6 +18,7 @@
import android.net.Uri;
import android.os.Bundle;
+import android.telecomm.CallVideoProvider;
import java.util.ArrayList;
import java.util.Collections;
@@ -40,6 +41,7 @@
void onDestroyed(Connection c);
void onConferenceCapableChanged(Connection c, boolean isConferenceCapable);
void onParentConnectionChanged(Connection c, Connection parent);
+ void onSetCallVideoProvider(Connection c, CallVideoProvider callVideoProvider);
}
public static class ListenerBase implements Listener {
@@ -78,6 +80,10 @@
/** ${inheritDoc} */
@Override
public void onParentConnectionChanged(Connection c, Connection parent) {}
+
+ /** {@inheritDoc} */
+ @Override
+ public void onSetCallVideoProvider(Connection c, CallVideoProvider callVideoProvider) {}
}
public final class State {
@@ -123,8 +129,6 @@
/**
* @return The state of this Connection.
- *
- * @hide
*/
public final int getState() {
return mState;
@@ -275,6 +279,8 @@
/**
* TODO(santoscordon): Needs updated documentation.
+ *
+ * @hide
*/
public final void conference() {
Log.d(this, "conference");
@@ -285,9 +291,14 @@
* Inform this Connection that the state of its audio output has been changed externally.
*
* @param state The new audio state.
+ * @hide
*/
- public void setAudioState(CallAudioState state) {
+ public final void setAudioState(CallAudioState state) {
Log.d(this, "setAudioState %s", state);
+ mCallAudioState = state;
+ for (Listener l : mListeners) {
+ l.onAudioStateChanged(this, state);
+ }
onSetAudioState(state);
}
@@ -319,18 +330,21 @@
* Returns whether this connection is requesting that the system play a ringback tone
* on its behalf.
*/
- public boolean isRequestingRingback() {
+ public final boolean isRequestingRingback() {
return mRequestingRingback;
}
/**
* Returns whether this connection is a conference connection (has child connections).
*/
- public boolean isConferenceConnection() {
+ public final boolean isConferenceConnection() {
return !mChildConnections.isEmpty();
}
- public void setParentConnection(Connection parentConnection) {
+ /**
+ * TODO(santoscordon): Needs documentation.
+ */
+ public final void setParentConnection(Connection parentConnection) {
Log.d(this, "parenting %s to %s", this, parentConnection);
if (mParentConnection != parentConnection) {
if (mParentConnection != null) {
@@ -347,18 +361,18 @@
}
}
- public Connection getParentConnection() {
+ public final Connection getParentConnection() {
return mParentConnection;
}
- public List<Connection> getChildConnections() {
+ public final List<Connection> getChildConnections() {
return mChildConnections;
}
/**
* Returns whether this connection is capable of being conferenced.
*/
- public boolean isConferenceCapable() {
+ public final boolean isConferenceCapable() {
return mIsConferenceCapable;
}
@@ -367,7 +381,7 @@
*
* @param handle The new handle.
*/
- protected void setHandle(Uri handle) {
+ public final void setHandle(Uri handle) {
Log.d(this, "setHandle %s", handle);
// TODO: Enforce super called
mHandle = handle;
@@ -380,7 +394,7 @@
* Sets state to active (e.g., an ongoing call where two or more parties can actively
* communicate).
*/
- protected void setActive() {
+ public final void setActive() {
setRequestingRingback(false);
setState(State.ACTIVE);
}
@@ -388,25 +402,35 @@
/**
* Sets state to ringing (e.g., an inbound ringing call).
*/
- protected void setRinging() {
+ public final void setRinging() {
setState(State.RINGING);
}
/**
* Sets state to dialing (e.g., dialing an outbound call).
*/
- protected void setDialing() {
+ public final void setDialing() {
setState(State.DIALING);
}
/**
* Sets state to be on hold.
*/
- protected void setOnHold() {
+ public final void setOnHold() {
setState(State.HOLDING);
}
/**
+ * Sets the call video provider.
+ * @param callVideoProvider The call video provider.
+ */
+ public final void setCallVideoProvider(CallVideoProvider callVideoProvider) {
+ for (Listener l : mListeners) {
+ l.onSetCallVideoProvider(this, callVideoProvider);
+ }
+ }
+
+ /**
* Sets state to disconnected. This will first notify listeners with an
* {@link Listener#onStateChanged(Connection, int)} event, then will fire an
* {@link Listener#onDisconnected(Connection, int, String)} event with additional
@@ -416,7 +440,7 @@
* {@link android.telephony.DisconnectCause}.
* @param message Optional call-service-provided message about the disconnect.
*/
- protected void setDisconnected(int cause, String message) {
+ public final void setDisconnected(int cause, String message) {
setState(State.DISCONNECTED);
Log.d(this, "Disconnected with cause %d message %s", cause, message);
for (Listener l : mListeners) {
@@ -430,7 +454,7 @@
*
* @param ringback Whether the ringback tone is to be played.
*/
- protected void setRequestingRingback(boolean ringback) {
+ public final void setRequestingRingback(boolean ringback) {
if (mRequestingRingback != ringback) {
mRequestingRingback = ringback;
for (Listener l : mListeners) {
@@ -442,7 +466,7 @@
/**
* TODO(santoscordon): Needs documentation.
*/
- protected void setIsConferenceCapable(boolean isConferenceCapable) {
+ public final void setIsConferenceCapable(boolean isConferenceCapable) {
if (mIsConferenceCapable != isConferenceCapable) {
mIsConferenceCapable = isConferenceCapable;
for (Listener l : mListeners) {
@@ -454,7 +478,7 @@
/**
* TODO(santoscordon): Needs documentation.
*/
- protected void setDestroyed() {
+ public final void setDestroyed() {
// It is possible that onDestroy() will trigger the listener to remove itself which will
// result in a concurrent modification exception. To counteract this we make a copy of the
// listeners and iterate on that.
@@ -466,46 +490,32 @@
}
/**
- * Notifies this Connection and listeners that the {@link #getCallAudioState()} property
- * has a new value.
- *
- * @param state The new call audio state.
- */
- protected void onSetAudioState(CallAudioState state) {
- // TODO: Enforce super called
- mCallAudioState = state;
- for (Listener l : mListeners) {
- l.onAudioStateChanged(this, state);
- }
- }
-
- /**
* Notifies this Connection and listeners of a change in the current signal levels
* for the underlying data transport.
*
* @param details A {@link android.os.Bundle} containing details of the current level.
*/
- protected void onSetSignal(Bundle details) {
- // TODO: Enforce super called
+ public final void setSignal(Bundle details) {
for (Listener l : mListeners) {
l.onSignalChanged(this, details);
}
}
/**
+ * Notifies this Connection and listeners that the {@link #getCallAudioState()} property
+ * has a new value.
+ *
+ * @param state The new call audio state.
+ */
+ protected void onSetAudioState(CallAudioState state) {}
+
+ /**
* Notifies this Connection of an internal state change. This method is called before the
- * state is actually changed. Overriding implementations must call
- * {@code super.onSetState(state)}.
+ * state is actually changed.
*
* @param state The new state, a {@link Connection.State} member.
*/
- protected void onSetState(int state) {
- // TODO: Enforce super called
- this.mState = state;
- for (Listener l : mListeners) {
- l.onStateChanged(this, state);
- }
- }
+ protected void onSetState(int state) {}
/**
* Notifies this Connection of a request to play a DTMF tone.
@@ -585,6 +595,10 @@
private void setState(int state) {
Log.d(this, "setState: %s", stateToString(state));
+ this.mState = state;
+ for (Listener l : mListeners) {
+ l.onStateChanged(this, state);
+ }
onSetState(state);
}
}
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 23b99fa..4d525f20 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -155,6 +155,12 @@
String parentId = parent == null ? null : mIdByConnection.get(parent);
getAdapter().setIsConferenced(id, parentId);
}
+
+ @Override
+ public void onSetCallVideoProvider(Connection c, CallVideoProvider callVideoProvider) {
+ String id = mIdByConnection.get(c);
+ getAdapter().setCallVideoProvider(id, callVideoProvider);
+ }
};
@Override
diff --git a/telecomm/java/android/telecomm/InCallCall.java b/telecomm/java/android/telecomm/InCallCall.java
index 66974f9..8cbe2e6 100644
--- a/telecomm/java/android/telecomm/InCallCall.java
+++ b/telecomm/java/android/telecomm/InCallCall.java
@@ -38,6 +38,7 @@
private final long mConnectTimeMillis;
private final Uri mHandle;
private final GatewayInfo mGatewayInfo;
+ private final Subscription mSubscription;
private final CallServiceDescriptor mCurrentCallServiceDescriptor;
private final CallServiceDescriptor mHandoffCallServiceDescriptor;
private final String mParentCallId;
@@ -55,11 +56,12 @@
long connectTimeMillis,
Uri handle,
GatewayInfo gatewayInfo,
+ Subscription subscription,
CallServiceDescriptor descriptor,
CallServiceDescriptor handoffDescriptor) {
this(id, state, disconnectCauseCode, disconnectCauseMsg, cannedSmsResponses,
- capabilities, connectTimeMillis, handle, gatewayInfo, descriptor, handoffDescriptor,
- null, Collections.EMPTY_LIST);
+ capabilities, connectTimeMillis, handle, gatewayInfo, subscription, descriptor,
+ handoffDescriptor, null, Collections.EMPTY_LIST);
}
/** @hide */
@@ -73,6 +75,7 @@
long connectTimeMillis,
Uri handle,
GatewayInfo gatewayInfo,
+ Subscription subscription,
CallServiceDescriptor descriptor,
CallServiceDescriptor handoffDescriptor,
String parentCallId,
@@ -86,6 +89,7 @@
mConnectTimeMillis = connectTimeMillis;
mHandle = handle;
mGatewayInfo = gatewayInfo;
+ mSubscription = subscription;
mCurrentCallServiceDescriptor = descriptor;
mHandoffCallServiceDescriptor = handoffDescriptor;
mParentCallId = parentCallId;
@@ -145,6 +149,11 @@
return mGatewayInfo;
}
+ /** Subscription information for the call. */
+ public Subscription getSubscription() {
+ return mSubscription;
+ }
+
/** The descriptor for the call service currently routing this call. */
public CallServiceDescriptor getCurrentCallServiceDescriptor() {
return mCurrentCallServiceDescriptor;
@@ -191,6 +200,7 @@
long connectTimeMillis = source.readLong();
Uri handle = source.readParcelable(classLoader);
GatewayInfo gatewayInfo = source.readParcelable(classLoader);
+ Subscription subscription = source.readParcelable(classLoader);
CallServiceDescriptor descriptor = source.readParcelable(classLoader);
CallServiceDescriptor handoffDescriptor = source.readParcelable(classLoader);
String parentCallId = source.readString();
@@ -198,7 +208,7 @@
source.readList(childCallIds, classLoader);
return new InCallCall(id, state, disconnectCauseCode, disconnectCauseMsg,
cannedSmsResponses, capabilities, connectTimeMillis, handle, gatewayInfo,
- descriptor, handoffDescriptor, parentCallId, childCallIds);
+ subscription, descriptor, handoffDescriptor, parentCallId, childCallIds);
}
@Override
@@ -225,6 +235,7 @@
destination.writeLong(mConnectTimeMillis);
destination.writeParcelable(mHandle, 0);
destination.writeParcelable(mGatewayInfo, 0);
+ destination.writeParcelable(mSubscription, 0);
destination.writeParcelable(mCurrentCallServiceDescriptor, 0);
destination.writeParcelable(mHandoffCallServiceDescriptor, 0);
destination.writeString(mParentCallId);
diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java
index 7658a76d..64e5871 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionService.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionService.java
@@ -26,6 +26,7 @@
import com.android.internal.telecomm.ICallService;
import com.android.internal.telecomm.ICallServiceAdapter;
+import com.android.internal.telecomm.ICallVideoProvider;
import com.android.internal.telecomm.RemoteServiceCallback;
import java.util.ArrayList;
@@ -105,6 +106,12 @@
}
/** ${inheritDoc} */
+ public void setCallVideoProvider(
+ String connectionId, ICallVideoProvider callVideoProvider) {
+ // not supported for remote connections.
+ }
+
+ /** ${inheritDoc} */
@Override
public void setDialing(String connectionId) {
if (isCurrentConnection(connectionId)) {
diff --git a/telecomm/java/android/telecomm/VideoCallProfile.aidl b/telecomm/java/android/telecomm/VideoCallProfile.aidl
new file mode 100644
index 0000000..adbf94d
--- /dev/null
+++ b/telecomm/java/android/telecomm/VideoCallProfile.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+
+package android.telecomm;
+
+parcelable VideoCallProfile;
diff --git a/telecomm/java/android/telecomm/VideoCallProfile.java b/telecomm/java/android/telecomm/VideoCallProfile.java
new file mode 100644
index 0000000..fc7b2c3
--- /dev/null
+++ b/telecomm/java/android/telecomm/VideoCallProfile.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecomm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents attributes of video calls.
+ */
+public class VideoCallProfile implements Parcelable {
+ /**
+ * Call is currently in an audio-only mode with no video transmission or receipt.
+ */
+ public static final int VIDEO_STATE_AUDIO_ONLY = 0x0;
+
+ /**
+ * Video transmission is enabled.
+ */
+ public static final int VIDEO_STATE_TX_ENABLED = 0x1;
+
+ /**
+ * Video reception is enabled.
+ */
+ public static final int VIDEO_STATE_RX_ENABLED = 0x2;
+
+ /**
+ * Video signal is bi-directional.
+ */
+ public static final int VIDEO_STATE_BIDIRECTIONAL =
+ VIDEO_STATE_TX_ENABLED | VIDEO_STATE_RX_ENABLED;
+
+ /**
+ * Video is paused.
+ */
+ public static final int VIDEO_STATE_PAUSED = 0x4;
+
+ /**
+ * "High" video quality.
+ */
+ public static final int QUALITY_HIGH = 1;
+
+ /**
+ * "Medium" video quality.
+ */
+ public static final int QUALITY_MEDIUM = 2;
+
+ /**
+ * "Low" video quality.
+ */
+ public static final int QUALITY_LOW = 3;
+
+ /**
+ * Use default video quality.
+ */
+ public static final int QUALITY_DEFAULT = 4;
+
+ private final int mVideoState;
+
+ private final int mQuality;
+
+ /**
+ * Creates an instance of the VideoCallProfile
+ *
+ * @param videoState The video state.
+ * @param quality The video quality.
+ */
+ public VideoCallProfile(int videoState, int quality) {
+ mVideoState = videoState;
+ mQuality = quality;
+ }
+
+ /**
+ * The video state of the call. Stored as a bit-field describing whether video transmission and
+ * receipt it enabled, as well as whether the video is currently muted.
+ * Valid values: {@link VideoCallProfile#VIDEO_STATE_AUDIO_ONLY},
+ * {@link VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL},
+ * {@link VideoCallProfile#VIDEO_STATE_TX_ENABLED},
+ * {@link VideoCallProfile#VIDEO_STATE_RX_ENABLED},
+ * {@link VideoCallProfile#VIDEO_STATE_PAUSED}.
+ */
+ public int getVideoState() {
+ return mVideoState;
+ }
+
+ /**
+ * The desired video quality for the call.
+ * Valid values: {@link VideoCallProfile#QUALITY_HIGH}, {@link VideoCallProfile#QUALITY_MEDIUM},
+ * {@link VideoCallProfile#QUALITY_LOW}, {@link VideoCallProfile#QUALITY_DEFAULT}.
+ */
+ public int getQuality() {
+ return mQuality;
+ }
+
+ /**
+ * Responsible for creating VideoCallProfile objects from deserialized Parcels.
+ **/
+ public static final Parcelable.Creator<VideoCallProfile> CREATOR =
+ new Parcelable.Creator<VideoCallProfile> () {
+ /**
+ * Creates a MediaProfile instances from a parcel.
+ *
+ * @param source The parcel.
+ * @return The MediaProfile.
+ */
+ @Override
+ public VideoCallProfile createFromParcel(Parcel source) {
+ int state = source.readInt();
+ int quality = source.readInt();
+
+ ClassLoader classLoader = VideoCallProfile.class.getClassLoader();
+ return new VideoCallProfile(state, quality);
+ }
+
+ @Override
+ public VideoCallProfile[] newArray(int size) {
+ return new VideoCallProfile[size];
+ }
+ };
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return a bitmask indicating the set of special object types marshalled
+ * by the Parcelable.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mVideoState);
+ dest.writeInt(mQuality);
+ }
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
index 373fb16..b81ef37 100644
--- a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
@@ -19,6 +19,7 @@
import android.telecomm.CallInfo;
import android.telecomm.ConnectionRequest;
+import com.android.internal.telecomm.ICallVideoProvider;
import com.android.internal.telecomm.RemoteServiceCallback;
/**
@@ -62,4 +63,6 @@
void handoffCall(String callId);
void queryRemoteConnectionServices(RemoteServiceCallback callback);
+
+ void setCallVideoProvider(String callId, ICallVideoProvider callVideoProvider);
}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallVideoClient.aidl b/telecomm/java/com/android/internal/telecomm/ICallVideoClient.aidl
new file mode 100644
index 0000000..0a854a1
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallVideoClient.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telecomm;
+
+import android.telecomm.CallCameraCapabilities;
+import android.telecomm.VideoCallProfile;
+
+ /**
+ * Internal definition of the CallVideoClient, used for an InCall-UI to respond to video telephony
+ * related changes.
+ *
+ * @see android.telecomm.CallVideoClient
+ *
+ * {@hide}
+ */
+ oneway interface ICallVideoClient {
+
+ void onReceiveSessionModifyRequest(in VideoCallProfile videoCallProfile);
+
+ void onReceiveSessionModifyResponse(int status, in VideoCallProfile requestedProfile,
+ in VideoCallProfile responseProfile);
+
+ void onCallSessionEvent(int event);
+
+ void onUpdatedPeerDimensions(int width, int height);
+
+ void onUpdateCallDataUsage(int dataUsage);
+
+ void onCameraCapabilitiesChange(in CallCameraCapabilities callCameraCapabilities);
+ }
diff --git a/tests/VectorDrawableTest/res/anim/animation_favorite.xml b/tests/VectorDrawableTest/res/anim/animation_favorite.xml
new file mode 100644
index 0000000..c81ba40
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_favorite.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ android:duration="8000"
+ android:interpolator="@interpolator/custom_path_interpolator_favorite"
+ android:propertyName="pathData"
+ android:repeatCount="-1"
+ android:valueFrom="@string/round_box"
+ android:valueTo="@string/heart"
+ android:valueType="pathType" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/anim/animation_favorite02.xml b/tests/VectorDrawableTest/res/anim/animation_favorite02.xml
new file mode 100644
index 0000000..15d3b8e
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_favorite02.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ android:duration="8000"
+ android:interpolator="@interpolator/custom_path_interpolator_favorite"
+ android:propertyName="scaleX"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="20" />
+ <objectAnimator
+ android:duration="8000"
+ android:interpolator="@interpolator/custom_path_interpolator_favorite"
+ android:propertyName="scaleY"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="20" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/anim/animation_grouping_1_01.xml b/tests/VectorDrawableTest/res/anim/animation_grouping_1_01.xml
new file mode 100644
index 0000000..8d82d05
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_grouping_1_01.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ android:duration="3300"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="360"
+ android:repeatCount="-1" />
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/anim/animation_grouping_1_02.xml b/tests/VectorDrawableTest/res/anim/animation_grouping_1_02.xml
new file mode 100644
index 0000000..ae63203
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/animation_grouping_1_02.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ android:duration="2000"
+ android:interpolator="@interpolator/custom_path_interpolator_favorite"
+ android:propertyName="scaleX"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="20" />
+ <objectAnimator
+ android:duration="2000"
+ android:interpolator="@interpolator/custom_path_interpolator_favorite"
+ android:propertyName="scaleY"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="20" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/anim/trim_path_animation05.xml b/tests/VectorDrawableTest/res/anim/trim_path_animation05.xml
index 7012f4b..92b1ab5 100644
--- a/tests/VectorDrawableTest/res/anim/trim_path_animation05.xml
+++ b/tests/VectorDrawableTest/res/anim/trim_path_animation05.xml
@@ -21,8 +21,8 @@
<objectAnimator
android:duration="3000"
android:propertyName="pathData"
- android:valueFrom="@string/triangle"
- android:valueTo="@string/rectangle"
+ android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
+ android:valueTo= "M300,70 l 0,-70 70,0 0,140 -70,0 z"
android:valueType="pathType"/>
<objectAnimator
diff --git a/tests/VectorDrawableTest/res/anim/trim_path_animation_progress_bar.xml b/tests/VectorDrawableTest/res/anim/trim_path_animation_progress_bar.xml
new file mode 100644
index 0000000..f510256
--- /dev/null
+++ b/tests/VectorDrawableTest/res/anim/trim_path_animation_progress_bar.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ android:duration="1300"
+ android:interpolator="@interpolator/trim_start_interpolator"
+ android:propertyName="trimPathStart"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType" />
+ <objectAnimator
+ android:duration="1300"
+ android:interpolator="@interpolator/trim_end_interpolator"
+ android:propertyName="trimPathEnd"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType" />
+ <objectAnimator
+ android:duration="1300"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:propertyName="trimPathOffset"
+ android:repeatCount="-1"
+ android:valueFrom="0"
+ android:valueTo="1.25"
+ android:valueType="floatType" />
+
+</set>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/animation_vector_drawable01.xml b/tests/VectorDrawableTest/res/drawable/animation_vector_drawable01.xml
index b37b19f..19b82ad 100644
--- a/tests/VectorDrawableTest/res/drawable/animation_vector_drawable01.xml
+++ b/tests/VectorDrawableTest/res/drawable/animation_vector_drawable01.xml
@@ -19,14 +19,12 @@
<target
android:name="pie1"
android:animation="@anim/trim_path_animation01" />
-
<target
android:name="v"
android:animation="@anim/trim_path_animation02" />
<target
android:name="v"
android:animation="@anim/trim_path_animation05" />
-
<target
android:name="rotationGroup"
android:animation="@anim/trim_path_animation03" />
@@ -40,4 +38,4 @@
android:name="rotationGroup"
android:animation="@anim/trim_path_animation04" />
-</animated-vector>
+</animated-vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/animation_vector_drawable_favorite.xml b/tests/VectorDrawableTest/res/drawable/animation_vector_drawable_favorite.xml
new file mode 100644
index 0000000..9d8381f
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/animation_vector_drawable_favorite.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/vector_drawable_favorite" >
+
+ <target
+ android:name="favorite"
+ android:animation="@anim/animation_favorite" />
+ <target
+ android:name="root"
+ android:animation="@anim/animation_favorite02" />
+
+</animated-vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/animation_vector_drawable_grouping_1.xml b/tests/VectorDrawableTest/res/drawable/animation_vector_drawable_grouping_1.xml
new file mode 100644
index 0000000..4a7e4f6
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/animation_vector_drawable_grouping_1.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/vector_drawable_grouping_1" >
+
+ <target
+ android:name="sun"
+ android:animation="@anim/animation_grouping_1_01" />
+ <target
+ android:name="earth"
+ android:animation="@anim/animation_grouping_1_01" />
+
+</animated-vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/animation_vector_progress_bar.xml b/tests/VectorDrawableTest/res/drawable/animation_vector_progress_bar.xml
new file mode 100644
index 0000000..6621e41
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/animation_vector_progress_bar.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/vector_drawable_progress_bar" >
+
+ <target
+ android:name="pie1"
+ android:animation="@anim/trim_path_animation_progress_bar" />
+
+</animated-vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
new file mode 100644
index 0000000..c8840f5
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="128dp"
+ android:width="128dp" />
+
+ <viewport
+ android:viewportHeight="480"
+ android:viewportWidth="480" />
+
+ <group
+ android:name="root"
+ android:translateX="240.0"
+ android:translateY="240.0" >
+ <path
+ android:name="favorite"
+ android:fill="#ff000000"
+ android:pathData="M2.100006104,-6
+ C0.1449127197,-6,1.600006104,-5.975006104,0,-5.975006104
+ C-1.574996948,-5.975006104,0.00309753418,-6,-1.949996948,-6
+ C-4.492996216,-6,-5.949996948,-3.718399048,-5.949996948,-1.149993896
+ C-5.949996948,2.379302979,-5.699996948,5.100006104,0,5.100006104
+ C5.699996948,5.100006104,6,2.379302979,6,-1.149993896
+ C6,-3.718399048,4.643005371,-6,2.100006104,-6" />
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_grouping_1.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_grouping_1.xml
new file mode 100644
index 0000000..558de94
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_grouping_1.xml
@@ -0,0 +1,56 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="256"
+ android:viewportWidth="256" />
+
+ <group
+ android:name="shape_layer_1"
+ android:translateX="128"
+ android:translateY="128" >
+ <group android:name="sun" >
+ <path
+ android:name="ellipse_path_1"
+ android:fill="#ffff8000"
+ android:pathData="m -25 0 a 25,25 0 1,0 50,0 a 25,25 0 1,0 -50,0" />
+
+ <group
+ android:name="earth"
+ android:translateX="75" >
+ <path
+ android:name="ellipse_path_1_1"
+ android:fill="#ff5656ea"
+ android:pathData="m -10 0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0" />
+
+ <group
+ android:name="moon"
+ android:translateX="25" >
+ <path
+ android:name="ellipse_path_1_2"
+ android:fill="#ffadadad"
+ android:pathData="m -5 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0" />
+ </group>
+ </group>
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_progress_bar.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_progress_bar.xml
new file mode 100644
index 0000000..956c600
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_progress_bar.xml
@@ -0,0 +1,52 @@
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="64"
+ android:viewportWidth="64" />
+
+ <group
+ android:name="root"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="0"
+ android:translateX="32.0"
+ android:translateY="32.0" >
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="0" >
+ <path
+ android:name="pie1"
+ android:fill="#00000000"
+ android:pathData="M0, 0 m 0, -9.5 a 9.5,9.5 0 1,1 0,19 a 9.5,9.5 0 1,1 0,-19"
+ android:stroke="#89cff0"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="miter"
+ android:strokeWidth="2"
+ android:trimPathEnd="0.1"
+ android:trimPathOffset="0"
+ android:trimPathStart="0" />
+ </group>
+ </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/interpolator/custom_path_interpolator_favorite.xml b/tests/VectorDrawableTest/res/interpolator/custom_path_interpolator_favorite.xml
new file mode 100644
index 0000000..935d5b5
--- /dev/null
+++ b/tests/VectorDrawableTest/res/interpolator/custom_path_interpolator_favorite.xml
@@ -0,0 +1,2 @@
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="L0.1, 0 C0.10066,0 0.198,1 0.2, 1 L 1,1" />
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/interpolator/custom_path_interpolator_grouping_1_01.xml b/tests/VectorDrawableTest/res/interpolator/custom_path_interpolator_grouping_1_01.xml
new file mode 100644
index 0000000..8c57395
--- /dev/null
+++ b/tests/VectorDrawableTest/res/interpolator/custom_path_interpolator_grouping_1_01.xml
@@ -0,0 +1,2 @@
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="L 0.09 1 L 1,1" />
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/interpolator/trim_end_interpolator.xml b/tests/VectorDrawableTest/res/interpolator/trim_end_interpolator.xml
new file mode 100644
index 0000000..b2770cd
--- /dev/null
+++ b/tests/VectorDrawableTest/res/interpolator/trim_end_interpolator.xml
@@ -0,0 +1,2 @@
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="C0.2,0 0.1,1 0.5, 1 L 1,1" />
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/interpolator/trim_start_interpolator.xml b/tests/VectorDrawableTest/res/interpolator/trim_start_interpolator.xml
new file mode 100644
index 0000000..798f7e6
--- /dev/null
+++ b/tests/VectorDrawableTest/res/interpolator/trim_start_interpolator.xml
@@ -0,0 +1,2 @@
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="L0.5,0 C 0.7,0 0.6,1 1, 1" />
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/values/strings.xml b/tests/VectorDrawableTest/res/values/strings.xml
index 6ae3d7f..54cffa8 100644
--- a/tests/VectorDrawableTest/res/values/strings.xml
+++ b/tests/VectorDrawableTest/res/values/strings.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!--
+ Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,12 +16,13 @@
-->
<resources>
- <string name="twoLinePathData" >"M 0,0 v 100 M 0,0 h 100"</string>
- <string name="triangle" > "M300,70 l 0,-70 70,70 0,0 -70,70z"</string>
- <string name="rectangle" >"M300,70 l 0,-70 70,0 0,140 -70,0 z"</string>
+ <string name="twoLinePathData">"M 0,0 v 100 M 0,0 h 100"</string>
+ <string name="triangle"> "M300,70 l 0,-70 70,70 0,0 -70,70z"</string>
+ <string name="rectangle">"M300,70 l 0,-70 70,0 0,140 -70,0 z"</string>
+ <string name="rectangle2">"M300,70 l 0,-70 70,0 0,70z M300,70 l 70,0 0,70 -70,0z"</string>
+ <string name="equal2"> "M300,35 l 0,-35 70,0 0,35z M300,105 l 70,0 0,35 -70,0z"</string>
+ <string name="round_box">"m2.10001,-6c-1.9551,0 -0.5,0.02499 -2.10001,0.02499c-1.575,0 0.0031,-0.02499 -1.95,-0.02499c-2.543,0 -4,2.2816 -4,4.85001c0,3.52929 0.25,6.25 5.95,6.25c5.7,0 6,-2.72071 6,-6.25c0,-2.56841 -1.35699,-4.85001 -3.89999,-4.85001"</string>
+ <string name="heart"> "m4.5,-7c-1.95509,0 -3.83009,1.26759 -4.5,3c-0.66991,-1.73241 -2.54691,-3 -4.5,-3c-2.543,0 -4.5,1.93159 -4.5,4.5c0,3.5293 3.793,6.2578 9,11.5c5.207,-5.2422 9,-7.9707 9,-11.5c0,-2.56841 -1.957,-4.5 -4.5,-4.5"</string>
- <string name="rectangle2" >"M300,70 l 0,-70 70,0 0,70z M300,70 l 70,0 0,70 -70,0z"</string>
- <string name="equal2" > "M300,35 l 0,-35 70,0 0,35z M300,105 l 70,0 0,35 -70,0z"</string>
-
-</resources>
+</resources>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
index 6e864fa..b1ba0dd 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableTest.java
@@ -19,24 +19,43 @@
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
+import android.widget.GridLayout;
+import android.widget.ScrollView;
-public class AnimatedVectorDrawableTest extends Activity {
- private static final String LOGCAT = "VectorDrawableAnimationTest";
+public class AnimatedVectorDrawableTest extends Activity implements View.OnClickListener{
+ private static final String LOGCAT = "AnimatedVectorDrawableTest";
+
+ protected int[] icon = {
+ R.drawable.animation_vector_drawable_grouping_1,
+ R.drawable.animation_vector_progress_bar,
+ R.drawable.animation_vector_drawable_favorite,
+ R.drawable.animation_vector_drawable01,
+ };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Button button = new Button(this);
- button.setBackgroundResource(R.drawable.animation_vector_drawable01);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- AnimatedVectorDrawable frameAnimation = (AnimatedVectorDrawable) v.getBackground();
- frameAnimation.start();
- }
- });
+ ScrollView scrollView = new ScrollView(this);
+ GridLayout container = new GridLayout(this);
+ scrollView.addView(container);
+ container.setColumnCount(1);
- setContentView(button);
+ for (int i = 0; i < icon.length; i++) {
+ Button button = new Button(this);
+ button.setWidth(400);
+ button.setHeight(400);
+ button.setBackgroundResource(icon[i]);
+ container.addView(button);
+ button.setOnClickListener(this);
+ }
+
+ setContentView(scrollView);
+ }
+
+ @Override
+ public void onClick(View v) {
+ AnimatedVectorDrawable d = (AnimatedVectorDrawable) v.getBackground();
+ d.start();
}
}
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 816033e..5fefab6 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -819,6 +819,7 @@
bool hasCameraSecureActivity = false;
bool hasLauncher = false;
bool hasNotificationListenerService = false;
+ bool hasDreamService = false;
bool actMainActivity = false;
bool actWidgetReceivers = false;
@@ -831,6 +832,7 @@
bool actOffHostApduService = false;
bool actDocumentsProvider = false;
bool actNotificationListenerService = false;
+ bool actDreamService = false;
bool actCamera = false;
bool actCameraSecure = false;
bool catLauncher = false;
@@ -846,6 +848,7 @@
bool hasBindNfcServicePermission = false;
bool hasRequiredSafAttributes = false;
bool hasBindNotificationListenerServicePermission = false;
+ bool hasBindDreamServicePermission = false;
// These two implement the implicit permissions that are granted
// to pre-1.6 applications.
@@ -1007,6 +1010,7 @@
hasPrintService |= (actPrintService && hasBindPrintServicePermission);
hasNotificationListenerService |= actNotificationListenerService &&
hasBindNotificationListenerServicePermission;
+ hasDreamService |= actDreamService && hasBindDreamServicePermission;
hasOtherServices |= (!actImeService && !actWallpaperService &&
!actAccessibilityService && !actPrintService &&
!actHostApduService && !actOffHostApduService &&
@@ -1389,6 +1393,7 @@
hasBindNfcServicePermission = false;
hasRequiredSafAttributes = false;
hasBindNotificationListenerServicePermission = false;
+ hasBindDreamServicePermission = false;
if (withinApplication) {
if(tag == "activity") {
withinActivity = true;
@@ -1486,6 +1491,8 @@
hasBindNfcServicePermission = true;
} else if (permission == "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") {
hasBindNotificationListenerServicePermission = true;
+ } else if (permission == "android.permission.BIND_DREAM_SERVICE") {
+ hasBindDreamServicePermission = true;
}
} else {
fprintf(stderr, "ERROR getting 'android:permission' attribute for"
@@ -1569,6 +1576,7 @@
actOffHostApduService = false;
actDocumentsProvider = false;
actNotificationListenerService = false;
+ actDreamService = false;
actCamera = false;
actCameraSecure = false;
catLauncher = false;
@@ -1654,6 +1662,8 @@
actOffHostApduService = true;
} else if (action == "android.service.notification.NotificationListenerService") {
actNotificationListenerService = true;
+ } else if (action == "android.service.dreams.DreamService") {
+ actDreamService = true;
}
} else if (withinProvider) {
if (action == "android.content.action.DOCUMENTS_PROVIDER") {
@@ -1889,6 +1899,9 @@
if (hasNotificationListenerService) {
printComponentPresence("notification-listener");
}
+ if (hasDreamService) {
+ printComponentPresence("dream");
+ }
if (hasCameraActivity) {
printComponentPresence("camera");
}