Merge "Import translations. DO NOT MERGE"
diff --git a/api/current.txt b/api/current.txt
index c078189..9f39da5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -246,6 +246,7 @@
field public static final int actionBarTabBarStyle = 16843508; // 0x10102f4
field public static final int actionBarTabStyle = 16843507; // 0x10102f3
field public static final int actionBarTabTextStyle = 16843509; // 0x10102f5
+ field public static final int actionBarTheme = 16843836; // 0x101043c
field public static final int actionBarWidgetTheme = 16843671; // 0x1010397
field public static final int actionButtonStyle = 16843480; // 0x10102d8
field public static final int actionDropDownStyle = 16843479; // 0x10102d7
@@ -1020,6 +1021,7 @@
field public static final int shrinkColumns = 16843082; // 0x101014a
field public static final deprecated int singleLine = 16843101; // 0x101015d
field public static final int singleUser = 16843711; // 0x10103bf
+ field public static final int slideEdge = 16843835; // 0x101043b
field public static final int smallIcon = 16843422; // 0x101029e
field public static final int smallScreens = 16843396; // 0x1010284
field public static final int smoothScrollbar = 16843313; // 0x1010231
@@ -3150,6 +3152,7 @@
method public void finishActivityFromChild(android.app.Activity, int);
method public void finishAffinity();
method public void finishFromChild(android.app.Activity);
+ method public void finishWithTransition();
method public android.app.ActionBar getActionBar();
method public final android.app.Application getApplication();
method public android.content.ComponentName getCallingActivity();
@@ -10991,7 +10994,6 @@
method public void setRepeatMode(int);
method public void start();
method public void stop();
- field public static final int INFINITE = -1; // 0xffffffff
}
}
@@ -27406,6 +27408,16 @@
method public void setResizeClip(boolean);
}
+ public class CircularPropagation extends android.transition.VisibilityPropagation {
+ ctor public CircularPropagation();
+ method public long getStartDelay(android.view.ViewGroup, android.transition.Transition, android.transition.TransitionValues, android.transition.TransitionValues);
+ method public void setPropagationSpeed(float);
+ }
+
+ public class Explode extends android.transition.Visibility {
+ ctor public Explode();
+ }
+
public class Fade extends android.transition.Visibility {
ctor public Fade();
ctor public Fade(int);
@@ -27413,6 +27425,12 @@
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);
@@ -27425,6 +27443,27 @@
method public void setExitAction(java.lang.Runnable);
}
+ public class SidePropagation extends android.transition.VisibilityPropagation {
+ ctor public SidePropagation();
+ method public long getStartDelay(android.view.ViewGroup, android.transition.Transition, android.transition.TransitionValues, android.transition.TransitionValues);
+ method public void setPropagationSpeed(float);
+ method public void setSide(int);
+ field public static final int BOTTOM = 3; // 0x3
+ field public static final int LEFT = 0; // 0x0
+ field public static final int RIGHT = 2; // 0x2
+ field public static final int TOP = 1; // 0x1
+ }
+
+ public class Slide extends android.transition.Visibility {
+ ctor public Slide();
+ ctor public Slide(int);
+ method public void setSlideEdge(int);
+ field public static final int BOTTOM = 3; // 0x3
+ field public static final int LEFT = 0; // 0x0
+ field public static final int RIGHT = 2; // 0x2
+ field public static final int TOP = 1; // 0x1
+ }
+
public abstract class Transition implements java.lang.Cloneable {
ctor public Transition();
method public android.transition.Transition addListener(android.transition.Transition.TransitionListener);
@@ -27442,8 +27481,11 @@
method public android.transition.Transition excludeTarget(android.view.View, boolean);
method public android.transition.Transition excludeTarget(java.lang.Class, boolean);
method public long getDuration();
+ method public android.graphics.Rect getEpicenter();
+ method public android.transition.Transition.EpicenterCallback getEpicenterCallback();
method public android.animation.TimeInterpolator getInterpolator();
method public java.lang.String getName();
+ method public android.transition.TransitionPropagation getPropagation();
method public long getStartDelay();
method public java.util.List<java.lang.Integer> getTargetIds();
method public java.util.List<android.view.View> getTargets();
@@ -27453,10 +27495,17 @@
method public android.transition.Transition removeTarget(int);
method public android.transition.Transition removeTarget(android.view.View);
method public android.transition.Transition setDuration(long);
+ method public void setEpicenterCallback(android.transition.Transition.EpicenterCallback);
method public android.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+ method public void setPropagation(android.transition.TransitionPropagation);
method public android.transition.Transition setStartDelay(long);
}
+ public static abstract class Transition.EpicenterCallback {
+ ctor public Transition.EpicenterCallback();
+ method public abstract android.graphics.Rect getEpicenter(android.transition.Transition);
+ }
+
public static abstract interface Transition.TransitionListener {
method public abstract void onTransitionCancel(android.transition.Transition);
method public abstract void onTransitionEnd(android.transition.Transition);
@@ -27483,6 +27532,13 @@
method public void transitionTo(android.transition.Scene);
}
+ public abstract class TransitionPropagation {
+ ctor public TransitionPropagation();
+ method public abstract void captureValues(android.transition.TransitionValues);
+ method public abstract java.lang.String[] getPropagationProperties();
+ method public abstract long getStartDelay(android.view.ViewGroup, android.transition.Transition, android.transition.TransitionValues, android.transition.TransitionValues);
+ }
+
public class TransitionSet extends android.transition.Transition {
ctor public TransitionSet();
method public android.transition.TransitionSet addTransition(android.transition.Transition);
@@ -27507,7 +27563,18 @@
method public void captureStartValues(android.transition.TransitionValues);
method public boolean isVisible(android.transition.TransitionValues);
method public android.animation.Animator onAppear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+ 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);
+ }
+
+ public abstract class VisibilityPropagation extends android.transition.TransitionPropagation {
+ ctor public VisibilityPropagation();
+ method public void captureValues(android.transition.TransitionValues);
+ method public java.lang.String[] getPropagationProperties();
+ method public int getViewVisibility(android.transition.TransitionValues);
+ method public int getViewX(android.transition.TransitionValues);
+ method public int getViewY(android.transition.TransitionValues);
}
}
@@ -30460,6 +30527,8 @@
method public boolean requestFeature(int);
method public abstract void restoreHierarchyState(android.os.Bundle);
method public abstract android.os.Bundle saveHierarchyState();
+ method public void setAllowOverlappingEnterTransition(boolean);
+ method public void setAllowOverlappingExitTransition(boolean);
method public void setAttributes(android.view.WindowManager.LayoutParams);
method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable);
method public void setBackgroundDrawableResource(int);
@@ -30488,7 +30557,6 @@
method public abstract void setTitle(java.lang.CharSequence);
method public abstract deprecated void setTitleColor(int);
method public void setTransitionManager(android.transition.TransitionManager);
- method public void setTriggerEarlyEnterTransition(boolean);
method public void setType(int);
method public void setUiOptions(int);
method public void setUiOptions(int, int);
diff --git a/core/java/android/alsa/AlsaCardsParser.java b/core/java/android/alsa/AlsaCardsParser.java
deleted file mode 100644
index f9af979..0000000
--- a/core/java/android/alsa/AlsaCardsParser.java
+++ /dev/null
@@ -1,116 +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 com.android.alsascan;
-
-import android.util.Slog;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Vector;
-
-/**
- * @hide Retrieves information from an ALSA "cards" file.
- */
-public class AlsaCardsParser {
- private static final String TAG = "AlsaCardsParser";
-
- private static LineTokenizer tokenizer_ = new LineTokenizer(" :[]");
-
- public class AlsaCardRecord {
- public int mCardNum = -1;
- public String mField1 = "";
- public String mCardName = "";
- public String mCardDescription = "";
-
- public AlsaCardRecord() {}
-
- public boolean parse(String line, int lineIndex) {
- int tokenIndex = 0;
- int delimIndex = 0;
- if (lineIndex == 0) {
- // line # (skip)
- tokenIndex = tokenizer_.nextToken(line, tokenIndex);
- delimIndex = tokenizer_.nextDelimiter(line, tokenIndex);
-
- // mField1
- tokenIndex = tokenizer_.nextToken(line, delimIndex);
- delimIndex = tokenizer_.nextDelimiter(line, tokenIndex);
- mField1 = line.substring(tokenIndex, delimIndex);
-
- // mCardName
- tokenIndex = tokenizer_.nextToken(line, delimIndex);
- // delimIndex = tokenizer_.nextDelimiter(line, tokenIndex);
- mCardName = line.substring(tokenIndex);
- // done
- } else if (lineIndex == 1) {
- tokenIndex = tokenizer_.nextToken(line, 0);
- if (tokenIndex != -1) {
- mCardDescription = line.substring(tokenIndex);
- }
- }
-
- return true;
- }
-
- public String textFormat() {
- return mCardName + " : " + mCardDescription;
- }
- }
-
- private Vector<AlsaCardRecord> cardRecords_ = new Vector<AlsaCardRecord>();
-
- public void scan() {
- cardRecords_.clear();
- final String cardsFilePath = "/proc/asound/cards";
- File cardsFile = new File(cardsFilePath);
- try {
- FileReader reader = new FileReader(cardsFile);
- BufferedReader bufferedReader = new BufferedReader(reader);
- String line = "";
- while ((line = bufferedReader.readLine()) != null) {
- AlsaCardRecord cardRecord = new AlsaCardRecord();
- cardRecord.parse(line, 0);
- cardRecord.parse(line = bufferedReader.readLine(), 1);
- cardRecords_.add(cardRecord);
- }
- reader.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public AlsaCardRecord getCardRecordAt(int index) {
- return cardRecords_.get(index);
- }
-
- public int getNumCardRecords() {
- return cardRecords_.size();
- }
-
- public void Log() {
- int numCardRecs = getNumCardRecords();
- for (int index = 0; index < numCardRecs; ++index) {
- Slog.w(TAG, "usb:" + getCardRecordAt(index).textFormat());
- }
- }
-
- public AlsaCardsParser() {}
-}
diff --git a/core/java/android/alsa/AlsaDevicesParser.java b/core/java/android/alsa/AlsaDevicesParser.java
deleted file mode 100644
index 3835942..0000000
--- a/core/java/android/alsa/AlsaDevicesParser.java
+++ /dev/null
@@ -1,240 +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 com.android.alsascan;
-
-import android.util.Slog;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Vector;
-
-/**
- * @hide
- * Retrieves information from an ALSA "devices" file.
- */
-public class AlsaDevicesParser {
- private static final String TAG = "AlsaDevicesParser";
-
- private static final int kIndex_CardDeviceField = 5;
- private static final int kStartIndex_CardNum = 6;
- private static final int kEndIndex_CardNum = 8; // one past
- private static final int kStartIndex_DeviceNum = 9;
- private static final int kEndIndex_DeviceNum = 11; // one past
- private static final int kStartIndex_Type = 14;
-
- private static LineTokenizer mTokenizer = new LineTokenizer(" :[]-");
-
- private boolean mHasCaptureDevices = false;
- private boolean mHasPlaybackDevices = false;
- private boolean mHasMIDIDevices = false;
-
- public class AlsaDeviceRecord {
- public static final int kDeviceType_Unknown = -1;
- public static final int kDeviceType_Audio = 0;
- public static final int kDeviceType_Control = 1;
- public static final int kDeviceType_MIDI = 2;
-
- public static final int kDeviceDir_Unknown = -1;
- public static final int kDeviceDir_Capture = 0;
- public static final int kDeviceDir_Playback = 1;
-
- int mCardNum = -1;
- int mDeviceNum = -1;
- int mDeviceType = kDeviceType_Unknown;
- int mDeviceDir = kDeviceDir_Unknown;
-
- public AlsaDeviceRecord() {
- }
-
- public boolean parse(String line) {
- // "0123456789012345678901234567890"
- // " 2: [ 0-31]: digital audio playback"
- // " 3: [ 0-30]: digital audio capture"
- // " 35: [ 1] : control"
- // " 36: [ 2- 0]: raw midi"
-
- final int kToken_LineNum = 0;
- final int kToken_CardNum = 1;
- final int kToken_DeviceNum = 2;
- final int kToken_Type0 = 3; // "digital", "control", "raw"
- final int kToken_Type1 = 4; // "audio", "midi"
- final int kToken_Type2 = 5; // "capture", "playback"
-
- int tokenOffset = 0;
- int delimOffset = 0;
- int tokenIndex = kToken_LineNum;
- while (true) {
- tokenOffset = mTokenizer.nextToken(line, delimOffset);
- if (tokenOffset == LineTokenizer.kTokenNotFound) {
- break; // bail
- }
- delimOffset = mTokenizer.nextDelimiter(line, tokenOffset);
- if (delimOffset == LineTokenizer.kTokenNotFound) {
- delimOffset = line.length();
- }
- String token = line.substring(tokenOffset, delimOffset);
-
- switch (tokenIndex) {
- case kToken_LineNum:
- // ignore
- break;
-
- case kToken_CardNum:
- mCardNum = Integer.parseInt(token);
- if (line.charAt(delimOffset) != '-') {
- tokenIndex++; // no device # in the token stream
- }
- break;
-
- case kToken_DeviceNum:
- mDeviceNum = Integer.parseInt(token);
- break;
-
- case kToken_Type0:
- if (token.equals("digital")) {
- // NOP
- } else if (token.equals("control")) {
- mDeviceType = kDeviceType_Control;
- } else if (token.equals("raw")) {
- // NOP
- }
- break;
-
- case kToken_Type1:
- if (token.equals("audio")) {
- mDeviceType = kDeviceType_Audio;
- } else if (token.equals("midi")) {
- mDeviceType = kDeviceType_MIDI;
- mHasMIDIDevices = true;
- }
- break;
-
- case kToken_Type2:
- if (token.equals("capture")) {
- mDeviceDir = kDeviceDir_Capture;
- mHasCaptureDevices = true;
- } else if (token.equals("playback")) {
- mDeviceDir = kDeviceDir_Playback;
- mHasPlaybackDevices = true;
- }
- break;
- } // switch (tokenIndex)
-
- tokenIndex++;
- } // while (true)
-
- return true;
- } // parse()
-
- public String textFormat() {
- StringBuilder sb = new StringBuilder();
- sb.append("[" + mCardNum + ":" + mDeviceNum + "]");
-
- switch (mDeviceType) {
- case kDeviceType_Unknown:
- sb.append(" N/A");
- break;
- case kDeviceType_Audio:
- sb.append(" Audio");
- break;
- case kDeviceType_Control:
- sb.append(" Control");
- break;
- case kDeviceType_MIDI:
- sb.append(" MIDI");
- break;
- }
-
- switch (mDeviceDir) {
- case kDeviceDir_Unknown:
- sb.append(" N/A");
- break;
- case kDeviceDir_Capture:
- sb.append(" Capture");
- break;
- case kDeviceDir_Playback:
- sb.append(" Playback");
- break;
- }
-
- return sb.toString();
- }
- }
-
- private Vector<AlsaDeviceRecord>
- deviceRecords_ = new Vector<AlsaDeviceRecord>();
-
- private boolean isLineDeviceRecord(String line) {
- return line.charAt(kIndex_CardDeviceField) == '[';
- }
-
- public AlsaDevicesParser() {
- }
-
- public int getNumDeviceRecords() {
- return deviceRecords_.size();
- }
-
- public AlsaDeviceRecord getDeviceRecordAt(int index) {
- return deviceRecords_.get(index);
- }
-
- public void Log() {
- int numDevRecs = getNumDeviceRecords();
- for (int index = 0; index < numDevRecs; ++index) {
- Slog.w(TAG, "usb:" + getDeviceRecordAt(index).textFormat());
- }
- }
-
- public boolean hasPlaybackDevices() {
- return mHasPlaybackDevices;
- }
-
- public boolean hasCaptureDevices() {
- return mHasCaptureDevices;
- }
-
- public boolean hasMIDIDevices() {
- return mHasMIDIDevices;
- }
-
- public void scan() {
- deviceRecords_.clear();
-
- final String devicesFilePath = "/proc/asound/devices";
- File devicesFile = new File(devicesFilePath);
- try {
- FileReader reader = new FileReader(devicesFile);
- BufferedReader bufferedReader = new BufferedReader(reader);
- String line = "";
- while ((line = bufferedReader.readLine()) != null) {
- if (isLineDeviceRecord(line)) {
- AlsaDeviceRecord deviceRecord = new AlsaDeviceRecord();
- deviceRecord.parse(line);
- deviceRecords_.add(deviceRecord);
- }
- }
- reader.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-} // class AlsaDevicesParser
-
diff --git a/core/java/android/alsa/LineTokenizer.java b/core/java/android/alsa/LineTokenizer.java
deleted file mode 100644
index c138fc5..0000000
--- a/core/java/android/alsa/LineTokenizer.java
+++ /dev/null
@@ -1,57 +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 com.android.alsascan;
-
-/**
- * @hide
- * Breaks lines in an ALSA "cards" or "devices" file into tokens.
- * TODO(pmclean) Look into replacing this with String.split().
- */
-public class LineTokenizer {
- public static final int kTokenNotFound = -1;
-
- private String mDelimiters = "";
-
- public LineTokenizer(String delimiters) {
- mDelimiters = delimiters;
- }
-
- int nextToken(String line, int startIndex) {
- int len = line.length();
- int offset = startIndex;
- for (; offset < len; offset++) {
- if (mDelimiters.indexOf(line.charAt(offset)) == -1) {
- // past a delimiter
- break;
- }
- }
-
- return offset < len ? offset : kTokenNotFound;
- }
-
- int nextDelimiter(String line, int startIndex) {
- int len = line.length();
- int offset = startIndex;
- for (; offset < len; offset++) {
- if (mDelimiters.indexOf(line.charAt(offset)) != -1) {
- // past a delimiter
- break;
- }
- }
-
- return offset < len ? offset : kTokenNotFound;
- }
-}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index e8fdcaf..b18eb98 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -21,7 +21,6 @@
import android.transition.Transition;
import android.transition.TransitionManager;
import android.util.ArrayMap;
-import android.util.Pair;
import android.util.SuperNotCalledException;
import android.widget.Toolbar;
import com.android.internal.app.WindowDecorActionBar;
@@ -774,7 +773,6 @@
private Thread mUiThread;
final Handler mHandler = new Handler();
- private ActivityOptions mTransitionActivityOptions;
/** Return the intent that started this activity. */
public Intent getIntent() {
@@ -1400,6 +1398,9 @@
protected void onStop() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
+ if (mWindow != null) {
+ mWindow.restoreViewVisibilityAfterTransitionToCallee();
+ }
getApplication().dispatchActivityStopped(this);
mTranslucentCallback = null;
mCalled = true;
@@ -2300,7 +2301,7 @@
*/
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
- finish();
+ finishWithTransition();
}
}
@@ -3483,8 +3484,7 @@
public void startActivityForResult(Intent intent, int requestCode) {
Bundle options = null;
if (mWindow.hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
- final Pair<View, String>[] noSharedElements = null;
- options = ActivityOptions.makeSceneTransitionAnimation(noSharedElements).toBundle();
+ options = ActivityOptions.makeSceneTransitionAnimation().toBundle();
}
startActivityForResult(intent, requestCode, options);
}
@@ -3532,7 +3532,7 @@
mActionBar.captureSharedElements(sharedElementMap);
activityOptions.addSharedElements(sharedElementMap);
}
- options = mWindow.startExitTransition(activityOptions);
+ options = mWindow.startExitTransitionToCallee(options);
}
}
if (mParent == null) {
@@ -4387,6 +4387,23 @@
}
/**
+ * Reverses the Activity Scene entry Transition and triggers the calling Activity
+ * to reverse its exit Transition. When the exit Transition completes,
+ * {@link #finish()} is called. If no entry Transition was used, finish() is called
+ * immediately and the Activity exit Transition is run.
+ * @see android.view.Window#setTriggerEarlySceneTransition(boolean, boolean)
+ * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.view.View, String)
+ */
+ public void finishWithTransition() {
+ mWindow.startExitTransitionToCaller(new Runnable() {
+ @Override
+ public void run() {
+ finish();
+ }
+ });
+ }
+
+ /**
* Force finish another activity that you had previously started with
* {@link #startActivityForResult}.
*
@@ -5396,43 +5413,34 @@
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
- mTransitionActivityOptions = null;
- Window.SceneTransitionListener sceneTransitionListener = null;
- if (options != null) {
- ActivityOptions activityOptions = new ActivityOptions(options);
- if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
- mTransitionActivityOptions = activityOptions;
- sceneTransitionListener = new Window.SceneTransitionListener() {
- @Override
- public void nullPendingTransition() {
- overridePendingTransition(0, 0);
- }
-
- @Override
- public void convertFromTranslucent() {
- Activity.this.convertFromTranslucent();
- }
-
- @Override
- public void convertToTranslucent() {
- Activity.this.convertToTranslucent(null);
- }
-
- @Override
- public void sharedElementStart(Transition transition) {
- Activity.this.onCaptureSharedElementStart(transition);
- }
-
- @Override
- public void sharedElementEnd() {
- Activity.this.onCaptureSharedElementEnd();
- }
- };
-
+ Window.SceneTransitionListener sceneTransitionListener
+ = new Window.SceneTransitionListener() {
+ @Override
+ public void nullPendingTransition() {
+ overridePendingTransition(0, 0);
}
- }
- mWindow.setTransitionOptions(mTransitionActivityOptions, sceneTransitionListener);
+ @Override
+ public void convertFromTranslucent() {
+ Activity.this.convertFromTranslucent();
+ }
+
+ @Override
+ public void convertToTranslucent() {
+ Activity.this.convertToTranslucent(null);
+ }
+
+ @Override
+ public void sharedElementStart(Transition transition) {
+ Activity.this.onCaptureSharedElementStart(transition);
+ }
+
+ @Override
+ public void sharedElementEnd() {
+ Activity.this.onCaptureSharedElementEnd();
+ }
+ };
+ mWindow.setTransitionOptions(options, sceneTransitionListener);
}
/** @hide */
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 07247ff..4384580 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -20,8 +20,10 @@
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
+import android.os.ResultReceiver;
import android.transition.Transition;
import android.util.Log;
import android.util.Pair;
@@ -136,6 +138,11 @@
/** @hide */
public static final int ANIM_SCENE_TRANSITION = 5;
+ private static final int MSG_SET_LISTENER = 100;
+ private static final int MSG_HIDE_SHARED_ELEMENTS = 101;
+ private static final int MSG_PREPARE_RESTORE = 102;
+ private static final int MSG_RESTORE = 103;
+
private String mPackageName;
private int mAnimationType = ANIM_NONE;
private int mCustomEnterResId;
@@ -146,7 +153,7 @@
private int mStartWidth;
private int mStartHeight;
private IRemoteCallback mAnimationStartedListener;
- private IRemoteCallback mTransitionCompleteListener;
+ private ResultReceiver mTransitionCompleteListener;
private ArrayList<String> mSharedElementNames;
private ArrayList<String> mLocalElementNames;
@@ -428,8 +435,7 @@
break;
case ANIM_SCENE_TRANSITION:
- mTransitionCompleteListener = IRemoteCallback.Stub.asInterface(
- opts.getBinder(KEY_TRANSITION_COMPLETE_LISTENER));
+ mTransitionCompleteListener = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
mSharedElementNames = opts.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
mLocalElementNames = opts.getStringArrayList(KEY_LOCAL_ELEMENT_NAMES);
break;
@@ -495,7 +501,6 @@
/** @hide */
public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target,
ArrayList<String> sharedElementNames) {
- boolean listenerSent = false;
if (mTransitionCompleteListener != null) {
IRemoteCallback callback = new IRemoteCallback.Stub() {
@Override
@@ -510,27 +515,28 @@
Bundle bundle = new Bundle();
bundle.putBinder(KEY_TRANSITION_TARGET_LISTENER, callback.asBinder());
bundle.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, sharedElementNames);
- try {
- mTransitionCompleteListener.sendResult(bundle);
- listenerSent = true;
- } catch (RemoteException e) {
- Log.w(TAG, "Couldn't retrieve transition notifications", e);
- }
- }
- if (!listenerSent) {
- target.sharedElementTransitionComplete(null);
- target.exitTransitionComplete();
+ mTransitionCompleteListener.send(MSG_SET_LISTENER, bundle);
}
}
/** @hide */
public void dispatchSharedElementsReady() {
if (mTransitionCompleteListener != null) {
- try {
- mTransitionCompleteListener.sendResult(null);
- } catch (RemoteException e) {
- Log.w(TAG, "Couldn't synchronize shared elements", e);
- }
+ mTransitionCompleteListener.send(MSG_HIDE_SHARED_ELEMENTS, null);
+ }
+ }
+
+ /** @hide */
+ public void dispatchPrepareRestore() {
+ if (mTransitionCompleteListener != null) {
+ mTransitionCompleteListener.send(MSG_PREPARE_RESTORE, null);
+ }
+ }
+
+ /** @hide */
+ public void dispatchRestore(Bundle sharedElementsArgs) {
+ if (mTransitionCompleteListener != null) {
+ mTransitionCompleteListener.send(MSG_RESTORE, sharedElementsArgs);
}
}
@@ -658,8 +664,7 @@
case ANIM_SCENE_TRANSITION:
b.putInt(KEY_ANIM_TYPE, mAnimationType);
if (mTransitionCompleteListener != null) {
- b.putBinder(KEY_TRANSITION_COMPLETE_LISTENER,
- mTransitionCompleteListener.asBinder());
+ b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionCompleteListener);
}
b.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, mSharedElementNames);
b.putStringArrayList(KEY_LOCAL_ELEMENT_NAMES, mLocalElementNames);
@@ -710,13 +715,13 @@
Bundle getSharedElementExitState();
void acceptedSharedElements(ArrayList<String> sharedElementNames);
void hideSharedElements();
+ void restore(Bundle sharedElementState);
+ void prepareForRestore();
}
- private static class ExitTransitionListener extends IRemoteCallback.Stub
+ private static class ExitTransitionListener extends ResultReceiver
implements Transition.TransitionListener {
private boolean mSharedElementNotified;
- private Transition mExitTransition;
- private Transition mSharedElementTransition;
private IRemoteCallback mTransitionCompleteCallback;
private boolean mExitComplete;
private boolean mSharedElementComplete;
@@ -724,25 +729,40 @@
public ExitTransitionListener(Transition exitTransition, Transition sharedElementTransition,
SharedElementSource sharedElementSource) {
+ super(null);
mSharedElementSource = sharedElementSource;
- mExitTransition = exitTransition;
- mExitTransition.addListener(this);
- mSharedElementTransition = sharedElementTransition;
- mSharedElementTransition.addListener(this);
+ exitTransition.addListener(this);
+ sharedElementTransition.addListener(new Transition.TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ mSharedElementComplete = true;
+ notifySharedElement();
+ transition.removeListener(this);
+ }
+ });
}
@Override
- public void sendResult(Bundle data) throws RemoteException {
- if (data != null) {
- mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(
- data.getBinder(KEY_TRANSITION_TARGET_LISTENER));
- ArrayList<String> sharedElementNames
- = data.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
- mSharedElementSource.acceptedSharedElements(sharedElementNames);
- notifySharedElement();
- notifyExit();
- } else {
- mSharedElementSource.hideSharedElements();
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ switch (resultCode) {
+ case MSG_SET_LISTENER:
+ IBinder listener = resultData.getBinder(KEY_TRANSITION_TARGET_LISTENER);
+ mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(listener);
+ ArrayList<String> sharedElementNames
+ = resultData.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
+ mSharedElementSource.acceptedSharedElements(sharedElementNames);
+ notifySharedElement();
+ notifyExit();
+ break;
+ case MSG_HIDE_SHARED_ELEMENTS:
+ mSharedElementSource.hideSharedElements();
+ break;
+ case MSG_PREPARE_RESTORE:
+ mSharedElementSource.prepareForRestore();
+ break;
+ case MSG_RESTORE:
+ mSharedElementSource.restore(resultData);
+ break;
}
}
@@ -752,15 +772,9 @@
@Override
public void onTransitionEnd(Transition transition) {
- if (transition == mExitTransition) {
- mExitComplete = true;
- notifyExit();
- mExitTransition.removeListener(this);
- } else {
- mSharedElementComplete = true;
- notifySharedElement();
- mSharedElementTransition.removeListener(this);
- }
+ mExitComplete = true;
+ notifyExit();
+ transition.removeListener(this);
}
@Override
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index d6eafc6..4879c23 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1585,6 +1585,15 @@
/** Resource identifier for the theme. */
private int mThemeResId = 0;
+
+ // Needed by layoutlib.
+ /*package*/ long getNativeTheme() {
+ return mTheme;
+ }
+
+ /*package*/ int getAppliedStyleResId() {
+ return mThemeResId;
+ }
}
/**
diff --git a/core/java/android/transition/CircularPropagation.java b/core/java/android/transition/CircularPropagation.java
new file mode 100644
index 0000000..18a3d22
--- /dev/null
+++ b/core/java/android/transition/CircularPropagation.java
@@ -0,0 +1,103 @@
+/*
+ * 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.graphics.Rect;
+import android.util.FloatMath;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A propagation that varies with the distance to the epicenter of the Transition
+ * or center of the scene if no epicenter exists. When a View is visible in the
+ * start of the transition, Views farther from the epicenter will transition
+ * sooner than Views closer to the epicenter. When a View is not in the start
+ * of the transition or is not visible at the start of the transition, it will
+ * transition sooner when closer to the epicenter and later when farther from
+ * the epicenter. This is the default TransitionPropagation used with
+ * {@link android.transition.Explode}.
+ */
+public class CircularPropagation extends VisibilityPropagation {
+ private static final String TAG = "CircularPropagation";
+
+ private float mPropagationSpeed = 4.0f;
+
+ /**
+ * Sets the speed at which transition propagation happens, relative to the duration of the
+ * Transition. A <code>propagationSpeed</code> of 1 means that a View centered farthest from
+ * the epicenter and View centered at the epicenter will have a difference
+ * in start delay of approximately the duration of the Transition. A speed of 2 means the
+ * start delay difference will be approximately half of the duration of the transition. A
+ * value of 0 is illegal, but negative values will invert the propagation.
+ *
+ * @param propagationSpeed The speed at which propagation occurs, relative to the duration
+ * of the transition. A speed of 4 means it works 4 times as fast
+ * as the duration of the transition. May not be 0.
+ */
+ public void setPropagationSpeed(float propagationSpeed) {
+ if (propagationSpeed == 0) {
+ throw new IllegalArgumentException("propagationSpeed may not be 0");
+ }
+ mPropagationSpeed = propagationSpeed;
+ }
+
+ @Override
+ public long getStartDelay(ViewGroup sceneRoot, Transition transition,
+ TransitionValues startValues, TransitionValues endValues) {
+ if (startValues == null && endValues == null) {
+ return 0;
+ }
+ int directionMultiplier = 1;
+ TransitionValues positionValues;
+ if (endValues == null || getViewVisibility(startValues) == View.VISIBLE) {
+ positionValues = startValues;
+ directionMultiplier = -1;
+ } else {
+ positionValues = endValues;
+ }
+
+ int viewCenterX = getViewX(positionValues);
+ int viewCenterY = getViewY(positionValues);
+
+ Rect epicenter = transition.getEpicenter();
+ int epicenterX;
+ int epicenterY;
+ if (epicenter != null) {
+ epicenterX = epicenter.centerX();
+ epicenterY = epicenter.centerY();
+ } else {
+ int[] loc = new int[2];
+ sceneRoot.getLocationOnScreen(loc);
+ epicenterX = Math.round(loc[0] + (sceneRoot.getWidth() / 2)
+ + sceneRoot.getTranslationX());
+ epicenterY = Math.round(loc[1] + (sceneRoot.getHeight() / 2)
+ + sceneRoot.getTranslationY());
+ }
+ float distance = distance(viewCenterX, viewCenterY, epicenterX, epicenterY);
+ float maxDistance = distance(0, 0, sceneRoot.getWidth(), sceneRoot.getHeight());
+ float distanceFraction = distance/maxDistance;
+
+ return Math.round(transition.getDuration() * directionMultiplier / mPropagationSpeed
+ * distanceFraction);
+ }
+
+ private static float distance(float x1, float y1, float x2, float y2) {
+ float x = x2 - x1;
+ float y = y2 - y1;
+ return FloatMath.sqrt((x * x) + (y * y));
+ }
+}
diff --git a/core/java/android/transition/Explode.java b/core/java/android/transition/Explode.java
new file mode 100644
index 0000000..fae527c
--- /dev/null
+++ b/core/java/android/transition/Explode.java
@@ -0,0 +1,228 @@
+/*
+ * 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.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.util.FloatMath;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+
+/**
+ * This transition tracks changes to the visibility of target views in the
+ * start and end scenes and moves views in or out from the edges of the
+ * scene. Visibility is determined by both the
+ * {@link View#setVisibility(int)} state of the view as well as whether it
+ * is parented in the current view hierarchy. Disappearing Views are
+ * limited as described in {@link Visibility#onDisappear(android.view.ViewGroup,
+ * TransitionValues, int, TransitionValues, int)}.
+ * <p>Views move away from the focal View or the center of the Scene if
+ * no epicenter was provided.</p>
+ */
+public class Explode extends Visibility {
+ private static final TimeInterpolator sDecelerate = new DecelerateInterpolator();
+ private static final TimeInterpolator sAccelerate = new AccelerateInterpolator();
+ private static final String TAG = "Explode";
+
+ private static final String PROPNAME_SCREEN_BOUNDS = "android:out:screenBounds";
+
+ private int[] mTempLoc = new int[2];
+
+ public Explode() {
+ setPropagation(new CircularPropagation());
+ }
+
+ private void captureValues(TransitionValues transitionValues) {
+ View view = transitionValues.view;
+ view.getLocationOnScreen(mTempLoc);
+ int left = mTempLoc[0] + Math.round(view.getTranslationX());
+ int top = mTempLoc[1] + Math.round(view.getTranslationY());
+ int right = left + view.getWidth();
+ int bottom = top + view.getHeight();
+ transitionValues.values.put(PROPNAME_SCREEN_BOUNDS, new Rect(left, top, right, bottom));
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ super.captureStartValues(transitionValues);
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ super.captureEndValues(transitionValues);
+ captureValues(transitionValues);
+ }
+
+ private Animator createAnimation(final View view, float startX, float startY, float endX,
+ float endY, float terminalX, float terminalY, TimeInterpolator interpolator) {
+ view.setTranslationX(startX);
+ view.setTranslationY(startY);
+ if (startY == endY && startX == endX) {
+ return null;
+ }
+ Path path = new Path();
+ path.moveTo(startX, startY);
+ path.lineTo(endX, endY);
+ ObjectAnimator pathAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X,
+ View.TRANSLATION_Y, path);
+ pathAnimator.setInterpolator(interpolator);
+ OutAnimatorListener listener = new OutAnimatorListener(view, terminalX, terminalY,
+ endX, endY);
+ pathAnimator.addListener(listener);
+ pathAnimator.addPauseListener(listener);
+
+ return pathAnimator;
+ }
+
+ @Override
+ public Animator onAppear(ViewGroup sceneRoot, View view,
+ TransitionValues startValues, TransitionValues endValues) {
+ if (endValues == null) {
+ return null;
+ }
+ Rect bounds = (Rect) endValues.values.get(PROPNAME_SCREEN_BOUNDS);
+ calculateOut(sceneRoot, bounds, mTempLoc);
+
+ final float endX = view.getTranslationX();
+ final float startX = endX + mTempLoc[0];
+ final float endY = view.getTranslationY();
+ final float startY = endY + mTempLoc[1];
+
+ return createAnimation(view, startX, startY, endX, endY, endX, endY, sDecelerate);
+ }
+
+ @Override
+ public Animator onDisappear(ViewGroup sceneRoot, View view,
+ TransitionValues startValues, TransitionValues endValues) {
+ Rect bounds = (Rect) startValues.values.get(PROPNAME_SCREEN_BOUNDS);
+ calculateOut(sceneRoot, bounds, mTempLoc);
+
+ final float startX = view.getTranslationX();
+ final float endX = startX + mTempLoc[0];
+ final float startY = view.getTranslationY();
+ final float endY = startY + mTempLoc[1];
+
+ return createAnimation(view, startX, startY, endX, endY, startX, startY,
+ sAccelerate);
+ }
+
+ private void calculateOut(View sceneRoot, Rect bounds, int[] outVector) {
+ sceneRoot.getLocationOnScreen(mTempLoc);
+ int sceneRootX = mTempLoc[0];
+ int sceneRootY = mTempLoc[1];
+ int focalX;
+ int focalY;
+
+ Rect epicenter = getEpicenter();
+ if (epicenter == null) {
+ focalX = sceneRootX + (sceneRoot.getWidth() / 2)
+ + Math.round(sceneRoot.getTranslationX());
+ focalY = sceneRootY + (sceneRoot.getHeight() / 2)
+ + Math.round(sceneRoot.getTranslationY());
+ } else {
+ focalX = epicenter.centerX();
+ focalY = epicenter.centerY();
+ }
+
+ int centerX = bounds.centerX();
+ int centerY = bounds.centerY();
+ float xVector = centerX - focalX;
+ float yVector = centerY - focalY;
+
+ if (xVector == 0 && yVector == 0) {
+ // Random direction when View is centered on focal View.
+ xVector = (float)(Math.random() * 2) - 1;
+ yVector = (float)(Math.random() * 2) - 1;
+ }
+ float vectorSize = calculateDistance(xVector, yVector);
+ xVector /= vectorSize;
+ yVector /= vectorSize;
+
+ float maxDistance =
+ calculateMaxDistance(sceneRoot, focalX - sceneRootX, focalY - sceneRootY);
+
+ outVector[0] = Math.round(maxDistance * xVector);
+ outVector[1] = Math.round(maxDistance * yVector);
+ }
+
+ private static float calculateMaxDistance(View sceneRoot, int focalX, int focalY) {
+ int maxX = Math.max(focalX, sceneRoot.getWidth() - focalX);
+ int maxY = Math.max(focalY, sceneRoot.getHeight() - focalY);
+ return calculateDistance(maxX, maxY);
+ }
+
+ private static float calculateDistance(float x, float y) {
+ return FloatMath.sqrt((x * x) + (y * y));
+ }
+
+ private static class OutAnimatorListener extends AnimatorListenerAdapter {
+ private final View mView;
+ private boolean mCanceled = false;
+ private float mPausedX;
+ private float mPausedY;
+ private final float mTerminalX;
+ private final float mTerminalY;
+ private final float mEndX;
+ private final float mEndY;
+
+ public OutAnimatorListener(View view, float terminalX, float terminalY,
+ float endX, float endY) {
+ mView = view;
+ mTerminalX = terminalX;
+ mTerminalY = terminalY;
+ mEndX = endX;
+ mEndY = endY;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animator) {
+ mView.setTranslationX(mTerminalX);
+ mView.setTranslationY(mTerminalY);
+ mCanceled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if (!mCanceled) {
+ mView.setTranslationX(mTerminalX);
+ mView.setTranslationY(mTerminalY);
+ }
+ }
+
+ @Override
+ public void onAnimationPause(Animator animator) {
+ mPausedX = mView.getTranslationX();
+ mPausedY = mView.getTranslationY();
+ mView.setTranslationY(mEndX);
+ mView.setTranslationY(mEndY);
+ }
+
+ @Override
+ public void onAnimationResume(Animator animator) {
+ mView.setTranslationX(mPausedX);
+ mView.setTranslationY(mPausedY);
+ }
+ }
+}
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index 8edb1ff..08e27d3 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -59,8 +59,6 @@
private static boolean DBG = Transition.DBG && false;
private static final String LOG_TAG = "Fade";
- private static final String PROPNAME_SCREEN_X = "android:fade:screenX";
- private static final String PROPNAME_SCREEN_Y = "android:fade:screenY";
/**
* Fading mode used in {@link #Fade(int)} to make the transition
@@ -98,245 +96,81 @@
/**
* Utility method to handle creating and running the Animator.
*/
- private Animator createAnimation(View view, float startAlpha, float endAlpha,
- AnimatorListenerAdapter listener) {
+ private Animator createAnimation(View view, float startAlpha, float endAlpha) {
if (startAlpha == endAlpha) {
- // run listener if we're noop'ing the animation, to get the end-state results now
- if (listener != null) {
- listener.onAnimationEnd(null);
- }
return null;
}
- final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "transitionAlpha", startAlpha,
- endAlpha);
+ view.setTransitionAlpha(startAlpha);
+ final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "transitionAlpha", endAlpha);
if (DBG) {
Log.d(LOG_TAG, "Created animator " + anim);
}
- if (listener != null) {
- anim.addListener(listener);
- anim.addPauseListener(listener);
- }
+ FadeAnimatorListener listener = new FadeAnimatorListener(view, endAlpha);
+ anim.addListener(listener);
+ anim.addPauseListener(listener);
return anim;
}
- private void captureValues(TransitionValues transitionValues) {
- int[] loc = new int[2];
- transitionValues.view.getLocationOnScreen(loc);
- transitionValues.values.put(PROPNAME_SCREEN_X, loc[0]);
- transitionValues.values.put(PROPNAME_SCREEN_Y, loc[1]);
- }
-
@Override
- public void captureStartValues(TransitionValues transitionValues) {
- super.captureStartValues(transitionValues);
- captureValues(transitionValues);
- }
-
- @Override
- public Animator onAppear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
+ public Animator onAppear(ViewGroup sceneRoot, View view,
+ TransitionValues startValues,
+ TransitionValues endValues) {
if ((mFadingMode & IN) != IN || endValues == null) {
return null;
}
- final View endView = endValues.view;
if (DBG) {
View startView = (startValues != null) ? startValues.view : null;
Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = " +
- startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+ startView + ", " + view);
}
- endView.setTransitionAlpha(0);
- TransitionListener transitionListener = new TransitionListenerAdapter() {
- boolean mCanceled = false;
- float mPausedAlpha;
-
- @Override
- public void onTransitionCancel(Transition transition) {
- endView.setTransitionAlpha(1);
- mCanceled = true;
- }
-
- @Override
- public void onTransitionEnd(Transition transition) {
- if (!mCanceled) {
- endView.setTransitionAlpha(1);
- }
- }
-
- @Override
- public void onTransitionPause(Transition transition) {
- mPausedAlpha = endView.getTransitionAlpha();
- endView.setTransitionAlpha(1);
- }
-
- @Override
- public void onTransitionResume(Transition transition) {
- endView.setTransitionAlpha(mPausedAlpha);
- }
- };
- addListener(transitionListener);
- return createAnimation(endView, 0, 1, null);
+ return createAnimation(view, 0, 1);
}
@Override
- public Animator onDisappear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
+ public Animator onDisappear(ViewGroup sceneRoot, final View view, TransitionValues startValues,
+ TransitionValues endValues) {
if ((mFadingMode & OUT) != OUT) {
return null;
}
- View view = null;
- View startView = (startValues != null) ? startValues.view : null;
- View endView = (endValues != null) ? endValues.view : null;
- if (DBG) {
- Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
- startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
- }
- View overlayView = null;
- View viewToKeep = null;
- if (endView == null || endView.getParent() == null) {
- if (endView != null) {
- // endView was removed from its parent - add it to the overlay
- view = overlayView = endView;
- } else if (startView != null) {
- // endView does not exist. Use startView only under certain
- // conditions, because placing a view in an overlay necessitates
- // it being removed from its current parent
- if (startView.getParent() == null) {
- // no parent - safe to use
- view = overlayView = startView;
- } else if (startView.getParent() instanceof View &&
- startView.getParent().getParent() == null) {
- View startParent = (View) startView.getParent();
- int id = startParent.getId();
- if (id != View.NO_ID && sceneRoot.findViewById(id) != null && mCanRemoveViews) {
- // no parent, but its parent is unparented but the parent
- // hierarchy has been replaced by a new hierarchy with the same id
- // and it is safe to un-parent startView
- view = overlayView = startView;
- }
- }
- }
- } else {
- // visibility change
- if (endVisibility == View.INVISIBLE) {
- view = endView;
- viewToKeep = view;
- } else {
- // Becoming GONE
- if (startView == endView) {
- view = endView;
- viewToKeep = view;
- } else {
- view = startView;
- overlayView = view;
- }
- }
- }
- final int finalVisibility = endVisibility;
- // TODO: add automatic facility to Visibility superclass for keeping views around
- if (overlayView != null) {
- // TODO: Need to do this for general case of adding to overlay
- int screenX = (Integer) startValues.values.get(PROPNAME_SCREEN_X);
- int screenY = (Integer) startValues.values.get(PROPNAME_SCREEN_Y);
- int[] loc = new int[2];
- sceneRoot.getLocationOnScreen(loc);
- overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
- overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
- sceneRoot.getOverlay().add(overlayView);
- // TODO: add automatic facility to Visibility superclass for keeping views around
- final float startAlpha = 1;
- float endAlpha = 0;
- final View finalView = view;
- final View finalOverlayView = overlayView;
- final View finalViewToKeep = viewToKeep;
- final ViewGroup finalSceneRoot = sceneRoot;
- final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- finalView.setTransitionAlpha(startAlpha);
- // TODO: restore view offset from overlay repositioning
- if (finalViewToKeep != null) {
- finalViewToKeep.setVisibility(finalVisibility);
- }
- if (finalOverlayView != null) {
- finalSceneRoot.getOverlay().remove(finalOverlayView);
- }
- }
- @Override
- public void onAnimationPause(Animator animation) {
- if (finalOverlayView != null) {
- finalSceneRoot.getOverlay().remove(finalOverlayView);
- }
- }
-
- @Override
- public void onAnimationResume(Animator animation) {
- if (finalOverlayView != null) {
- finalSceneRoot.getOverlay().add(finalOverlayView);
- }
- }
- };
- return createAnimation(view, startAlpha, endAlpha, endListener);
- }
- if (viewToKeep != null) {
- // TODO: find a different way to do this, like just changing the view to be
- // VISIBLE for the duration of the transition
- viewToKeep.setVisibility((View.VISIBLE));
- // TODO: add automatic facility to Visibility superclass for keeping views around
- final float startAlpha = 1;
- float endAlpha = 0;
- final View finalView = view;
- final View finalOverlayView = overlayView;
- final View finalViewToKeep = viewToKeep;
- final ViewGroup finalSceneRoot = sceneRoot;
- final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
- boolean mCanceled = false;
- float mPausedAlpha = -1;
-
- @Override
- public void onAnimationPause(Animator animation) {
- if (finalViewToKeep != null && !mCanceled) {
- finalViewToKeep.setVisibility(finalVisibility);
- }
- mPausedAlpha = finalView.getTransitionAlpha();
- finalView.setTransitionAlpha(startAlpha);
- }
-
- @Override
- public void onAnimationResume(Animator animation) {
- if (finalViewToKeep != null && !mCanceled) {
- finalViewToKeep.setVisibility(View.VISIBLE);
- }
- finalView.setTransitionAlpha(mPausedAlpha);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCanceled = true;
- if (mPausedAlpha >= 0) {
- finalView.setTransitionAlpha(mPausedAlpha);
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mCanceled) {
- finalView.setTransitionAlpha(startAlpha);
- }
- // TODO: restore view offset from overlay repositioning
- if (finalViewToKeep != null && !mCanceled) {
- finalViewToKeep.setVisibility(finalVisibility);
- }
- if (finalOverlayView != null) {
- finalSceneRoot.getOverlay().remove(finalOverlayView);
- }
- }
- };
- return createAnimation(view, startAlpha, endAlpha, endListener);
- }
- return null;
+ return createAnimation(view, 1, 0);
}
-}
\ No newline at end of file
+ private static class FadeAnimatorListener extends AnimatorListenerAdapter {
+ private final View mView;
+ private final float mEndAlpha;
+ private boolean mCanceled = false;
+ private float mPausedAlpha;
+
+ public FadeAnimatorListener(View view, float endAlpha) {
+ mView = view;
+ mEndAlpha = endAlpha;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animator) {
+ mCanceled = true;
+ if (mPausedAlpha >= 0) {
+ mView.setTransitionAlpha(mPausedAlpha);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if (!mCanceled) {
+ mView.setTransitionAlpha(mEndAlpha);
+ }
+ }
+
+ @Override
+ public void onAnimationPause(Animator animator) {
+ mPausedAlpha = mView.getTransitionAlpha();
+ mView.setTransitionAlpha(mEndAlpha);
+ }
+
+ @Override
+ public void onAnimationResume(Animator animator) {
+ mView.setTransitionAlpha(mPausedAlpha);
+ }
+ }
+}
diff --git a/core/java/android/transition/MatrixClippedDrawable.java b/core/java/android/transition/MatrixClippedDrawable.java
new file mode 100644
index 0000000..ebaad59
--- /dev/null
+++ b/core/java/android/transition/MatrixClippedDrawable.java
@@ -0,0 +1,300 @@
+/*
+ * 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
new file mode 100644
index 0000000..d68e971
--- /dev/null
+++ b/core/java/android/transition/MoveImage.java
@@ -0,0 +1,326 @@
+/*
+ * 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.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.
+ */
+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";
+
+ 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;
+ }
+ Map<String, Object> values = transitionValues.values;
+
+ 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);
+ ImageView imageView = (ImageView) view;
+ Matrix matrix = getMatrix(imageView);
+ values.put(PROPNAME_MATRIX, matrix);
+ values.put(PROPNAME_CLIP, findClip(imageView));
+ values.put(PROPNAME_DRAWABLE, imageView.getDrawable());
+ }
+
+ @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.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);
+ matrixClippedDrawable.setMatrix(startMatrix);
+ matrixClippedDrawable.setBounds(startBounds);
+ matrixClippedDrawable.setClipRect(startClip);
+
+ imageView.setVisibility(View.INVISIBLE);
+ final ViewGroupOverlay overlay = sceneRoot.getOverlay();
+ overlay.add(matrixClippedDrawable);
+ 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(matrixClippedDrawable);
+ }
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ imageView.setVisibility(View.VISIBLE);
+ overlay.remove(matrixClippedDrawable);
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ imageView.setVisibility(View.INVISIBLE);
+ overlay.add(matrixClippedDrawable);
+ }
+ };
+
+ 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);
+ 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();
+ if (drawableWidth <= 0 || drawableHeight <= 0 || scaleType == ImageView.ScaleType.FIT_XY) {
+ return null;
+ }
+ return new Matrix(imageView.getImageMatrix());
+ }
+
+ 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;
+ }
+ }
+}
diff --git a/core/java/android/transition/SidePropagation.java b/core/java/android/transition/SidePropagation.java
new file mode 100644
index 0000000..c331945
--- /dev/null
+++ b/core/java/android/transition/SidePropagation.java
@@ -0,0 +1,165 @@
+/*
+ * 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.graphics.Rect;
+import android.util.FloatMath;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A <code>TransitionPropagation</code> that propagates based on the distance to the side
+ * and, orthogonally, the distance to epicenter. If the transitioning View is visible in
+ * the start of the transition, then it will transition sooner when closer to the side and
+ * later when farther. If the view is not visible in the start of the transition, then
+ * it will transition later when closer to the side and sooner when farther from the edge.
+ * This is the default TransitionPropagation used with {@link android.transition.Slide}.
+ */
+public class SidePropagation extends VisibilityPropagation {
+ private static final String TAG = "SlidePropagation";
+
+ /**
+ * Transition propagates relative to the distance of the left side of the scene.
+ */
+ public static final int LEFT = Slide.LEFT;
+
+ /**
+ * Transition propagates relative to the distance of the top of the scene.
+ */
+ public static final int TOP = Slide.TOP;
+
+ /**
+ * Transition propagates relative to the distance of the right side of the scene.
+ */
+ public static final int RIGHT = Slide.RIGHT;
+
+ /**
+ * Transition propagates relative to the distance of the bottom of the scene.
+ */
+ public static final int BOTTOM = Slide.BOTTOM;
+
+ private float mPropagationSpeed = 4.0f;
+ private int mSide = BOTTOM;
+
+ /**
+ * Sets the side that is used to calculate the transition propagation. If the transitioning
+ * View is visible in the start of the transition, then it will transition sooner when
+ * closer to the side and later when farther. If the view is not visible in the start of
+ * the transition, then it will transition later when closer to the side and sooner when
+ * farther from the edge. The default is {@link #BOTTOM}.
+ *
+ * @param side The side that is used to calculate the transition propagation. Must be one of
+ * {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, or {@link #BOTTOM}.
+ */
+ public void setSide(int side) {
+ mSide = side;
+ }
+
+ /**
+ * Sets the speed at which transition propagation happens, relative to the duration of the
+ * Transition. A <code>propagationSpeed</code> of 1 means that a View centered at the side
+ * set in {@link #setSide(int)} and View centered at the opposite edge will have a difference
+ * in start delay of approximately the duration of the Transition. A speed of 2 means the
+ * start delay difference will be approximately half of the duration of the transition. A
+ * value of 0 is illegal, but negative values will invert the propagation.
+ *
+ * @param propagationSpeed The speed at which propagation occurs, relative to the duration
+ * of the transition. A speed of 4 means it works 4 times as fast
+ * as the duration of the transition. May not be 0.
+ */
+ public void setPropagationSpeed(float propagationSpeed) {
+ if (propagationSpeed == 0) {
+ throw new IllegalArgumentException("propagationSpeed may not be 0");
+ }
+ mPropagationSpeed = propagationSpeed;
+ }
+
+ @Override
+ public long getStartDelay(ViewGroup sceneRoot, Transition transition,
+ TransitionValues startValues, TransitionValues endValues) {
+ if (startValues == null && endValues == null) {
+ return 0;
+ }
+ int directionMultiplier = 1;
+ Rect epicenter = transition.getEpicenter();
+ TransitionValues positionValues;
+ if (endValues == null || getViewVisibility(startValues) == View.VISIBLE) {
+ positionValues = startValues;
+ directionMultiplier = -1;
+ } else {
+ positionValues = endValues;
+ }
+
+ int viewCenterX = getViewX(positionValues);
+ int viewCenterY = getViewY(positionValues);
+
+ int[] loc = new int[2];
+ sceneRoot.getLocationOnScreen(loc);
+ int left = loc[0] + Math.round(sceneRoot.getTranslationX());
+ int top = loc[1] + Math.round(sceneRoot.getTranslationY());
+ int right = left + sceneRoot.getWidth();
+ int bottom = top + sceneRoot.getHeight();
+
+ int epicenterX;
+ int epicenterY;
+ if (epicenter != null) {
+ epicenterX = epicenter.centerX();
+ epicenterY = epicenter.centerY();
+ } else {
+ epicenterX = (left + right) / 2;
+ epicenterY = (top + bottom) / 2;
+ }
+
+ float distance = distance(viewCenterX, viewCenterY, epicenterX, epicenterY,
+ left, top, right, bottom);
+ float maxDistance = getMaxDistance(sceneRoot);
+ float distanceFraction = distance/maxDistance;
+
+ return Math.round(transition.getDuration() * directionMultiplier / mPropagationSpeed
+ * distanceFraction);
+ }
+
+ private int distance(int viewX, int viewY, int epicenterX, int epicenterY,
+ int left, int top, int right, int bottom) {
+ int distance = 0;
+ switch (mSide) {
+ case LEFT:
+ distance = right - viewX + Math.abs(epicenterY - viewY);
+ break;
+ case TOP:
+ distance = bottom - viewY + Math.abs(epicenterX - viewX);
+ break;
+ case RIGHT:
+ distance = viewX - left + Math.abs(epicenterY - viewY);
+ break;
+ case BOTTOM:
+ distance = viewY - top + Math.abs(epicenterX - viewX);
+ break;
+ }
+ return distance;
+ }
+
+ private int getMaxDistance(ViewGroup sceneRoot) {
+ switch (mSide) {
+ case LEFT:
+ case RIGHT:
+ return sceneRoot.getWidth();
+ default:
+ return sceneRoot.getHeight();
+ }
+ }
+}
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
index b38973c..0ff8ddd 100644
--- a/core/java/android/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 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.
@@ -13,53 +13,240 @@
* 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.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.graphics.Rect;
+import android.util.Log;
+import android.util.Property;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
/**
- * This transition captures the visibility of target objects before and
- * after a scene change and animates any changes by sliding the target
- * objects into or out of place.
- *
- * @hide
+ * This transition tracks changes to the visibility of target views in the
+ * start and end scenes and moves views in or out from one of the edges of the
+ * scene. Visibility is determined by both the
+ * {@link View#setVisibility(int)} state of the view as well as whether it
+ * is parented in the current view hierarchy. Disappearing Views are
+ * limited as described in {@link Visibility#onDisappear(android.view.ViewGroup,
+ * TransitionValues, int, TransitionValues, int)}.
*/
public class Slide extends Visibility {
+ private static final String TAG = "Slide";
- // TODO: Add parameter for sliding factor - it's hard-coded below
+ /**
+ * Move Views in or out of the left edge of the scene.
+ * @see #setSlideEdge(int)
+ */
+ public static final int LEFT = 0;
- private static final TimeInterpolator sAccelerator = new AccelerateInterpolator();
- private static final TimeInterpolator sDecelerator = new DecelerateInterpolator();
+ /**
+ * Move Views in or out of the top edge of the scene.
+ * @see #setSlideEdge(int)
+ */
+ public static final int TOP = 1;
- @Override
- public Animator onAppear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- View endView = (endValues != null) ? endValues.view : null;
- endView.setTranslationY(-2 * endView.getHeight());
- ObjectAnimator anim = ObjectAnimator.ofFloat(endView, View.TRANSLATION_Y,
- -2 * endView.getHeight(), 0);
- anim.setInterpolator(sDecelerator);
+ /**
+ * Move Views in or out of the right edge of the scene.
+ * @see #setSlideEdge(int)
+ */
+ public static final int RIGHT = 2;
+
+ /**
+ * Move Views in or out of the bottom edge of the scene. This is the
+ * default slide direction.
+ * @see #setSlideEdge(int)
+ */
+ public static final int BOTTOM = 3;
+
+ private static final TimeInterpolator sDecelerate = new DecelerateInterpolator();
+ private static final TimeInterpolator sAccelerate = new AccelerateInterpolator();
+
+ private int[] mTempLoc = new int[2];
+ private CalculateSlide mSlideCalculator = sCalculateBottom;
+
+ private interface CalculateSlide {
+ /** Returns the translation value for view when it out of the scene */
+ float getGone(ViewGroup sceneRoot, View view);
+
+ /** Returns the translation value for view when it is in the scene */
+ float getHere(View view);
+
+ /** Returns the property to animate translation */
+ Property<View, Float> getProperty();
+ }
+
+ private static abstract class CalculateSlideHorizontal implements CalculateSlide {
+ @Override
+ public float getHere(View view) {
+ return view.getTranslationX();
+ }
+
+ @Override
+ public Property<View, Float> getProperty() {
+ return View.TRANSLATION_X;
+ }
+ }
+
+ private static abstract class CalculateSlideVertical implements CalculateSlide {
+ @Override
+ public float getHere(View view) {
+ return view.getTranslationY();
+ }
+
+ @Override
+ public Property<View, Float> getProperty() {
+ return View.TRANSLATION_Y;
+ }
+ }
+
+ private static final CalculateSlide sCalculateLeft = new CalculateSlideHorizontal() {
+ @Override
+ public float getGone(ViewGroup sceneRoot, View view) {
+ return view.getTranslationX() - sceneRoot.getWidth();
+ }
+ };
+
+ private static final CalculateSlide sCalculateTop = new CalculateSlideVertical() {
+ @Override
+ public float getGone(ViewGroup sceneRoot, View view) {
+ return view.getTranslationY() - sceneRoot.getHeight();
+ }
+ };
+
+ private static final CalculateSlide sCalculateRight = new CalculateSlideHorizontal() {
+ @Override
+ public float getGone(ViewGroup sceneRoot, View view) {
+ return view.getTranslationX() + sceneRoot.getWidth();
+ }
+ };
+
+ private static final CalculateSlide sCalculateBottom = new CalculateSlideVertical() {
+ @Override
+ public float getGone(ViewGroup sceneRoot, View view) {
+ return view.getTranslationY() + sceneRoot.getHeight();
+ }
+ };
+
+ /**
+ * Constructor using the default {@link android.transition.Slide#BOTTOM}
+ * slide edge direction.
+ */
+ public Slide() {
+ setSlideEdge(BOTTOM);
+ }
+
+ /**
+ * Constructor using the provided slide edge direction.
+ */
+ public Slide(int slideEdge) {
+ setSlideEdge(slideEdge);
+ }
+
+ /**
+ * Change the edge that Views appear and disappear from.
+ * @param slideEdge The edge of the scene to use for Views appearing and disappearing.
+ */
+ public void setSlideEdge(int slideEdge) {
+ switch (slideEdge) {
+ case LEFT:
+ mSlideCalculator = sCalculateLeft;
+ break;
+ case TOP:
+ mSlideCalculator = sCalculateTop;
+ break;
+ case RIGHT:
+ mSlideCalculator = sCalculateRight;
+ break;
+ case BOTTOM:
+ mSlideCalculator = sCalculateBottom;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid slide direction");
+ }
+ SidePropagation propagation = new SidePropagation();
+ propagation.setSide(slideEdge);
+ setPropagation(propagation);
+ }
+
+ private Animator createAnimation(final View view, Property<View, Float> property,
+ float start, float end, float terminalValue, TimeInterpolator interpolator) {
+ view.setTranslationY(start);
+ if (start == end) {
+ return null;
+ }
+ final ObjectAnimator anim = ObjectAnimator.ofFloat(view, property, start, end);
+
+ SlideAnimatorListener listener = new SlideAnimatorListener(view, terminalValue, end);
+ anim.addListener(listener);
+ anim.addPauseListener(listener);
+ anim.setInterpolator(interpolator);
return anim;
}
@Override
- public Animator onDisappear(ViewGroup sceneRoot,
- TransitionValues startValues, int startVisibility,
- TransitionValues endValues, int endVisibility) {
- View startView = (startValues != null) ? startValues.view : null;
- startView.setTranslationY(0);
- ObjectAnimator anim = ObjectAnimator.ofFloat(startView, View.TRANSLATION_Y, 0,
- -2 * startView.getHeight());
- anim.setInterpolator(sAccelerator);
- return anim;
+ public Animator onAppear(ViewGroup sceneRoot, View view,
+ TransitionValues startValues, TransitionValues endValues) {
+ if (endValues == null) {
+ return null;
+ }
+ float end = mSlideCalculator.getHere(view);
+ float start = mSlideCalculator.getGone(sceneRoot, view);
+ return createAnimation(view, mSlideCalculator.getProperty(), start, end, end, sDecelerate);
}
+ @Override
+ public Animator onDisappear(ViewGroup sceneRoot, View view,
+ TransitionValues startValues, TransitionValues endValues) {
+ float start = mSlideCalculator.getHere(view);
+ float end = mSlideCalculator.getGone(sceneRoot, view);
+
+ return createAnimation(view, mSlideCalculator.getProperty(), start, end, start,
+ sAccelerate);
+ }
+
+ private static class SlideAnimatorListener extends AnimatorListenerAdapter {
+ private boolean mCanceled = false;
+ private float mPausedY;
+ private final View mView;
+ private final float mEndY;
+ private final float mTerminalY;
+
+ public SlideAnimatorListener(View view, float terminalY, float endY) {
+ mView = view;
+ mTerminalY = terminalY;
+ mEndY = endY;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animator) {
+ mView.setTranslationY(mTerminalY);
+ mCanceled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if (!mCanceled) {
+ mView.setTranslationY(mTerminalY);
+ }
+ }
+
+ @Override
+ public void onAnimationPause(Animator animator) {
+ mPausedY = mView.getTranslationY();
+ mView.setTranslationY(mEndY);
+ }
+
+ @Override
+ public void onAnimationResume(Animator animator) {
+ mView.setTranslationY(mPausedY);
+ }
+ }
}
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index c88b4c0..b7ae31e 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -19,10 +19,12 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
+import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
+import android.util.SparseLongArray;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
@@ -60,10 +62,18 @@
* <p>Transitions can be declared in XML resource files inside the <code>res/transition</code>
* directory. Transition resources consist of a tag name for one of the Transition
* subclasses along with attributes to define some of the attributes of that transition.
- * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:</p>
+ * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:
*
* {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds}
*
+ * <p>{@link android.transition.Explode} transition:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/explode.xml Explode}
+ *
+ * <p>{@link android.transition.MoveImage} transition:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/move_image.xml MoveImage}
+ *
* <p>Note that attributes for the transition are not required, just as they are
* optional when declared in code; Transitions created from XML resources will use
* the same defaults as their code-created equivalents. Here is a slightly more
@@ -87,7 +97,8 @@
*
* Further information on XML resource descriptions for transitions can be found for
* {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
- * {@link android.R.styleable#TransitionTarget}, and {@link android.R.styleable#Fade}.
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade}, and
+ * {@link android.R.styleable#Slide}.
*
*/
public abstract class Transition implements Cloneable {
@@ -149,6 +160,13 @@
// to be run in runAnimators()
ArrayList<Animator> mAnimators = new ArrayList<Animator>();
+ // The function for calculating the Animation start delay.
+ TransitionPropagation mPropagation;
+
+ // The rectangular region for Transitions like Explode and TransitionPropagations
+ // like CircularPropagation
+ EpicenterCallback mEpicenterCallback;
+
/**
* Constructs a Transition object with no target objects. A transition with
* no targets defaults to running on all target objects in the scene hierarchy
@@ -435,6 +453,9 @@
endValuesList.add(end);
}
ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+ long minStartDelay = Long.MAX_VALUE;
+ int minAnimator = mAnimators.size();
+ SparseLongArray startDelays = new SparseLongArray();
for (int i = 0; i < startValuesList.size(); ++i) {
TransitionValues start = startValuesList.get(i);
TransitionValues end = endValuesList.get(i);
@@ -497,6 +518,12 @@
view = (start != null) ? start.view : null;
}
if (animator != null) {
+ if (mPropagation != null) {
+ long delay = mPropagation
+ .getStartDelay(sceneRoot, this, start, end);
+ startDelays.put(mAnimators.size(), delay);
+ minStartDelay = Math.min(delay, minStartDelay);
+ }
AnimationInfo info = new AnimationInfo(view, getName(),
sceneRoot.getWindowId(), infoValues);
runningAnimators.put(animator, info);
@@ -506,6 +533,14 @@
}
}
}
+ if (minStartDelay != 0) {
+ for (int i = 0; i < startDelays.size(); i++) {
+ int index = startDelays.keyAt(i);
+ Animator animator = mAnimators.get(index);
+ long delay = startDelays.valueAt(i) - minStartDelay + animator.getStartDelay();
+ animator.setStartDelay(delay);
+ }
+ }
}
/**
@@ -565,7 +600,7 @@
/**
* This is called internally once all animations have been set up by the
- * transition hierarchy. \
+ * transition hierarchy.
*
* @hide
*/
@@ -1010,6 +1045,7 @@
} else {
captureEndValues(values);
}
+ capturePropagationValues(values);
if (start) {
mStartValues.viewValues.put(view, values);
if (id >= 0) {
@@ -1035,6 +1071,7 @@
} else {
captureEndValues(values);
}
+ capturePropagationValues(values);
if (start) {
mStartValues.viewValues.put(view, values);
} else {
@@ -1122,6 +1159,7 @@
} else {
captureEndValues(values);
}
+ capturePropagationValues(values);
if (start) {
if (!isListViewItem) {
mStartValues.viewValues.put(view, values);
@@ -1340,7 +1378,7 @@
animator.setDuration(getDuration());
}
if (getStartDelay() >= 0) {
- animator.setStartDelay(getStartDelay());
+ animator.setStartDelay(getStartDelay() + animator.getStartDelay());
}
if (getInterpolator() != null) {
animator.setInterpolator(getInterpolator());
@@ -1473,6 +1511,98 @@
return this;
}
+ /**
+ * Sets the callback to use to find the epicenter of a Transition. A null value indicates
+ * that there is no epicenter in the Transition and getEpicenter() will return null.
+ * Transitions like {@link android.transition.Explode} use a point or Rect to orient
+ * the direction of travel. This is called the epicenter of the Transition and is
+ * typically centered on a touched View. The
+ * {@link android.transition.Transition.EpicenterCallback} allows a Transition to
+ * dynamically retrieve the epicenter during a Transition.
+ * @param epicenterCallback The callback to use to find the epicenter of the Transition.
+ */
+ public void setEpicenterCallback(EpicenterCallback epicenterCallback) {
+ mEpicenterCallback = epicenterCallback;
+ }
+
+ /**
+ * Returns the callback used to find the epicenter of the Transition.
+ * Transitions like {@link android.transition.Explode} use a point or Rect to orient
+ * the direction of travel. This is called the epicenter of the Transition and is
+ * typically centered on a touched View. The
+ * {@link android.transition.Transition.EpicenterCallback} allows a Transition to
+ * dynamically retrieve the epicenter during a Transition.
+ * @return the callback used to find the epicenter of the Transition.
+ */
+ public EpicenterCallback getEpicenterCallback() {
+ return mEpicenterCallback;
+ }
+
+ /**
+ * Returns the epicenter as specified by the
+ * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists.
+ * @return the epicenter as specified by the
+ * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists.
+ * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback)
+ */
+ public Rect getEpicenter() {
+ if (mEpicenterCallback == null) {
+ return null;
+ }
+ return mEpicenterCallback.getEpicenter(this);
+ }
+
+ /**
+ * Sets the method for determining Animator start delays.
+ * When a Transition affects several Views like {@link android.transition.Explode} or
+ * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect
+ * such that the Animator start delay depends on position of the View. The
+ * TransitionPropagation specifies how the start delays are calculated.
+ * @param transitionPropagation The class used to determine the start delay of
+ * Animators created by this Transition. A null value
+ * indicates that no delay should be used.
+ */
+ public void setPropagation(TransitionPropagation transitionPropagation) {
+ mPropagation = transitionPropagation;
+ }
+
+ /**
+ * Returns the {@link android.transition.TransitionPropagation} used to calculate Animator start
+ * delays.
+ * When a Transition affects several Views like {@link android.transition.Explode} or
+ * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect
+ * such that the Animator start delay depends on position of the View. The
+ * TransitionPropagation specifies how the start delays are calculated.
+ * @return the {@link android.transition.TransitionPropagation} used to calculate Animator start
+ * delays. This is null by default.
+ */
+ public TransitionPropagation getPropagation() {
+ return mPropagation;
+ }
+
+ /**
+ * Captures TransitionPropagation values for the given view and the
+ * hierarchy underneath it.
+ */
+ void capturePropagationValues(TransitionValues transitionValues) {
+ if (mPropagation != null) {
+ String[] propertyNames = mPropagation.getPropagationProperties();
+ if (propertyNames == null) {
+ return;
+ }
+ boolean containsAll = true;
+ for (int i = 0; i < propertyNames.length; i++) {
+ if (!transitionValues.values.containsKey(propertyNames[i])) {
+ containsAll = false;
+ break;
+ }
+ }
+ if (!containsAll) {
+ mPropagation.captureValues(transitionValues);
+ }
+ }
+ }
+
Transition setSceneRoot(ViewGroup sceneRoot) {
mSceneRoot = sceneRoot;
return this;
@@ -1710,4 +1840,28 @@
}
}
+ /**
+ * Class to get the epicenter of Transition. Use
+ * {@link #setEpicenterCallback(android.transition.Transition.EpicenterCallback)} to
+ * set the callback used to calculate the epicenter of the Transition. Override
+ * {@link #getEpicenter()} to return the rectangular region in screen coordinates of
+ * the epicenter of the transition.
+ * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback)
+ */
+ public static abstract class EpicenterCallback {
+
+ /**
+ * Implementers must override to return the epicenter of the Transition in screen
+ * coordinates. Transitions like {@link android.transition.Explode} depend upon
+ * an epicenter for the Transition. In Explode, Views move toward or away from the
+ * center of the epicenter Rect along the vector between the epicenter and the center
+ * of the View appearing and disappearing. Some Transitions, such as
+ * {@link android.transition.Fade} pay no attention to the epicenter.
+ *
+ * @param transition The transition for which the epicenter applies.
+ * @return The Rect region of the epicenter of <code>transition</code> or null if
+ * there is no epicenter.
+ */
+ public abstract Rect getEpicenter(Transition transition);
+ }
}
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 912f2ed..f675c6a 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -20,7 +20,6 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
-import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.InflateException;
@@ -146,7 +145,13 @@
transition = new ChangeBounds();
newTransition = true;
} else if ("slide".equals(name)) {
- transition = new Slide();
+ transition = createSlideTransition(attrs);
+ newTransition = true;
+ } else if ("explode".equals(name)) {
+ transition = new Explode();
+ newTransition = true;
+ } else if ("moveImage".equals(name)) {
+ transition = new MoveImage();
newTransition = true;
} else if ("autoTransition".equals(name)) {
transition = new AutoTransition();
@@ -189,6 +194,15 @@
return transition;
}
+ private Slide createSlideTransition(AttributeSet attrs) {
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.Slide);
+ int edge = a.getInt(com.android.internal.R.styleable.Slide_slideEdge, Slide.BOTTOM);
+ Slide slide = new Slide(edge);
+ a.recycle();
+ return slide;
+ }
+
private void getTargetIds(XmlPullParser parser,
AttributeSet attrs, Transition transition) throws XmlPullParserException, IOException {
diff --git a/core/java/android/transition/TransitionPropagation.java b/core/java/android/transition/TransitionPropagation.java
new file mode 100644
index 0000000..9a481c2
--- /dev/null
+++ b/core/java/android/transition/TransitionPropagation.java
@@ -0,0 +1,88 @@
+/*
+ * 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.graphics.Rect;
+import android.view.ViewGroup;
+
+/**
+ * Extend <code>TransitionPropagation</code> to customize start delays for Animators created
+ * in {@link android.transition.Transition#createAnimator(ViewGroup,
+ * TransitionValues, TransitionValues)}. A Transition such as {@link android.transition.Explode}
+ * defaults to using {@link android.transition.CircularPropagation} and Views closer to the
+ * epicenter will move out of the scene later and into the scene sooner than Views farther
+ * from the epicenter, giving the appearance of inertia. With no TransitionPropagation, all
+ * Views will react simultaneously to the start of the transition.
+ *
+ * @see Transition#setPropagation(TransitionPropagation)
+ * @see Transition#getEpicenter()
+ */
+public abstract class TransitionPropagation {
+ /**
+ * Called by Transition to alter the Animator start delay. All start delays will be adjusted
+ * such that the minimum becomes zero.
+ * @param sceneRoot The root of the View hierarchy running the transition.
+ * @param transition The transition that created the Animator
+ * @param startValues The values for a specific target in the start scene.
+ * @param endValues The values for the target in the end scene.
+ * @return A start delay to use with the Animator created by <code>transition</code>. The
+ * delay will be offset by the minimum delay of all <code>TransitionPropagation</code>s
+ * used in the Transition so that the smallest delay will be 0. Returned values may be
+ * negative.
+ */
+ public abstract long getStartDelay(ViewGroup sceneRoot, Transition transition,
+ TransitionValues startValues, TransitionValues endValues);
+
+ /**
+ * Captures the values in the start or end scene for the properties that this
+ * transition propagation monitors. These values are then passed as the startValues
+ * or endValues structure in a later call to
+ * {@link #getStartDelay(ViewGroup, Transition, TransitionValues, TransitionValues)}.
+ * The main concern for an implementation is what the
+ * properties are that the transition cares about and what the values are
+ * for all of those properties. The start and end values will be compared
+ * later during the
+ * {@link #getStartDelay(ViewGroup, Transition, TransitionValues, TransitionValues)}.
+ * method to determine the start delay.
+ *
+ * <p>Subclasses must implement this method. The method should only be called by the
+ * transition system; it is not intended to be called from external classes.</p>
+ *
+ * @param transitionValues The holder for any values that the Transition
+ * wishes to store. Values are stored in the <code>values</code> field
+ * of this TransitionValues object and are keyed from
+ * a String value. For example, to store a view's rotation value,
+ * a transition might call
+ * <code>transitionValues.values.put("appname:transitionname:rotation",
+ * view.getRotation())</code>. The target view will already be stored in
+ * the transitionValues structure when this method is called.
+ */
+ public abstract void captureValues(TransitionValues transitionValues);
+
+ /**
+ * Returns the set of property names stored in the {@link TransitionValues}
+ * object passed into {@link #captureValues(TransitionValues)} that
+ * this transition propagation cares about for the purposes of preventing
+ * duplicate capturing of property values.
+
+ * <p>A <code>TransitionPropagation</code> must override this method to prevent
+ * duplicate capturing of values and must contain at least one </p>
+ *
+ * @return An array of property names as described in the class documentation for
+ * {@link TransitionValues}.
+ */
+ public abstract String[] getPropagationProperties() ;
+}
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 19d6b3d..966b24d 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -17,6 +17,7 @@
package android.transition;
import android.animation.TimeInterpolator;
+import android.graphics.Rect;
import android.util.AndroidRuntimeException;
import android.view.View;
import android.view.ViewGroup;
@@ -315,6 +316,15 @@
}
}
+ @Override
+ void capturePropagationValues(TransitionValues transitionValues) {
+ super.capturePropagationValues(transitionValues);
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.get(i).capturePropagationValues(transitionValues);
+ }
+ }
+
/** @hide */
@Override
public void pause(View sceneRoot) {
@@ -365,6 +375,24 @@
}
@Override
+ public void setPropagation(TransitionPropagation propagation) {
+ super.setPropagation(propagation);
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.get(i).setPropagation(propagation);
+ }
+ }
+
+ @Override
+ public void setEpicenterCallback(EpicenterCallback epicenterCallback) {
+ super.setEpicenterCallback(epicenterCallback);
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.get(i).setEpicenterCallback(epicenterCallback);
+ }
+ }
+
+ @Override
String toString(String indent) {
String result = super.toString(indent);
for (int i = 0; i < mTransitions.size(); ++i) {
@@ -383,5 +411,4 @@
}
return clone;
}
-
}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 44f92cd..7783b6f 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -17,6 +17,7 @@
package android.transition;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.view.View;
import android.view.ViewGroup;
@@ -29,15 +30,20 @@
* information to determine the specific animations to run when visibility
* changes occur. Subclasses should implement one or both of the methods
* {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
- * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)} or
+ * {@link #onAppear(ViewGroup, View, TransitionValues, TransitionValues)},
+ * {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)}.
*/
public abstract class Visibility extends Transition {
private static final String PROPNAME_VISIBILITY = "android:visibility:visibility";
private static final String PROPNAME_PARENT = "android:visibility:parent";
+ private static final String PROPNAME_SCREEN_LOCATION = "android:visibility:screenLocation";
+
private static final String[] sTransitionProperties = {
PROPNAME_VISIBILITY,
PROPNAME_PARENT,
+ PROPNAME_SCREEN_LOCATION,
};
private static class VisibilityInfo {
@@ -58,6 +64,9 @@
int visibility = transitionValues.view.getVisibility();
transitionValues.values.put(PROPNAME_VISIBILITY, visibility);
transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent());
+ int[] loc = new int[2];
+ transitionValues.view.getLocationOnScreen(loc);
+ transitionValues.values.put(PROPNAME_SCREEN_LOCATION, loc);
}
@Override
@@ -179,8 +188,11 @@
}
/**
- * The default implementation of this method does nothing. Subclasses
- * should override if they need to create an Animator when targets appear.
+ * The default implementation of this method calls
+ * {@link #onAppear(ViewGroup, View, TransitionValues, TransitionValues)}.
+ * Subclasses should override this method or
+ * {@link #onAppear(ViewGroup, View, TransitionValues, TransitionValues)}.
+ * if they need to create an Animator when targets appear.
* The method should only be called by the Visibility class; it is
* not intended to be called from external classes.
*
@@ -196,15 +208,53 @@
public Animator onAppear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
+ return onAppear(sceneRoot, endValues.view, startValues, endValues);
+ }
+
+ /**
+ * The default implementation of this method returns a null Animator. Subclasses should
+ * override this method to make targets appear with the desired transition. The
+ * method should only be called from
+ * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)}.
+ *
+ * @param sceneRoot The root of the transition hierarchy
+ * @param view The View to make appear. This will be in the target scene's View hierarchy and
+ * will be VISIBLE.
+ * @param startValues The target values in the start scene
+ * @param endValues The target values in the end scene
+ * @return An Animator to be started at the appropriate time in the
+ * overall transition for this scene change. A null value means no animation
+ * should be run.
+ */
+ public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+ TransitionValues endValues) {
return null;
}
/**
- * The default implementation of this method does nothing. Subclasses
- * should override if they need to create an Animator when targets disappear.
+ * Subclasses should override this method or
+ * {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)}
+ * if they need to create an Animator when targets disappear.
* The method should only be called by the Visibility class; it is
* not intended to be called from external classes.
- *
+ * <p>
+ * The default implementation of this method attempts to find a View to use to call
+ * {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)},
+ * based on the situation of the View in the View hierarchy. For example,
+ * if a View was simply removed from its parent, then the View will be added
+ * into a {@link android.view.ViewGroupOverlay} and passed as the <code>view</code>
+ * parameter in {@link #onDisappear(ViewGroup, View, TransitionValues, TransitionValues)}.
+ * If a visible View is changed to be {@link View#GONE} or {@link View#INVISIBLE},
+ * then it can be used as the <code>view</code> and the visibility will be changed
+ * to {@link View#VISIBLE} for the duration of the animation. However, if a View
+ * is in a hierarchy which is also altering its visibility, the situation can be
+ * more complicated. In general, if a view that is no longer in the hierarchy in
+ * the end scene still has a parent (so its parent hierarchy was removed, but it
+ * was not removed from its parent), then it will be left alone to avoid side-effects from
+ * improperly removing it from its parent. The only exception to this is if
+ * the previous {@link Scene} was {@link Scene#getSceneForLayout(ViewGroup, int,
+ * android.content.Context) created from a layout resource file}, then it is considered
+ * safe to un-parent the starting scene view in order to make it disappear.</p>
*
* @param sceneRoot The root of the transition hierarchy
* @param startValues The target values in the start scene
@@ -218,6 +268,144 @@
public Animator onDisappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
+ View startView = (startValues != null) ? startValues.view : null;
+ View endView = (endValues != null) ? endValues.view : null;
+ View overlayView = null;
+ View viewToKeep = null;
+ if (endView == null || endView.getParent() == null) {
+ if (endView != null) {
+ // endView was removed from its parent - add it to the overlay
+ overlayView = endView;
+ } else if (startView != null) {
+ // endView does not exist. Use startView only under certain
+ // conditions, because placing a view in an overlay necessitates
+ // it being removed from its current parent
+ if (startView.getParent() == null) {
+ // no parent - safe to use
+ overlayView = startView;
+ } else if (startView.getParent() instanceof View &&
+ startView.getParent().getParent() == null) {
+ View startParent = (View) startView.getParent();
+ int id = startParent.getId();
+ if (id != View.NO_ID && sceneRoot.findViewById(id) != null && mCanRemoveViews) {
+ // no parent, but its parent is unparented but the parent
+ // hierarchy has been replaced by a new hierarchy with the same id
+ // and it is safe to un-parent startView
+ overlayView = startView;
+ }
+ }
+ }
+ } else {
+ // visibility change
+ if (endVisibility == View.INVISIBLE) {
+ viewToKeep = endView;
+ } else {
+ // Becoming GONE
+ if (startView == endView) {
+ viewToKeep = endView;
+ } else {
+ overlayView = startView;
+ }
+ }
+ }
+ final int finalVisibility = endVisibility;
+ final ViewGroup finalSceneRoot = sceneRoot;
+
+ if (overlayView != null) {
+ // TODO: Need to do this for general case of adding to overlay
+ int[] screenLoc = (int[]) startValues.values.get(PROPNAME_SCREEN_LOCATION);
+ int screenX = screenLoc[0];
+ int screenY = screenLoc[1];
+ int[] loc = new int[2];
+ sceneRoot.getLocationOnScreen(loc);
+ overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
+ overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
+ sceneRoot.getOverlay().add(overlayView);
+ Animator animator = onDisappear(sceneRoot, overlayView, startValues, endValues);
+ if (animator == null) {
+ sceneRoot.getOverlay().remove(overlayView);
+ } else {
+ final View finalOverlayView = overlayView;
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finalSceneRoot.getOverlay().remove(finalOverlayView);
+ }
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ finalSceneRoot.getOverlay().remove(finalOverlayView);
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ finalSceneRoot.getOverlay().add(finalOverlayView);
+ }
+ });
+ }
+ return animator;
+ }
+
+ if (viewToKeep != null) {
+ viewToKeep.setVisibility(View.VISIBLE);
+ Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues);
+ if (animator == null) {
+ viewToKeep.setVisibility(finalVisibility);
+ } else {
+ final View finalViewToKeep = viewToKeep;
+ animator.addListener(new AnimatorListenerAdapter() {
+ boolean mCanceled = false;
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ if (!mCanceled) {
+ finalViewToKeep.setVisibility(finalVisibility);
+ }
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ if (!mCanceled) {
+ finalViewToKeep.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCanceled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mCanceled) {
+ finalViewToKeep.setVisibility(finalVisibility);
+ }
+ }
+ });
+ }
+ return animator;
+ }
+ return null;
+ }
+
+ /**
+ * The default implementation of this method returns a null Animator. Subclasses should
+ * override this method to make targets disappear with the desired transition. The
+ * method should only be called from
+ * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)}.
+ *
+ * @param sceneRoot The root of the transition hierarchy
+ * @param view The View to make disappear. This will be in the target scene's View
+ * hierarchy or in an {@link android.view.ViewGroupOverlay} and will be
+ * VISIBLE.
+ * @param startValues The target values in the start scene
+ * @param endValues The target values in the end scene
+ * @return An Animator to be started at the appropriate time in the
+ * overall transition for this scene change. A null value means no animation
+ * should be run.
+ */
+ public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+ TransitionValues endValues) {
return null;
}
}
diff --git a/core/java/android/transition/VisibilityPropagation.java b/core/java/android/transition/VisibilityPropagation.java
new file mode 100644
index 0000000..0326d47
--- /dev/null
+++ b/core/java/android/transition/VisibilityPropagation.java
@@ -0,0 +1,112 @@
+/*
+ * 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.view.View;
+
+/**
+ * Base class for <code>TransitionPropagation</code>s that care about
+ * View Visibility and the center position of the View.
+ */
+public abstract class VisibilityPropagation extends TransitionPropagation {
+
+ /**
+ * The property key used for {@link android.view.View#getVisibility()}.
+ */
+ private static final String PROPNAME_VISIBILITY = "android:visibilityPropagation:visibility";
+
+ /**
+ * The property key used for the center of the View in screen coordinates. This is an
+ * int[2] with the index 0 taking the x coordinate and index 1 taking the y coordinate.
+ */
+ private static final String PROPNAME_VIEW_CENTER = "android:visibilityPropagation:center";
+
+ private static final String[] VISIBILITY_PROPAGATION_VALUES = {
+ PROPNAME_VISIBILITY,
+ PROPNAME_VIEW_CENTER,
+ };
+
+ @Override
+ public void captureValues(TransitionValues values) {
+ View view = values.view;
+ values.values.put(PROPNAME_VISIBILITY, view.getVisibility());
+ int[] loc = new int[2];
+ view.getLocationOnScreen(loc);
+ loc[0] += Math.round(view.getTranslationX());
+ loc[0] += view.getWidth() / 2;
+ loc[1] += Math.round(view.getTranslationY());
+ loc[1] += view.getHeight() / 2;
+ values.values.put(PROPNAME_VIEW_CENTER, loc);
+ }
+
+ @Override
+ public String[] getPropagationProperties() {
+ return VISIBILITY_PROPAGATION_VALUES;
+ }
+
+ /**
+ * Returns {@link android.view.View#getVisibility()} for the View at the time the values
+ * were captured.
+ * @param values The TransitionValues captured at the start or end of the Transition.
+ * @return {@link android.view.View#getVisibility()} for the View at the time the values
+ * were captured.
+ */
+ public int getViewVisibility(TransitionValues values) {
+ if (values == null) {
+ return View.GONE;
+ }
+ Integer visibility = (Integer) values.values.get(PROPNAME_VISIBILITY);
+ if (visibility == null) {
+ return View.GONE;
+ }
+ return visibility;
+ }
+
+ /**
+ * Returns the View's center x coordinate, relative to the screen, at the time the values
+ * were captured.
+ * @param values The TransitionValues captured at the start or end of the Transition.
+ * @return the View's center x coordinate, relative to the screen, at the time the values
+ * were captured.
+ */
+ public int getViewX(TransitionValues values) {
+ return getViewCoordinate(values, 0);
+ }
+
+ /**
+ * Returns the View's center y coordinate, relative to the screen, at the time the values
+ * were captured.
+ * @param values The TransitionValues captured at the start or end of the Transition.
+ * @return the View's center y coordinate, relative to the screen, at the time the values
+ * were captured.
+ */
+ public int getViewY(TransitionValues values) {
+ return getViewCoordinate(values, 1);
+ }
+
+ private static int getViewCoordinate(TransitionValues values, int coordinateIndex) {
+ if (values == null) {
+ return -1;
+ }
+
+ int[] coordinates = (int[]) values.values.get(PROPNAME_VIEW_CENTER);
+ if (coordinates == null) {
+ return -1;
+ }
+
+ return coordinates[coordinateIndex];
+ }
+}
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index d6e1781..ad33b6f 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -1226,6 +1226,11 @@
}
private static native void nSetDisplayListData(long displayList, long newData);
+ @Override
+ void fence() {
+ // Everything is immediate, so this is a no-op
+ }
+
private RenderNode buildDisplayList(View view, HardwareCanvas canvas) {
if (mDrawDelta <= 0) {
return view.mRenderNode;
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 4f646e1..ae265aa 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -576,6 +576,11 @@
abstract void setDisplayListData(long displayList, long newData);
/**
+ * Blocks until all previously queued work has completed.
+ */
+ abstract void fence();
+
+ /**
* Describes a series of frames that should be drawn on screen as a graph.
* Each frame is composed of 1 or more elements.
*/
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 7b8a1ff..3d143d7 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -245,6 +245,11 @@
}
@Override
+ void fence() {
+ nFence(mNativeProxy);
+ }
+
+ @Override
protected void finalize() throws Throwable {
try {
nDeleteProxy(mNativeProxy);
@@ -277,4 +282,6 @@
private static native long nCreateTextureLayer(long nativeProxy);
private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
private static native void nDestroyLayer(long nativeProxy, long layer);
+
+ private static native void nFence(long nativeProxy);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a35c28e..94f0683 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2259,6 +2259,9 @@
if (mReportNextDraw) {
mReportNextDraw = false;
+ if (mAttachInfo.mHardwareRenderer != null) {
+ mAttachInfo.mHardwareRenderer.fence();
+ }
if (LOCAL_LOGV) {
Log.v(TAG, "FINISHED DRAWING: " + mWindowAttributes.getTitle());
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 0cd6325..7bd1f56 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityOptions;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
@@ -1390,11 +1389,11 @@
* @param options Options to set or null for none
* @hide
*/
- public void setTransitionOptions(ActivityOptions options, SceneTransitionListener listener) {
+ public void setTransitionOptions(Bundle options, SceneTransitionListener listener) {
}
/**
- * A callback for Activity transitions to be told when the shared element is ready to be shown
+ * A callback for Window transitions to be told when the shared element is ready to be shown
* and start the transition to its target location.
* @hide
*/
@@ -1407,27 +1406,57 @@
}
/**
- * Controls when the Activity enter scene is triggered and the background is faded in. If
- * triggerEarly is true, the enter scene will begin as soon as possible and the background
- * will fade in when all shared elements are ready to begin transitioning. If triggerEarly is
- * false, the Activity enter scene and background fade will be triggered when the calling
- * Activity's exit transition completes.
- *
- * @param triggerEarly Set to true to have the Activity enter scene transition in as early as
- * possible or set to false to wait for the calling Activity to exit first.
+ * Controls how the Activity's start Scene is faded in and when the enter scene
+ * is triggered to start.
+ * <p>When allow is true, the enter Scene will begin as soon as possible
+ * and the background will fade in when all shared elements are ready to begin
+ * transitioning. If allow is false, the Activity enter Scene and
+ * background fade will be triggered when the calling Activity's exit transition
+ * completes.</p>
+ * @param allow Set to true to have the Activity enter scene transition in
+ * as early as possible or set to false to wait for the calling
+ * Activity to exit first. The default value is true.
*/
- public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
+ public void setAllowOverlappingEnterTransition(boolean allow) {
+ }
+
+ /**
+ * Controls how the Activity's Scene fades out and when the calling Activity's
+ * enter scene is triggered when finishing to return to a calling Activity.
+ * <p>When allow is true, the Scene will fade out quickly
+ * and inform the calling Activity to transition in when the fade completes.
+ * When allow is false, the calling Activity will transition in after
+ * the Activity's Scene has exited.
+ * </p>
+ * @param allow Set to true to have the Activity fade out as soon as possible
+ * and transition in the calling Activity. The default value is
+ * true.
+ */
+ public void setAllowOverlappingExitTransition(boolean allow) {
}
/**
* Start the exit transition.
* @hide
*/
- public Bundle startExitTransition(ActivityOptions options) {
+ public Bundle startExitTransitionToCallee(Bundle options) {
return null;
}
/**
+ * Starts the transition back to the calling Activity.
+ * onTransitionEnd will be called on the current thread if there is no exit transition.
+ * @hide
+ */
+ public void startExitTransitionToCaller(Runnable onTransitionEnd) {
+ onTransitionEnd.run();
+ }
+
+ /** @hide */
+ public void restoreViewVisibilityAfterTransitionToCallee() {
+ }
+
+ /**
* On entering Activity Scene transitions, shared element names may be mapped from a
* source Activity's specified name to a unique shared element name in the View hierarchy.
* Under most circumstances, mapping is not necessary - a single View will have the
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 4734712..dfdb9ae 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -41,6 +41,7 @@
out List<IBinder> notificationKeys, out List<StatusBarNotification> notifications,
out int[] switches, out List<IBinder> binders);
void onPanelRevealed();
+ void onPanelHidden();
void onNotificationClick(String pkg, String tag, int id, int userId);
void onNotificationError(String pkg, String tag, int id,
int uid, int initialPid, String message, int userId);
diff --git a/core/java/com/android/internal/widget/AutoScrollHelper.java b/core/java/com/android/internal/widget/AutoScrollHelper.java
index 7a294aa..0d468ca 100644
--- a/core/java/com/android/internal/widget/AutoScrollHelper.java
+++ b/core/java/com/android/internal/widget/AutoScrollHelper.java
@@ -892,6 +892,10 @@
public boolean canTargetScrollVertically(int direction) {
final AbsListView target = mTarget;
final int itemCount = target.getCount();
+ if (itemCount == 0) {
+ return false;
+ }
+
final int childCount = target.getChildCount();
final int firstPosition = target.getFirstVisiblePosition();
final int lastPosition = firstPosition + childCount;
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index d079349c..cf95657 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -59,13 +59,14 @@
static jlong android_view_RenderNode_create(JNIEnv* env, jobject clazz) {
RenderNode* displayList = new RenderNode();
+ displayList->incStrong(0);
return reinterpret_cast<jlong>(displayList);
}
static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,
jobject clazz, jlong displayListPtr) {
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
- RenderNode::destroyDisplayListDeferred(displayList);
+ displayList->decStrong(0);
}
// ----------------------------------------------------------------------------
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 98bec1b..32890cf 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -182,6 +182,12 @@
proxy->destroyLayer(layer);
}
+static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
+ jlong proxyPtr) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ proxy->fence();
+}
+
#endif
// ----------------------------------------------------------------------------
@@ -209,6 +215,7 @@
{ "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
{ "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
{ "nDestroyLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_destroyLayer },
+ { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
#endif
};
diff --git a/core/res/res/drawable-hdpi/ab_bottom_solid_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_bottom_solid_qntm_alpha.9.png
deleted file mode 100644
index 406bf58..0000000
--- a/core/res/res/drawable-hdpi/ab_bottom_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_bottom_transparent_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_bottom_transparent_qntm_alpha.9.png
deleted file mode 100644
index 409d3cd..0000000
--- a/core/res/res/drawable-hdpi/ab_bottom_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_solid_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_solid_qntm_alpha.9.png
deleted file mode 100644
index 9d7b25f..0000000
--- a/core/res/res/drawable-hdpi/ab_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_solid_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_stacked_solid_qntm_alpha.9.png
deleted file mode 100644
index 1222711..0000000
--- a/core/res/res/drawable-hdpi/ab_stacked_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_stacked_transparent_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_stacked_transparent_qntm_alpha.9.png
deleted file mode 100644
index d0fcc25..0000000
--- a/core/res/res/drawable-hdpi/ab_stacked_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_transparent_qntm_alpha.9.png
deleted file mode 100644
index 5fa4ec4..0000000
--- a/core/res/res/drawable-hdpi/ab_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_solid_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_bottom_solid_qntm_alpha.9.png
deleted file mode 100644
index 219d311..0000000
--- a/core/res/res/drawable-mdpi/ab_bottom_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_bottom_transparent_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_bottom_transparent_qntm_alpha.9.png
deleted file mode 100644
index bfdc933..0000000
--- a/core/res/res/drawable-mdpi/ab_bottom_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_solid_qntm_alpha.9.png
deleted file mode 100644
index bd818b5..0000000
--- a/core/res/res/drawable-mdpi/ab_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_solid_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_stacked_solid_qntm_alpha.9.png
deleted file mode 100644
index 41c7ce6..0000000
--- a/core/res/res/drawable-mdpi/ab_stacked_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_stacked_transparent_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_stacked_transparent_qntm_alpha.9.png
deleted file mode 100644
index 961a73e5..0000000
--- a/core/res/res/drawable-mdpi/ab_stacked_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_transparent_qntm_alpha.9.png
deleted file mode 100644
index 2e42386..0000000
--- a/core/res/res/drawable-mdpi/ab_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_solid_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_bottom_solid_qntm_alpha.9.png
deleted file mode 100644
index 312f76c..0000000
--- a/core/res/res/drawable-xhdpi/ab_bottom_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_bottom_transparent_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_bottom_transparent_qntm_alpha.9.png
deleted file mode 100644
index 49e0a49..0000000
--- a/core/res/res/drawable-xhdpi/ab_bottom_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_solid_qntm_alpha.9.png
deleted file mode 100644
index fb0d0b6..0000000
--- a/core/res/res/drawable-xhdpi/ab_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_solid_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_stacked_solid_qntm_alpha.9.png
deleted file mode 100644
index 6d87890..0000000
--- a/core/res/res/drawable-xhdpi/ab_stacked_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_stacked_transparent_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_stacked_transparent_qntm_alpha.9.png
deleted file mode 100644
index 58f3e0f..0000000
--- a/core/res/res/drawable-xhdpi/ab_stacked_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_transparent_qntm_alpha.9.png
deleted file mode 100644
index c37ba9e..0000000
--- a/core/res/res/drawable-xhdpi/ab_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_bottom_solid_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_bottom_solid_qntm_alpha.9.png
deleted file mode 100644
index 65b8d4a..0000000
--- a/core/res/res/drawable-xxhdpi/ab_bottom_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_bottom_transparent_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_bottom_transparent_qntm_alpha.9.png
deleted file mode 100644
index a397baa..0000000
--- a/core/res/res/drawable-xxhdpi/ab_bottom_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_solid_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_solid_qntm_alpha.9.png
deleted file mode 100644
index b56fa4a..0000000
--- a/core/res/res/drawable-xxhdpi/ab_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_stacked_solid_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_stacked_solid_qntm_alpha.9.png
deleted file mode 100644
index 71b9737..0000000
--- a/core/res/res/drawable-xxhdpi/ab_stacked_solid_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_stacked_transparent_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_stacked_transparent_qntm_alpha.9.png
deleted file mode 100644
index e2cc715..0000000
--- a/core/res/res/drawable-xxhdpi/ab_stacked_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png
deleted file mode 100644
index 605d1de..0000000
--- a/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ab_bottom_solid_quantum.xml b/core/res/res/drawable/ab_bottom_solid_quantum.xml
deleted file mode 100644
index 848737e..0000000
--- a/core/res/res/drawable/ab_bottom_solid_quantum.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ab_bottom_solid_qntm_alpha"
- android:tint="?attr/colorBackground"
- android:tintMode="multiply" />
diff --git a/core/res/res/drawable/ab_bottom_transparent_quantum.xml b/core/res/res/drawable/ab_bottom_transparent_quantum.xml
deleted file mode 100644
index 29df6b9..0000000
--- a/core/res/res/drawable/ab_bottom_transparent_quantum.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ab_bottom_transparent_qntm_alpha"
- android:tint="?attr/colorBackground"
- android:tintMode="multiply" />
diff --git a/core/res/res/drawable/ab_solid_quantum.xml b/core/res/res/drawable/ab_solid_quantum.xml
deleted file mode 100644
index e56bb40..0000000
--- a/core/res/res/drawable/ab_solid_quantum.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ab_solid_qntm_alpha"
- android:tint="?attr/colorBackground"
- android:tintMode="multiply" />
diff --git a/core/res/res/drawable/ab_stacked_solid_quantum.xml b/core/res/res/drawable/ab_stacked_solid_quantum.xml
deleted file mode 100644
index df775af..0000000
--- a/core/res/res/drawable/ab_stacked_solid_quantum.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ab_stacked_solid_qntm_alpha"
- android:tint="?attr/colorBackground"
- android:tintMode="multiply" />
diff --git a/core/res/res/drawable/ab_stacked_transparent_quantum.xml b/core/res/res/drawable/ab_stacked_transparent_quantum.xml
deleted file mode 100644
index bdae6b9..0000000
--- a/core/res/res/drawable/ab_stacked_transparent_quantum.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ab_stacked_transparent_qntm_alpha"
- android:tint="?attr/colorBackground"
- android:tintMode="multiply" />
diff --git a/core/res/res/drawable/ab_transparent_quantum.xml b/core/res/res/drawable/ab_transparent_quantum.xml
deleted file mode 100644
index 495bfb6..0000000
--- a/core/res/res/drawable/ab_transparent_quantum.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ab_transparent_qntm_alpha"
- android:tint="?attr/colorControlNormal" />
diff --git a/core/res/res/layout/alert_dialog_quantum.xml b/core/res/res/layout/alert_dialog_quantum.xml
index 93d6d1e..98b68797 100644
--- a/core/res/res/layout/alert_dialog_quantum.xml
+++ b/core/res/res/layout/alert_dialog_quantum.xml
@@ -18,7 +18,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parentPanel"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@@ -102,10 +102,6 @@
android:maxLines="2"
android:minHeight="@dimen/alert_dialog_button_bar_height"
style="?android:attr/buttonBarButtonStyle" />
- <View android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:visibility="invisible" />
<Button android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index b1afec1..77f537b 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -24,7 +24,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:splitMotionEvents="false"
- android:theme="?attr/actionBarWidgetTheme">
+ android:theme="?attr/actionBarTheme">
<FrameLayout android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@@ -33,25 +33,25 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
- style="?android:attr/actionBarStyle"
+ style="?attr/actionBarStyle"
android:sharedElementName="android:action_bar"
android:gravity="top">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="?android:attr/actionBarStyle" />
+ style="?attr/actionBarStyle" />
<com.android.internal.widget.ActionBarContextView
android:id="@+id/action_context_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
- style="?android:attr/actionModeStyle" />
+ style="?attr/actionModeStyle" />
</com.android.internal.widget.ActionBarContainer>
<com.android.internal.widget.ActionBarContainer android:id="@+id/split_action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="?android:attr/actionBarSplitStyle"
+ style="?attr/actionBarSplitStyle"
android:visibility="gone"
android:gravity="center"/>
</com.android.internal.widget.ActionBarOverlayLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 89b16e9..b9bdfb9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Laat \'n program luister vir waarnemings oor netwerktoestande. Behoort nooit nodig te wees vir normale programme nie."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"verander invoertoestelkalibrasie"</string>
<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="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>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 7703532..22246c1 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -270,13 +270,13 @@
<string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"የበመልዕክት-በኩል-ምላሽ-ስጥ ክስተቶችን ይላኩ"</string>
<string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"መተግበሪያው ሌሎች የመልዕክት መላኪያ መተግበሪያዎች ለመጪ ጥሪዎች በመልዕክት-በኩል-ምላሽ-መስጠት ስራን እንዲይዙ ጥያቄዎች እንዲልክላቸው ያስችለዋል።"</string>
<string name="permlab_readSms" msgid="8745086572213270480">"የጽሑፍ መልዕክቶችዎን ያንብቡ (ኤስ.ኤም.ኤስ. ወይም ኤም.ኤም.ኤስ.)"</string>
- <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"መገለጫው በጡባዊ ቱኮህ ወይም በSIM ካርድህ የተከማቹ የኤስ.ኤም.ኤስ. መልእክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልእክቶች እንዲያነብ ይፈቅድለታል።"</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"መገለጫው በጡባዊ ተኮዎ ወይም በSIM ካርድዎ የተከማቹ የኤስኤምኤስ. መልዕክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስኤምኤስ መልዕክቶች እንዲያነብ ይፈቅድለታል።"</string>
<string name="permdesc_readSms" product="default" msgid="3695967533457240550">"መገለጫው በስልክዎ ወይም በSIM ካርድዎ የተከማቹ የኤስ.ኤም.ኤስ. መልዕክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልዕክቶች እንዲያነብ ይፈቅድለታል።"</string>
<string name="permlab_writeSms" msgid="3216950472636214774">"የጽሑፍ መልዕክቶችህን አርትዕ (ኤስ.ኤም.ኤስ. ወይም ኤም.ኤም.ኤስ.)"</string>
<string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"በጡባዊ ተኮህ ወይም ሲም ካርድህ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ፡፡መልዕክቶችህን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ፡፡"</string>
<string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"በስልክዎ ወይም ሲም ካርድዎ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። መልዕክቶችዎን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ።"</string>
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"የፅሁፍ መልዕክቶችን ተቀበል (WAP)"</string>
- <string name="permdesc_receiveWapPush" msgid="748232190220583385">"መተግበሪያው የWAP መልእክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ፈቃድ የተላኩልህን መልእክቶች ላንተ ሳያሳይህ የመቆጣጠር ወይም የመሰረዝ ብቃትን ያጠቃልላል።"</string>
+ <string name="permdesc_receiveWapPush" msgid="748232190220583385">"መተግበሪያው የWAP መልዕክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ፈቃድ የተላኩልዎን መልዕክቶች ለእርስዎ ሳያሳይዎ የመቆጣጠር ወይም የመሰረዝ ብቃትን ያጠቃልላል።"</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"አሂድ መተግበሪያዎችን ሰርስረው ያውጡ"</string>
<string name="permdesc_getTasks" msgid="7454215995847658102">"መተግበሪያው በአሁኑ ጊዜና በቅርቡ እየተካሄዱ ስላሉ ተግባሮችን መረጃ ሰርስሮ እንዲያወጣ ይፈቅድለታል። ይህ መተግበሪያው በመሳሪያው ላይ የትኛዎቹ መተግበሪያዎች ጥቅም ላይ ስለመዋላቸው መረጃ እንዲያገኝ ሊፈቅድለት ይችላል።"</string>
<string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"በተለያዩ ተጠቃሚዎች መካከል መስተጋብር መፍጠር"</string>
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"አንድ መተግበሪያ በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን እንዲያዳምጥ ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አስፈላጊ ሊሆን አይገባም።"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"የግቤት መሣሪያ ማስተካከያ ቀይር"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4e04215..9efd8eb 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"للسماح للتطبيق بالاستماع إلى ملاحظات حول أحوال الشبكة. لا حاجة إلى هذا مع التطبيقات العادية."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"تغيير معايرة أجهزة الإدخال"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 0556d7a..366de7c 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Разрешава на приложението да слуша за наблюдения на мрежовите условия. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"промяна на калибрирането на устройството за въвеждане"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -1321,8 +1323,8 @@
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Разрешава на приложението да контролира функцията за защита на клавишите."</string>
<string name="permlab_trust_listener" msgid="1765718054003704476">"Следене за промени в състоянието на надеждност"</string>
<string name="permdesc_trust_listener" msgid="8233895334214716864">"Разрешава на приложението да следи за промени в състоянието на надеждност."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Обвързване с услуга за надеждни агенти"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Разрешава на приложението да се обвърже с услуга за надеждни агенти."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Обвързване с услуга за trust agents"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Разрешава на приложението да се обвърже с услуга за trust agents."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Взаимодействие със системата за актуализации и възстановяване"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Разрешава на приложението да взаимодейства със системата за възстановяване и системните актуализации."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Докоснете двукратно за управление на промяната на мащаба"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3e8bc78..6cba689 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -430,19 +430,19 @@
<string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permet que una aplicació concedeixi o denegui permisos específics per a aquesta o per a altres aplicacions. És possible que les aplicacions malicioses ho facin servir per accedir a funcions a les quals no has concedit accés."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"defineix les aplicacions preferides"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permet que l\'aplicació modifiqui les aplicacions preferides. Les aplicacions malicioses poden canviar silenciosament les aplicacions que s\'executen, falsejar les aplicacions existents o recollir dades privades de l\'usuari."</string>
- <string name="permlab_writeSettings" msgid="2226195290955224730">"modificació de la configuració del sistema"</string>
+ <string name="permlab_writeSettings" msgid="2226195290955224730">"modificar la configuració del sistema"</string>
<string name="permdesc_writeSettings" msgid="7775723441558907181">"Permet que l\'aplicació modifiqui les dades de configuració del sistema. Les aplicacions malicioses poden malmetre la configuració del sistema."</string>
<string name="permlab_writeSecureSettings" msgid="204676251876718288">"modificar la configuració de seguretat del sistema"</string>
<string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Permet que l\'aplicació modifiqui les dades de la configuració de seguretat del sistema. No indicat per a les aplicacions normals."</string>
<string name="permlab_writeGservices" msgid="2149426664226152185">"modificar el mapa de serveis de Google"</string>
<string name="permdesc_writeGservices" msgid="1287309437638380229">"Permet que l\'aplicació modifiqui el mapa dels serveis de Google. No la poden fer servir les aplicacions normals."</string>
- <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"execució en iniciar"</string>
+ <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"executar-se a l\'inici"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Permet que l\'aplicació s\'iniciï tan bon punt el sistema hagi acabat d\'arrencar. Això pot fer que es trigui més a iniciar el telèfon i permetre a l\'aplicació alentir-ne el funcionament general en executar-se sempre."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permet que l\'aplicació s\'iniciï tan bon punt el sistema hagi acabat d\'arrencar. Això pot fer que es trigui més a iniciar el telèfon i permetre a l\'aplicació alentir-ne el funcionament general si s\'executa sempre."</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"enviar difusió permanent"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permet que l\'aplicació enviï emissions permanents, que es conserven després de finalitzar l\'emissió. L\'ús excessiu pot alentir o desestabilitzar la tauleta si li fan utilitzar massa memòria."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permet que l\'aplicació enviï emissions permanents, que es conserven després de finalitzar l\'emissió. L\'ús excessiu pot alentir o desestabilitzar el telèfon si li fan utilitzar massa memòria."</string>
- <string name="permlab_readContacts" msgid="8348481131899886131">"lectura dels contactes"</string>
+ <string name="permlab_readContacts" msgid="8348481131899886131">"consultar els contactes"</string>
<string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permet que l\'aplicació llegeixi dades sobre els contactes que tinguis emmagatzemats a la tauleta, inclosa la freqüència amb què has trucat, has enviat correus electrònics o t\'has comunicat d\'altres maneres amb persones concretes. Aquest permís permet que les aplicacions desin les dades dels teus contactes, i és possible que les aplicacions malicioses comparteixin dades dels contactes sense el teu coneixement."</string>
<string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permet que l\'aplicació llegeixi dades sobre els contactes que tinguis emmagatzemats al telèfon, inclosa la freqüència amb què has trucat, has enviat correus electrònics o t\'has comunicat d\'altres maneres amb persones concretes. Aquest permís permet que les aplicacions desin les dades dels teus contactes, i és possible que les aplicacions malicioses comparteixin dades dels contactes sense el teu coneixement."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"modificar els teus contactes"</string>
@@ -504,7 +504,7 @@
<string name="permdesc_recordAudio" msgid="4906839301087980680">"Permet que l\'aplicació enregistri àudio amb el micròfon. Aquest permís permet que l\'aplicació enregistri àudio en qualsevol moment sense la teva confirmació."</string>
<string name="permlab_sim_communication" msgid="1180265879464893029">"comunicació SIM"</string>
<string name="permdesc_sim_communication" msgid="5725159654279639498">"Permet que l\'aplicació enviï ordres a la SIM. Això és molt perillós."</string>
- <string name="permlab_camera" msgid="3616391919559751192">"fes fotos i vídeos"</string>
+ <string name="permlab_camera" msgid="3616391919559751192">"fer fotos i vídeos"</string>
<string name="permdesc_camera" msgid="8497216524735535009">"Permet que l\'aplicació faci fotos i vídeos amb la càmera. Aquest permís permet que l\'aplicació utilitzi la càmera en qualsevol moment sense la teva confirmació."</string>
<string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"desactiva la transmissió del LED indicador en fer servir la càmera"</string>
<string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Permet que una aplicació dels sistema preinstal·lada desactivi el LED indicador d\'ús de la càmera."</string>
@@ -594,7 +594,7 @@
<string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Permet que l\'aplicació obtingui la llista de comptes coneguts pel telèfon. Això pot incloure tots els comptes que hagin creat les aplicacions que tens instal·lades."</string>
<string name="permlab_authenticateAccounts" msgid="5265908481172736933">"creació de comptes i definició de contrasenyes"</string>
<string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Permet que l\'aplicació utilitzi les funcions d\'autenticador de comptes del gestor de comptes, incloses la creació de comptes i l\'obtenció i la definició de les seves contrasenyes."</string>
- <string name="permlab_manageAccounts" msgid="4983126304757177305">"addició o eliminació de comptes"</string>
+ <string name="permlab_manageAccounts" msgid="4983126304757177305">"afegir o eliminar comptes"</string>
<string name="permdesc_manageAccounts" msgid="8698295625488292506">"Permet que l\'aplicació dugui a terme operacions com ara afegir i eliminar comptes i suprimir-ne la contrasenya."</string>
<string name="permlab_useCredentials" msgid="235481396163877642">"fer servir comptes del dispositiu"</string>
<string name="permdesc_useCredentials" msgid="7984227147403346422">"Permet que l\'aplicació sol·liciti testimonis d\'autenticació."</string>
@@ -631,13 +631,13 @@
<string name="permlab_bluetooth" msgid="6127769336339276828">"emparella amb dispositius Bluetooth"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Permet que l\'aplicació visualitzi la configuració de Bluetooth de la tauleta i que estableixi i accepti connexions amb dispositius sincronitzats."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permet que una aplicació visualitzi la configuració de Bluetooth del telèfon i que estableixi i accepti connexions amb els dispositius sincronitzats."</string>
- <string name="permlab_nfc" msgid="4423351274757876953">"controla Near Field Communication (NFC)"</string>
+ <string name="permlab_nfc" msgid="4423351274757876953">"controlar Comunicació de camp proper (NFC)"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivació del bloqueig de pantalla"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet que l\'aplicació desactivi el bloqueig del teclat i qualsevol element de seguretat de contrasenyes associat. Per exemple, el telèfon desactiva el bloqueig del teclat en rebre una trucada telefònica entrant i, a continuació, reactiva el bloqueig del teclat quan finalitza la trucada."</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"llegir la configuració de sincronització"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet que l\'aplicació llegeixi la configuració de sincronització d\'un compte. Per exemple, això pot determinar que l\'aplicació Persones estigui sincronitzada amb un compte."</string>
- <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activació o desactivació de la sincronització"</string>
+ <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activar o desactivar la sincronització"</string>
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet que una aplicació modifiqui la configuració de sincronització d\'un compte. Per exemple, aquesta acció es pot fer servir per activar la sincronització de l\'aplicació Persones amb un compte."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"llegir les estadístiques de sincronització"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permet que una aplicació llegeixi les estadístiques de sincronització d\'un compte, inclòs l\'historial d\'esdeveniments sincronitzats i quantes dades se sincronitzen."</string>
@@ -649,7 +649,7 @@
<string name="permdesc_readDictionary" msgid="659614600338904243">"Permet que l\'aplicació llegeixi les paraules, els noms i les frases que l\'usuari pot haver emmagatzemat al seu diccionari."</string>
<string name="permlab_writeDictionary" msgid="2183110402314441106">"afegeix paraules al diccionari definit per l\'usuari"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permet que l\'aplicació escrigui paraules noves al diccionari de l\'usuari."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"lectura contingut emmagat. USB"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"consultar contingut emmagatzematge USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"lectura del contingut de la targeta SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permet que l\'aplicació llegeixi el contingut de l\'emmagatzematge USB."</string>
<string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Permet que l\'aplicació llegeixi el contingut de la targeta SD."</string>
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet que una aplicació conegui les observacions sobre les condicions de la xarxa. No s\'ha de necessitar mai per a aplicacions normals."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"canviar el calibratge del dispositiu d\'entrada"</string>
<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">"accés 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="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 intents de desbloqueig de pantalla"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0cd8f53..b4972ef 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikaci naslouchat informacím o stavu sítě. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"měnit kalibraci vstupního zařízení"</string>
<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="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>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ece8bce..d3469f1 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillader, at en applikation observerer netværksforhold. Bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"skift kalibrering for inputenheden"</string>
<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>
<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>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tillader, at en applikation får adgang til et nøglebeskyttet lager."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Administrer, om nøglebeskyttelse skal vises eller skjules"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillader, at en applikation styrer nøglebeskyttelsen."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Registrer ændringer i tillidstilstand."</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"Tillader, at en applikation registrerer ændringer i tillidstilstand."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Forpligt til en tillidsagenttjeneste"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Tillader, at en applikation forpligter sig til en tillidsagenttjeneste."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Registrere ændringer i trust-tilstand."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Tillader, at en applikation registrerer ændringer i trust-tilstand."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Knytte sig til en trust agent-tjeneste"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Tillader, at en applikation knytter sig til en trust agent-tjeneste."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interager med opdaterings- og gendannelsessystemet"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Giver en applikation tilladelse til at interagere med gendannelsessystemet og systemopdateringerne."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tryk to gange for zoomstyring"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 639d8ca..52ea81c 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ermöglicht der App, Informationen zu den Netzwerkbedingungen zu erfassen. Sollte für normale Apps nie benötigt werden."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"Kalibrierung für Eingabegerät ändern"</string>
<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="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>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ermöglicht einer App den Zugriff auf mit Keyguard geschützten Speicher"</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Anzeige und Ausblenden des Keyguard steuern"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Apps können den Keyguard steuern."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Auf Änderungen im vertrauenswürdigen Status überwachen"</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"Ermöglicht einer App die Überwachungen auf Änderungen im vertrauenswürdigen Status"</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"An einen Dienst für vertrauenswürdige Anbieter binden"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ermöglicht einer App das Binden an einen Dienst für vertrauenswürdige Anbieter"</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Überwachung von Änderungen des Trust-Status"</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Ermöglicht einer App die Überwachungen von Änderungen des Trust-Status"</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"An Trust Agent-Service anbinden"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ermöglicht einer App die Anbindung an einen Trust Agent-Service"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Mit Update- und Wiederherstellungssystem interagieren"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Ermöglicht einer App die Interaktion mit dem Wiederherstellungssystem und den Systemupdates"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Für Zoomeinstellung zweimal berühren"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index aacb9a2..8b7e618 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Επιτρέπει σε μια εφαρμογή να λαμβάνει παρατηρήσεις σχετικά με την κατάσταση δικτύου. Δεν θα πρέπει να απαιτείται ποτέ για κανονικές εφαρμογές."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"αλλαγή βαθμονόμησης της συσκευής εισόδου"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -1321,8 +1323,8 @@
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Επιτρέπει σε μια εφαρμογή τον έλεγχο του κλειδώματος πληκτρολογίου."</string>
<string name="permlab_trust_listener" msgid="1765718054003704476">"Αντίληψη αλλαγών καταστάσεων εμπιστοσύνης."</string>
<string name="permdesc_trust_listener" msgid="8233895334214716864">"Επιτρέπει σε μια εφαρμογή να αντιλαμβάνεται τις αλλαγές στην κατάσταση εμπιστοσύνης."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Σύνδεση σε υπηρεσία έμπιστου αντιπροσώπου"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Επιτρέπει σε μια εφαρμογή να συνδεθεί σε μια υπηρεσία έμπιστου αντιπροσώπου."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Σύνδεση σε υπηρεσία trust agent"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Επιτρέπει σε μια εφαρμογή να συνδεθεί σε μια υπηρεσία trust agents."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Αλληλεπίδραση με το σύστημα ενημέρωσης και ανάκτησης"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Επιτρέπει σε μια εφαρμογή να αλληλεπιδρά με το σύστημα ανάκτησης και ενημερώσεων συστήματος."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Αγγίξτε δύο φορές για έλεγχο εστίασης"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 1b2e61b..179691b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
<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="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>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 1b2e61b..179691b 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
<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="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>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1483f0f..dc67e27 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"cambiar la calibración del dispositivo de entrada"</string>
<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>
<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>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 3e4b19b..8386b02 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. No debe ser necesario para aplicaciones normales."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"cambiar la calibración del dispositivo de entrada"</string>
<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="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>
@@ -1319,7 +1321,7 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que una aplicación acceda al almacenamiento seguro de bloqueos."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar cuándo se muestra y se oculta el bloqueo"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que una aplicación controle los bloqueos."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Detectar cambios en estado de confianza."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Detectar cambios en el estado de confianza."</string>
<string name="permdesc_trust_listener" msgid="8233895334214716864">"Permite que una aplicación detecte cambios en el estado de confianza."</string>
<string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Enlazar con un servicio de agente de confianza"</string>
<string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite a una aplicación enlazar con un servicio de agente de confianza."</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 1cb8ba1..4d15e4a 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lubab rakendusel kuulata võrgutingimuste teavet. Ei ole kunagi vajalik tavaliste rakenduste puhul."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"sisendseadme kalibreerimise muutmine"</string>
<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="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>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index ca85f96..b621d49 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"به برنامه امکان میدهد برای بررسی شرایط شبکه گوش دهد. این امکان هرگز نباید برای برنامههای معمولی مورد نیاز باشد."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"تغییر کالیبراسیون دستگاه ورودی"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"طول و نویسههای مجاز در گذرواژههای بازکردن قفل صفحه را کنترل کنید."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاشهای قفل گشایی صفحه"</string>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"به یک برنامه کاربردی برای دسترسی به فضای ذخیرهسازی ایمن محافظ کلید اجازه میدهد."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"کنترل نمایش و پنهان کردن محافظ کلید"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"اجازه میدهد برنامهای محافظ کلید را کنترل کند."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"گوش دادن به تغییرات حالت اعتماد."</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"به یک برنامه کاربردی برای گوش دادن به تغییرات در حالت اعتماد اجازه میدهد."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"اتصال به یک سرویس عامل اعتماد"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"به یک برنامه کاربردی برای اتصال به یک سرویس عامل اعتماد اجازه میدهد."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"گوش دادن به تغییرات وضعیت trust."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"به یک برنامه کاربردی برای گوش دادن به تغییرات در trust اجازه میدهد."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"اتصال به یک سرویس trust agent"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"به یک برنامه کاربردی برای اتصال به یک سرویس trust agent اجازه میدهد."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"تعامل با سیستم بهروزرسانی و بازیابی"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"به یک برنامه کاربردی اجازه میدهد با سیستم بازیابی و بهروزرسانیهای سیستم تعامل داشته باشد."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"دوبار لمس کنید تا بزرگنمایی کنترل شود"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 35e8910..6dd5e56 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Antaa sovellukselle luvan kuunnella verkon tilahavaintoja. Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"Muuttaa syöttölaitteen kalibrointia."</string>
<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="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>
@@ -1319,14 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Sallii sovelluksen käyttää salasanalla suojattua tallennustilaa."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Hallinnoi näppäinvahdin näyttämistä ja piilottamista"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Antaa sovelluksen hallita näppäinvahtia."</string>
- <!-- no translation found for permlab_trust_listener (1765718054003704476) -->
- <skip />
- <!-- no translation found for permdesc_trust_listener (8233895334214716864) -->
- <skip />
- <!-- no translation found for permlab_bind_trust_agent_service (8242093169457695334) -->
- <skip />
- <!-- no translation found for permdesc_bind_trust_agent_service (7041930026024507515) -->
- <skip />
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Seuraa luottamuksen tilamuutoksia."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Antaa sovelluksen seurata luottamuksen tilamuutoksia."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Luotettavaan tahoon sitoutuminen"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Antaa sovelluksen sitoutua luotettavaan tahoon."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Vuorovaikutus päivitys- ja palautusjärjestelmän kanssa"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Sallii sovelluksen vuorovaikutuksen palautusjärjestelmän ja järjestelmäpäivitysten kanssa."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ohjaa zoomausta napauttamalla kahdesti"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 365bbc26..7a8c975 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applications standards."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"modifier le calibrage du périphérique d\'entrée"</string>
<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>
<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>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index ff5f106..a57823f 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter des observations sur les conditions du réseau. Les applications standards ne devraient pas nécessiter cette autorisation."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"modifier le calibrage du périphérique d\'entrée"</string>
<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>
<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>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index e61c815..bdba457 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -641,9 +641,9 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ऐप्स को किसी खाते की समन्वयन सेटिंग संशोधित करने देता है. उदाहरण के लिए, इसका उपयोग लोग ऐप्स का समन्वयन किसी खाते से सक्षम करने में हो सकता है."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"समन्वयन आंकड़े पढ़ें"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"ऐप्स को किसी खाते के समन्वयन आंकड़े, साथ ही समन्वयित ईवेंट का इतिहास और समन्वयित डेटा की मात्रा पढ़ने देता है."</string>
- <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ग्राहकी-प्राप्त फ़ीड पढ़ें"</string>
+ <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता-प्राप्त फ़ीड पढ़ें"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ऐप्स को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string>
- <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"ग्राहकी-प्राप्त फ़ीड लिखें"</string>
+ <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"सदस्यता-प्राप्त फ़ीड लिखें"</string>
<string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ऐप्स को आपके वर्तमान समन्वयित फ़ीड को संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके समन्वयित फ़ीड को बदल सकते है."</string>
<string name="permlab_readDictionary" msgid="4107101525746035718">"शब्दकोश में आपके द्वारा जोड़े गए शब्दों को पढ़ें"</string>
<string name="permdesc_readDictionary" msgid="659614600338904243">"ऐप्स को ऐसे सभी शब्दों, नामों और वाक्यांशों को पढ़ने देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता शब्दकोश में संग्रहीत किए गए हों."</string>
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ऐप्स को नेटवर्क स्थितियों के अवलोकनों को सुनने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट उपकरण कैलिब्रेशन बदलें"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"स्क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 38dd782..fcd51ab 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Omogućuje aplikaciji praćenje motrenja mrežnih uvjeta. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"promjena kalibracije uređaja za unos"</string>
<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. Nikad ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
<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>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 9047cfa..4932e88 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lehetővé teszi egy alkalmazás számára, hogy figyelemmel kísérje a hálózati körülményekkel kapcsolatos észrevételeket. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"beviteli eszköz kalibrációjának módosítása"</string>
<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ége."</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>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 224a9d2..805f77b 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Հավելվածին թույլ է տալիս լսել դիտարկումներ ցանցային պայմանների վերաբերյալ: Սովորական հավելվածների համար երբեք պետք չի գալիս:"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"փոփոխել մուտքի սարքի չափաբերումը"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
@@ -1319,14 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Թույլ է տալիս հավելվածին մուտք գործել ստեղնակողպեքով պաշտպանված պահոց:"</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Կառավարել ստեղնակողպեքի ցուցադրումը և թաքցնումը"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Թույլ է տալիս հավելվածին կառավարել ստեղնաշարի պաշտպանիչը:"</string>
- <!-- no translation found for permlab_trust_listener (1765718054003704476) -->
- <skip />
- <!-- no translation found for permdesc_trust_listener (8233895334214716864) -->
- <skip />
- <!-- no translation found for permlab_bind_trust_agent_service (8242093169457695334) -->
- <skip />
- <!-- no translation found for permdesc_bind_trust_agent_service (7041930026024507515) -->
- <skip />
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Լսել վստահության կարգավիճակի փոփոխությունները:"</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Ծրագրին թույլ է տալիս լսել վստահության կարգավիճակի փոփոխությունները:"</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Կապվել վստահելի գործակալի ծառայությանը"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Ծրագրին թույլ է տալիս կապվել վստահելի գործակալի ծառայությանը:"</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Փոխազդել թարմացման և վերականգնման համակարգի հետ"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Թույլ է տալիս ծրագրին փոխազդել վերականգնման համակարգի և համակարգի թարմացումների հետ:"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Հպեք երկու անգամ` դիտափոխման կարգավորման համար"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 38a2144..e161466 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Memungkinkan aplikasi mendengar untuk observasi kondisi jaringan. Tidak pernah dibutuhkan oleh aplikasi normal."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"mengubah kalibrasi perangkat masukan"</string>
<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="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>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index e99cc45..740075f 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Consente a un\'applicazione di ascoltare le osservazioni sulle condizioni di rete. Da non utilizzare mai con app normali."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"modifica calibrazione del dispositivo di immissione"</string>
<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="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>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index d19b48a..61754c3 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"מאפשרת לאפליקציה לקלוט מעקב אחר תנאי רשת. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"שינוי הכיול של מכשיר קלט"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 9317ee5..62ee883 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ネットワーク状況を監視するためリッスンすることをアプリに許可します。通常のアプリで必要になることはありません。"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"入力デバイスの調整を変更"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index e0efe68..4855f27 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"საშუალებას აძლევს აპლიკაციებს განახორციელოს ქსელის მდგომარეობის მონიტორინგი. ეს ფუნქცია ჩვეულებრივ აპებს არ ჭირდება."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"შეყვანის მოწყობილობის კალიბრაციის ცვლილება"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
@@ -1319,14 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"აპლიკაციას ღილაკების დამცავის უსაფრთხო საცავზე წვდომის უფლება ექნება."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"ღილაკების დამცავის გამოჩენისა და დამალვის მართვა"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"აპლიკაციას შეეძლება ღილაკების დამცავის კონტროლი."</string>
- <!-- no translation found for permlab_trust_listener (1765718054003704476) -->
- <skip />
- <!-- no translation found for permdesc_trust_listener (8233895334214716864) -->
- <skip />
- <!-- no translation found for permlab_bind_trust_agent_service (8242093169457695334) -->
- <skip />
- <!-- no translation found for permdesc_bind_trust_agent_service (7041930026024507515) -->
- <skip />
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"ნდობის მდგომარეობის ცვლილებების მოსმენა."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"საშუალებას აძლევს აპლიკაციას მოუსმინოს ცვლილებებს სანდო მდგომარეობაში."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"სანდო აგენტის სერვისზე მიმაგრება."</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"საშუალებას აძლევს აპლიკაციას მიემაგროს სანდო აგენტის სერვისს."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"განახლებასთან და აღდგენის სისტემასთან ინტერაქცია"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"საშუალებას აძლევს აპლიკაციას მოახდინოს აღდგენის სისტემასთან და სისტემის განახლებასთან ინტერაქცია."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"მასშტაბის მართვისთვის შეეხეთ ორჯერ."</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index f843cdd..73769fb 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ឲ្យកម្មវិធីសង្កេតមើលលើលក្ខខណ្ឌបណ្ដាញ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"ប្ដូរចំណុចឧបករណ៍បញ្ចូល"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"កំណត់ក្បួនពាក្យសម្ងាត់"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យប្រវែង និងតួអក្សរដែលបានអនុញ្ញាតក្នុងពាក្យសម្ងាត់ចាក់សោអេក្រង់។"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យការព្យាយាមដោះសោអេក្រង់"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index be93447..bb26d4f 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"애플리케이션이 네트워크 상태에 대한 관측 보고를 수신하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"입력 기기 보정 변경"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 78d5d1a..60b7da4 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັ່ນຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ. ປົກກະຕິແລ້ວແອັບຯທຳມະດາຈະບໍ່ຕ້ອງການໃຊ້."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"ປ່ຽນການວັດແທ້ອຸປະກອນປ້ອນຂໍ້ມູນ"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1b4d57c..b40e10b 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Leidžiama programai vykdyti tinklo sąlygų stebėjimą. To niekada neturėtų prireikti naudojant įprastas programas."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"keisti įvesties įrenginio kalibravimą"</string>
<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>
<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>
@@ -1321,8 +1323,8 @@
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Programai leidžiama valdyti „KeyGuard“."</string>
<string name="permlab_trust_listener" msgid="1765718054003704476">"Atsižvelgti į patikimos būsenos pakeitimus."</string>
<string name="permdesc_trust_listener" msgid="8233895334214716864">"Programai leidžiama atsižvelgti į patikimos būsenos pakeitimus."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Susisaistyti su patikimos priemonės paslauga"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Programai leidžiama susisaistyti su patikimos priemonės paslauga."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Susisaistyti su „trust agent“ paslauga"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Programai leidžiama susisaistyti su „trust agent“ paslauga."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Sąveikauti su naujiniu ir atkūrimo sistema"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Programai leidžiama sąveikauti su atkūrimo sistema ir sistemos naujiniais."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dukart palieskite, kad valdytumėte mastelio keitimą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 3e86a8e..6b91a6d 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ļauj lietojumprogrammai iegūt informāciju par tīkla stāvokļa novērojumiem. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"mainīt ievadierīces kalibrēšanu"</string>
<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>
<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>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index a52ed6d..ea1baa1 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Аппликешнд сүлжээний байдлын талаар ажиглалтуудыг хүлээн авахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"оролтын төхөөрөмжийн калибрешныг өөрчлөх"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index a997bcd..219e47b 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Membenarkan aplikasi mendengar pemerhatian tentang keadaan rangkaian. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"tukar penentukuran peranti input"</string>
<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>
<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>
@@ -1319,14 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Membenarkan aplikasi mengakses storan selamat pengawal kekunci."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Kawal paparkan dan sembunyikan pengawal kekunci"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Membenarkan aplikasi untuk mengawal pengawal kekunci."</string>
- <!-- no translation found for permlab_trust_listener (1765718054003704476) -->
- <skip />
- <!-- no translation found for permdesc_trust_listener (8233895334214716864) -->
- <skip />
- <!-- no translation found for permlab_bind_trust_agent_service (8242093169457695334) -->
- <skip />
- <!-- no translation found for permdesc_bind_trust_agent_service (7041930026024507515) -->
- <skip />
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Dengar perubahan keadaan amanah."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Membenarkan aplikasi mendengar perubahan dalam keadaan amanah."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Mengikat kepada perkhidmatan ejen amanah"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Membenarkan aplikasi terikat kepada perkhidmatan ejen amanah."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Berinteraksi dengan kemas kini dan sistem pemulihan"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Membenarkan aplikasi berinteraksi dengan sistem pemulihan dan kemas kini sistem."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mendapatkan kawalan zum"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index e5f5a03..593d260 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -164,7 +164,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"Slå av"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string>
<string name="bugreport_title" msgid="2667494803742548533">"Utfør feilrapport"</string>
- <string name="bugreport_message" msgid="398447048750350456">"Informasjon om den nåværende tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stillemodus"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Lyden er av"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Lyden er på"</string>
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Gir appen tillatelse til å lytte etter observasjoner om nettverksforhold. Dette skal ikke være nødvendig for vanlige apper."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"endre kalibreringen av inndataenheter"</string>
<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">"Lar en app klargjøre og bruke DRM-sertifikater. Denne tillatelsen bør aldri være nødvendig for vanlige apper."</string>
<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>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lar en app bruke sikker lagring via keyguard."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrollér om tastelåsen er skjult eller vist"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillater at en app kontrollerer tastelåsen."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Oppdag endringer i pålitelighetsstatusen."</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"Gir appen tillatelse til å oppdage endringer i pålitelighetsstatusen."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Tilknytt en pålitelighetstagent-tjeneste."</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Gir appen tillatelse til å knyttes til en pålitelighetsagent-tjeneste."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Oppdag endringer i tillitsstatusen."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Gir appen tillatelse til å oppdage endringer i tillitsstatusen."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Tilknytt en tillitsagent-tjeneste."</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Gir appen tillatelse til å knyttes til en tillitsagent-tjeneste."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Samhandling med oppdateringer og gjenopprettingssystem"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Tillater en app å samhandle med gjenopprettingsssystemet og systemoppdateringer."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Trykk to ganger for zoomkontroll"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 59d662a..9225c23 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Hiermee kan een app controleren op waarnemingen met betrekking tot netwerkomstandigheden. Nooit vereist voor normale apps."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"kalibratie van invoerapparaat wijzigen"</string>
<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="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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index e888927..931c24c 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Pozwala aplikacji śledzić stan sieci. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"zmiana kalibracji urządzenia wejściwego"</string>
<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="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>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 43a5b68..9eb7512 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que uma aplicação ouça observações sobre as condições da rede. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"alterar a calibragem de entrada do dispositivo"</string>
<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="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>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite a uma aplicação aceder ao armazenamento seguro de proteção de teclado."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar apresentação e ocultação de proteção de teclado"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que uma aplicação controle a proteção de teclado."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Registar alterações no estado fidedigno."</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"Permite que uma aplicação registe alterações no estado fidedigno."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Vincular a um serviço de agente fidedigno"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite que uma aplicação fique vinculada a um serviço de agente fidedigno."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Registar alterações no estado trust."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Permite que uma aplicação registe alterações no trust state."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Vincular a um serviço de trust agent"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite que uma aplicação fique vinculada a um serviço de trust agent."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interagir com o sistema de recuperação e de atualização"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Permite que uma aplicação interaja com o sistema de recuperação e as atualizações do sistema."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 046ad13..fd75660 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que o aplicativo detecte observações nas condições da rede. Não deve ser necessário para aplicativos comuns."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"alterar calibragem do dispositivo de entrada"</string>
<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>
<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>
@@ -1319,14 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que o aplicativo acesse o armazenamento seguro do bloqueio de teclado."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar a exibição e ocultação do bloqueio de tela"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que o aplicativo controle o bloqueio de teclado."</string>
- <!-- no translation found for permlab_trust_listener (1765718054003704476) -->
- <skip />
- <!-- no translation found for permdesc_trust_listener (8233895334214716864) -->
- <skip />
- <!-- no translation found for permlab_bind_trust_agent_service (8242093169457695334) -->
- <skip />
- <!-- no translation found for permdesc_bind_trust_agent_service (7041930026024507515) -->
- <skip />
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Detectar alterações no estado de confiança."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Permite que o aplicativo detecte alterações no estado de confiança."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Associar a um serviço de agente de confiança"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite que o aplicativo se associe a um serviço de agente de confiança."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interagir com o sistema de atualizações e recuperação"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Permite que um aplicativo interaja com o sistema de recuperação e as atualizações do sistema."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 79f10aa..4e9806b 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1166,6 +1166,10 @@
<skip />
<!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
<skip />
+ <!-- no translation found for permlab_accessDrmCertificates (7436886640723203615) -->
+ <skip />
+ <!-- no translation found for permdesc_accessDrmCertificates (8073288354426159089) -->
+ <skip />
<!-- no translation found for policylab_limitPassword (4497420728857585791) -->
<skip />
<!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 92f9c52..a8a75a5 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite unei aplicații să asculte observații despre starea rețelei. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"schimbați calibrarea dispozitivului de intrare"</string>
<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">"accesați 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>
<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>
@@ -1319,14 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite unei aplicații să acceseze stocarea securizată când tastatura este blocată."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Stabilește afișarea și ascunderea blocării tastaturii"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite unei aplicații să controleze blocarea tastaturii."</string>
- <!-- no translation found for permlab_trust_listener (1765718054003704476) -->
- <skip />
- <!-- no translation found for permdesc_trust_listener (8233895334214716864) -->
- <skip />
- <!-- no translation found for permlab_bind_trust_agent_service (8242093169457695334) -->
- <skip />
- <!-- no translation found for permdesc_bind_trust_agent_service (7041930026024507515) -->
- <skip />
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Detectarea modificărilor în starea de încredere."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Permite unei aplicații să detecteze modificările în starea de încredere."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Asocierea la un serviciu „agenți de încredere”."</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Permite unei aplicații să se asocieze la un serviciu „agent de încredere”."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Interacțiune cu sistemul de recuperare și de actualizare"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Permite unei aplicații să interacționeze cu sistemul de recuperare și cu actualizările de sistem."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Atingeţi de două ori pentru a mări/micşora"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index fa1bab5..d142e9a 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Приложение сможет использовать данные о состоянии сети. Это разрешение обычно используется только специальными приложениями."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"изменение параметров калибровки экрана"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Приложение сможет получить доступ к хранилищу ключей."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Управлять отображением хранилища ключей"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Приложение сможет управлять хранилищем ключей."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Отслеживание изменений"</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"Приложение сможет отслеживать изменения в работе промежуточного агента."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Подключение к промежуточному агенту"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Приложение сможет подключаться к промежуточному агенту."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Отслеживание изменений статуса доверия"</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Приложение сможет отслеживать изменения в статусе доверия."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Подключение к службе Trust Agents"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Приложение сможет подключаться к службе Trust Agents."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Взаимодействовать с системой восстановления и обновлениями"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Приложение сможет взаимодействовать с системой восстановления и обновлениями системы."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Нажмите дважды для изменения масштаба"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 59bf1a0..707bdf1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikácii zachytávať informácie o stave siete. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"zmeniť kalibráciu vstupného zariadenia"</string>
<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>
<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>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 35607c2..e93b128 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Aplikaciji omogoča spremljanje razmer v omrežju. Pri navadnih aplikacijah to ne bi smelo biti potrebno."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"sprememba umerjanja vhodne naprave"</string>
<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>
<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>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index ecf78e7..b2928e4 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозвољава апликацији да прати податке о условима на мрежи. Не би никада требало да буде потребно за нормалне апликације."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"промени калибрацију улазног уређаја"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дозвољава апликацији да приступа безбедној меморији заштићеној шифром."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Контролиши приказивање и скривање заштите шифром"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дозвољава апликацији да контролише заштиту шифром."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Праћење промена стања поузданости."</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"Дозвољава апликацији да прати промене у стању поузданости."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Везивање за услугу поузданог агента"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Дозвољава апликацији да се веже за услугу поузданог агента."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Праћење промена Trust стања."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Дозвољава апликацији да прати промене Trust стања."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Везивање за услугу Trust agents"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Дозвољава апликацији да се веже за услугу Trust agents."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Интеракција са системом за ажурирање и опоравак"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Дозвољава апликацији да ступа у интеракцију са системом за опоравак и ажурирањима система."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Додирните двапут да бисте контролисали зум"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 016d9da..b134a85 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillåter att appen lyssnar efter information om nätverksförhållanden. Vanliga appar bör aldrig behöva den här behörigheten."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"ändra kalibreringen för inmatningsenheten"</string>
<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="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>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 9e72fe3..8f319f3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Huruhusu programu kusikiliza matukio katika hali za mtandao. Haipaswi kuhitajika kamwe kwa programu za kawaida."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"badilisha urekebishaji wa kifaa cha kuingiza data"</string>
<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="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 idadi ya mara ambazo skrini inajaribu kufunguliwa"</string>
@@ -1319,10 +1321,10 @@
<string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Inaruhusu programu kufikia hifadhi salama ya ufunguo wa ulinzi."</string>
<string name="permlab_control_keyguard" msgid="172195184207828387">"Dhibiti uonyeshaji na ufichaji wa kilinda-funguo"</string>
<string name="permdesc_control_keyguard" msgid="3043732290518629061">"Huruhusu programu kudhibiti kilinda-funguo."</string>
- <string name="permlab_trust_listener" msgid="1765718054003704476">"Sikiliza mabadiliko ya hali ya kuaminiana."</string>
- <string name="permdesc_trust_listener" msgid="8233895334214716864">"Huruhusu programu kusikiliza mabadiliko katika hali ya kuaminiana."</string>
- <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Funga kwenye huduma ya dalali wa kuaminiana"</string>
- <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Huruhusu programu kufunga pamoja kwa huduma ya dalali wa kuaminiana."</string>
+ <string name="permlab_trust_listener" msgid="1765718054003704476">"Sikiliza mabadiliko ya hali ya kuaminiwa."</string>
+ <string name="permdesc_trust_listener" msgid="8233895334214716864">"Huruhusu programu kusikiliza mabadiliko katika hali ya kuaminiwa."</string>
+ <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Funga kwenye huduma ya dalali wa kuaminiwa"</string>
+ <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Huruhusu programu kufungamanisha kwenye huduma ya dalali wa kuaminiwa."</string>
<string name="permlab_recovery" msgid="3157024487744125846">"Ingiliana na sasisho na mfumo wa kurejesha"</string>
<string name="permdesc_recovery" msgid="8511774533266359571">"Huruhusu programu kuingiliana na mfumo wa kurejesha na sasisho la mfumo."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Gusa mara mbili kwa udhibiti cha kuza"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 9890734..ecb3a58 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"อนุญาตให้แอปพลิเคชันฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย ไม่จำเป็นสำหรับแอปปกติ"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"เปลี่ยนการเทียบมาตรฐานอุปกรณ์อินพุต"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index f1c31b62..0a5e64c 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Nagbibigay-daan sa isang application na makinig sa mga obserbasyon sa mga kundisyon ng network. Dapat na hindi kailanman kakailanganin para sa normal na apps."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"baguhin ang pag-calibrate ng input device"</string>
<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>
<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>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index b992aa2..72e149f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Bir uygulamaya, ağ koşullarındaki gözlemleri dinleme izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"giriş cihazı kalibrasyonunu değiştir"</string>
<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>
<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>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 7564602..563d5ee 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозволяє програмі прослуховувати дані спостережень за станом мережі. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"змінювати калібрування пристрою введення"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 28d3776..8c424c3 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Cho phép ứng dụng quan sát các điều kiện mạng. Không bao giờ cần cho ứng dụng thông thường."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"thay đổi hiệu chỉnh thiết bị đầu vào"</string>
<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>
<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>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 382268c..acb4a81 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允许应用监听网络状况的观测信息。普通应用绝不需要此权限。"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"更改输入设备校准设置"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index e892f31..deb5a11 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽對網絡狀況的觀察 (不建議一般應用程式使用)。"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"變更輸入裝置校正設定"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解鎖密碼所允許的長度和字元。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"監控屏幕解鎖嘗試次數"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index df2daa3..b058860 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽網路狀況觀察資訊 (一般應用程式並不需要)。"</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"變更輸入裝置校正設定"</string>
<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="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index fd2134d..aacd3c1 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -687,6 +687,8 @@
<string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ivumela uhlelo lokusebenza ukuthi lulalele okubonwa kuzimo zenethiwekhi. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
<string name="permlab_setInputCalibration" msgid="4902620118878467615">"guqula ukulinganisa kokufaka kwedivayisi"</string>
<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="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>
@@ -796,7 +798,7 @@
<string name="imProtocolYahoo" msgid="8271439408469021273">"i-Yahoo"</string>
<string name="imProtocolSkype" msgid="9019296744622832951">"i-Skype"</string>
<string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
- <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Ama-Hangout"</string>
+ <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string>
<string name="imProtocolIcq" msgid="1574870433606517315">"i-ICQ"</string>
<string name="imProtocolJabber" msgid="2279917630875771722">"i-Jabber"</string>
<string name="imProtocolNetMeeting" msgid="8287625655986827971">"Umhlangano we-Net"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 0fc198e2..46cb9b22 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -691,6 +691,10 @@
buttons. actionBarStyle is still used for the primary
bar. -->
<attr name="actionBarSplitStyle" format="reference" />
+ <!-- Reference to a theme that should be used to inflate the
+ action bar. This will be inherited by any widget inflated
+ into the action bar. -->
+ <attr name="actionBarTheme" format="reference" />
<!-- Reference to a theme that should be used to inflate widgets
and layouts destined for the action bar. Most of the time
this will be a reference to the current theme, but when
@@ -913,8 +917,14 @@
<!-- ============= -->
<!-- Color palette -->
<!-- ============= -->
+ <attr name="colorPrimaryDark" format="color" />
+ <attr name="colorPrimary" format="color" />
+ <attr name="colorPrimaryLight" format="color" />
+ <attr name="colorAccent" format="color" />
+
<attr name="colorControlNormal" format="color" />
<attr name="colorControlActivated" format="color" />
+
<attr name="colorButtonNormal" format="color" />
<attr name="colorButtonPressed" format="color" />
<attr name="colorButtonNormalColored" format="color" />
@@ -4891,6 +4901,24 @@
</attr>
</declare-styleable>
+ <!-- Use <code>slide</code>as the root tag of the XML resource that
+ describes a {@link android.transition.Slide Slide} transition.
+ The attributes of the {@link android.R.styleable#Transition Transition}
+ resource are available in addition to the specific attributes of Slide
+ described here. -->
+ <declare-styleable name="Slide">
+ <attr name="slideEdge">
+ <!-- Slide to and from the bottom edge of the Scene. -->
+ <enum name="left" value="0" />
+ <!-- Slide to and from the bottom edge of the Scene. -->
+ <enum name="top" value="1" />
+ <!-- Slide to and from the bottom edge of the Scene. -->
+ <enum name="right" value="2" />
+ <!-- Slide to and from the bottom edge of the Scene. -->
+ <enum name="bottom" 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
diff --git a/core/res/res/values/colors_quantum.xml b/core/res/res/values/colors_quantum.xml
index d10f7c0..ebe4a49 100644
--- a/core/res/res/values/colors_quantum.xml
+++ b/core/res/res/values/colors_quantum.xml
@@ -16,16 +16,14 @@
<resources>
<color name="background_quantum_dark">@color/black</color>
- <color name="background_quantum_light">@color/quantum_grey_50</color>
- <color name="secondary_background_quantum_dark">@color/quantum_grey_700</color>
- <color name="secondary_background_quantum_light">@color/quantum_grey_100</color>
+ <color name="background_quantum_light">@color/white</color>
<color name="bright_foreground_quantum_dark">@color/background_quantum_light</color>
<color name="bright_foreground_quantum_light">@color/background_quantum_dark</color>
<!-- TODO: This is 50% alpha black -->
<color name="bright_foreground_disabled_quantum_dark">#80000000</color>
- <!-- TODO: This is 50% alpha grey_50 -->
- <color name="bright_foreground_disabled_quantum_light">#80fafafa</color>
+ <!-- TODO: This is 50% alpha white -->
+ <color name="bright_foreground_disabled_quantum_light">#80ffffff</color>
<color name="bright_foreground_inverse_quantum_dark">@color/bright_foreground_quantum_light</color>
<color name="bright_foreground_inverse_quantum_light">@color/bright_foreground_quantum_dark</color>
@@ -34,41 +32,13 @@
<color name="dim_foreground_disabled_quantum_dark">#80bebebe</color>
<color name="dim_foreground_disabled_quantum_light">#80323232</color>
- <!-- TODO: These should be theme attributes. -->
- <color name="control_normal_foreground_quantum_light">@color/secondary_text_quantum_light</color>
- <color name="control_activated_foreground_quantum_light">@color/quantum_teal_700</color>
-
- <!-- TODO: These should be theme attributes. -->
- <color name="control_normal_foreground_quantum_dark">@color/secondary_text_quantum_dark</color>
- <color name="control_activated_foreground_quantum_dark">@color/quantum_lime_A200</color>
-
- <!-- TODO: These should be theme attributes. -->
- <color name="btn_default_normal_quantum_light">@color/quantum_grey_300</color>
- <color name="btn_default_pressed_quantum_light">@color/quantum_grey_500</color>
-
- <!-- TODO: These should be theme attributes. -->
- <color name="btn_default_normal_quantum_dark">@color/quantum_grey_700</color>
- <color name="btn_default_pressed_quantum_dark">@color/quantum_grey_500</color>
-
<color name="hint_foreground_quantum_dark">@color/bright_foreground_disabled_quantum_dark</color>
<color name="hint_foreground_quantum_light">@color/bright_foreground_disabled_quantum_light</color>
- <!-- TODO: This is 40% alpha lime_A200 -->
- <color name="highlighted_text_quantum_dark">#66eeff41</color>
- <!-- TODO: This is 40% alpha teal_700 -->
+ <!-- TODO: This is 40% alpha teal_A200 -->
+ <color name="highlighted_text_quantum_dark">#660097a7</color>
+ <!-- TODO: This is 40% alpha teal_A200 -->
<color name="highlighted_text_quantum_light">#660097a7</color>
- <!-- TODO: These should all be pushed into a TimePicker widget style. -->
- <color name="timepicker_default_background_quantum_dark">@color/background_quantum_dark</color>
- <color name="timepicker_default_background_quantum_light">@color/background_quantum_light</color>
- <color name="timepicker_default_text_color_quantum_dark">@color/bright_foreground_quantum_dark</color>
- <color name="timepicker_default_text_color_quantum_light">@color/bright_foreground_quantum_light</color>
- <color name="timepicker_default_disabled_color_quantum_dark">@color/bright_foreground_disabled_quantum_dark</color>
- <color name="timepicker_default_disabled_color_quantum_light">@color/bright_foreground_disabled_quantum_light</color>
- <color name="timepicker_default_ampm_selected_background_color_quantum_dark">@color/control_activated_foreground_quantum_dark</color>
- <color name="timepicker_default_ampm_selected_background_color_quantum_light">@color/control_activated_foreground_quantum_light</color>
- <color name="timepicker_default_ampm_unselected_background_color_quantum_dark">@color/transparent</color>
- <color name="timepicker_default_ampm_unselected_background_color_quantum_light">@color/white</color>
-
<!-- Primary & accent colors -->
<color name="quantum_red_100">#fff4c7c3</color>
@@ -155,10 +125,4 @@
<color name="primary_text_quantum_dark">#deffffff</color>
<color name="secondary_text_quantum_dark">#8affffff</color>
<color name="tertiary_text_quantum_dark">#4dffffff</color>
-
- <!-- "Theme" colors to be replaced by attrs when available -->
- <color name="theme_color_100">@color/quantum_teal_100</color>
- <color name="theme_color_300">@color/quantum_teal_300</color>
- <color name="theme_color_500">@color/quantum_teal_500</color>
- <color name="theme_color_700">@color/quantum_teal_700</color>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 76a3bd7..0233b73 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2145,6 +2145,8 @@
<public type="attr" name="persistable" />
<public type="attr" name="titleTextAppearance" />
<public type="attr" name="subtitleTextAppearance" />
+ <public type="attr" name="slideEdge" />
+ <public type="attr" name="actionBarTheme" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index 85d8761..dd148c4 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -340,13 +340,13 @@
<style name="TextAppearance.Quantum.TimePicker.TimeLabel" parent="TextAppearance.Quantum">
<item name="textSize">@dimen/timepicker_time_label_size</item>
- <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Quantum.TimePicker.AmPmLabel" parent="TextAppearance.Quantum">
<item name="textSize">@dimen/timepicker_ampm_label_size</item>
<item name="textAllCaps">true</item>
- <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
+ <item name="textColor">?attr/textColorSecondary</item>
<item name="textStyle">bold</item>
</style>
@@ -377,11 +377,11 @@
<style name="TextAppearance.Quantum.Light.CalendarViewWeekDayView" parent="TextAppearance.Quantum.CalendarViewWeekDayView"/>
<style name="TextAppearance.Quantum.Light.TimePicker.TimeLabel" parent="TextAppearance.Quantum.TimePicker.TimeLabel">
- <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Quantum.Light.TimePicker.AmPmLabel" parent="TextAppearance.Quantum.TimePicker.AmPmLabel">
- <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<!-- Widget Styles -->
@@ -545,16 +545,16 @@
<style name="Widget.Quantum.TimePicker" parent="Widget.TimePicker">
<item name="legacyLayout">@layout/time_picker_legacy_holo</item>
<item name="internalLayout">@layout/time_picker_holo</item>
- <item name="disabledColor">@color/timepicker_default_disabled_color_quantum_dark</item>
- <item name="headerSelectedTextColor">@color/holo_blue_light</item>
- <item name="headerUnselectedTextColor">@color/timepicker_default_text_color_quantum_dark</item>
- <item name="headerBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
- <item name="numbersTextColor">@color/timepicker_default_text_color_quantum_dark</item>
- <item name="numbersBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
- <item name="amPmTextColor">@color/timepicker_default_text_color_quantum_dark</item>
- <item name="amPmUnselectedBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
- <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
- <item name="numbersSelectorColor">@color/holo_blue_light</item>
+ <item name="disabledColor">@color/bright_foreground_disabled_quantum_dark</item>
+ <item name="headerSelectedTextColor">?attr/colorControlActivated</item>
+ <item name="headerUnselectedTextColor">?attr/textColorPrimary</item>
+ <item name="headerBackgroundColor">?attr/colorBackground</item>
+ <item name="numbersTextColor">?attr/textColorSecondary</item>
+ <item name="numbersBackgroundColor">?attr/colorControlNormal</item>
+ <item name="amPmTextColor">?attr/textColorSecondary</item>
+ <item name="amPmUnselectedBackgroundColor">?attr/colorControlNormal</item>
+ <item name="amPmSelectedBackgroundColor">?attr/colorControlActivated</item>
+ <item name="numbersSelectorColor">?attr/colorControlActivated</item>
</style>
<style name="Widget.Quantum.DatePicker" parent="Widget.DatePicker">
@@ -758,9 +758,9 @@
<style name="Widget.Quantum.ActionBar" parent="Widget.ActionBar">
<item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
- <item name="background">@drawable/ab_transparent_quantum</item>
- <item name="backgroundStacked">@drawable/ab_stacked_transparent_quantum</item>
- <item name="backgroundSplit">@drawable/ab_bottom_transparent_quantum</item>
+ <item name="background">@null</item>
+ <item name="backgroundStacked">@null</item>
+ <item name="backgroundSplit">@null</item>
<item name="divider">?attr/dividerVertical</item>
<item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
<item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
@@ -769,16 +769,9 @@
</style>
<style name="Widget.Quantum.ActionBar.Solid">
- <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
- <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
- <item name="background">@drawable/ab_solid_quantum</item>
- <item name="backgroundStacked">@drawable/ab_stacked_solid_quantum</item>
- <item name="backgroundSplit">@drawable/ab_bottom_solid_quantum</item>
- <item name="divider">?attr/dividerVertical</item>
- <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
- <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
- <item name="progressBarPadding">32dip</item>
- <item name="itemPadding">8dip</item>
+ <item name="background">?attr/colorPrimary</item>
+ <item name="backgroundStacked">?attr/colorPrimary</item>
+ <item name="backgroundSplit">?attr/colorPrimary</item>
</style>
<style name="Widget.Quantum.ActionMode" parent="Widget.ActionMode">
@@ -869,19 +862,10 @@
<style name="Widget.Quantum.Light.NumberPicker" parent="Widget.Quantum.NumberPicker"/>
- <style name="Widget.Quantum.Light.TimePicker" parent="Widget.TimePicker">
+ <style name="Widget.Quantum.Light.TimePicker" parent="Widget.Quantum.TimePicker">
<item name="legacyLayout">@layout/time_picker_legacy_holo</item>
<item name="internalLayout">@layout/time_picker_holo</item>
- <item name="disabledColor">@color/timepicker_default_disabled_color_quantum_light</item>
- <item name="headerSelectedTextColor">@color/holo_blue_light</item>
- <item name="headerUnselectedTextColor">@color/timepicker_default_text_color_quantum_light</item>
- <item name="headerBackgroundColor">@color/timepicker_default_background_quantum_light</item>
- <item name="numbersTextColor">@color/timepicker_default_text_color_quantum_light</item>
- <item name="numbersBackgroundColor">@color/timepicker_default_background_quantum_light</item>
- <item name="amPmTextColor">@color/timepicker_default_text_color_quantum_light</item>
- <item name="amPmUnselectedBackgroundColor">@color/timepicker_default_background_quantum_light</item>
- <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
- <item name="numbersSelectorColor">@color/holo_blue_light</item>
+ <item name="disabledColor">@color/bright_foreground_disabled_quantum_light</item>
</style>
<style name="Widget.Quantum.Light.DatePicker" parent="Widget.Quantum.DatePicker"/>
@@ -985,25 +969,18 @@
<style name="Widget.Quantum.Light.ActionBar" parent="Widget.Quantum.ActionBar">
<item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
- <item name="background">@drawable/ab_transparent_quantum</item>
- <item name="backgroundStacked">@drawable/ab_stacked_transparent_quantum</item>
- <item name="backgroundSplit">@drawable/ab_bottom_transparent_quantum</item>
+ <item name="background">@null</item>
+ <item name="backgroundStacked">@null</item>
+ <item name="backgroundSplit">@null</item>
<item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum</item>
<item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
<item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
</style>
<style name="Widget.Quantum.Light.ActionBar.Solid">
- <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
- <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
- <item name="background">@drawable/ab_solid_quantum</item>
- <item name="backgroundStacked">@drawable/ab_stacked_solid_quantum</item>
- <item name="backgroundSplit">@drawable/ab_bottom_solid_quantum</item>
- <item name="divider">?attr/dividerVertical</item>
- <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
- <item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
- <item name="progressBarPadding">32dip</item>
- <item name="itemPadding">8dip</item>
+ <item name="background">?attr/colorPrimary</item>
+ <item name="backgroundStacked">?attr/colorPrimary</item>
+ <item name="backgroundSplit">?attr/colorPrimary</item>
</style>
<style name="Widget.Quantum.Light.CompoundButton.Switch" parent="Widget.Quantum.CompoundButton.Switch">
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
index 50f1ca6..17bab30 100644
--- a/core/res/res/values/themes_quantum.xml
+++ b/core/res/res/values/themes_quantum.xml
@@ -288,8 +288,8 @@
<item name="actionDropDownStyle">@style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
<item name="actionButtonStyle">@style/Widget.Quantum.ActionButton</item>
<item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
- <item name="actionModeBackground">@color/theme_color_700</item>
- <item name="actionModeSplitBackground">@color/theme_color_700</item>
+ <item name="actionModeBackground">?attr/colorPrimaryDark</item>
+ <item name="actionModeSplitBackground">?attr/colorPrimaryDark</item>
<item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum</item>
<item name="actionBarTabStyle">@style/Widget.Quantum.ActionBar.TabView</item>
<item name="actionBarTabBarStyle">@style/Widget.Quantum.ActionBar.TabBar</item>
@@ -334,7 +334,7 @@
<item name="timePickerStyle">@style/Widget.Quantum.TimePicker</item>
<!-- TimePicker background color -->
- <item name="timePickerHeaderBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+ <item name="timePickerHeaderBackgroundColor">?colorBackground</item>
<!-- TimePicker Header time label text appearance -->
<item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.TimeLabel</item>
@@ -356,13 +356,18 @@
<item name="fastScrollOverlayPosition">atThumb</item>
<!-- Color palette -->
- <item name="colorControlNormal">@color/control_normal_foreground_quantum_dark</item>
- <item name="colorControlActivated">@color/control_activated_foreground_quantum_dark</item>
- <item name="colorButtonNormal">@color/btn_default_normal_quantum_dark</item>
- <item name="colorButtonPressed">@color/btn_default_pressed_quantum_dark</item>
+ <item name="colorPrimaryDark">@color/quantum_grey_700</item>
+ <item name="colorPrimary">@color/quantum_grey_500</item>
+ <item name="colorPrimaryLight">@color/quantum_grey_100</item>
+ <item name="colorAccent">@color/quantum_teal_A200</item>
+
+ <item name="colorControlNormal">?attr/textColorSecondary</item>
+ <item name="colorControlActivated">?attr/colorPrimaryDark</item>
+ <item name="colorButtonNormal">@color/quantum_grey_700</item>
+ <item name="colorButtonPressed">@color/quantum_grey_500</item>
<!-- TODO: Remove these attrs and move into button style. -->
- <item name="colorButtonNormalColored">@color/theme_color_500</item>
- <item name="colorButtonPressedColored">@color/theme_color_300</item>
+ <item name="colorButtonNormalColored">?attr/colorPrimary</item>
+ <item name="colorButtonPressedColored">?attr/colorPrimaryDark</item>
</style>
<!-- Quantum Paper theme (light version). -->
@@ -660,7 +665,7 @@
<item name="timePickerStyle">@style/Widget.Quantum.Light.TimePicker</item>
<!-- TimePicker Header background color -->
- <item name="timePickerHeaderBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+ <item name="timePickerHeaderBackgroundColor">?attr/colorBackground</item>
<!-- TimePicker Header time label text appearance -->
<item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.Light.TimePicker.TimeLabel</item>
@@ -681,20 +686,25 @@
<item name="fastScrollOverlayPosition">atThumb</item>
<!-- Color palette -->
- <item name="colorControlNormal">@color/control_normal_foreground_quantum_light</item>
- <item name="colorControlActivated">@color/control_activated_foreground_quantum_light</item>
- <item name="colorButtonNormal">@color/btn_default_normal_quantum_light</item>
- <item name="colorButtonPressed">@color/btn_default_pressed_quantum_light</item>
+ <item name="colorPrimaryDark">@color/quantum_grey_700</item>
+ <item name="colorPrimary">@color/quantum_grey_500</item>
+ <item name="colorPrimaryLight">@color/quantum_grey_100</item>
+ <item name="colorAccent">@color/quantum_teal_A200</item>
+
+ <item name="colorControlNormal">?attr/textColorSecondary</item>
+ <item name="colorControlActivated">?attr/colorPrimaryLight</item>
+ <item name="colorButtonNormal">@color/quantum_grey_100</item>
+ <item name="colorButtonPressed">@color/quantum_grey_500</item>
<!-- TODO: Remove these attrs and move into button style. -->
- <item name="colorButtonNormalColored">@color/theme_color_500</item>
- <item name="colorButtonPressedColored">@color/theme_color_700</item>
+ <item name="colorButtonNormalColored">?attr/colorPrimary</item>
+ <item name="colorButtonPressedColored">?attr/colorPrimaryLight</item>
</style>
<!-- Variant of the quantum (light) theme that has a solid (opaque) action bar
with an inverse color profile. The dark action bar sharply stands out against
the light content. -->
<style name="Theme.Quantum.Light.DarkActionBar">
- <item name="actionBarWidgetTheme">@style/Theme.Quantum</item>
+ <item name="actionBarTheme">@style/Theme.Quantum</item>
</style>
<!-- Variant of the quantum (dark) theme with no action bar. -->
diff --git a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
index 64de95f..1641511 100644
--- a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
+++ b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
@@ -485,7 +485,10 @@
} else if (state == null) {
ns = new TouchFeedbackState(null, this, res);
} else {
- ns = state;
+ // We always need a new state since child drawables contain local
+ // state but live within the parent's constant state.
+ // TODO: Move child drawables into local state.
+ ns = new TouchFeedbackState(state, this, res);
}
if (res != null) {
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 33683ab..d6f75ba 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -14,7 +14,6 @@
package android.graphics.drawable;
-import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.res.Resources;
@@ -28,11 +27,7 @@
import android.graphics.PathMeasure;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.Region;
-import android.location.Address;
-import android.net.ParseException;
-import android.sax.StartElementListener;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -47,7 +42,6 @@
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -157,8 +151,8 @@
* </dd>
*/
public class VectorDrawable extends Drawable {
- private static final String LOGTAG = "VectorDrawable";
- public static final int INFINITE = ValueAnimator.INFINITE;
+ private static final String LOGTAG = VectorDrawable.class.getSimpleName();
+
private static final String SHAPE_SIZE = "size";
private static final String SHAPE_VIEWPORT = "viewport";
private static final String SHAPE_GROUP = "group";
@@ -170,23 +164,32 @@
private static final int LINECAP_BUTT = 0;
private static final int LINECAP_ROUND = 1;
private static final int LINECAP_SQUARE = 2;
+
private static final int LINEJOIN_MITER = 0;
private static final int LINEJOIN_ROUND = 1;
private static final int LINEJOIN_BEVEL = 2;
+
private static final int DEFAULT_DURATION = 1000;
private static final long DEFAULT_INFINITE_DURATION = 60 * 60 * 1000;
+
private VectorDrawableState mVectorState;
private int mAlpha = 0xFF;
public VectorDrawable() {
- mVectorState = new VectorDrawableState();
+ mVectorState = new VectorDrawableState(null);
mVectorState.mBasicAnimator = ObjectAnimator.ofFloat(this, "AnimationFraction", 0, 1);
+
setDuration(DEFAULT_DURATION);
}
- private VectorDrawable(VectorDrawableState state) {
+ private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) {
mVectorState = new VectorDrawableState(state);
mVectorState.mBasicAnimator = ObjectAnimator.ofFloat(this, "AnimationFraction", 0, 1);
+
+ if (theme != null && canApplyTheme()) {
+ applyTheme(theme);
+ }
+
long duration = mVectorState.mVAnimatedPath.getTotalAnimationDuration();
if (duration == -1) { // if it set to infinite set to 1 hour
duration = DEFAULT_INFINITE_DURATION; // TODO define correct approach for infinite
@@ -197,6 +200,7 @@
}
final static class VectorDrawableState extends ConstantState {
+ int[] mThemeAttrs;
int mChangingConfigurations;
ValueAnimator mBasicAnimator;
VAnimatedPath mVAnimatedPath = new VAnimatedPath();
@@ -204,20 +208,29 @@
int mIntrinsicHeight;
int mIntrinsicWidth;
- public VectorDrawableState(){
- }
-
- public VectorDrawableState(VectorDrawableState copy){
- mChangingConfigurations = copy.mChangingConfigurations;
- mVAnimatedPath = new VAnimatedPath(copy.mVAnimatedPath);
- mPadding = new Rect(copy.mPadding);
- mIntrinsicHeight = copy.mIntrinsicHeight;
- mIntrinsicWidth = copy.mIntrinsicWidth;
+ public VectorDrawableState(VectorDrawableState copy) {
+ if (copy != null) {
+ mChangingConfigurations = copy.mChangingConfigurations;
+ mVAnimatedPath = new VAnimatedPath(copy.mVAnimatedPath);
+ mPadding = new Rect(copy.mPadding);
+ mIntrinsicHeight = copy.mIntrinsicHeight;
+ mIntrinsicWidth = copy.mIntrinsicWidth;
+ }
}
@Override
public Drawable newDrawable() {
- return new VectorDrawable(this);
+ return new VectorDrawable(this, null, null);
+ }
+
+ @Override
+ public Drawable newDrawable(Resources res) {
+ return new VectorDrawable(this, res, null);
+ }
+
+ @Override
+ public Drawable newDrawable(Resources res, Theme theme) {
+ return new VectorDrawable(this, res, theme);
}
@Override
@@ -459,29 +472,49 @@
@Override
public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
- setAnimatedPath(inflateInternal(res, parser, attrs));
+ final VAnimatedPath p = inflateInternal(res, parser, attrs, theme);
+ setAnimatedPath(p);
}
- private VAnimatedPath inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs)
- throws XmlPullParserException, IOException {
+ @Override
+ public boolean canApplyTheme() {
+ return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme();
+ }
+
+ @Override
+ public void applyTheme(Theme t) {
+ super.applyTheme(t);
+
+ final VectorDrawableState state = mVectorState;
+ final VAnimatedPath path = state.mVAnimatedPath;
+ if (path != null && path.canApplyTheme()) {
+ path.applyTheme(t);
+ }
+ }
+
+ private VAnimatedPath inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs,
+ Theme theme) throws XmlPullParserException, IOException {
+ final VAnimatedPath animatedPath = new VAnimatedPath();
+
boolean noSizeTag = true;
boolean noViewportTag = true;
boolean noGroupTag = true;
boolean noPathTag = true;
- final VAnimatedPath animatedPath = new VAnimatedPath();
- VectorDrawable.VGroup currentGroup = null;
+
+ VGroup currentGroup = null;
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
- String tagName = parser.getName();
+ final String tagName = parser.getName();
if (SHAPE_PATH.equals(tagName)) {
- VectorDrawable.VPath p = new VPath(res, attrs);
- currentGroup.add(p);
+ final VPath path = new VPath();
+ path.inflate(res, attrs, theme);
+ currentGroup.add(path);
noPathTag = false;
} else if (SHAPE_ANIMATION.equals(tagName)) {
- VectorDrawable.VAnimation anim =
- new VAnimation(res, attrs, animatedPath.mGroupList);
+ final VAnimation anim = new VAnimation();
+ anim.inflate(animatedPath.mGroupList, res, attrs, theme);
animatedPath.addAnimation(anim);
} else if (SHAPE_SIZE.equals(tagName)) {
animatedPath.parseSize(res, attrs);
@@ -490,17 +523,17 @@
animatedPath.parseViewport(res, attrs);
noViewportTag = false;
} else if (SHAPE_GROUP.equals(tagName)) {
- currentGroup = new VectorDrawable.VGroup();
+ currentGroup = new VGroup();
animatedPath.mGroupList.add(currentGroup);
noGroupTag = false;
} else if (SHAPE_VECTOR.equals(tagName)) {
- TypedArray a = res.obtainAttributes(attrs, R.styleable.VectorDrawable);
+ final TypedArray a = res.obtainAttributes(attrs, R.styleable.VectorDrawable);
animatedPath.setTrigger(a.getInteger(R.styleable.VectorDrawable_trigger, 0));
// Parsing the version information.
// Right now, we only support version "1".
// If the xml didn't specify the version number, the default version is "1".
- int versionCode = a.getInt(R.styleable.VectorDrawable_versionCode, 1);
+ final int versionCode = a.getInt(R.styleable.VectorDrawable_versionCode, 1);
if (versionCode != 1) {
throw new IllegalArgumentException(
"So far, VectorDrawable only support version 1");
@@ -509,33 +542,41 @@
a.recycle();
}
}
+
eventType = parser.next();
}
+
if (noSizeTag || noViewportTag || noGroupTag || noPathTag) {
- StringBuffer tag = new StringBuffer();
+ final StringBuffer tag = new StringBuffer();
+
if (noSizeTag) {
- tag.append("size");
+ tag.append(SHAPE_SIZE);
}
+
if (noViewportTag){
if (tag.length()>0) {
tag.append(" & ");
}
- tag.append("size");
+ tag.append(SHAPE_SIZE);
}
+
if (noGroupTag){
if (tag.length()>0) {
tag.append(" & ");
}
- tag.append("group");
+ tag.append(SHAPE_GROUP);
}
+
if (noPathTag){
if (tag.length()>0) {
tag.append(" or ");
}
- tag.append("path");
+ tag.append(SHAPE_PATH);
}
- throw new XmlPullParserException("no "+tag+" defined");
+
+ throw new XmlPullParserException("no " + tag + " defined");
}
+
// post parse cleanup
animatedPath.parseFinish();
return animatedPath;
@@ -543,16 +584,18 @@
private void setAnimatedPath(VAnimatedPath animatedPath) {
mVectorState.mVAnimatedPath = animatedPath;
+
setIntrinsicWidth((int) mVectorState.mVAnimatedPath.mBaseWidth);
setIntrinsicHeight((int) mVectorState.mVAnimatedPath.mBaseHeight);
+
long duration = mVectorState.mVAnimatedPath.getTotalAnimationDuration();
if (duration == -1) { // if it set to infinite set to 1 hour
duration = DEFAULT_INFINITE_DURATION; // TODO define correct approach for infinite
mVectorState.mBasicAnimator.setFloatValues(0, duration / 1000);
mVectorState.mBasicAnimator.setInterpolator(new LinearInterpolator());
}
- setDuration(duration);
+ setDuration(duration);
setAnimationFraction(0);
}
@@ -570,8 +613,6 @@
}
private static class VAnimatedPath {
- private static final String LOGTAG = "VAnimatedPath";
-
private ArrayList<VAnimation> mCurrentAnimList = null;
private VPath[] mCurrentPaths;
private float mAnimationValue = 0; // value goes from 0 to 1
@@ -585,7 +626,9 @@
private int[] mCurrentState = new int[0];
private int mTrigger;
private boolean mTriggerState;
- ArrayList<VGroup> mGroupList = new ArrayList<VGroup>();
+
+ final ArrayList<VGroup> mGroupList = new ArrayList<VGroup>();
+
float mBaseWidth = 1;
float mBaseHeight = 1;
float mViewportWidth;
@@ -594,10 +637,11 @@
public VAnimatedPath() {
setup();
}
+
public VAnimatedPath(VAnimatedPath copy) {
setup();
mCurrentAnimList = new ArrayList<VAnimation>(copy.mCurrentAnimList);
- mGroupList = new ArrayList<VGroup>(copy.mGroupList);
+ mGroupList.addAll(copy.mGroupList);
if (copy.mCurrentPaths != null) {
mCurrentPaths = new VPath[copy.mCurrentPaths.length];
for (int i = 0; i < mCurrentPaths.length; i++) {
@@ -615,8 +659,53 @@
mCurrentState = new int[0];
}
+ public boolean canApplyTheme() {
+ final ArrayList<VGroup> groups = mGroupList;
+ for (int i = groups.size() - 1; i >= 0; i--) {
+ final ArrayList<VPath> paths = groups.get(i).mVGList;
+ for (int j = paths.size() - 1; j >= 0; j--) {
+ final VPath path = paths.get(j);
+ if (path.canApplyTheme()) {
+ return true;
+ }
+ }
+ }
+
+ final ArrayList<VAnimation> anims = mCurrentAnimList;
+ for (int i = anims.size() - 1; i >= 0; i--) {
+ final VAnimation anim = anims.get(i);
+ if (anim.canApplyTheme()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void applyTheme(Theme t) {
+ final ArrayList<VGroup> groups = mGroupList;
+ for (int i = groups.size() - 1; i >= 0; i--) {
+ final ArrayList<VPath> paths = groups.get(i).mVGList;
+ for (int j = paths.size() - 1; j >= 0; j--) {
+ final VPath path = paths.get(j);
+ if (path.canApplyTheme()) {
+ path.applyTheme(t);
+ }
+ }
+ }
+
+ final ArrayList<VAnimation> anims = mCurrentAnimList;
+ for (int i = anims.size() - 1; i >= 0; i--) {
+ final VAnimation anim = anims.get(i);
+ if (anim.canApplyTheme()) {
+ anim.applyTheme(t);
+ }
+ }
+ }
+
public void setTrigger(int trigger){
- int []lut = { 0,
+ final int [] lut = {
+ 0,
R.attr.state_pressed,
R.attr.state_focused,
R.attr.state_hovered,
@@ -626,6 +715,7 @@
R.attr.state_activated,
R.attr.state_focused
};
+
mTrigger = lut[trigger];
}
@@ -663,23 +753,27 @@
* @return true if you need to keep repeating
*/
public boolean setAnimationFraction(float value) {
- int len = mCurrentPaths.length;
getTotalAnimationDuration();
+
long animationTime = (long) (value * mTotalDuration);
+ final int len = mCurrentPaths.length;
for (int i = 0; i < len; i++) {
- VPath path = mCurrentPaths[i];
animationTime =
(long) ((mTotalDuration == -1) ? value * 1000 : mTotalDuration * value);
- int size = mCurrentAnimList.size();
+
+ final VPath path = mCurrentPaths[i];
+ final int size = mCurrentAnimList.size();
for (int j = 0; j < size; j++) {
- VAnimation vAnimation = mCurrentAnimList.get(j);
+ final VAnimation vAnimation = mCurrentAnimList.get(j);
if (vAnimation.doesAdjustPath(path)) {
mCurrentPaths[i] = vAnimation.getPathAtTime(animationTime, path);
}
}
}
- this.mAnimationValue = value;
+
+ mAnimationValue = value;
+
if (mTotalDuration == -1) {
return true;
} else {
@@ -688,16 +782,15 @@
}
public void draw(Canvas canvas) {
- int w = canvas.getWidth();
- int h = canvas.getHeight();
- float scale = w / mViewportWidth;
- scale = Math.min(h / mViewportHeight, scale);
-
if (mCurrentPaths == null) {
Log.e(LOGTAG,"mCurrentPaths == null");
return;
}
+ // TODO: This should probably use getBounds().
+ final int w = canvas.getWidth();
+ final int h = canvas.getHeight();
+
for (int i = 0; i < mCurrentPaths.length; i++) {
if (mCurrentPaths[i] != null && mCurrentPaths[i].isVisible(mCurrentState)) {
drawPath(mCurrentPaths[i], canvas, w, h);
@@ -706,8 +799,7 @@
}
private void drawPath(VPath vPath, Canvas canvas, int w, int h) {
- float scale = w / mViewportWidth;
- scale = Math.min(h / mViewportHeight, scale);
+ final float scale = Math.min(h / mViewportHeight, w / mViewportWidth);
vPath.toPath(mPath);
Path path = mPath;
@@ -746,12 +838,14 @@
if (vPath.mClip) {
canvas.clipPath(mRenderPath, Region.Op.REPLACE);
}
+
if (vPath.mFillColor != 0) {
mFillPaint.setColor(vPath.mFillColor);
int alpha = 0xFF & (vPath.mFillColor >> 24);
mFillPaint.setAlpha(alpha);
canvas.drawPath(mRenderPath, mFillPaint);
}
+
if (vPath.mStrokeColor != 0) {
if (vPath.mStrokelineJoin != null) {
mStrokePaint.setStrokeJoin(vPath.mStrokelineJoin);
@@ -773,7 +867,7 @@
* TODO: improve memory use & performance or move to C++
*/
public void parseFinish() {
- HashMap<String, VAnimation> newAnimations = new HashMap<String, VAnimation>();
+ final HashMap<String, VAnimation> newAnimations = new HashMap<String, VAnimation>();
for (VGroup group : mGroupList) {
for (VPath vPath : group.getPaths()) {
if (!vPath.mAnimated) {
@@ -784,16 +878,19 @@
} else {
ap = newAnimations.get(vPath.getID());
}
+
ap.addPath(vPath);
vPath.mAnimated = true;
}
}
}
+
if (mCurrentAnimList == null) {
mCurrentAnimList = new ArrayList<VectorDrawable.VAnimation>();
}
mCurrentAnimList.addAll(newAnimations.values());
- Collection<VPath> paths = mGroupList.get(0).getPaths();
+
+ final Collection<VPath> paths = mGroupList.get(0).getPaths();
mCurrentPaths = paths.toArray(new VPath[paths.size()]);
for (int i = 0; i < mCurrentPaths.length; i++) {
mCurrentPaths[i] = new VPath(mCurrentPaths[i]);
@@ -854,40 +951,41 @@
}
private static class VAnimation {
- private static final String LOGTAG = "VAnimation";
+ private final static int DIRECTION_FORWARD = 0;
+ private final static int DIRECTION_IN_AND_OUT = 1;
+
private VPath[] mPaths = new VPath[0];
public enum Style {
INTERPOLATE, CROSSFADE, WIPE
}
+
Interpolator mAnimInterpolator = new AccelerateDecelerateInterpolator();
+
+ private int[] mThemeAttrs;
private Style mStyle;
private int mLimitProperty = 0;
private long[] mDuration = {DEFAULT_DURATION};
private long mStartOffset;
private long mRepeat = 1;
- private HashSet<String>mSeqMap = new HashSet<String>();
+ private HashSet<String> mSeqMap = new HashSet<String>();
private long mWipeDirection;
private int mMode = 0; // forward = 0 inAndOut = 1;
private int mInterpolatorType;
private String mId;
- private final static int DIRECTION_FORWARD = 0;
- private final static int DIRECTION_IN_AND_OUT = 1;
public VAnimation() {
+ // Empty constructor.
}
- public boolean doesAdjustPath(VPath path) {
- return mSeqMap.contains(path.getID());
- }
-
- public VAnimation(Resources r, AttributeSet attrs, ArrayList<VGroup> groups)
+ public void inflate(ArrayList<VGroup> groups, Resources r, AttributeSet attrs, Theme theme)
throws XmlPullParserException {
String value;
String[] sp;
int name;
- TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableAnimation);
+ final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableAnimation);
+ mThemeAttrs = a.extractThemeAttrs();
value = a.getString(R.styleable.VectorDrawableAnimation_sequence);
if (value != null) {
@@ -910,28 +1008,42 @@
if (value != null) {
long totalDuration = 0;
sp = value.split(",");
- long[] dur = new long[sp.length];
+
+ final long[] dur = new long[sp.length];
for (int j = 0; j < dur.length; j++) {
dur[j] = Long.parseLong(sp[j]);
totalDuration += dur[j];
}
+
if (totalDuration == 0){
throw new XmlPullParserException(a.getPositionDescription()+
"total duration must not be zero");
}
+
setDuration(dur);
}
setRepeat(a.getInt(R.styleable.VectorDrawableAnimation_repeatCount, 1));
-
setStartOffset(a.getInt(R.styleable.VectorDrawableAnimation_startDelay, 0));
-
setMode(a.getInt(R.styleable.VectorDrawableAnimation_repeatStyle, 0));
fixMissingParameters();
+
a.recycle();
}
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null;
+ }
+
+ public void applyTheme(Theme t) {
+ // TODO: Apply theme.
+ }
+
+ public boolean doesAdjustPath(VPath path) {
+ return mSeqMap.contains(path.getID());
+ }
+
public String getId() {
if (mId == null) {
mId = mPaths[0].getID();
@@ -1031,7 +1143,7 @@
}
public void setPaths(VPath[] paths) {
- this.mPaths = paths;
+ mPaths = paths;
}
public void addPath(VPath path) {
@@ -1049,7 +1161,7 @@
}
public void interpolate(VPath p1, VPath p2, float time, VPath dest) {
- dest.interpolate(time, p1, p2, dest, mLimitProperty);
+ VPath.interpolate(time, p1, p2, dest, mLimitProperty);
}
public VPath getPathAtTime(long milliseconds, VPath dest) {
@@ -1150,8 +1262,8 @@
}
private static class VGroup {
- private HashMap<String, VPath> mVGPathMap = new HashMap<String, VPath>();
- private ArrayList<VPath> mVGList = new ArrayList<VPath>();
+ private final HashMap<String, VPath> mVGPathMap = new HashMap<String, VPath>();
+ private final ArrayList<VPath> mVGList = new ArrayList<VPath>();
public void add(VPath path) {
String id = path.getID();
@@ -1183,34 +1295,52 @@
private static final int LIMIT_TRIM_PATH_START = 3;
private static final int LIMIT_TRIM_PATH_OFFSET = 5;
private static final int LIMIT_TRIM_PATH_END = 4;
+
private static final int STATE_UNDEFINED=0;
private static final int STATE_TRUE=1;
private static final int STATE_FALSE=2;
+
private static final int MAX_STATES = 10;
- private VNode[] mNode = null;
- private String mId;
+
+ private int[] mThemeAttrs;
+
int mStrokeColor = 0;
float mStrokeWidth = 0;
float mStrokeOpacity = Float.NaN;
+
int mFillColor = 0;
int mFillRule;
float mFillOpacity = Float.NaN;
+
float mRotate = 0;
float mPivotX = 0;
float mPivotY = 0;
+
float mTrimPathStart = 0;
float mTrimPathEnd = 1;
float mTrimPathOffset = 0;
+
boolean mAnimated = false;
boolean mClip = false;
- public Paint.Cap mStrokelineCap = null;
- public Paint.Join mStrokelineJoin = null;
+ Paint.Cap mStrokelineCap = null;
+ Paint.Join mStrokelineJoin = null;
float mStrokeMiterlimit = 4;
+
+ private VNode[] mNode = null;
+ private String mId;
private int[] mCheckState = new int[MAX_STATES];
private boolean[] mCheckValue = new boolean[MAX_STATES];
private int mNumberOfStates = 0;
private int mNumberOfTrue = 0;
+ public VPath() {
+ // Empty constructor.
+ }
+
+ public VPath(VPath p) {
+ copyFrom(p);
+ }
+
public void addStateFilter(int state, boolean condition) {
int k = 0;
while (k < mNumberOfStates) {
@@ -1228,7 +1358,7 @@
}
}
- int getState(int state){
+ private int getState(int state){
for (int i = 0; i < mNumberOfStates; i++) {
if (mCheckState[mNumberOfStates] == state){
return (mCheckValue[i])?STATE_TRUE:STATE_FALSE;
@@ -1250,34 +1380,33 @@
}
}
- public VPath() {
- mId = this.toString(); // to ensure paths have unique names
- }
-
- public VPath(VPath p) {
- copyFrom(p);
- }
-
public String getID(){
return mId;
}
- public VPath(Resources r, AttributeSet attrs) {
- TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawablePath);
+ public void inflate(Resources r, AttributeSet attrs, Theme theme) {
+ final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath);
+ final int[] themeAttrs = a.extractThemeAttrs();
+ mThemeAttrs = themeAttrs;
+
mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, false);
mId = a.getString(R.styleable.VectorDrawablePath_name);
mNode = parsePath(a.getString(R.styleable.VectorDrawablePath_pathData));
- mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, 0);
- mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, Float.NaN);
- if (!Float.isNaN(mFillOpacity)) {
- mFillColor &= 0x00FFFFFF;
- mFillColor |= ((int) (0xFF * mFillOpacity)) << 24;
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_fill] == 0) {
+ mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, 0);
}
+
+ if (themeAttrs == null
+ || themeAttrs[R.styleable.VectorDrawablePath_fillOpacity] == 0) {
+ mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, Float.NaN);
+ }
+
mRotate = a.getFloat(R.styleable.VectorDrawablePath_rotation, 0);
mPivotX = a.getFloat(R.styleable.VectorDrawablePath_pivotX, 0);
mPivotY = a.getFloat(R.styleable.VectorDrawablePath_pivotY, 0);
- int lineCap = a.getInt(R.styleable.VectorDrawablePath_strokeLineCap, 0);
+
+ final int lineCap = a.getInt(R.styleable.VectorDrawablePath_strokeLineCap, 0);
switch (lineCap) {
case LINECAP_BUTT:
mStrokelineCap = Paint.Cap.BUTT;
@@ -1289,7 +1418,8 @@
mStrokelineCap = Paint.Cap.SQUARE;
break;
}
- int lineJoin = a.getInt(R.styleable.VectorDrawablePath_strokeLineJoin, 0);
+
+ final int lineJoin = a.getInt(R.styleable.VectorDrawablePath_strokeLineJoin, 0);
switch (lineJoin) {
case LINEJOIN_MITER:
mStrokelineJoin = Paint.Join.MITER;
@@ -1301,19 +1431,27 @@
mStrokelineJoin = Paint.Join.BEVEL;
break;
}
+
mStrokeMiterlimit = a.getFloat(R.styleable.VectorDrawablePath_strokeMiterLimit,
mStrokeMiterlimit);
- mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor);
- mStrokeOpacity = a.getFloat(R.styleable.VectorDrawablePath_strokeOpacity, Float.NaN);
- if (!Float.isNaN(mStrokeOpacity)) {
- mStrokeColor &= 0x00FFFFFF;
- mStrokeColor |= ((int) (0xFF * mStrokeOpacity)) << 24;
+
+ if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_stroke] == 0) {
+ mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor);
}
+
+ if (themeAttrs == null
+ || themeAttrs[R.styleable.VectorDrawablePath_strokeOpacity] == 0) {
+ mStrokeOpacity = a.getFloat(
+ R.styleable.VectorDrawablePath_strokeOpacity, Float.NaN);
+ }
+
mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, 0);
mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, 1);
mTrimPathOffset = a.getFloat(R.styleable.VectorDrawablePath_trimPathOffset, 0);
mTrimPathStart = a.getFloat(R.styleable.VectorDrawablePath_trimPathStart, 0);
- int[] states = {R.styleable.VectorDrawablePath_state_activated,
+
+ final int[] states = {
+ R.styleable.VectorDrawablePath_state_activated,
R.styleable.VectorDrawablePath_state_checkable,
R.styleable.VectorDrawablePath_state_checked,
R.styleable.VectorDrawablePath_state_enabled,
@@ -1321,15 +1459,66 @@
R.styleable.VectorDrawablePath_state_hovered,
R.styleable.VectorDrawablePath_state_pressed,
R.styleable.VectorDrawablePath_state_selected,
- R.styleable.VectorDrawablePath_state_window_focused};
- for (int state : states) {
+ R.styleable.VectorDrawablePath_state_window_focused
+ };
+
+ final int N = states.length;
+ for (int i = 0; i < N; i++) {
+ final int state = states[i];
if (a.hasValue(state)) {
addStateFilter(state, a.getBoolean(state, false));
}
}
+
+ updateColorAlphas();
+
a.recycle();
}
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null;
+ }
+
+ public void applyTheme(Theme t) {
+ if (mThemeAttrs == null) {
+ return;
+ }
+
+ final TypedArray a = t.resolveAttributes(
+ mThemeAttrs, R.styleable.VectorDrawablePath, 0, 0);
+
+ if (a.hasValue(R.styleable.VectorDrawablePath_fill)) {
+ mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, 0);
+ }
+
+ if (a.hasValue(R.styleable.VectorDrawablePath_fillOpacity)) {
+ mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, Float.NaN);
+ }
+
+ if (a.hasValue(R.styleable.VectorDrawablePath_stroke)) {
+ mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor);
+ }
+
+ if (a.hasValue(R.styleable.VectorDrawablePath_strokeOpacity)) {
+ mStrokeOpacity = a.getFloat(
+ R.styleable.VectorDrawablePath_strokeOpacity, Float.NaN);
+ }
+
+ updateColorAlphas();
+ }
+
+ private void updateColorAlphas() {
+ if (!Float.isNaN(mFillOpacity)) {
+ mFillColor &= 0x00FFFFFF;
+ mFillColor |= ((int) (0xFF * mFillOpacity)) << 24;
+ }
+
+ if (!Float.isNaN(mStrokeOpacity)) {
+ mStrokeColor &= 0x00FFFFFF;
+ mStrokeColor |= ((int) (0xFF * mStrokeOpacity)) << 24;
+ }
+ }
+
private static int nextStart(String s, int end) {
char c;
@@ -1564,9 +1753,11 @@
}
private static class VNode {
+ private static float[] current = new float[4];
+
char type;
float[] params;
- private static float[] current = new float[4];
+
public VNode(char type, float[] params) {
this.type = type;
this.params = params;
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 477d691..df2123b 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -315,24 +315,15 @@
pathCache.clearGarbage();
patchCache.clearGarbage();
- Vector<RenderNode*> displayLists;
Vector<Layer*> layers;
{ // scope for the lock
Mutex::Autolock _l(mGarbageLock);
- displayLists = mDisplayListGarbage;
layers = mLayerGarbage;
- mDisplayListGarbage.clear();
mLayerGarbage.clear();
}
- size_t count = displayLists.size();
- for (size_t i = 0; i < count; i++) {
- RenderNode* displayList = displayLists.itemAt(i);
- delete displayList;
- }
-
- count = layers.size();
+ size_t count = layers.size();
for (size_t i = 0; i < count; i++) {
Layer* layer = layers.itemAt(i);
delete layer;
@@ -345,11 +336,6 @@
mLayerGarbage.push(layer);
}
-void Caches::deleteDisplayListDeferred(RenderNode* displayList) {
- Mutex::Autolock _l(mGarbageLock);
- mDisplayListGarbage.push(displayList);
-}
-
void Caches::flush(FlushMode mode) {
FLUSH_LOGD("Flushing caches (mode %d)", mode);
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 50c5fef..ba3ccaf 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -166,11 +166,6 @@
*/
void deleteLayerDeferred(Layer* layer);
- /*
- * Can be used to delete a display list from a non EGL thread.
- */
- void deleteDisplayListDeferred(RenderNode* layer);
-
/**
* Binds the VBO used to render simple textured quads.
*/
@@ -420,7 +415,6 @@
mutable Mutex mGarbageLock;
Vector<Layer*> mLayerGarbage;
- Vector<RenderNode*> mDisplayListGarbage;
DebugLevel mDebugLevel;
bool mInitialized;
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 5b4e03f..ce711b6 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -68,13 +68,13 @@
mLayer->setColorFilter(mColorFilter);
mLayer->setAlpha(mAlpha, mMode);
- if (mDisplayList) {
+ if (mDisplayList.get()) {
if (mWidth != mLayer->layer.getWidth() || mHeight != mLayer->layer.getHeight()) {
success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
}
mLayer->setBlend(mBlend);
mDisplayList->updateProperties();
- mLayer->updateDeferred(mDisplayList,
+ mLayer->updateDeferred(mDisplayList.get(),
mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
mDirtyRect.setEmpty();
mDisplayList = 0;
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 10fa264..ce08c2d 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -101,7 +101,7 @@
// Layer type specific properties
// displayList and surfaceTexture are mutually exclusive, only 1 may be set
// dirtyRect is only valid if displayList is set
- RenderNode* mDisplayList;
+ sp<RenderNode> mDisplayList;
Rect mDirtyRect;
sp<GLConsumer> mSurfaceTexture;
SkMatrix* mTransform;
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 9e6a96d..a5d8dcb 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -29,6 +29,13 @@
namespace android {
namespace uirenderer {
+DisplayListData::DisplayListData() : projectionReceiveIndex(-1), functorCount(0), hasDrawOps(false) {
+}
+
+DisplayListData::~DisplayListData() {
+ cleanupResources();
+}
+
void DisplayListData::cleanupResources() {
Caches& caches = Caches::getInstance();
caches.unregisterFunctors(functorCount);
@@ -91,5 +98,12 @@
layers.clear();
}
+void DisplayListData::addChild(DrawDisplayListOp* op) {
+ LOG_ALWAYS_FATAL_IF(!op->renderNode(), "DrawDisplayListOp with no render node!");
+
+ mChildren.push(op);
+ mReferenceHolders.push(op->renderNode());
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index df5cba6..fe70d13 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -41,6 +41,7 @@
#include "Matrix.h"
#include "DeferredDisplayList.h"
#include "RenderProperties.h"
+#include "utils/VirtualLightRefBase.h"
class SkBitmap;
class SkPaint;
@@ -106,8 +107,8 @@
*/
class DisplayListData {
public:
- DisplayListData() : projectionReceiveIndex(-1), functorCount(0), hasDrawOps(false) {}
- virtual ~DisplayListData() { cleanupResources(); }
+ DisplayListData();
+ ~DisplayListData();
// allocator into which all ops were allocated
LinearAllocator allocator;
@@ -115,9 +116,6 @@
// pointers to all ops within display list, pointing into allocator data
Vector<DisplayListOp*> displayListOps;
- // list of children display lists for quick, non-drawing traversal
- Vector<DrawDisplayListOp*> children;
-
// index of DisplayListOp restore, after which projected descendents should be drawn
int projectionReceiveIndex;
@@ -139,7 +137,15 @@
return !displayListOps.size();
}
+ void addChild(DrawDisplayListOp* childOp);
+ const Vector<DrawDisplayListOp*>& children() { return mChildren; }
+
private:
+ Vector< sp<VirtualLightRefBase> > mReferenceHolders;
+
+ // list of children display lists for quick, non-drawing traversal
+ Vector<DrawDisplayListOp*> mChildren;
+
void cleanupResources();
};
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 5fa8f1d..06f675e 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1523,6 +1523,8 @@
virtual const char* name() { return "DrawDisplayList"; }
+ RenderNode* renderNode() { return mDisplayList; }
+
private:
RenderNode* mDisplayList;
const int mFlags;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 78c97e1..a84aa6b 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -191,7 +191,7 @@
DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList,
flags, *currentTransform());
addDrawOp(op);
- mDisplayListData->children.push(op);
+ mDisplayListData->addChild(op);
if (displayList->isProjectionReceiver()) {
mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1;
}
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 27409a2..bfe4eda 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -140,6 +140,15 @@
}
}
+void Layer::updateDeferred(RenderNode* displayList,
+ int left, int top, int right, int bottom) {
+ requireRenderer();
+ this->displayList = displayList;
+ const Rect r(left, top, right, bottom);
+ dirtyRect.unionWith(r);
+ deferredUpdateScheduled = true;
+}
+
void Layer::setPaint(const SkPaint* paint) {
OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
setColorFilter((paint) ? paint->getColorFilter() : NULL);
@@ -244,7 +253,7 @@
renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
!isBlend());
- renderer->drawDisplayList(displayList, dirtyRect, RenderNode::kReplayFlag_ClipChildren);
+ renderer->drawDisplayList(displayList.get(), dirtyRect, RenderNode::kReplayFlag_ClipChildren);
renderer->finish();
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index b428404..5375b45 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -19,6 +19,7 @@
#include <cutils/compiler.h>
#include <sys/types.h>
+#include <utils/StrongPointer.h>
#include <GLES2/gl2.h>
@@ -85,13 +86,7 @@
}
void updateDeferred(RenderNode* displayList,
- int left, int top, int right, int bottom) {
- requireRenderer();
- this->displayList = displayList;
- const Rect r(left, top, right, bottom);
- dirtyRect.unionWith(r);
- deferredUpdateScheduled = true;
- }
+ int left, int top, int right, int bottom);
inline uint32_t getWidth() const {
return texture.width;
@@ -294,7 +289,7 @@
*/
bool deferredUpdateScheduled;
OpenGLRenderer* renderer;
- RenderNode* displayList;
+ sp<RenderNode> displayList;
Rect dirtyRect;
bool debugDrawUpdate;
bool hasDrawnSinceUpdate;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index e1f484d..9dbcd36 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -537,7 +537,7 @@
bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
if (layer->deferredUpdateScheduled && layer->renderer &&
- layer->displayList && layer->displayList->isRenderable()) {
+ layer->displayList.get() && layer->displayList->isRenderable()) {
ATRACE_CALL();
Rect& dirty = layer->dirtyRect;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 663b67e..5010076 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -59,17 +59,6 @@
delete mDisplayListData;
}
-void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) {
- if (displayList) {
- if (Caches::hasInstance()) {
- DISPLAY_LIST_LOGD("Deferring display list destruction");
- Caches::getInstance().deleteDisplayListDeferred(displayList);
- } else {
- delete displayList;
- }
- }
-}
-
void RenderNode::setData(DisplayListData* data) {
delete mDisplayListData;
mDisplayListData = data;
@@ -104,8 +93,8 @@
}
if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
- RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
+ for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
+ RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
childNode->updateProperties();
}
}
@@ -118,8 +107,8 @@
return true;
}
- for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
- RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
+ for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
+ RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
if (childNode->hasFunctors()) {
return true;
}
@@ -248,8 +237,8 @@
// TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that
// transform properties are applied correctly to top level children
if (mDisplayListData == NULL) return;
- for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
- DrawDisplayListOp* childOp = mDisplayListData->children[i];
+ for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
+ DrawDisplayListOp* childOp = mDisplayListData->children()[i];
childOp->mDisplayList->computeOrderingImpl(childOp,
&mProjectedNodes, &mat4::identity());
}
@@ -277,11 +266,11 @@
opState->mSkipInOrderDraw = false;
}
- if (mDisplayListData->children.size() > 0) {
+ if (mDisplayListData->children().size() > 0) {
const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0;
bool haveAppliedPropertiesToProjection = false;
- for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
- DrawDisplayListOp* childOp = mDisplayListData->children[i];
+ for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
+ DrawDisplayListOp* childOp = mDisplayListData->children()[i];
RenderNode* child = childOp->mDisplayList;
Vector<DrawDisplayListOp*>* projectionChildren = NULL;
@@ -375,10 +364,10 @@
}
void RenderNode::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes) {
- if (mDisplayListData == NULL || mDisplayListData->children.size() == 0) return;
+ if (mDisplayListData == NULL || mDisplayListData->children().size() == 0) return;
- for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
- DrawDisplayListOp* childOp = mDisplayListData->children[i];
+ for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
+ DrawDisplayListOp* childOp = mDisplayListData->children()[i];
RenderNode* child = childOp->mDisplayList;
float childZ = child->properties().getTranslationZ();
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index fb5336d..fd0fabc 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -41,6 +41,7 @@
#include "DeferredDisplayList.h"
#include "DisplayList.h"
#include "RenderProperties.h"
+#include "utils/VirtualLightRefBase.h"
class SkBitmap;
class SkPaint;
@@ -76,7 +77,7 @@
* recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay
* attached.
*/
-class RenderNode {
+class RenderNode : public VirtualLightRefBase {
public:
ANDROID_API RenderNode();
ANDROID_API ~RenderNode();
@@ -86,7 +87,6 @@
kReplayFlag_ClipChildren = 0x1
};
- ANDROID_API static void destroyDisplayListDeferred(RenderNode* displayList);
ANDROID_API static void outputLogBuffer(int fd);
ANDROID_API void setData(DisplayListData* newData);
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 1e9089a..7b509a2 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -30,7 +30,19 @@
namespace uirenderer {
namespace renderthread {
-DrawFrameTask::DrawFrameTask() : mContext(0), mRenderNode(0) {
+SetDisplayListData::SetDisplayListData() : mNewData(0) {}
+
+SetDisplayListData::SetDisplayListData(RenderNode* node, DisplayListData* newData)
+ : mTargetNode(node), mNewData(newData) {
+}
+
+SetDisplayListData::~SetDisplayListData() {}
+
+void SetDisplayListData::apply() const {
+ mTargetNode->setData(mNewData);
+}
+
+DrawFrameTask::DrawFrameTask() : mContext(0), mTaskMode(MODE_INVALID), mRenderNode(0) {
}
DrawFrameTask::~DrawFrameTask() {
@@ -41,13 +53,15 @@
}
void DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
- SetDisplayListData setter;
- setter.targetNode = renderNode;
- setter.newData = newData;
+ LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to setDisplayListData with!");
+
+ SetDisplayListData setter(renderNode, newData);
mDisplayListDataUpdates.push(setter);
}
void DrawFrameTask::addLayer(DeferredLayerUpdater* layer) {
+ LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!");
+
mLayers.push(layer);
}
@@ -61,6 +75,8 @@
}
void DrawFrameTask::setRenderNode(RenderNode* renderNode) {
+ LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to setRenderNode with!");
+
mRenderNode = renderNode;
}
@@ -69,37 +85,55 @@
}
void DrawFrameTask::drawFrame(RenderThread* renderThread) {
- LOG_ALWAYS_FATAL_IF(!mRenderNode, "Cannot drawFrame with no render node!");
+ LOG_ALWAYS_FATAL_IF(!mRenderNode.get(), "Cannot drawFrame with no render node!");
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
- AutoMutex _lock(mLock);
- renderThread->queue(this);
- mSignal.wait(mLock);
+ postAndWait(renderThread, MODE_FULL);
// Reset the single-frame data
mDirty.setEmpty();
mRenderNode = 0;
}
+void DrawFrameTask::flushStateChanges(RenderThread* renderThread) {
+ LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
+
+ postAndWait(renderThread, MODE_STATE_ONLY);
+}
+
+void DrawFrameTask::postAndWait(RenderThread* renderThread, TaskMode mode) {
+ LOG_ALWAYS_FATAL_IF(mode == MODE_INVALID, "That's not a real mode, silly!");
+
+ mTaskMode = mode;
+ AutoMutex _lock(mLock);
+ renderThread->queue(this);
+ mSignal.wait(mLock);
+}
+
void DrawFrameTask::run() {
ATRACE_NAME("DrawFrame");
syncFrameState();
+ if (mTaskMode == MODE_STATE_ONLY) {
+ unblockUiThread();
+ return;
+ }
+
// Grab a copy of everything we need
Rect dirtyCopy(mDirty);
- RenderNode* renderNode = mRenderNode;
+ sp<RenderNode> renderNode = mRenderNode;
CanvasContext* context = mContext;
// This is temporary until WebView has a solution for syncing frame state
- bool canUnblockUiThread = !requiresSynchronousDraw(renderNode);
+ bool canUnblockUiThread = !requiresSynchronousDraw(renderNode.get());
// From this point on anything in "this" is *UNSAFE TO ACCESS*
if (canUnblockUiThread) {
unblockUiThread();
}
- drawRenderNode(context, renderNode, &dirtyCopy);
+ drawRenderNode(context, renderNode.get(), &dirtyCopy);
if (!canUnblockUiThread) {
unblockUiThread();
@@ -111,12 +145,16 @@
for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) {
const SetDisplayListData& setter = mDisplayListDataUpdates[i];
- setter.targetNode->setData(setter.newData);
+ setter.apply();
}
mDisplayListDataUpdates.clear();
mContext->processLayerUpdates(&mLayers);
- mRenderNode->updateProperties();
+
+ // If we don't have an mRenderNode this is a state flush only
+ if (mRenderNode.get()) {
+ mRenderNode->updateProperties();
+ }
}
void DrawFrameTask::unblockUiThread() {
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 5450dd5..4e9b244 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -18,6 +18,7 @@
#include <utils/Condition.h>
#include <utils/Mutex.h>
+#include <utils/StrongPointer.h>
#include <utils/Vector.h>
#include "RenderTask.h"
@@ -36,9 +37,16 @@
class CanvasContext;
class RenderThread;
-struct SetDisplayListData {
- RenderNode* targetNode;
- DisplayListData* newData;
+class SetDisplayListData {
+public:
+ // This ctor exists for Vector's usage
+ SetDisplayListData();
+ SetDisplayListData(RenderNode* node, DisplayListData* newData);
+ ~SetDisplayListData();
+ void apply() const;
+private:
+ sp<RenderNode> mTargetNode;
+ DisplayListData* mNewData;
};
/*
@@ -61,10 +69,18 @@
void setRenderNode(RenderNode* renderNode);
void setDirty(int left, int top, int right, int bottom);
void drawFrame(RenderThread* renderThread);
+ void flushStateChanges(RenderThread* renderThread);
virtual void run();
private:
+ enum TaskMode {
+ MODE_INVALID,
+ MODE_FULL,
+ MODE_STATE_ONLY,
+ };
+
+ void postAndWait(RenderThread* renderThread, TaskMode mode);
void syncFrameState();
void unblockUiThread();
static void drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty);
@@ -81,7 +97,8 @@
/*********************************************
* Single frame data
*********************************************/
- RenderNode* mRenderNode;
+ TaskMode mTaskMode;
+ sp<RenderNode> mRenderNode;
Rect mDirty;
Vector<SetDisplayListData> mDisplayListDataUpdates;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index cd711b0..489dc90 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -48,7 +48,7 @@
LOG_ALWAYS_FATAL_IF( METHOD_INVOKE_PAYLOAD_SIZE < sizeof(ARGS(method)), \
"METHOD_INVOKE_PAYLOAD_SIZE %d is smaller than sizeof(" #method "Args) %d", \
METHOD_INVOKE_PAYLOAD_SIZE, sizeof(ARGS(method))); \
- MethodInvokeRenderTask* task = createTask((RunnableMethod) Bridge_ ## method); \
+ MethodInvokeRenderTask* task = new MethodInvokeRenderTask((RunnableMethod) Bridge_ ## method); \
ARGS(method) *args = (ARGS(method) *) task->payload()
CREATE_BRIDGE1(createContext, bool translucent) {
@@ -75,6 +75,9 @@
void RenderProxy::destroyContext() {
if (mContext) {
+ // Flush any pending changes to ensure all garbage is destroyed
+ mDrawFrameTask.flushStateChanges(&mRenderThread);
+
SETUP_TASK(destroyContext);
args->context = mContext;
mContext = 0;
@@ -138,6 +141,10 @@
}
void RenderProxy::destroyCanvas() {
+ // If the canvas is being destroyed we won't be drawing again anytime soon
+ // So flush any pending state changes to allow for resource cleanup.
+ mDrawFrameTask.flushStateChanges(&mRenderThread);
+
SETUP_TASK(destroyCanvas);
args->context = mContext;
post(task);
@@ -252,9 +259,14 @@
post(task);
}
-MethodInvokeRenderTask* RenderProxy::createTask(RunnableMethod method) {
- // TODO: Consider having a small pool of these to avoid alloc churn
- return new MethodInvokeRenderTask(method);
+CREATE_BRIDGE0(fence) {
+ // Intentionally empty
+ return NULL;
+}
+
+void RenderProxy::fence() {
+ SETUP_TASK(fence);
+ postAndWait(task);
}
void RenderProxy::post(RenderTask* task) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index f1ca534..c50da79 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -78,6 +78,8 @@
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
ANDROID_API void destroyLayer(DeferredLayerUpdater* layer);
+ ANDROID_API void fence();
+
private:
RenderThread& mRenderThread;
CanvasContext* mContext;
@@ -89,7 +91,6 @@
void destroyContext();
- MethodInvokeRenderTask* createTask(RunnableMethod method);
void post(RenderTask* task);
void* postAndWait(MethodInvokeRenderTask* task);
diff --git a/libs/hwui/utils/VirtualLightRefBase.h b/libs/hwui/utils/VirtualLightRefBase.h
new file mode 100644
index 0000000..b545aab
--- /dev/null
+++ b/libs/hwui/utils/VirtualLightRefBase.h
@@ -0,0 +1,34 @@
+/*
+ * 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 VIRTUALLIGHTREFBASE_H
+#define VIRTUALLIGHTREFBASE_H
+
+#include <utils/RefBase.h>
+
+namespace android {
+namespace uirenderer {
+
+// This is a wrapper around LightRefBase that simply enforces a virtual
+// destructor to eliminate the template requirement of LightRefBase
+class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> {
+public:
+ virtual ~VirtualLightRefBase() {}
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* VIRTUALLIGHTREFBASE_H */
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 4bd5a80..7f1c5c7 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -43,7 +43,6 @@
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
-import android.hardware.usb.UsbManager;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Binder;
@@ -529,7 +528,6 @@
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
- intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
// TODO merge orientation and rotation
@@ -3977,8 +3975,7 @@
(device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
setBluetoothA2dpOnInt(true);
}
- boolean isUsb = ((device & AudioSystem.DEVICE_OUT_ALL_USB) != 0) ||
- ((device & AudioSystem.DEVICE_IN_ALL_USB) != 0);
+ boolean isUsb = ((device & AudioSystem.DEVICE_OUT_ALL_USB) != 0);
handleDeviceConnection((state == 1), device, (isUsb ? name : ""));
if (state != 0) {
if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
@@ -4086,31 +4083,18 @@
} else if (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ||
action.equals(Intent.ACTION_USB_AUDIO_DEVICE_PLUG)) {
state = intent.getIntExtra("state", 0);
-
int alsaCard = intent.getIntExtra("card", -1);
int alsaDevice = intent.getIntExtra("device", -1);
- boolean hasPlayback = intent.getBooleanExtra("hasPlayback", false);
- boolean hasCapture = intent.getBooleanExtra("hasCapture", false);
- boolean hasMIDI = intent.getBooleanExtra("hasMIDI", false);
-
String params = (alsaCard == -1 && alsaDevice == -1 ? ""
: "card=" + alsaCard + ";device=" + alsaDevice);
-
- //TODO(pmclean) - Ignore for now the hasPlayback & hasCapture flags since we
- // still need to call setWiredDeviceConnectionState() on disconnect (when we
- // don't have card/device files to parse for this info). We will need to store
- // that info here when we get smarter about multiple USB card/devices.
- // Playback Device
device = action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ?
AudioSystem.DEVICE_OUT_USB_ACCESSORY : AudioSystem.DEVICE_OUT_USB_DEVICE;
+ Log.v(TAG, "Broadcast Receiver: Got "
+ + (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ?
+ "ACTION_USB_AUDIO_ACCESSORY_PLUG" : "ACTION_USB_AUDIO_DEVICE_PLUG")
+ + ", state = " + state + ", card: " + alsaCard + ", device: " + alsaDevice);
setWiredDeviceConnectionState(device, state, params);
-
- // Capture Device
- device = action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ?
- AudioSystem.DEVICE_IN_USB_ACCESSORY : AudioSystem.DEVICE_IN_USB_DEVICE;
- setWiredDeviceConnectionState(device, state, params);
- }
- else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
+ } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
boolean broadcast = false;
int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
synchronized (mScoClients) {
@@ -4215,7 +4199,7 @@
mStreamStates[AudioSystem.STREAM_MUSIC], 0);
}
}
- } // end class AudioServiceBroadcastReceiver
+ }
//==========================================================================================
// RemoteControlDisplay / RemoteControlClient / Remote info
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 327c10c..9c67bae 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -288,8 +288,6 @@
DEVICE_IN_USB_DEVICE |
DEVICE_IN_DEFAULT);
public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
- public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY |
- DEVICE_IN_USB_DEVICE);
// device states, must match AudioSystem::device_connection_state
public static final int DEVICE_STATE_UNAVAILABLE = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f349036..844b964 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -970,7 +970,11 @@
if (mPanelSlightlyVisible != visible) {
mPanelSlightlyVisible = visible;
try {
- mBarService.onPanelRevealed();
+ if (visible) {
+ mBarService.onPanelRevealed();
+ } else {
+ mBarService.onPanelHidden();
+ }
} catch (RemoteException ex) {
// Won't fail unless the world has ended.
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 3c8af30..20fb225 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -529,7 +529,6 @@
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- mTracking = true;
if (mHandleView != null) {
mHandleView.setPressed(true);
// catch the press state change
@@ -561,6 +560,7 @@
if (h < -mTouchSlop) {
mInitialOffsetOnTouch = mExpandedHeight;
mInitialTouchY = y;
+ mTracking = true;
return true;
}
}
@@ -793,7 +793,7 @@
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(String.format("[PanelView(%s): expandedHeight=%f maxPanelHeight=%f closing=%s"
+ pw.println(String.format("[PanelView(%s): expandedHeight=%f maxPanelHeight=%d closing=%s"
+ " tracking=%s rubberbanding=%s justPeeked=%s peekAnim=%s%s timeAnim=%s%s"
+ "]",
this.getClass().getSimpleName(),
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index f1db904..79ed866 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -25,6 +25,8 @@
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.app.ActivityOptions;
+import android.os.Looper;
+import android.transition.Fade;
import android.transition.Scene;
import android.transition.Transition;
import android.transition.TransitionInflater;
@@ -109,7 +111,6 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
/**
@@ -253,8 +254,10 @@
private ActivityOptions mActivityOptions;
private SceneTransitionListener mSceneTransitionListener;
- private boolean mTriggerEarly = true;
+ private boolean mAllowEnterOverlap = true;
+ private boolean mAllowExitOverlap = true;
private Map<String, String> mSharedElementsMap;
+ private ArrayList<View> mTransitioningViews;
static class WindowManagerHolder {
static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
@@ -4081,14 +4084,26 @@
}
@Override
- public void setTransitionOptions(ActivityOptions options, SceneTransitionListener listener) {
+ public void setTransitionOptions(Bundle options, SceneTransitionListener listener) {
mSceneTransitionListener = listener;
- mActivityOptions = options;
+ ActivityOptions activityOptions = null;
+ if (options != null) {
+ activityOptions = new ActivityOptions(options);
+ if (activityOptions.getAnimationType() != ActivityOptions.ANIM_SCENE_TRANSITION) {
+ activityOptions = null;
+ }
+ }
+ mActivityOptions = activityOptions;
}
@Override
- public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
- mTriggerEarly = triggerEarly;
+ public void setAllowOverlappingEnterTransition(boolean allow) {
+ mAllowEnterOverlap = allow;
+ }
+
+ @Override
+ public void setAllowOverlappingExitTransition(boolean allow) {
+ mAllowExitOverlap = allow;
}
@Override
@@ -4097,7 +4112,50 @@
}
@Override
- public Bundle startExitTransition(ActivityOptions activityOptions) {
+ public void restoreViewVisibilityAfterTransitionToCallee() {
+ if (mTransitioningViews != null) {
+ setViewVisibility(mTransitioningViews, View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void startExitTransitionToCaller(final Runnable onTransitionEnd) {
+ Transition transition;
+ if (mContentScene == null || mTransitionManager == null || mActivityOptions == null
+ || (transition = mTransitionManager.getEnterTransition(mContentScene)) == null) {
+ onTransitionEnd.run();
+ return;
+ }
+ if (mAllowExitOverlap) {
+ TransitionSet transitionSet = new TransitionSet();
+ transitionSet.addTransition(transition);
+ Fade fade = new Fade();
+ transitionSet.addTransition(fade);
+ transition = transitionSet;
+ }
+
+ final ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
+ mapSharedElements(sharedElements);
+ final Bundle sharedElementArgs = new Bundle();
+ captureTerminalSharedElementState(sharedElements, sharedElementArgs);
+
+ final ArrayList<View> transitioningViews = new ArrayList<View>();
+ mDecor.captureTransitioningViews(transitioningViews);
+ transitioningViews.removeAll(sharedElements.values());
+
+ mSceneTransitionListener.convertToTranslucent();
+ transition = transition.clone();
+ Rect epicenter = calcEpicenter(sharedElements, mActivityOptions.getSharedElementNames());
+ transition.setEpicenterCallback(new FixedEpicenterCallback(epicenter));
+ ExitSceneBack exitScene =
+ new ExitSceneBack(onTransitionEnd, sharedElementArgs, sharedElements.values());
+ exitScene.start(transition);
+ mTransitionManager.beginDelayedTransition(mDecor, transition);
+ setViewVisibility(transitioningViews, View.INVISIBLE);
+ }
+
+ @Override
+ public Bundle startExitTransitionToCallee(Bundle options) {
if (mContentScene == null) {
return null;
}
@@ -4106,16 +4164,15 @@
return null;
}
+ ActivityOptions activityOptions = new ActivityOptions(options);
ArrayMap<String, View> sharedElements = findSharedElements(activityOptions);
// Find exiting Views and shared elements
- final ArrayList<View> transitioningViews = new ArrayList<View>();
- mDecor.captureTransitioningViews(transitioningViews);
- transitioningViews.removeAll(sharedElements.values());
+ ArrayList<View> transitioningViews = captureTransitioningViews(sharedElements.values());
- Transition exitTransition = cloneAndSetTransitionTargets(transition,
+ Transition exitTransition = addTransitionTargets(transition,
transitioningViews, true);
- Transition sharedElementTransition = cloneAndSetTransitionTargets(transition,
+ Transition sharedElementTransition = addTransitionTargets(transition,
transitioningViews, false);
// transitionSet is the total exit transition, including hero animation.
@@ -4123,8 +4180,12 @@
transitionSet.addTransition(exitTransition);
transitionSet.addTransition(sharedElementTransition);
+ Rect epicenter = calcEpicenter(sharedElements, activityOptions.getSharedElementNames());
+ FixedEpicenterCallback epicenterCallback = new FixedEpicenterCallback(epicenter);
+ transitionSet.setEpicenterCallback(epicenterCallback);
+
updateExitActivityOptions(activityOptions, sharedElements,
- sharedElementTransition, exitTransition);
+ sharedElementTransition, transitioningViews, exitTransition, epicenterCallback);
// Start exiting the Views that need to exit
TransitionManager.beginDelayedTransition(mDecor, transitionSet);
@@ -4133,6 +4194,14 @@
return activityOptions.toBundle();
}
+ private ArrayList<View> captureTransitioningViews(Collection<View> sharedElements) {
+ mTransitioningViews = new ArrayList<View>();
+ mDecor.captureTransitioningViews(mTransitioningViews);
+ ArrayList<View> transitioningViews = (ArrayList<View>) mTransitioningViews.clone();
+ transitioningViews.removeAll(sharedElements);
+ return transitioningViews;
+ }
+
private ArrayMap<String, View> findSharedElements(ActivityOptions activityOptions) {
ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
mDecor.findSharedElements(sharedElements);
@@ -4149,9 +4218,18 @@
return sharedElements;
}
+ private static void runOnUiThread(Handler handler, Runnable runnable) {
+ if (handler.getLooper() != Looper.myLooper()) {
+ handler.post(runnable);
+ } else {
+ runnable.run();
+ }
+ }
+
private void updateExitActivityOptions(ActivityOptions activityOptions,
final Map<String, View> sharedElements, Transition sharedElementTransition,
- Transition exitTransition) {
+ final ArrayList<View> transitioningViews, Transition exitTransition,
+ final Transition.EpicenterCallback epicenterCallback) {
// Schedule capturing of the shared element state
final Bundle sharedElementArgs = new Bundle();
@@ -4159,30 +4237,88 @@
ActivityOptions.SharedElementSource sharedElementSource
= new ActivityOptions.SharedElementSource() {
+ private Handler mHandler = new Handler();
+
@Override
public Bundle getSharedElementExitState() {
return sharedElementArgs;
}
@Override
- public void acceptedSharedElements(ArrayList<String> sharedElementNames) {
+ public void acceptedSharedElements(final ArrayList<String> sharedElementNames) {
if (sharedElementNames.size() == sharedElements.size()) {
return; // They were all accepted
}
- Transition transition = mTransitionManager.getExitTransition(mContentScene).clone();
- TransitionManager.beginDelayedTransition(mDecor, transition);
- for (String name: sharedElements.keySet()) {
- if (!sharedElementNames.contains(name)) {
- sharedElements.get(name).setVisibility(View.INVISIBLE);
+ runOnUiThread(mHandler, new Runnable() {
+ @Override
+ public void run() {
+ Transition transition = mTransitionManager.getExitTransition(mContentScene);
+ transition = transition.clone();
+ transition.setEpicenterCallback(epicenterCallback);
+ TransitionManager.beginDelayedTransition(mDecor, transition);
+ for (String name : sharedElements.keySet()) {
+ if (!sharedElementNames.contains(name)) {
+ sharedElements.get(name).setVisibility(View.INVISIBLE);
+ }
+ }
+ sharedElements.keySet().retainAll(sharedElementNames);
}
- }
- sharedElements.keySet().retainAll(sharedElementNames);
+ });
}
@Override
public void hideSharedElements() {
if (sharedElements != null) {
- setViewVisibility(sharedElements.values(), View.INVISIBLE);
+ runOnUiThread(mHandler, new Runnable() {
+ @Override
+ public void run() {
+ setViewVisibility(sharedElements.values(), View.INVISIBLE);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void restore(final Bundle sharedElementState) {
+ runOnUiThread(mHandler, new Runnable() {
+ @Override
+ public void run() {
+ mTransitioningViews = null;
+ Transition transition = mTransitionManager.getExitTransition(mContentScene);
+ transition = transition.clone();
+ transition.setEpicenterCallback(epicenterCallback);
+ setSharedElementState(sharedElements, sharedElementState);
+ setViewVisibility(sharedElements.values(), View.VISIBLE);
+ if (mSceneTransitionListener != null) {
+ mSceneTransitionListener.sharedElementStart(transition);
+ mDecor.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ mDecor.getViewTreeObserver().removeOnPreDrawListener(this);
+ mSceneTransitionListener.sharedElementEnd();
+ return true;
+ }
+ });
+ }
+ TransitionManager.beginDelayedTransition(mDecor, transition);
+ setViewVisibility(transitioningViews, View.VISIBLE);
+ for (View sharedElement: sharedElements.values()) {
+ sharedElement.requestLayout();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void prepareForRestore() {
+ if (mTransitioningViews != null) {
+ runOnUiThread(mHandler, new Runnable() {
+ @Override
+ public void run() {
+ setViewVisibility(mTransitioningViews, View.INVISIBLE);
+ }
+ });
}
}
};
@@ -4207,22 +4343,18 @@
});
}
- private static Transition cloneAndSetTransitionTargets(Transition transition,
- List<View> views, boolean add) {
- transition = transition.clone();
- if (!transition.getTargetIds().isEmpty() || !transition.getTargets().isEmpty()) {
- TransitionSet set = new TransitionSet();
- set.addTransition(transition);
- transition = set;
- }
+ private static Transition addTransitionTargets(Transition transition, Collection<View> views,
+ boolean add) {
+ TransitionSet set = new TransitionSet();
+ set.addTransition(transition.clone());
for (View view: views) {
if (add) {
- transition.addTarget(view);
+ set.addTarget(view);
} else {
- transition.excludeTarget(view, true);
+ set.excludeTarget(view, true);
}
}
- return transition;
+ return set;
}
private static void setViewVisibility(Collection<View> views, int visibility) {
@@ -4231,6 +4363,14 @@
}
}
+ private static void setSharedElementState(Map<String, View> sharedElements,
+ Bundle sharedElementState) {
+ int[] tempLoc = new int[2];
+ for (Map.Entry<String, View> entry: sharedElements.entrySet()) {
+ setSharedElementState(entry.getValue(), entry.getKey(), sharedElementState, tempLoc);
+ }
+ }
+
/**
* Sets the captured values from a previous
* {@link #captureSharedElementState(android.view.View, String, android.os.Bundle, int[])}
@@ -4247,23 +4387,27 @@
return;
}
- int x = sharedElementBundle.getInt(KEY_SCREEN_X);
- view.getLocationOnScreen(tempLoc);
- int offsetX = x - tempLoc[0];
- view.offsetLeftAndRight(offsetX);
-
- int width = sharedElementBundle.getInt(KEY_WIDTH);
- view.setRight(view.getLeft() + width);
-
- int y = sharedElementBundle.getInt(KEY_SCREEN_Y);
- int offsetY = y - tempLoc[1];
- view.offsetTopAndBottom(offsetY);
-
- int height = sharedElementBundle.getInt(KEY_HEIGHT);
- view.setBottom(view.getTop() + height);
-
float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z);
view.setTranslationZ(z);
+
+ int x = sharedElementBundle.getInt(KEY_SCREEN_X);
+ int y = sharedElementBundle.getInt(KEY_SCREEN_Y);
+ int width = sharedElementBundle.getInt(KEY_WIDTH);
+ int height = sharedElementBundle.getInt(KEY_HEIGHT);
+
+ int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
+ int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
+ view.measure(widthSpec, heightSpec);
+
+ ViewGroup parent = (ViewGroup) view.getParent();
+ parent.getLocationOnScreen(tempLoc);
+ int left = x - tempLoc[0];
+ int top = y - tempLoc[1];
+ int right = left + width;
+ int bottom = top + height;
+ view.layout(left, top, right, bottom);
+
+ view.requestLayout();
}
/**
@@ -4297,6 +4441,124 @@
transitionArgs.putBundle(name, sharedElementBundle);
}
+ private void mapSharedElements(ArrayMap<String, View> sharedElements) {
+ ArrayList<String> sharedElementNames = mActivityOptions.getSharedElementNames();
+ if (sharedElementNames != null) {
+ mDecor.findSharedElements(sharedElements);
+ if (mSharedElementsMap != null) {
+ for (Map.Entry<String, String> entry : mSharedElementsMap.entrySet()) {
+ View sharedElement = sharedElements.remove(entry.getValue());
+ if (sharedElement != null) {
+ sharedElements.put(entry.getKey(), sharedElement);
+ }
+ }
+ }
+ sharedElements.keySet().retainAll(sharedElementNames);
+ }
+ }
+
+ private static Rect calcEpicenter(ArrayMap<String, View> sharedElements,
+ ArrayList<String> sharedElementNames) {
+ if (sharedElementNames != null) {
+ for (String name: sharedElementNames) {
+ if (name.startsWith("android:")) {
+ return null;
+ }
+ View view = sharedElements.get(name);
+ if (view != null) {
+ int[] loc = new int[2];
+ view.getLocationOnScreen(loc);
+ int left = loc[0] + Math.round(view.getTranslationX());
+ int top = loc[1] + Math.round(view.getTranslationY());
+ int right = left + view.getWidth();
+ int bottom = top + view.getHeight();
+ return new Rect(left, top, right, bottom);
+ }
+ }
+ }
+ return null;
+ }
+
+ private class ExitSceneBack extends Transition.TransitionListenerAdapter implements
+ Animator.AnimatorListener {
+ private boolean mExitTransitionComplete;
+ private boolean mBackgroundFadeComplete;
+ private boolean mOnCompleteExecuted;
+ private boolean mSharedElementTransitioned;
+ private Runnable mOnComplete;
+ private Bundle mSharedElementArgs;
+ private Collection<View> mSharedElements;
+
+ public ExitSceneBack(Runnable onComplete, Bundle sharedElementArgs,
+ Collection<View> sharedElements) {
+ mOnComplete = onComplete;
+ mSharedElementArgs = sharedElementArgs;
+ mSharedElements = sharedElements;
+ }
+
+ public void start(Transition exitTransition) {
+ if (mActivityOptions != null) {
+ mActivityOptions.dispatchPrepareRestore();
+ }
+ exitTransition.addListener(this);
+ Drawable background = mDecor.getBackground();
+ if (background != null) {
+ ObjectAnimator animator = ObjectAnimator.ofInt(background, "alpha", 0);
+ animator.addListener(this);
+ animator.start();
+ } else {
+ mBackgroundFadeComplete = true;
+ startCalledActivityEnter();
+ }
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ transition.removeListener(this);
+ mExitTransitionComplete = true;
+ notifyComplete();
+ if (!mAllowExitOverlap) {
+ startCalledActivityEnter();
+ }
+ }
+
+ private void notifyComplete() {
+ if (mExitTransitionComplete && mBackgroundFadeComplete
+ && mSharedElementTransitioned && !mOnCompleteExecuted) {
+ mOnComplete.run();
+ mSceneTransitionListener.nullPendingTransition();
+ mOnCompleteExecuted = true;
+ }
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mBackgroundFadeComplete = true;
+ if (mAllowExitOverlap) {
+ startCalledActivityEnter();
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ private void startCalledActivityEnter() {
+ mActivityOptions.dispatchRestore(mSharedElementArgs);
+ setViewVisibility(mSharedElements, View.INVISIBLE);
+ mSharedElementTransitioned = true;
+ notifyComplete();
+ }
+ }
+
/**
* Provides code for handling the Activity transition entering scene.
* When the first scene is laid out (onPreDraw), it makes views invisible.
@@ -4317,6 +4579,7 @@
private boolean mEnterTransitionStarted;
private ArrayMap<String, View> mSharedElementTargets = new ArrayMap<String, View>();
private ArrayList<View> mEnteringViews = new ArrayList<View>();
+ private Transition.EpicenterCallback mEpicenterCallback;
public EnterScene() {
mSceneTransitionListener.nullPendingTransition();
@@ -4335,33 +4598,25 @@
if (!mEnterTransitionStarted && mSceneTransitionListener != null) {
mEnterTransitionStarted = true;
mDecor.captureTransitioningViews(mEnteringViews);
- ArrayList<String> sharedElementNames = mActivityOptions.getSharedElementNames();
- if (sharedElementNames != null) {
- mDecor.findSharedElements(mSharedElementTargets);
- if (mSharedElementsMap != null) {
- for (Map.Entry<String, String> entry : mSharedElementsMap.entrySet()) {
- View sharedElement = mSharedElementTargets.remove(entry.getValue());
- if (sharedElement != null) {
- mSharedElementTargets.put(entry.getKey(), sharedElement);
- }
- }
- }
- mSharedElementTargets.keySet().retainAll(sharedElementNames);
- mEnteringViews.removeAll(mSharedElementTargets.values());
- }
+ mapSharedElements(mSharedElementTargets);
+ mEnteringViews.removeAll(mSharedElementTargets.values());
+ Rect epicenter = calcEpicenter(mSharedElementTargets,
+ mActivityOptions.getSharedElementNames());
+ mEpicenterCallback = new FixedEpicenterCallback(epicenter);
setViewVisibility(mEnteringViews, View.INVISIBLE);
setViewVisibility(mSharedElementTargets.values(), View.INVISIBLE);
- if (mTriggerEarly) {
+ if (mAllowEnterOverlap) {
beginEnterScene();
}
observer.addOnPreDrawListener(this);
+ return false;
} else {
mHandler.postDelayed(this, MAX_TRANSITION_START_WAIT);
mActivityOptions.dispatchSceneTransitionStarted(this,
new ArrayList<String>(mSharedElementTargets.keySet()));
+ return !mSharedElementReadyReceived;
}
- return true;
}
public void start() {
@@ -4375,43 +4630,48 @@
}
@Override
- public void sharedElementTransitionComplete(Bundle transitionArgs) {
+ public void sharedElementTransitionComplete(final Bundle transitionArgs) {
if (!mSharedElementReadyReceived) {
mSharedElementReadyReceived = true;
mHandler.removeCallbacks(this);
mHandler.postDelayed(this, MAX_TRANSITION_FINISH_WAIT);
if (!mSharedElementTargets.isEmpty()) {
- Transition transition = getTransitionManager().getEnterTransition(
- mContentScene);
- if (transition == null) {
- transition = TransitionManager.getDefaultTransition();
- }
- transition = transition.clone();
- if (transitionArgs == null) {
- TransitionManager.beginDelayedTransition(mDecor, transition);
- setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
- } else {
- int[] tempLoc = new int[2];
- for (Map.Entry<String, View> entry: mSharedElementTargets.entrySet()) {
- setSharedElementState(entry.getValue(), entry.getKey(), transitionArgs,
- tempLoc);
+ runOnUiThread(mHandler, new Runnable() {
+ @Override
+ public void run() {
+ Transition transition = getTransitionManager().getEnterTransition(
+ mContentScene);
+ if (transition == null) {
+ transition = TransitionManager.getDefaultTransition();
+ }
+ transition = addTransitionTargets(transition,
+ mSharedElementTargets.values(),
+ true);
+ transition.setEpicenterCallback(mEpicenterCallback);
+ if (transitionArgs == null) {
+ TransitionManager.beginDelayedTransition(mDecor, transition);
+ setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
+ } else {
+ mSceneTransitionListener.sharedElementStart(transition);
+ setSharedElementState(mSharedElementTargets, transitionArgs);
+ setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
+ mDecor.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ mDecor.getViewTreeObserver()
+ .removeOnPreDrawListener(this);
+ mSceneTransitionListener.sharedElementEnd();
+ mActivityOptions.dispatchSharedElementsReady();
+ return true;
+ }
+ });
+ TransitionManager.beginDelayedTransition(mDecor, transition);
+ }
}
- setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
- mSceneTransitionListener.sharedElementStart(transition);
- mDecor.getViewTreeObserver().addOnPreDrawListener(
- new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- mDecor.getViewTreeObserver().removeOnPreDrawListener(this);
- mSceneTransitionListener.sharedElementEnd();
- mActivityOptions.dispatchSharedElementsReady();
- return true;
- }
- });
- TransitionManager.beginDelayedTransition(mDecor, transition);
- }
+ });
}
- if (mTriggerEarly) {
+ if (mAllowEnterOverlap) {
fadeInBackground();
}
}
@@ -4436,9 +4696,14 @@
mAllDone = true;
sharedElementTransitionComplete(null);
mHandler.removeCallbacks(this);
- if (!mTriggerEarly) {
- beginEnterScene();
- fadeInBackground();
+ if (!mAllowEnterOverlap) {
+ runOnUiThread(mHandler, new Runnable() {
+ @Override
+ public void run() {
+ beginEnterScene();
+ fadeInBackground();
+ }
+ });
}
}
@@ -4462,10 +4727,25 @@
private void beginEnterScene() {
Transition transition = getTransitionManager().getEnterTransition(mContentScene);
if (transition == null) {
- transition = TransitionManager.getDefaultTransition().clone();
+ transition = TransitionManager.getDefaultTransition();
}
+ transition = addTransitionTargets(transition, mEnteringViews, true);
+ transition.setEpicenterCallback(mEpicenterCallback);
TransitionManager.beginDelayedTransition(mDecor, transition);
setViewVisibility(mEnteringViews, View.VISIBLE);
}
}
+
+ private static class FixedEpicenterCallback extends Transition.EpicenterCallback {
+ private Rect mEpicenter;
+
+ public FixedEpicenterCallback(Rect epicenter) {
+ mEpicenter = epicenter;
+ }
+
+ @Override
+ public Rect getEpicenter(Transition transition) {
+ return mEpicenter;
+ }
+ };
}
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 0f78c9b..9768934 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -58,7 +58,11 @@
2751 notification_cancel (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
# when someone tries to cancel all of the notifications for a particular package
2752 notification_cancel_all (uid|1|5),(pid|1|5),(pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
-
+# when the notification panel is shown
+# Note: New tag range starts here since 2753+ have been used below.
+27500 notification_panel_revealed
+# when the notification panel is hidden
+27501 notification_panel_hidden
# ---------------------------
# Watchdog.java
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
old mode 100644
new mode 100755
index 33b12c5..d596472
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -522,13 +522,6 @@
if (fullscreen == toOpaque) {
return false;
}
- AttributeCache.Entry ent =
- AttributeCache.instance().get(packageName, realTheme, styleable.Window, userId);
- if (ent == null
- || !ent.array.getBoolean(styleable.Window_windowIsTranslucent, false)
- || ent.array.getBoolean(styleable.Window_windowIsFloating, false)) {
- return false;
- }
// Keep track of the number of fullscreen activities in this task.
task.numFullscreen += toOpaque ? +1 : -1;
@@ -956,8 +949,8 @@
// for another app to start, then we have paused dispatching
// for this activity.
ActivityRecord r = this;
- final ActivityStack stack = task.stack;
if (r.waitingVisible) {
+ final ActivityStack stack = mStackSupervisor.getFocusedStack();
// Hmmm, who might we be waiting for?
r = stack.mResumedActivity;
if (r == null) {
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 4c8dcc3..e0591a2 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -29,5 +29,6 @@
String pkg, String tag, int id,
int uid, int initialPid, String message, int userId);
void onPanelRevealed();
+ void onPanelHidden();
boolean allowDisable(int what, IBinder token, String pkg);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 3b6d288..8be2410 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -966,6 +966,7 @@
@Override
public void onPanelRevealed() {
+ EventLogTags.writeNotificationPanelRevealed();
synchronized (mNotificationList) {
// sound
mSoundNotification = null;
@@ -998,6 +999,11 @@
}
@Override
+ public void onPanelHidden() {
+ EventLogTags.writeNotificationPanelHidden();
+ }
+
+ @Override
public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id,
int uid, int initialPid, String message, int userId) {
Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
@@ -1915,8 +1921,8 @@
mNotificationList.add(r);
mUsageStats.registerPostedByApp(r);
} else {
- old = mNotificationList.remove(index);
- mNotificationList.add(index, r);
+ old = mNotificationList.get(index);
+ mNotificationList.set(index, r);
mUsageStats.registerUpdatedByApp(r);
// Make sure we don't lose the foreground service state.
if (old != null) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 4ce02c1..e4b5f3a 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -535,6 +535,17 @@
}
@Override
+ public void onPanelHidden() throws RemoteException {
+ enforceStatusBarService();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mNotificationDelegate.onPanelHidden();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public void onNotificationClick(String pkg, String tag, int id, int userId) {
enforceStatusBarService();
final int callingUid = Binder.getCallingUid();
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index 9ccb809..7ae5460 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -17,7 +17,6 @@
package com.android.server.usb;
import android.content.Context;
-import android.content.Intent;
import android.hardware.usb.UsbConfiguration;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
@@ -26,25 +25,21 @@
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
-import android.os.UserHandle;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
-import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Scanner;
/**
* UsbHostManager manages USB state in host mode.
*/
public class UsbHostManager {
private static final String TAG = UsbHostManager.class.getSimpleName();
- private static final boolean DEBUG_AUDIO = false;
+ private static final boolean LOG = false;
// contains all connected USB devices
private final HashMap<String, UsbDevice> mDevices = new HashMap<String, UsbDevice>();
@@ -107,30 +102,6 @@
return false;
}
- // Broadcasts the arrival/departure of a USB audio interface
- // card - the ALSA card number of the physical interface
- // device - the ALSA device number of the physical interface
- // enabled - if true, we're connecting a device (it's arrived), else disconnecting
- private void sendDeviceNotification(int card, int device, boolean enabled,
- boolean hasPlayback, boolean hasCapture, boolean hasMIDI) {
- // send a sticky broadcast containing current USB state
- Intent intent = new Intent(Intent.ACTION_USB_AUDIO_DEVICE_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", enabled ? 1 : 0);
- intent.putExtra("card", card);
- intent.putExtra("device", device);
- intent.putExtra("hasPlayback", hasPlayback);
- intent.putExtra("hasCapture", hasCapture);
- intent.putExtra("hasMIDI", hasMIDI);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
- static boolean isBuiltInUsbDevice(String deviceName) {
- // This may be too broad an assumption
- return deviceName.equals("/dev/bus/usb/001/001");
- }
-
/* Called from JNI in monitorUsbHostBus() to report new USB devices
Returns true if successful, in which case the JNI code will continue adding configurations,
interfaces and endpoints, and finally call endUsbDeviceAdded after all descriptors
@@ -140,59 +111,6 @@
int deviceClass, int deviceSubclass, int deviceProtocol,
String manufacturerName, String productName, String serialNumber) {
- if (DEBUG_AUDIO) {
- Slog.d(TAG, "usb:UsbHostManager.beginUsbDeviceAdded(" + deviceName + ")");
- // Audio Class Codes:
- // Audio: 0x01
- // Audio Subclass Codes:
- // undefined: 0x00
- // audio control: 0x01
- // audio streaming: 0x02
- // midi streaming: 0x03
-
- // some useful debugging info
- Slog.d(TAG, "usb:UsbHostManager.usbDeviceAdded()");
- Slog.d(TAG, "usb: nm:" + deviceName +
- " vnd:" + vendorID +
- " prd:" + productID +
- " cls:" + deviceClass +
- " sub:" + deviceSubclass +
- " proto:" + deviceProtocol);
- }
-
- if (!isBuiltInUsbDevice(deviceName)) {
- //TODO(pmclean) we will need this when we need to support USB interfaces
- // beyond card1, device0 but turn them off for now
- //com.android.alsascan.AlsaCardsParser cardsParser =
- // new com.android.alsascan.AlsaCardsParser();
- //cardsParser.scan();
- //cardsParser.Log();
-
- // But we need to parse the device to determine its capabilities.
- com.android.alsascan.AlsaDevicesParser devicesParser =
- new com.android.alsascan.AlsaDevicesParser();
- devicesParser.scan();
- //devicesParser.Log();
-
- boolean hasPlaybackDevices = devicesParser.hasPlaybackDevices();
- boolean hasCaptureDevices = devicesParser.hasCaptureDevices();
- boolean hasMIDI = devicesParser.hasMIDIDevices();
-
- if (DEBUG_AUDIO) {
- Slog.d(TAG, "usb: hasPlayback:" + hasPlaybackDevices
- + " hasCapture:" + hasCaptureDevices);
- }
-
- //TODO(pmclean)
- // For now just assume that any USB device that is attached is:
- // 1. An audio interface and
- // 2. is card:1 device:0
- int cardNum = 1;
- int deviceNum = 0;
- sendDeviceNotification(cardNum, deviceNum, true,
- hasPlaybackDevices, hasCaptureDevices, hasMIDI);
- }
-
if (isBlackListed(deviceName) ||
isBlackListed(deviceClass, deviceSubclass, deviceProtocol)) {
return false;
@@ -258,9 +176,6 @@
/* Called from JNI in monitorUsbHostBus() to finish adding a new device */
private void endUsbDeviceAdded() {
- if (DEBUG_AUDIO) {
- Slog.d(TAG, "usb:UsbHostManager.endUsbDeviceAdded()");
- }
if (mNewInterface != null) {
mNewInterface.setEndpoints(
mNewEndpoints.toArray(new UsbEndpoint[mNewEndpoints.size()]));
@@ -289,13 +204,6 @@
/* Called from JNI in monitorUsbHostBus to report USB device removal */
private void usbDeviceRemoved(String deviceName) {
- if (DEBUG_AUDIO) {
- Slog.d(TAG, "usb:UsbHostManager.usbDeviceRemoved() nm:" + deviceName);
- }
-
- // Same assumptions as the fake-out above
- sendDeviceNotification(1, 0, false, /*NA*/false, /*NA*/false, /*NA*/false);
-
synchronized (mLock) {
UsbDevice device = mDevices.remove(deviceName);
if (device != null) {
diff --git a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
new file mode 100644
index 0000000..914a359
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
@@ -0,0 +1,45 @@
+/*
+ * 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.content.res;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide implementation of a select few native methods of {@link AssetManager}
+ * <p/>
+ * Through the layoutlib_create tool, the original native methods of AssetManager have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class AssetManager_Delegate {
+
+ @LayoutlibDelegate
+ /*package*/ static long newTheme(AssetManager manager) {
+ return Resources_Theme_Delegate.getDelegateManager()
+ .addNewDelegate(new Resources_Theme_Delegate());
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void deleteTheme(AssetManager manager, long theme) {
+ Resources_Theme_Delegate.getDelegateManager().removeJavaReferenceFor(theme);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void applyThemeStyle(long theme, int styleRes, boolean force) {
+ Resources_Theme_Delegate.getDelegateManager().getDelegate(theme).force = force;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
index c9d615c..31d1594 100644
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
@@ -16,7 +16,13 @@
package android.content.res;
+import com.android.annotations.Nullable;
+import com.android.ide.common.rendering.api.ResourceReference;
+import com.android.ide.common.rendering.api.StyleResourceValue;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.layoutlib.bridge.impl.RenderSessionImpl;
+import com.android.resources.ResourceType;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.content.res.Resources.NotFoundException;
@@ -25,7 +31,7 @@
import android.util.TypedValue;
/**
- * Delegate used to provide new implementation of a select few methods of {@link Resources$Theme}
+ * Delegate used to provide new implementation of a select few methods of {@link Resources.Theme}
*
* Through the layoutlib_create tool, the original methods of Theme have been replaced
* by calls to methods of the same name in this delegate class.
@@ -33,11 +39,28 @@
*/
public class Resources_Theme_Delegate {
+ // Whether to use the Theme.mThemeResId as primary theme.
+ boolean force;
+
+ // ---- delegate manager ----
+
+ private static final DelegateManager<Resources_Theme_Delegate> sManager =
+ new DelegateManager<Resources_Theme_Delegate>(Resources_Theme_Delegate.class);
+
+ public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() {
+ return sManager;
+ }
+
+ // ---- delegate methods. ----
+
@LayoutlibDelegate
/*package*/ static TypedArray obtainStyledAttributes(
Resources thisResources, Theme thisTheme,
int[] attrs) {
- return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
+ boolean changed = setupResources(thisTheme);
+ TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
+ restoreResources(changed);
+ return ta;
}
@LayoutlibDelegate
@@ -45,15 +68,21 @@
Resources thisResources, Theme thisTheme,
int resid, int[] attrs)
throws NotFoundException {
- return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid, attrs);
+ boolean changed = setupResources(thisTheme);
+ TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid, attrs);
+ restoreResources(changed);
+ return ta;
}
@LayoutlibDelegate
/*package*/ static TypedArray obtainStyledAttributes(
Resources thisResources, Theme thisTheme,
AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
- return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(
- set, attrs, defStyleAttr, defStyleRes);
+ boolean changed = setupResources(thisTheme);
+ TypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(set, attrs,
+ defStyleAttr, defStyleRes);
+ restoreResources(changed);
+ return ta;
}
@LayoutlibDelegate
@@ -61,7 +90,45 @@
Resources thisResources, Theme thisTheme,
int resid, TypedValue outValue,
boolean resolveRefs) {
- return RenderSessionImpl.getCurrentContext().resolveThemeAttribute(
+ boolean changed = setupResources(thisTheme);
+ boolean found = RenderSessionImpl.getCurrentContext().resolveThemeAttribute(
resid, outValue, resolveRefs);
+ restoreResources(changed);
+ return found;
+ }
+
+ // ---- private helper methods ----
+
+ private static boolean setupResources(Theme thisTheme) {
+ Resources_Theme_Delegate themeDelegate = sManager.getDelegate(thisTheme.getNativeTheme());
+ StyleResourceValue style = resolveStyle(thisTheme.getAppliedStyleResId());
+ if (style != null) {
+ RenderSessionImpl.getCurrentContext().getRenderResources()
+ .applyStyle(style, themeDelegate.force);
+ return true;
+ }
+ return false;
+ }
+
+ private static void restoreResources(boolean changed) {
+ if (changed) {
+ RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles();
+ }
+ }
+
+ @Nullable
+ private static StyleResourceValue resolveStyle(int nativeResid) {
+ if (nativeResid == 0) {
+ return null;
+ }
+ BridgeContext context = RenderSessionImpl.getCurrentContext();
+ ResourceReference theme = context.resolveId(nativeResid);
+ if (theme.isFramework()) {
+ return (StyleResourceValue) context.getRenderResources()
+ .getFrameworkResource(ResourceType.STYLE, theme.getName());
+ } else {
+ return (StyleResourceValue) context.getRenderResources()
+ .getProjectResource(ResourceType.STYLE, theme.getName());
+ }
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index b9294ab..9ee2f60 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -16,6 +16,7 @@
package com.android.layoutlib.bridge.android;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
@@ -109,7 +110,7 @@
// maps for dynamically generated id representing style objects (StyleResourceValue)
private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap;
private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
- private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style
+ private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
// cache for TypedArray generated from IStyleResourceValue object
private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache;
@@ -315,6 +316,11 @@
}
}
+ // The base value for R.style is 0x01030000 and the custom style is 0x02030000.
+ // So, if the second byte is 03, it's probably a style.
+ if ((id >> 16 & 0xFF) == 0x03) {
+ return getStyleByDynamicId(id);
+ }
return null;
}
@@ -455,7 +461,10 @@
@Override
public final TypedArray obtainStyledAttributes(int[] attrs) {
- return createStyleBasedTypedArray(mRenderResources.getCurrentTheme(), attrs);
+ // No style is specified here, so create the typed array based on the default theme
+ // and the styles already applied to it. A null value of style indicates that the default
+ // theme should be used.
+ return createStyleBasedTypedArray(null, attrs);
}
@Override
@@ -723,11 +732,13 @@
/**
* Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
- * values found in the given style.
+ * values found in the given style. If no style is specified, the default theme, along with the
+ * styles applied to it are used.
+ *
* @see #obtainStyledAttributes(int, int[])
*/
- private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs)
- throws Resources.NotFoundException {
+ private BridgeTypedArray createStyleBasedTypedArray(@Nullable StyleResourceValue style,
+ int[] attrs) throws Resources.NotFoundException {
List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
@@ -740,8 +751,14 @@
if (attribute != null) {
// look for the value in the given style
- ResourceValue resValue = mRenderResources.findItemInStyle(style,
- attribute.getFirst(), attribute.getSecond());
+ ResourceValue resValue;
+ if (style != null) {
+ resValue = mRenderResources.findItemInStyle(style, attribute.getFirst(),
+ attribute.getSecond());
+ } else {
+ resValue = mRenderResources.findItemInTheme(attribute.getFirst(),
+ attribute.getSecond());
+ }
if (resValue != null) {
// resolve it to make sure there are no references left.
@@ -756,7 +773,6 @@
return ta;
}
-
/**
* The input int[] attrs is a list of attributes. The returns a list of information about
* each attributes. The information is (name, isFramework)
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 4236038..e0c05de 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -126,6 +126,9 @@
"android.content.res.Resources$Theme#obtainStyledAttributes",
"android.content.res.Resources$Theme#resolveAttribute",
"android.content.res.Resources#localeToLanguageTag",
+ "android.content.res.AssetManager#newTheme",
+ "android.content.res.AssetManager#deleteTheme",
+ "android.content.res.AssetManager#applyThemeStyle",
"android.content.res.TypedArray#getValueAt",
"android.graphics.BitmapFactory#finishDecode",
"android.os.Handler#sendMessageAtTime",