Merge "Fix SCO start stop tests." into ics-mr1
diff --git a/api/current.txt b/api/current.txt
index b302cf3..23b441b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14243,13 +14243,6 @@
method public static void texSubImage2D(int, int, int, int, android.graphics.Bitmap, int, int);
}
- public abstract class ManagedEGLContext {
- ctor public ManagedEGLContext(javax.microedition.khronos.egl.EGLContext);
- method public javax.microedition.khronos.egl.EGLContext getContext();
- method public abstract void onTerminate(javax.microedition.khronos.egl.EGLContext);
- method public void terminate();
- }
-
public class Matrix {
ctor public Matrix();
method public static void frustumM(float[], int, float, float, float, float, float, float);
@@ -18432,14 +18425,14 @@
ctor public RSSurfaceView(android.content.Context);
ctor public RSSurfaceView(android.content.Context, android.util.AttributeSet);
method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public synchronized void destroyRenderScriptGL();
+ method public void destroyRenderScriptGL();
method public android.renderscript.RenderScriptGL getRenderScriptGL();
method public void pause();
method public void resume();
method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
- method public synchronized void surfaceChanged(android.view.SurfaceHolder, int, int, int);
+ method public void surfaceChanged(android.view.SurfaceHolder, int, int, int);
method public void surfaceCreated(android.view.SurfaceHolder);
- method public synchronized void surfaceDestroyed(android.view.SurfaceHolder);
+ method public void surfaceDestroyed(android.view.SurfaceHolder);
}
public class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index fe81d2b..395c28b 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -120,6 +120,12 @@
dump_file("NETWORK ROUTES", "/proc/net/route");
dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
+ run_command("IP RULES", 10, "ip", "rule", "show", NULL);
+ run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
+ run_command("ROUTE TABLE 60", 10, "ip", "route", "show", "table", "60", NULL);
+ run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "60", NULL);
+ run_command("ROUTE TABLE 61", 10, "ip", "route", "show", "table", "61", NULL);
+ run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "61", NULL);
dump_file("ARP CACHE", "/proc/net/arp");
run_command("IPTABLES", 10, "su", "root", "iptables", "-L", "-nvx", NULL);
run_command("IP6TABLES", 10, "su", "root", "ip6tables", "-L", "-nvx", NULL);
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 4e38011..7ca6155 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -22,12 +22,9 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
-import android.media.AudioManager;
-import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.SystemProperties;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
@@ -157,7 +154,6 @@
private boolean mOneShot;
private boolean mWithBuffer;
private boolean mFaceDetectionRunning = false;
- private boolean mReleased = false;
/**
* Broadcast Action: A new picture is taken by the camera, and the entry of
@@ -322,15 +318,6 @@
public final void release() {
native_release();
mFaceDetectionRunning = false;
- if (mCameraSoundPlayers != null) {
- for (CameraSoundPlayer csp: mCameraSoundPlayers) {
- if (csp != null) {
- csp.release();
- }
- }
- mCameraSoundPlayers = null;
- }
- mReleased = true;
}
/**
@@ -3503,194 +3490,4 @@
return false;
}
};
-
- /**
- * <p>The set of default system sounds for camera actions. Use this with
- * {@link #playSound} to play an appropriate sound when implementing a
- * custom still or video recording mechanism through the preview
- * callbacks.</p>
- *
- * <p>There is no need to play sounds when using {@link #takePicture} or
- * {@link android.media.MediaRecorder} for still images or video,
- * respectively, as these play their own sounds when needed.</p>
- *
- * @see #playSound
- * @hide
- */
- public static class Sound {
- /**
- * The sound used by {@link android.hardware.Camera#takePicture} to
- * indicate still image capture.
- */
- public static final int SHUTTER_CLICK = 0;
-
- /**
- * A sound to indicate that focusing has completed. Because deciding
- * when this occurs is application-dependent, this sound is not used by
- * any methods in the Camera class.
- */
- public static final int FOCUS_COMPLETE = 1;
-
- /**
- * The sound used by {@link android.media.MediaRecorder#start} to
- * indicate the start of video recording.
- */
- public static final int START_VIDEO_RECORDING = 2;
-
- /**
- * The sound used by {@link android.media.MediaRecorder#stop} to
- * indicate the end of video recording.
- */
- public static final int STOP_VIDEO_RECORDING = 3;
-
- private static final int NUM_SOUNDS = 4;
- };
-
- /**
- * <p>Play one of the predefined platform sounds for camera actions.</p>
- *
- * <p>Use this method to play a platform-specific sound for various camera
- * actions. The sound playing is done asynchronously, with the same behavior
- * and content as the sounds played by {@link #takePicture takePicture},
- * {@link android.media.MediaRecorder#start MediaRecorder.start}, and
- * {@link android.media.MediaRecorder#stop MediaRecorder.stop}.</p>
- *
- * <p>Using this method makes it easy to match the default device sounds
- * when recording or capturing data through the preview callbacks
- * ({@link #setPreviewCallback setPreviewCallback},
- * {@link #setPreviewTexture setPreviewTexture}).</p>
- *
- * @param soundId The type of sound to play, selected from the options in
- * {@link android.hardware.Camera.Sound}
- * @see android.hardware.Camera.Sound
- * @see #takePicture
- * @see android.media.MediaRecorder
- * @hide
- */
- public void playSound(int soundId) {
- if (mReleased) return;
- if (mCameraSoundPlayers == null) {
- mCameraSoundPlayers = new CameraSoundPlayer[Sound.NUM_SOUNDS];
- }
- if (mCameraSoundPlayers[soundId] == null) {
- mCameraSoundPlayers[soundId] = new CameraSoundPlayer(soundId);
- }
- mCameraSoundPlayers[soundId].play();
- }
-
- private CameraSoundPlayer[] mCameraSoundPlayers;
-
- private static class CameraSoundPlayer implements Runnable {
- private int mSoundId;
- private int mAudioStreamType;
- private MediaPlayer mPlayer;
- private Thread mThread;
- private boolean mExit;
- private int mPlayCount;
-
- private static final String mShutterSound =
- "/system/media/audio/ui/camera_click.ogg";
- private static final String mFocusSound =
- "/system/media/audio/ui/camera_focus.ogg";
- private static final String mVideoStartSound =
- "/system/media/audio/ui/VideoRecord.ogg";
- private static final String mVideoStopSound =
- "/system/media/audio/ui/VideoRecord.ogg";
-
- @Override
- public void run() {
- String soundFilePath;
- switch (mSoundId) {
- case Sound.SHUTTER_CLICK:
- soundFilePath = mShutterSound;
- break;
- case Sound.FOCUS_COMPLETE:
- soundFilePath = mFocusSound;
- break;
- case Sound.START_VIDEO_RECORDING:
- soundFilePath = mVideoStartSound;
- break;
- case Sound.STOP_VIDEO_RECORDING:
- soundFilePath = mVideoStopSound;
- break;
- default:
- Log.e(TAG, "Unknown sound " + mSoundId + " requested.");
- return;
- }
- mPlayer = new MediaPlayer();
- try {
- mPlayer.setAudioStreamType(mAudioStreamType);
- mPlayer.setDataSource(soundFilePath);
- mPlayer.setLooping(false);
- mPlayer.prepare();
- } catch(IOException e) {
- Log.e(TAG, "Error setting up sound " + mSoundId, e);
- return;
- }
-
- while(true) {
- try {
- synchronized (this) {
- while(true) {
- if (mExit) {
- return;
- } else if (mPlayCount <= 0) {
- wait();
- } else {
- mPlayCount--;
- break;
- }
- }
- }
- mPlayer.start();
- } catch (Exception e) {
- Log.e(TAG, "Error playing sound " + mSoundId, e);
- }
- }
- }
-
- public CameraSoundPlayer(int soundId) {
- mSoundId = soundId;
- if (SystemProperties.get("ro.camera.sound.forced", "0").equals("0")) {
- mAudioStreamType = AudioManager.STREAM_MUSIC;
- } else {
- mAudioStreamType = AudioManager.STREAM_SYSTEM_ENFORCED;
- }
- }
-
- public void play() {
- if (mThread == null) {
- mThread = new Thread(this);
- mThread.start();
- }
- synchronized (this) {
- mPlayCount++;
- notifyAll();
- }
- }
-
- public void release() {
- if (mThread != null) {
- synchronized (this) {
- mExit = true;
- notifyAll();
- }
- try {
- mThread.join();
- } catch (InterruptedException e) {
- }
- mThread = null;
- }
- if (mPlayer != null) {
- mPlayer.release();
- mPlayer = null;
- }
- }
-
- @Override
- protected void finalize() {
- release();
- }
- }
-
}
diff --git a/core/java/android/hardware/CameraSound.java b/core/java/android/hardware/CameraSound.java
new file mode 100644
index 0000000..32de0cd
--- /dev/null
+++ b/core/java/android/hardware/CameraSound.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2011 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.hardware;
+
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * <p>Use this class to play an appropriate sound when implementing a custom
+ * still or video recording mechanism through the preview callbacks.</p>
+ *
+ * <p>There is no need to play sounds when using {@link #android.hardware.Camera#takePicture}
+ * or {@link android.media.MediaRecorder} for still images or video,
+ * respectively, as these play their own sounds when needed.</p>
+ *
+ * @hide
+ */
+public class CameraSound {
+ private static final String TAG = "CameraSound";
+ /**
+ * The sound used by {@link android.hardware.Camera#takePicture} to
+ * indicate still image capture.
+ */
+ public static final int SHUTTER_CLICK = 0;
+
+ /**
+ * A sound to indicate that focusing has completed. Because deciding
+ * when this occurs is application-dependent, this sound is not used by
+ * any methods in the Camera class.
+ */
+ public static final int FOCUS_COMPLETE = 1;
+
+ /**
+ * The sound used by {@link android.media.MediaRecorder#start} to
+ * indicate the start of video recording.
+ */
+ public static final int START_VIDEO_RECORDING = 2;
+
+ /**
+ * The sound used by {@link android.media.MediaRecorder#stop} to
+ * indicate the end of video recording.
+ */
+ public static final int STOP_VIDEO_RECORDING = 3;
+
+ private static final int NUM_SOUNDS = 4;
+ private CameraSoundPlayer[] mCameraSoundPlayers;
+
+ public CameraSound() {
+ }
+
+ /**
+ * <p>Play one of the predefined platform sounds for camera actions.</p>
+ *
+ * <p>Use this method to play a platform-specific sound for various camera
+ * actions. The sound playing is done asynchronously, with the same behavior
+ * and content as the sounds played by {@link #takePicture takePicture},
+ * {@link android.media.MediaRecorder#start MediaRecorder.start}, and
+ * {@link android.media.MediaRecorder#stop MediaRecorder.stop}.</p>
+ *
+ * <p>Using this method makes it easy to match the default device sounds
+ * when recording or capturing data through the preview callbacks.</p>
+ *
+ * @param soundId The type of sound to play, selected from SHUTTER_CLICK,
+ * FOCUS_COMPLETE, START_VIDEO_RECORDING, or STOP_VIDEO_RECORDING.
+ * @see android.hardware#takePicture
+ * @see android.media.MediaRecorder
+ * @see #SHUTTER_CLICK
+ * @see #FOCUS_COMPLETE
+ * @see #START_VIDEO_RECORDING
+ * @see #STOP_VIDEO_RECORDING
+ */
+ public void playSound(int soundId) {
+ if (mCameraSoundPlayers == null) {
+ mCameraSoundPlayers = new CameraSoundPlayer[NUM_SOUNDS];
+ }
+ if (mCameraSoundPlayers[soundId] == null) {
+ mCameraSoundPlayers[soundId] = new CameraSoundPlayer(soundId);
+ }
+ mCameraSoundPlayers[soundId].play();
+ }
+
+ public void release() {
+ if (mCameraSoundPlayers != null) {
+ for (CameraSoundPlayer csp: mCameraSoundPlayers) {
+ if (csp != null) {
+ csp.release();
+ }
+ }
+ mCameraSoundPlayers = null;
+ }
+ }
+
+ private static class CameraSoundPlayer implements Runnable {
+ private int mSoundId;
+ private int mAudioStreamType;
+ private MediaPlayer mPlayer;
+ private Thread mThread;
+ private boolean mExit;
+ private int mPlayCount;
+
+ private static final String mShutterSound =
+ "/system/media/audio/ui/camera_click.ogg";
+ private static final String mFocusSound =
+ "/system/media/audio/ui/camera_focus.ogg";
+ private static final String mVideoStartSound =
+ "/system/media/audio/ui/VideoRecord.ogg";
+ private static final String mVideoStopSound =
+ "/system/media/audio/ui/VideoRecord.ogg";
+
+ @Override
+ public void run() {
+ String soundFilePath;
+ switch (mSoundId) {
+ case SHUTTER_CLICK:
+ soundFilePath = mShutterSound;
+ break;
+ case FOCUS_COMPLETE:
+ soundFilePath = mFocusSound;
+ break;
+ case START_VIDEO_RECORDING:
+ soundFilePath = mVideoStartSound;
+ break;
+ case STOP_VIDEO_RECORDING:
+ soundFilePath = mVideoStopSound;
+ break;
+ default:
+ Log.e(TAG, "Unknown sound " + mSoundId + " requested.");
+ return;
+ }
+ mPlayer = new MediaPlayer();
+ try {
+ mPlayer.setAudioStreamType(mAudioStreamType);
+ mPlayer.setDataSource(soundFilePath);
+ mPlayer.setLooping(false);
+ mPlayer.prepare();
+ } catch(IOException e) {
+ Log.e(TAG, "Error setting up sound " + mSoundId, e);
+ return;
+ }
+
+ while(true) {
+ try {
+ synchronized (this) {
+ while(true) {
+ if (mExit) {
+ return;
+ } else if (mPlayCount <= 0) {
+ wait();
+ } else {
+ mPlayCount--;
+ break;
+ }
+ }
+ }
+ mPlayer.start();
+ } catch (Exception e) {
+ Log.e(TAG, "Error playing sound " + mSoundId, e);
+ }
+ }
+ }
+
+ public CameraSoundPlayer(int soundId) {
+ mSoundId = soundId;
+ if (SystemProperties.get("ro.camera.sound.forced", "0").equals("0")) {
+ mAudioStreamType = AudioManager.STREAM_MUSIC;
+ } else {
+ mAudioStreamType = AudioManager.STREAM_SYSTEM_ENFORCED;
+ }
+ }
+
+ public void play() {
+ if (mThread == null) {
+ mThread = new Thread(this);
+ mThread.start();
+ }
+ synchronized (this) {
+ mPlayCount++;
+ notifyAll();
+ }
+ }
+
+ public void release() {
+ if (mThread != null) {
+ synchronized (this) {
+ mExit = true;
+ notifyAll();
+ }
+ try {
+ mThread.join();
+ } catch (InterruptedException e) {
+ }
+ mThread = null;
+ }
+ if (mPlayer != null) {
+ mPlayer.release();
+ mPlayer = null;
+ }
+ }
+
+ @Override
+ protected void finalize() {
+ release();
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 3362575..e1bc275 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -101,7 +101,7 @@
* Defines the UID/GID for the NFC service process.
* @hide
*/
- public static final int NFC_UID = 1025;
+ public static final int NFC_UID = 1027;
/**
* Defines the GID for the group that allows write access to the internal media storage.
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 0194240..fd00dce 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -118,12 +118,26 @@
if (current != null && TextUtils.equals(callingApp, current.getCallingApp())) {
stop(current);
}
+
+ final MessageParams lastSynthesis = mLastSynthesisRequest;
+
+ if (lastSynthesis != null && lastSynthesis != current &&
+ TextUtils.equals(callingApp, lastSynthesis.getCallingApp())) {
+ stop(lastSynthesis);
+ }
}
synchronized public void removeAllItems() {
if (DBG_THREADING) Log.d(TAG, "Removing all items");
removeAllMessages();
- stop(getCurrentParams());
+
+ final MessageParams current = getCurrentParams();
+ final MessageParams lastSynthesis = mLastSynthesisRequest;
+ stop(current);
+
+ if (lastSynthesis != null && lastSynthesis != current) {
+ stop(lastSynthesis);
+ }
}
/**
@@ -350,7 +364,7 @@
// extra trouble to clean the data to prevent the AudioTrack resources
// from being leaked.
if (mLastSynthesisRequest != null) {
- Log.w(TAG, "Error : Missing call to done() for request : " +
+ Log.e(TAG, "Error : Missing call to done() for request : " +
mLastSynthesisRequest);
handleSynthesisDone(mLastSynthesisRequest);
}
@@ -443,7 +457,11 @@
audioTrack.release();
params.setAudioTrack(null);
}
- params.getDispatcher().dispatchOnDone();
+ if (params.isError()) {
+ params.getDispatcher().dispatchOnError();
+ } else {
+ params.getDispatcher().dispatchOnDone();
+ }
mLastSynthesisRequest = null;
params.mLogger.onWriteData();
}
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index ce3522b..91a3452 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -80,27 +80,23 @@
@Override
void stop() {
+ stopImpl(false);
+ }
+
+ void stopImpl(boolean wasError) {
if (DBG) Log.d(TAG, "stop()");
// Note that mLogger.mError might be true too at this point.
mLogger.onStopped();
- SynthesisMessageParams token = null;
+ SynthesisMessageParams token;
synchronized (mStateLock) {
if (mStopped) {
Log.w(TAG, "stop() called twice");
return;
}
- // mToken will be null if the engine encounters
- // an error before it called start().
- if (mToken == null) {
- // In all other cases, mAudioTrackHandler.stop() will
- // result in onComplete being called.
- mLogger.onWriteData();
- } else {
- token = mToken;
- }
+ token = mToken;
mStopped = true;
}
@@ -109,7 +105,24 @@
// point it will write an additional buffer to the token - but we
// won't worry about that because the audio playback queue will be cleared
// soon after (see SynthHandler#stop(String).
+ token.setIsError(wasError);
token.clearBuffers();
+ if (wasError) {
+ // Also clean up the audio track if an error occurs.
+ mAudioTrackHandler.enqueueSynthesisDone(token);
+ }
+ } else {
+ // This happens when stop() or error() were called before start() was.
+
+ // In all other cases, mAudioTrackHandler.stop() will
+ // result in onSynthesisDone being called, and we will
+ // write data there.
+ mLogger.onWriteData();
+
+ if (wasError) {
+ // We have to dispatch the error ourselves.
+ mDispatcher.dispatchOnError();
+ }
}
}
@@ -219,7 +232,7 @@
// Currently, this call will not be logged if error( ) is called
// before start.
mLogger.onError();
- stop();
+ stopImpl(true);
}
}
diff --git a/core/java/android/speech/tts/SynthesisMessageParams.java b/core/java/android/speech/tts/SynthesisMessageParams.java
index 0c0f033..ed66420 100644
--- a/core/java/android/speech/tts/SynthesisMessageParams.java
+++ b/core/java/android/speech/tts/SynthesisMessageParams.java
@@ -51,6 +51,7 @@
int mAudioBufferSize;
// Always synchronized on "this".
int mUnconsumedBytes;
+ volatile boolean mIsError;
private final LinkedList<ListEntry> mDataBufferList = new LinkedList<ListEntry>();
@@ -74,6 +75,7 @@
mAudioTrack = null;
mBytesWritten = 0;
mAudioBufferSize = 0;
+ mIsError = false;
}
@Override
@@ -120,6 +122,14 @@
return mAudioTrack;
}
+ void setIsError(boolean isError) {
+ mIsError = isError;
+ }
+
+ boolean isError() {
+ return mIsError;
+ }
+
// Must be called synchronized on this.
private long getUnconsumedAudioLengthMs() {
final int unconsumedFrames = mUnconsumedBytes / mBytesPerFrame;
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 38699ea..a220615 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -490,6 +490,7 @@
private final Map<String, Uri> mUtterances;
private final Bundle mParams = new Bundle();
private final TtsEngines mEnginesHelper;
+ private final String mPackageName;
private volatile String mCurrentEngine = null;
/**
@@ -518,19 +519,36 @@
* @param engine Package name of the TTS engine to use.
*/
public TextToSpeech(Context context, OnInitListener listener, String engine) {
+ this(context, listener, engine, null);
+ }
+
+ /**
+ * Used by the framework to instantiate TextToSpeech objects with a supplied
+ * package name, instead of using {@link android.content.Context#getPackageName()}
+ *
+ * @hide
+ */
+ public TextToSpeech(Context context, OnInitListener listener, String engine,
+ String packageName) {
mContext = context;
mInitListener = listener;
mRequestedEngine = engine;
mEarcons = new HashMap<String, Uri>();
mUtterances = new HashMap<String, Uri>();
+ mUtteranceProgressListener = null;
mEnginesHelper = new TtsEngines(mContext);
+ if (packageName != null) {
+ mPackageName = packageName;
+ } else {
+ mPackageName = mContext.getPackageName();
+ }
initTts();
}
private String getPackageName() {
- return mContext.getPackageName();
+ return mPackageName;
}
private <R> R runActionNoReconnect(Action<R> action, R errorResult, String method) {
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 39922da..aee678a 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -450,7 +450,7 @@
@Override
public void dispatchOnDone() {
final String utteranceId = getUtteranceId();
- if (!TextUtils.isEmpty(utteranceId)) {
+ if (utteranceId != null) {
mCallbacks.dispatchOnDone(getCallingApp(), utteranceId);
}
}
@@ -458,7 +458,7 @@
@Override
public void dispatchOnStart() {
final String utteranceId = getUtteranceId();
- if (!TextUtils.isEmpty(utteranceId)) {
+ if (utteranceId != null) {
mCallbacks.dispatchOnStart(getCallingApp(), utteranceId);
}
}
@@ -466,7 +466,7 @@
@Override
public void dispatchOnError() {
final String utteranceId = getUtteranceId();
- if (!TextUtils.isEmpty(utteranceId)) {
+ if (utteranceId != null) {
mCallbacks.dispatchOnError(getCallingApp(), utteranceId);
}
}
@@ -509,6 +509,7 @@
}
class SynthesisSpeechItem extends SpeechItem {
+ // Never null.
private final String mText;
private final SynthesisRequest mSynthesisRequest;
private final String[] mDefaultLocale;
@@ -532,8 +533,8 @@
@Override
public boolean isValid() {
- if (TextUtils.isEmpty(mText)) {
- Log.w(TAG, "Got empty text");
+ if (mText == null) {
+ Log.wtf(TAG, "Got null text");
return false;
}
if (mText.length() >= MAX_SPEECH_ITEM_CHAR_LENGTH) {
diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java
index a04458a..cf0d22c 100644
--- a/core/java/android/speech/tts/UtteranceProgressListener.java
+++ b/core/java/android/speech/tts/UtteranceProgressListener.java
@@ -57,12 +57,16 @@
listener.onUtteranceCompleted(utteranceId);
}
- // The following methods are left unimplemented.
@Override
- public void onStart(String utteranceId) { }
+ public void onError(String utteranceId) {
+ listener.onUtteranceCompleted(utteranceId);
+ }
@Override
- public void onError(String utteranceId) { }
+ public void onStart(String utteranceId) {
+ // Left unimplemented, has no equivalent in the old
+ // API.
+ }
};
}
}
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 353b628..7f8af7a 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -1415,7 +1415,7 @@
}
}
- if (noMonthDay && startMonthNum == endMonthNum) {
+ if (noMonthDay && startMonthNum == endMonthNum && startYear == endYear) {
// Example: "January, 2008"
return formatter.format("%s", startDate.format(defaultDateFormat));
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8e39d6e..f77cf7e 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -162,13 +162,21 @@
abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;
/**
- * Destoys the layers used by the specified view hierarchy.
+ * Destroys the layers used by the specified view hierarchy.
*
* @param view The root of the view hierarchy
*/
abstract void destroyLayers(View view);
/**
+ * Destroys all hardware rendering resources associated with the specified
+ * view hierarchy.
+ *
+ * @param view The root of the view hierarchy
+ */
+ abstract void destroyHardwareResources(View view);
+
+ /**
* This method should be invoked whenever the current hardware renderer
* context should be reset.
*
@@ -348,15 +356,6 @@
}
/**
- * Invoke this method when the system needs to clean up all resources
- * associated with hardware rendering.
- */
- static void terminate() {
- Log.d(LOG_TAG, "Terminating hardware rendering");
- Gl20Renderer.terminate();
- }
-
- /**
* Indicates whether hardware acceleration is currently enabled.
*
* @return True if hardware acceleration is in use, false otherwise.
@@ -412,8 +411,8 @@
static final Object[] sEglLock = new Object[0];
int mWidth = -1, mHeight = -1;
- static final ThreadLocal<Gl20Renderer.MyEGLContext> sEglContextStorage
- = new ThreadLocal<Gl20Renderer.MyEGLContext>();
+ static final ThreadLocal<Gl20Renderer.Gl20RendererEglContext> sEglContextStorage
+ = new ThreadLocal<Gl20Renderer.Gl20RendererEglContext>();
EGLContext mEglContext;
Thread mEglThread;
@@ -565,13 +564,13 @@
}
}
- Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
+ Gl20Renderer.Gl20RendererEglContext managedContext = sEglContextStorage.get();
mEglContext = managedContext != null ? managedContext.getContext() : null;
mEglThread = Thread.currentThread();
if (mEglContext == null) {
mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
- sEglContextStorage.set(new Gl20Renderer.MyEGLContext(mEglContext));
+ sEglContextStorage.set(new Gl20Renderer.Gl20RendererEglContext(mEglContext));
}
}
@@ -909,10 +908,10 @@
private static EGLSurface sPbuffer;
private static final Object[] sPbufferLock = new Object[0];
- static class MyEGLContext extends ManagedEGLContext {
+ static class Gl20RendererEglContext extends ManagedEGLContext {
final Handler mHandler = new Handler();
- public MyEGLContext(EGLContext context) {
+ public Gl20RendererEglContext(EGLContext context) {
super(context);
}
@@ -939,7 +938,8 @@
sEglContextStorage.remove();
sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT);
sEgl.eglReleaseThread();
sEgl.eglTerminate(sEglDisplay);
@@ -1046,10 +1046,9 @@
}
}
- private void destroyHardwareLayer(View view) {
- if (view.destroyLayer()) {
- view.invalidate(true);
- }
+ private static void destroyHardwareLayer(View view) {
+ view.destroyLayer();
+
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
@@ -1059,6 +1058,36 @@
}
}
}
+
+ @Override
+ void destroyHardwareResources(View view) {
+ if (view != null) {
+ boolean needsContext = true;
+ if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;
+
+ if (needsContext) {
+ Gl20RendererEglContext managedContext = sEglContextStorage.get();
+ if (managedContext == null) return;
+ usePbufferSurface(managedContext.getContext());
+ }
+
+ destroyResources(view);
+ GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+ }
+ }
+
+ private static void destroyResources(View view) {
+ view.destroyHardwareResources();
+
+ if (view instanceof ViewGroup) {
+ ViewGroup group = (ViewGroup) view;
+
+ int count = group.getChildCount();
+ for (int i = 0; i < count; i++) {
+ destroyResources(group.getChildAt(i));
+ }
+ }
+ }
static HardwareRenderer create(boolean translucent) {
if (GLES20Canvas.isAvailable()) {
@@ -1070,7 +1099,7 @@
static void trimMemory(int level) {
if (sEgl == null || sEglConfig == null) return;
- Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
+ Gl20RendererEglContext managedContext = sEglContextStorage.get();
// We do not have OpenGL objects
if (managedContext == null) {
return;
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 1697382..74916f0 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -203,7 +203,10 @@
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
+ destroySurface();
+ }
+ private void destroySurface() {
if (mLayer != null) {
boolean shouldRelease = true;
if (mListener != null) {
@@ -300,6 +303,17 @@
return false;
}
+ /**
+ * @hide
+ */
+ @Override
+ protected void destroyHardwareResources() {
+ super.destroyHardwareResources();
+ destroySurface();
+ invalidateParentCaches();
+ invalidate(true);
+ }
+
@Override
HardwareLayer getHardwareLayer() {
if (mLayer == null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e2f3919..6a9f1e6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10073,7 +10073,7 @@
switch (mLayerType) {
case LAYER_TYPE_HARDWARE:
destroyLayer();
- // fall through - unaccelerated views may use software layer mechanism instead
+ // fall through - non-accelerated views may use software layer mechanism instead
case LAYER_TYPE_SOFTWARE:
destroyDrawingCache();
break;
@@ -10140,7 +10140,11 @@
switch (mLayerType) {
case LAYER_TYPE_HARDWARE:
- getHardwareLayer();
+ if (mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled() &&
+ mAttachInfo.mHardwareRenderer.validate()) {
+ getHardwareLayer();
+ }
break;
case LAYER_TYPE_SOFTWARE:
buildDrawingCache(true);
@@ -10235,12 +10239,31 @@
if (mHardwareLayer != null) {
mHardwareLayer.destroy();
mHardwareLayer = null;
+
+ invalidate(true);
+ invalidateParentCaches();
+
return true;
}
return false;
}
/**
+ * Destroys all hardware rendering resources. This method is invoked
+ * when the system needs to reclaim resources. Upon execution of this
+ * method, you should free any OpenGL resources created by the view.
+ *
+ * Note: you <strong>must</strong> call
+ * <code>super.destroyHardwareResources()</code> when overriding
+ * this method.
+ *
+ * @hide
+ */
+ protected void destroyHardwareResources() {
+ destroyLayer();
+ }
+
+ /**
* <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
* to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
* bitmap. Calling {@link #draw(android.graphics.Canvas)} will not draw from the cache when
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b15b155..5f70a39 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -576,6 +576,13 @@
}
}
+ void terminateHardwareResources() {
+ if (mAttachInfo.mHardwareRenderer != null) {
+ mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView);
+ mAttachInfo.mHardwareRenderer.destroy(false);
+ }
+ }
+
void destroyHardwareLayers() {
if (mThread != Thread.currentThread()) {
if (mAttachInfo.mHardwareRenderer != null &&
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 660e3f4..dfd1d55 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -425,7 +425,7 @@
if (mViews == null) return;
int count = mViews.length;
for (int i = 0; i < count; i++) {
- mRoots[i].destroyHardwareResources();
+ mRoots[i].terminateHardwareResources();
}
}
// Terminate the hardware renderer to free all resources
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index f29aff2..cb555ea 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -261,6 +261,8 @@
mLayout.addView(getSurfaceView(), layoutParams);
mLayout.setVisibility(View.VISIBLE);
+ mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
WebChromeClient client = webView.getWebChromeClient();
if (client != null) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7045f8c..2af6e3b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -742,6 +742,7 @@
static final int SCREEN_ON = 136;
static final int ENTER_FULLSCREEN_VIDEO = 137;
static final int UPDATE_SELECTION = 138;
+ static final int UPDATE_ZOOM_DENSITY = 139;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
private static final int LAST_PACKAGE_MSG_ID = SET_TOUCH_HIGHLIGHT_RECTS;
@@ -797,7 +798,9 @@
"AUTOFILL_COMPLETE", // = 134;
"SELECT_AT", // = 135;
"SCREEN_ON", // = 136;
- "ENTER_FULLSCREEN_VIDEO" // = 137;
+ "ENTER_FULLSCREEN_VIDEO", // = 137;
+ "UPDATE_SELECTION", // = 138;
+ "UPDATE_ZOOM_DENSITY" // = 139;
};
// If the site doesn't use the viewport meta tag to specify the viewport,
@@ -1303,8 +1306,15 @@
if (AccessibilityManager.getInstance(mContext).isEnabled()
&& getSettings().getJavaScriptEnabled()) {
// exposing the TTS for now ...
- mTextToSpeech = new TextToSpeech(getContext(), null);
- addJavascriptInterface(mTextToSpeech, ALIAS_ACCESSIBILITY_JS_INTERFACE);
+ final Context ctx = getContext();
+ if (ctx != null) {
+ final String packageName = ctx.getPackageName();
+ if (packageName != null) {
+ mTextToSpeech = new TextToSpeech(getContext(), null, null,
+ packageName + ".**webview**");
+ addJavascriptInterface(mTextToSpeech, ALIAS_ACCESSIBILITY_JS_INTERFACE);
+ }
+ }
}
}
@@ -1625,6 +1635,14 @@
clearTextEntry();
clearActionModes();
dismissFullScreenMode();
+ cancelSelectDialog();
+ }
+
+ private void cancelSelectDialog() {
+ if (mListBoxDialog != null) {
+ mListBoxDialog.cancel();
+ mListBoxDialog = null;
+ }
}
/**
@@ -3276,6 +3294,8 @@
if (mNativeClass != 0) {
nativeSetPauseDrawing(mNativeClass, true);
}
+
+ cancelSelectDialog();
}
}
@@ -8444,6 +8464,11 @@
mZoomManager.updateZoomRange(viewState, getViewWidth(), viewState.mScrollX);
break;
}
+ case UPDATE_ZOOM_DENSITY: {
+ final float density = (Float) msg.obj;
+ mZoomManager.updateDefaultZoomDensity(density);
+ break;
+ }
case REPLACE_BASE_CONTENT: {
nativeReplaceBaseContent(msg.arg1);
break;
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index a97f4dd..2ad866b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2337,7 +2337,8 @@
/ mViewportDensityDpi;
}
if (adjust != mWebView.getDefaultZoomScale()) {
- mWebView.updateDefaultZoomDensity(adjust);
+ Message.obtain(mWebView.mPrivateHandler,
+ WebView.UPDATE_ZOOM_DENSITY, adjust).sendToTarget();
}
int defaultScale = (int) (adjust * 100);
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 84d00c9..cf2c8a6 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -498,6 +498,11 @@
if (mZoomScale == 0) {
// We've reached the end of the zoom animation.
mInHWAcceleratedZoom = false;
+
+ // Ensure that the zoom level is pushed to WebCore. This has not
+ // yet occurred because we prevent it from happening while
+ // mInHWAcceleratedZoom is true.
+ mWebView.sendViewSizeZoom(false);
}
} else {
canvas.translate(tx, ty);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3e96c81..fec4cbc 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1275,7 +1275,7 @@
// record changes to the battery level.
if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
(dataSize >= MAX_MAX_HISTORY_BUFFER
- || ((mHistoryEnd.states^mHistoryCur.states)
+ || ((mHistoryLastWritten.states^mHistoryCur.states)
& HistoryItem.MOST_INTERESTING_STATES) == 0)) {
return;
}
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index b7bc366..25b0065 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -29,6 +29,7 @@
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.animation.DecelerateInterpolator;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
@@ -392,7 +393,11 @@
final ActionBar.Tab tab = mTab;
final View custom = tab.getCustomView();
if (custom != null) {
- addView(custom);
+ final ViewParent customParent = custom.getParent();
+ if (customParent != this) {
+ if (customParent != null) ((ViewGroup) customParent).removeView(custom);
+ addView(custom);
+ }
mCustomView = custom;
if (mTextView != null) mTextView.setVisibility(GONE);
if (mIconView != null) {
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 168030c..42f3d8c 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1219,6 +1219,6 @@
<string name="status_bar_device_locked" msgid="3092703448690669768">"Toestel gesluit."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
<string name="sending" msgid="8715108995741758718">"Stuur tans..."</string>
- <string name="launchBrowserDefault" msgid="2057951947297614725">"Begin Browser?"</string>
- <string name="SetupCallDefault" msgid="6870275517518479651">"Aanvaar Bel?"</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Begin webblaaier?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Aanvaar oproep?"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 97996ab..9fb9946 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Апублікаваць праз..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Прылада заблакаваная."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Адпраўка..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Адказаць?"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 66b5cae..f86b74f 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Споделяне със..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Устройството е заключено."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Изпраща се..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Да се стартира ли браузърът?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Да се приеме ли обаждането?"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 74ee156..617c0b3 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Sdílet s..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Zařízení je uzamčeno."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Odesílání..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Přijmout hovor?"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 465ec4e..c1f4c9b 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Del med:"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Enhed låst."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Sender..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte browseren?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Vil du besvare opkaldet?"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f77187c..53c4f30 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1096,7 +1096,7 @@
<string name="throttled_notification_title" msgid="6269541897729781332">"Mobildatenlimit überschritten"</string>
<string name="throttled_notification_message" msgid="4712369856601275146">"Durch Berühren weitere Informationen zur Mobildatennutzung aufrufen"</string>
<string name="no_matches" msgid="8129421908915840737">"Keine Treffer"</string>
- <string name="find_on_page" msgid="1946799233822820384">"Auf Seite suchen"</string>
+ <string name="find_on_page" msgid="1946799233822820384">"Suchen"</string>
<plurals name="matches_found">
<item quantity="one" msgid="8167147081136579439">"1 Treffer"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> von <xliff:g id="TOTAL">%d</xliff:g>"</item>
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Teilen mit..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Gerät gesperrt"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Wird gesendet..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Anruf annehmen?"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 54980a5..f52d25d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Κοινή χρήση με..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Η συσκευή κλειδώθηκε."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Αποστολή..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Εκκίνηση προγράμματος περιήγησης;"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Αποδοχή κλήσης;"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index ba79143..f93aee3 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Compartir con..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Envío en curso..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Deseas iniciar el navegador?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"¿Deseas aceptar la llamada?"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a7aeb01..db9dab0 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Compartir con..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Enviando..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Iniciar el navegador?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"¿Aceptar la llamada?"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 4801b32..3b4d993 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Jaga kasutaja(te)ga ..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Seade lukustatud."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Saatmine ..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Kas käivitada brauser?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Kas vastata kõnele?"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 49cae50..9c06aa6 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Jaa seuraavien kautta:"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Laite lukittu."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Lähetetään..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Vastataanko puheluun?"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 4b33998..f2726d8b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Partager avec..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Appareil verrouillé"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Envoi en cours…"</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer l\'application Navigateur ?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Prendre l\'appel ?"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 7f140f1..925724e 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"इससे साझा करें..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"उपकरण लॉक कर दिया गया."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"भेज रहा है..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"कॉल स्वीकार करें?"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0599a6b..ae592f1 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Dijeli sa..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Uređaj zaključan."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Slanje u tijeku..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Prihvatiti poziv?"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 6e395f3..d303aa1 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Megosztás..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Az eszköz le van zárva."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Küldés..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Hívás fogadása?"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 930c89e..2699953 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Berbagi dengan..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Perangkat tergembok."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Mengirim..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Peramban?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Terima Panggilan?"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index bd7350d..0706a24 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Condividi con..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloccato."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Invio..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Avviare l\'applicazione Browser?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Accettare la chiamata?"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 7b315c2..b74d7fd 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -901,7 +901,7 @@
<string name="chooseUsbActivity" msgid="7892597146032121735">"בחר יישום עבור מכשיר ה-USB"</string>
<string name="noApplications" msgid="1691104391758345586">"אין יישומים שיכולים לבצע פעולה זו."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
- <string name="aerr_application" msgid="932628488013092776">"לצערנו ה<xliff:g id="APPLICATION">%1$s</xliff:g> הפסיק לפעול."</string>
+ <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת ה<xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string>
<string name="aerr_process" msgid="4507058997035697579">"לצערנו, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="8339738283149696827">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב."\n\n" האם ברצונך לסגור אותו?"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index d0e94c8..15dc2fe 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"共有相手..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"端末がロックされています。"</string>
<string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"送信しています..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"通話を受けますか?"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index fe048be..924198e 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"공유 대상..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"기기가 잠겼습니다."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"보내는 중..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"통화를 수락하시겠습니까?"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index bb3b044..ae92e56 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Bendrinti su..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Įrenginys užrakintas."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Siunčiama..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Paleisti naršyklę?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Priimti skambutį?"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index dc60a35..b4e4488 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Koplietot ar..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Ierīce ir bloķēta."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Notiek sūtīšana..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Vai palaist pārlūkprogrammu?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Vai pieņemt zvanu?"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index b268575..a2b253b 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Kongsi dengan..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Peranti dikunci."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Menghantar..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancarkan Penyemak Imbas?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Terima Panggilan?"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index e9c0965..0cab24a 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -302,7 +302,7 @@
<string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"Lar appen lese fra diverse loggfiler på systemet. Disse inneholder generell informasjon om hva som gjøres med nettbrettet, og kan inneholde personlig eller privat informasjon."</string>
<string name="permdesc_readLogs" product="default" msgid="8896449437464867766">"Lar appen lese fra diverse loggfiler på systemet. Disse inneholder generell informasjon om hva som gjøres med telefonen, og kan inneholde personlig eller privat informasjon."</string>
<string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"bruke en hvilken som helst mediedekoder for avspilling"</string>
- <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Gir en app tillatelse til å bruke en hvilken som helst installert mediedekoder for å dekode for avspilling."</string>
+ <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Lar apper bruke en hvilken som helst installert mediedekoder for å dekode for avspilling."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"lese/skrive ressurser eid av diag"</string>
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Lar applikasjonen lese og skrive enhver ressurs eid av gruppen diag; for eksempel, filer i /dev. Dette kan potensielt påvirke systemets sikkerhet og stabilitet. Dette bør KUN brukes for maskinvarespesifikke diagnoseverktøy laget av operatøren eller produsenten."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"aktivere eller deaktigere applikasjonskomponenter"</string>
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Del med"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Enheten er låst."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Sender …"</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Vil du besvare anropet?"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index cc04e9c..14d3d0c 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -36,7 +36,7 @@
<string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
<string name="mmiError" msgid="5154499457739052907">"Problem z połączeniem lub błędny kod MMI."</string>
<string name="mmiFdnError" msgid="5224398216385316471">"Operacja jest ograniczona wyłącznie do numerów ustalonych."</string>
- <string name="serviceEnabled" msgid="8147278346414714315">"Usługa była włączona."</string>
+ <string name="serviceEnabled" msgid="8147278346414714315">"Usługa została włączona."</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"Usługa została włączona dla:"</string>
<string name="serviceDisabled" msgid="1937553226592516411">"Usługa została wyłączona."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"Rejestracja powiodła się."</string>
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Udostępnij..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Urządzenie zablokowane."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Wysyłanie..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Odebrać połączenie?"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 16e1282..679d73d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1020,7 +1020,7 @@
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string>
- <string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string>
+ <string name="select_input_method" msgid="6865512749462072765"></string>
<string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de entrada"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Partilhar com..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Aparelho bloqueado."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"A enviar..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Iniciar Navegador?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Aceitar Chamada?"</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 86492fa..040ad38 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Distribuiţi cu..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Dispozitiv blocat."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Se trimite..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Lansaţi browserul?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Acceptaţi apelul?"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d0a40954..58b027c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Настройка доступа"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Устройство заблокировано."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Отправка..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустить браузер?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Принять вызов?"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f075d27..5476a84 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Zdieľať s..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Zariadenie je zamknuté."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Prebieha odosielanie..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Prijať hovor?"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e298819..1221b99 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Skupna raba z ..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Naprava zaklenjena."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Pošiljanje ..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Ali želite sprejeti klic?"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index f083a6d..5402394 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Дељење са..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Уређај је закључан."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Слање..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Желите ли да прихватите позив?"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 2e04d8f..f1dbe47 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Dela med..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Enheten är låst."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Skickas ..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Vill du öppna webbläsaren?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Vill du ta emot samtal?"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index d1287d8..5334bfc 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -266,11 +266,11 @@
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"funganisha kwa mbinu ya uingizaji"</string>
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Huruhusu kishikiliaji kufunga kiolesura cha kiwango cha juu cha mbinu ya uingizaji. Haipaswi kuhitajika kwa programu za kawaida za kompyuta."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
- <string name="permdesc_bindTextService" msgid="172508880651909350">"Huruhusu kishikiliaji kufunga kiolesura cha kiwango cha juu cha pazia cha huduma ya maandishi (k.m.SpellCheckerService). Haipaswi kuhitajika kwa programu za kawaida."</string>
+ <string name="permdesc_bindTextService" msgid="172508880651909350">"Huruhusu kishikiliaji kufunga kiolesura cha kiwango cha juu cha mandhari cha huduma ya maandishi (k.m.SpellCheckerService). Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"funga kwa huduma ya VPN"</string>
<string name="permdesc_bindVpnService" msgid="6011554199384584151">"Huruhusu kishikiliaji kufunga kusano cha kiwango cha juu cha huduma ya Vpn. Haipaswi kamwe kuhitajika kwa programu za kawaida."</string>
- <string name="permlab_bindWallpaper" msgid="8716400279937856462">"funga kwa pazia"</string>
- <string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Huruhusu kishikiliaji kufunga kiolesura cha kiwango cha juu cha pazia. Haipaswi kuhitajika kwa programu za kawaida za kompyuta."</string>
+ <string name="permlab_bindWallpaper" msgid="8716400279937856462">"funga kwa mandhari"</string>
+ <string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Huruhusu kishikiliaji kufunga kiolesura cha kiwango cha juu cha mandhari. Haipaswi kuhitajika kwa programu za kawaida za kompyuta."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"funga kwenye huduma ya widget"</string>
<string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Huruhusu kishikiliaji kufunga kiolesura cha kiwango cha juu cha huduma ya wiji. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"jiunge na msimamizi wa kifaa"</string>
@@ -333,9 +333,9 @@
<string name="permlab_writeProfile" msgid="4679878325177177400">"andika kwenye data ya maelezo yako mafupi"</string>
<string name="permdesc_writeProfile" product="default" msgid="6431297330378229453">"Inaruhusu programu kubadilisha au kuongeza maelezo binafsi ya maelezo yako mafupi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na maelezo ya anwani. Hii ina maanisha programu nyingine ziweze kukutambua na kutuma maelezo ya maelezo yako mafupi kwa wengine."</string>
<string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mkondo wako wa kijamii"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Inaruhusu programu kufikia na kulandanisha usasisho kutoka kwako na marafiki wako. Prog hasidi zinaweza kutumia hizi kusoma mawasiliano ya kibinafsi kati yako na marafiki wako kwenye mitandao ya kijamii."</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="6619997662735851111">"Inaruhusu programuramu kufikia na kulandanisha usasisho kutoka kwako na marafiki wako. Prog hasidi zinaweza kutumia hizi kusoma mawasiliano ya kibinafsi kati yako na marafiki wako kwenye mitandao ya kijamii."</string>
<string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mkondo wako wa kijamii"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Inaruhusu programu kuonyesha usasisho ya kijamii kutoka kwa marafiki wako. Prog hasidi zinaweza kutumia hizi zikijifanya kuwa rafiki na kukuhadaa kuonyesha nenosiri au taarifa zingine za siri."</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="2689083745826002521">"Inaruhusu programuramu kuonyesha usasisho ya kijamii kutoka kwa marafiki wako. Prog hasidi zinaweza kutumia hizi zikijifanya kuwa rafiki na kukuhadaa kuonyesha nenosiri au taarifa zingine za siri."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="5665520896961671949">"Huruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kompyuta yako ndogo, pamoja na za marafiki au wafanyakazi wenza. Programu hasidi yenye kibali hiki kinaweza kuchukua maelezo ya kibinagsi kutoka kwa kalenda hizi bila ufahamu wa mmiliki."</string>
<string name="permdesc_readCalendar" product="default" msgid="2915879965326930312">"Huruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye simu yako, pamoja na za marafiki au marafiki wenza. Programu hasidi yenye kibali hiki inaweza kuchukua maelezo ya kibinafsi kutoka kwa kalenda hizi bila ufahamu wa mmiliki."</string>
@@ -423,10 +423,10 @@
<string name="permlab_factoryTest" msgid="3715225492696416187">"endesha katika hali ya jaribio ya kiwanda"</string>
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Endesha kama jaribio la mtengenezaji la kiwango cha chini, kwa hivyo kuruhusu ufikiaji kamili wa maunzi ya kompyuta ndogo. Inapatikana tu wakati kompyuta ndogo inaendeshwa katika hali ya jaribio la mtengenezaji."</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Endesha kama jaribio la kiwango cha chini cha mtengenezaji, kwa hivyo kuruhusu ufikiaji kamili wa maunzi ya simu. Inapatikana tu wakati simu inaendeshwa katika gumzo ya jaribio ya mtengenezaji."</string>
- <string name="permlab_setWallpaper" msgid="6627192333373465143">"weka pazia"</string>
- <string name="permdesc_setWallpaper" msgid="6417041752170585837">"Huruhusu programu kuweka pazia ya mfumo."</string>
- <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"weka vidokezo vya ukubwa wa pazia"</string>
- <string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"Huruhusu programu kuweka vidokezo vya ukubwa wa pazia ya mfumo."</string>
+ <string name="permlab_setWallpaper" msgid="6627192333373465143">"weka mandhari"</string>
+ <string name="permdesc_setWallpaper" msgid="6417041752170585837">"Huruhusu programu kuweka mandhari ya mfumo."</string>
+ <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"weka vidokezo vya ukubwa wa mandhari"</string>
+ <string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"Huruhusu programu kuweka vidokezo vya ukubwa wa mandhari ya mfumo."</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"weka upya mfumo kwa chaguo-msingi za kiwanda"</string>
<string name="permdesc_masterClear" msgid="5033465107545174514">"Huruhusu programu kuweka upya kabisa mfumo kwa mipangilio yake ya kiwanda, kwa hivyo kufuta data zote, usanidi, na programu za kompyuta zilizosanidiwa."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"weka muda"</string>
@@ -844,7 +844,7 @@
<item quantity="one" msgid="2178576254385739855">"kesho"</item>
<item quantity="other" msgid="2973062968038355991">"kati ya siku <xliff:g id="COUNT">%d</xliff:g>"</item>
</plurals>
- <string name="preposition_for_date" msgid="9093949757757445117">"mnamo <xliff:g id="DATE">%s</xliff:g>"</string>
+ <string name="preposition_for_date" msgid="9093949757757445117">"tarehe <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="preposition_for_time" msgid="5506831244263083793">"Saa <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"ndani ya <xliff:g id="YEAR">%s</xliff:g>"</string>
<string name="day" msgid="8144195776058119424">"siku"</string>
@@ -1074,8 +1074,8 @@
<string name="input_method_binding_label" msgid="1283557179944992649">"Mbinu ya uingizaji"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Sawazisha"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Ufikiaji"</string>
- <string name="wallpaper_binding_label" msgid="1240087844304687662">"Pazia"</string>
- <string name="chooser_wallpaper" msgid="7873476199295190279">"Badilisha pazia"</string>
+ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Mandhari"</string>
+ <string name="chooser_wallpaper" msgid="7873476199295190279">"Badilisha mandhari"</string>
<string name="vpn_title" msgid="8219003246858087489">"VPN imeamilishwa."</string>
<string name="vpn_title_long" msgid="6400714798049252294">"VPN imeamilishwa na <xliff:g id="APP">%s</xliff:g>"</string>
<string name="vpn_text" msgid="1610714069627824309">"Gonga ili kudhibiti mtandao."</string>
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Shiriki na..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Kifaa kimefungwa."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Inatuma..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Zindua Kivinjari?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Kubali Simu?"</string>
</resources>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 921bcf4..431a502 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -62,8 +62,8 @@
<!-- Default padding to apply to AppWidgetHostViews containing widgets targeting API level 14 and up. -->
<dimen name="default_app_widget_padding_left">12dp</dimen>
- <dimen name="default_app_widget_padding_top">12dp</dimen>
- <dimen name="default_app_widget_padding_right">4dp</dimen>
+ <dimen name="default_app_widget_padding_top">4dp</dimen>
+ <dimen name="default_app_widget_padding_right">12dp</dimen>
<dimen name="default_app_widget_padding_bottom">20dp</dimen>
<!-- Minimum width for an action button in the menu area of an action bar -->
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index abd1208..c224d54 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"แบ่งปันกับ..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"ล็อกอุปกรณ์อยู่"</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"กำลังส่ง..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"เปิดเบราว์เซอร์หรือไม่"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"รับสายหรือไม่"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index bc47b0a..4ff92d2 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Ibahagi kay..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Naka-lock ang device."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Ipinapadala..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Ilunsad ang Browser?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Tanggapin ang Tawag?"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index d27d95b..7eaeedc 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Şununla paylaş..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Cihaz kilitli."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Gönderiliyor..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Çağrı Kabul Edilsin mi?"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 72b91fc..8213008 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -38,9 +38,9 @@
<string name="mmiFdnError" msgid="5224398216385316471">"Chỉ hạn chế thao tác đối với số quay số định sẵn."</string>
<string name="serviceEnabled" msgid="8147278346414714315">"Dịch vụ đã được bật."</string>
<string name="serviceEnabledFor" msgid="6856228140453471041">"Dịch vụ đã được bật cho:"</string>
- <string name="serviceDisabled" msgid="1937553226592516411">"Dịch vụ đã bị vô hiệu hoá."</string>
+ <string name="serviceDisabled" msgid="1937553226592516411">"Dịch vụ đã bị vô hiệu hóa."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"Đăng ký thành công."</string>
- <string name="serviceErased" msgid="1288584695297200972">"Xoá thành công."</string>
+ <string name="serviceErased" msgid="1288584695297200972">"Xóa thành công."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Mật khẩu không chính xác."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI hoàn tất."</string>
<string name="badPin" msgid="5085454289896032547">"Mã PIN cũ bạn đã nhập không chính xác."</string>
@@ -48,7 +48,7 @@
<string name="mismatchPin" msgid="3695902225843339274">"Mã PIN bạn đã nhập không khớp."</string>
<string name="invalidPin" msgid="3850018445187475377">"Nhập mã PIN có từ 4 đến 8 số."</string>
<string name="invalidPuk" msgid="8761456210898036513">"Nhập PUK có từ 8 số trở lên."</string>
- <string name="needPuk" msgid="919668385956251611">"Thẻ SIM của bạn đã bị khoá PUK. Nhập mã PUK để mở khoá thẻ SIM đó."</string>
+ <string name="needPuk" msgid="919668385956251611">"Thẻ SIM của bạn đã bị khóa PUK. Nhập mã PUK để mở khóa thẻ SIM đó."</string>
<string name="needPuk2" msgid="4526033371987193070">"Nhập mã PUK2 để bỏ chặn thẻ SIM."</string>
<string name="ClipMmi" msgid="6952821216480289285">"Số gọi đến"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Số gọi đi"</string>
@@ -83,7 +83,7 @@
<string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string>
<string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
<string name="serviceClassDataAsync" msgid="4523454783498551468">"Không đồng bộ"</string>
- <string name="serviceClassDataSync" msgid="7530000519646054776">"Đồng bộ hoá"</string>
+ <string name="serviceClassDataSync" msgid="7530000519646054776">"Đồng bộ hóa"</string>
<string name="serviceClassPacket" msgid="6991006557993423453">"Gói"</string>
<string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
<string name="roamingText0" msgid="7170335472198694945">"Chỉ báo Chuyển vùng Bật"</string>
@@ -124,11 +124,11 @@
<string name="httpErrorFileNotFound" msgid="5588380756326017105">"Không tìm thấy tệp được yêu cầu."</string>
<string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Quá nhiều yêu cầu đang được xử lý. Hãy thử lại sau."</string>
<string name="notification_title" msgid="1259940370369187045">"Lỗi đăng nhập đối với <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
- <string name="contentServiceSync" msgid="8353523060269335667">"Đồng bộ hoá"</string>
- <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Đồng bộ hoá"</string>
- <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Quá nhiều lần xoá <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+ <string name="contentServiceSync" msgid="8353523060269335667">"Đồng bộ hóa"</string>
+ <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Đồng bộ hóa"</string>
+ <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Quá nhiều lần xóa <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
<string name="low_memory" product="tablet" msgid="2292820184396262278">"Bộ nhớ máy tính bảng đã đầy! Hãy xóa một số tệp để giải phóng dung lượng."</string>
- <string name="low_memory" product="default" msgid="6632412458436461203">"Bộ nhớ điện thoại đã đầy! Hãy xoá một số tệp để tạo thêm dung lượng."</string>
+ <string name="low_memory" product="default" msgid="6632412458436461203">"Bộ nhớ điện thoại đã đầy! Hãy xóa một số tệp để tạo thêm dung lượng."</string>
<string name="me" msgid="6545696007631404292">"Tôi"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tùy chọn máy tính bảng"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Tùy chọn điện thoại"</string>
@@ -180,8 +180,8 @@
<string name="permgrouplab_storage" msgid="1971118770546336966">"Dung lượng"</string>
<string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Truy cập bộ nhớ USB."</string>
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Truy cập thẻ SD."</string>
- <string name="permlab_statusBar" msgid="7417192629601890791">"vô hiệu hoá hoặc sửa đổi thanh trạng thái"</string>
- <string name="permdesc_statusBar" msgid="1365473595331989732">"Cho phép ứng dụng vô hiệu hoá thanh trạng thái hoặc thêm và xoá biểu tượng hệ thống."</string>
+ <string name="permlab_statusBar" msgid="7417192629601890791">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string>
+ <string name="permdesc_statusBar" msgid="1365473595331989732">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string>
<string name="permlab_statusBarService" msgid="7247281911387931485">"thanh trạng thái"</string>
<string name="permdesc_statusBarService" msgid="4097605867643520920">"Cho phép ứng dụng là thanh trạng thái."</string>
<string name="permlab_expandStatusBar" msgid="1148198785937489264">"mở rộng/thu gọn thanh trạng thái"</string>
@@ -189,9 +189,9 @@
<string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"chặn các cuộc gọi đi"</string>
<string name="permdesc_processOutgoingCalls" msgid="2228988201852654461">"Cho phép ứng dụng xử lý cuộc gọi đi và thay đổi số đã được quay số. Các ứng dụng độc hại có thể giám sát, chuyển hướng hoặc chặn các cuộc gọi đi."</string>
<string name="permlab_receiveSms" msgid="2697628268086208535">"nhận SMS"</string>
- <string name="permdesc_receiveSms" msgid="6298292335965966117">"Cho phép ứng dụng nhận và xử lý tin nhắn SMS. Các ứng dụng độc hại có thể giám sát tin nhắn của bạn hoặc xoá chúng mà không cần hiển thị tin nhắn đó cho bạn."</string>
+ <string name="permdesc_receiveSms" msgid="6298292335965966117">"Cho phép ứng dụng nhận và xử lý tin nhắn SMS. Các ứng dụng độc hại có thể giám sát tin nhắn của bạn hoặc xóa chúng mà không cần hiển thị tin nhắn đó cho bạn."</string>
<string name="permlab_receiveMms" msgid="8894700916188083287">"nhận MMS"</string>
- <string name="permdesc_receiveMms" msgid="4563346832000174373">"Cho phép ứng dụng nhận và xử lý tin nhắn MMS. Các ứng dụng độc hại có thể giám sát tin nhắn của bạn hoặc xoá chúng mà không cần hiển thị tin nhắn đó cho bạn."</string>
+ <string name="permdesc_receiveMms" msgid="4563346832000174373">"Cho phép ứng dụng nhận và xử lý tin nhắn MMS. Các ứng dụng độc hại có thể giám sát tin nhắn của bạn hoặc xóa chúng mà không cần hiển thị tin nhắn đó cho bạn."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"nhận các truyền phát khẩn cấp"</string>
<string name="permdesc_receiveEmergencyBroadcast" msgid="7118393393716546131">"Cho phép ứng dụng truy xuất và xử lý các thư phát khẩn cấp. Quyền này chỉ khả dụng đối với các ứng dụng hệ thống."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"gửi tin nhắn SMS"</string>
@@ -203,9 +203,9 @@
<string name="permdesc_readSms" product="default" msgid="3002170087197294591">"Cho phép ứng dụng đọc tin nhắn SMS được lưu trữ trên điện thoại hoặc thẻ SIM của bạn. Các ứng dụng độc hại có thể đọc tin nhắn bí mật của bạn."</string>
<string name="permlab_writeSms" msgid="6881122575154940744">"chỉnh sửa SMS hoặc MMS"</string>
<string name="permdesc_writeSms" product="tablet" msgid="5332124772918835437">"Cho phép ứng dụng ghi vào tin nhắn SMS được lưu trữ trên máy tính bảng hoặc thẻ SIM của bạn. Các ứng dụng độc hại có thể xóa tin nhắn của bạn."</string>
- <string name="permdesc_writeSms" product="default" msgid="6299398896177548095">"Cho phép ứng dụng ghi vào tin nhắn SMS được lưu trữ trên điện thoại hoặc thẻ SIM của bạn. Các ứng dụng độc hại có thể xoá tin nhắn của bạn."</string>
+ <string name="permdesc_writeSms" product="default" msgid="6299398896177548095">"Cho phép ứng dụng ghi vào tin nhắn SMS được lưu trữ trên điện thoại hoặc thẻ SIM của bạn. Các ứng dụng độc hại có thể xóa tin nhắn của bạn."</string>
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"nhận WAP"</string>
- <string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Cho phép ứng dụng nhận và xử lý tin nhắn WAP. Các ứng dụng độc hại có thể giám sát tin nhắn của bạn hoặc xoá chúng mà không cần hiển thị tin nhắn đó cho bạn."</string>
+ <string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Cho phép ứng dụng nhận và xử lý tin nhắn WAP. Các ứng dụng độc hại có thể giám sát tin nhắn của bạn hoặc xóa chúng mà không cần hiển thị tin nhắn đó cho bạn."</string>
<string name="permlab_getTasks" msgid="5005277531132573353">"truy xuất các ứng dụng đang chạy"</string>
<string name="permdesc_getTasks" msgid="7048711358713443341">"Cho phép ứng dụng truy xuất thông tin về các công việc hiện đang chạy. Có thể cho phép các ứng dụng độc hại phát hiện thông tin riêng tư về các ứng dụng khác."</string>
<string name="permlab_reorderTasks" msgid="5669588525059921549">"sắp xếp lại các ứng dụng đang chạy"</string>
@@ -234,8 +234,8 @@
<string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"Ngăn người dùng chuyển sang ứng dụng khác."</string>
<string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"giám sát và kiểm soát tất cả khởi chạy ứng dụng"</string>
<string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"Cho phép ứng dụng giám sát và kiểm soát cách hệ thống khởi chạy các hoạt động. Các ứng dụng độc hại có thể làm tổn hại hoàn toàn hệ thống. Quyền này chỉ cần cho việc phát triển, không bao giờ dùng cho việc sử dụng thông thường."</string>
- <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"gửi truyền phát đã xoá của gói"</string>
- <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Cho phép ứng dụng truyền phát thông báo rằng gói ứng dụng đã bị xoá. Các ứng dụng độc hại có thể sử dụng quyền này để loại bỏ mọi ứng dụng đang chạy khác."</string>
+ <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"gửi truyền phát đã xóa của gói"</string>
+ <string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"Cho phép ứng dụng truyền phát thông báo rằng gói ứng dụng đã bị xóa. Các ứng dụng độc hại có thể sử dụng quyền này để loại bỏ mọi ứng dụng đang chạy khác."</string>
<string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"gửi truyền phát SMS nhận được"</string>
<string name="permdesc_broadcastSmsReceived" msgid="9122419277306740155">"Cho phép ứng dụng truyền phát thông báo rằng đã nhận được tin nhắn SMS. Các ứng dụng độc hại có thẻ sử dụng quyền này để giả mạo tin nhắn SMS đến."</string>
<string name="permlab_broadcastWapPush" msgid="3145347413028582371">"gửi truyền phát WAP-PUSH nhận được"</string>
@@ -283,19 +283,19 @@
<string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Cho phép ứng dụng yêu cầu tín hiệu đã cung cấp được gửi đến tất cả các quá trình liên tục."</string>
<string name="permlab_persistentActivity" msgid="8659652042401085862">"đặt ứng dụng luôn chạy"</string>
<string name="permdesc_persistentActivity" msgid="5037199778265006008">"Cho phép ứng dụng tạo sự đồng nhất cho các phần của mình để hệ thống không thể sử dụng ứng dụng đó cho các ứng dụng khác."</string>
- <string name="permlab_deletePackages" msgid="3343439331576348805">"xoá ứng dụng"</string>
- <string name="permdesc_deletePackages" msgid="3634943677518723314">"Cho phép ứng dụng xoá các gói Android. Các ứng dụng độc hại có thể sử dụng quyền này để xoá các ứng dụng quan trọng."</string>
- <string name="permlab_clearAppUserData" msgid="2192134353540277878">"xoá dữ liệu của ứng dụng khác"</string>
- <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Cho phép ứng dụng xoá dữ liệu của người dùng."</string>
- <string name="permlab_deleteCacheFiles" msgid="1518556602634276725">"xoá bộ nhớ cache của các ứng dụng khác"</string>
- <string name="permdesc_deleteCacheFiles" msgid="2283074077168165971">"Cho phép ứng dụng xoá các tệp bộ nhớ cache."</string>
+ <string name="permlab_deletePackages" msgid="3343439331576348805">"xóa ứng dụng"</string>
+ <string name="permdesc_deletePackages" msgid="3634943677518723314">"Cho phép ứng dụng xóa các gói Android. Các ứng dụng độc hại có thể sử dụng quyền này để xóa các ứng dụng quan trọng."</string>
+ <string name="permlab_clearAppUserData" msgid="2192134353540277878">"xóa dữ liệu của ứng dụng khác"</string>
+ <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Cho phép ứng dụng xóa dữ liệu của người dùng."</string>
+ <string name="permlab_deleteCacheFiles" msgid="1518556602634276725">"xóa bộ nhớ cache của các ứng dụng khác"</string>
+ <string name="permdesc_deleteCacheFiles" msgid="2283074077168165971">"Cho phép ứng dụng xóa các tệp bộ nhớ cache."</string>
<string name="permlab_getPackageSize" msgid="4799785352306641460">"đo dung lượng lưu trữ ứng dụng"</string>
<string name="permdesc_getPackageSize" msgid="5557253039670753437">"Cho phép ứng dụng truy xuất mã, dữ liệu và kích thước bộ nhớ cache của nó"</string>
<string name="permlab_installPackages" msgid="335800214119051089">"cài đặt trực tiếp ứng dụng"</string>
<string name="permdesc_installPackages" msgid="526669220850066132">"Cho phép ứng dụng cài đặt các gói Android mới hoặc đã được cập nhật. Các ứng dụng độc hại có thể sử dụng quyền này để thêm ứng dụng mới có quyền mạnh mẽ tùy ý."</string>
- <string name="permlab_clearAppCache" msgid="4747698311163766540">"xoá tất cả dữ liệu bộ nhớ cache của ứng dụng"</string>
+ <string name="permlab_clearAppCache" msgid="4747698311163766540">"xóa tất cả dữ liệu bộ nhớ cache của ứng dụng"</string>
<string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Cho phép ứng dụng giải phóng bộ nhớ máy tính bảng bằng cách xóa các tệp trong thư mục bộ nhớ cache ứng dụng. Quyền truy cập thường rất hạn chế đối với quy trình hệ thống."</string>
- <string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"Cho phép ứng dụng tạo thêm dung lượng điện thoại bằng cách xoá các tệp trong thư mục bộ nhớ cache ứng dụng. Quyền truy cập thường rất hạn chế đối với quy trình hệ thống."</string>
+ <string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"Cho phép ứng dụng tạo thêm dung lượng điện thoại bằng cách xóa các tệp trong thư mục bộ nhớ cache ứng dụng. Quyền truy cập thường rất hạn chế đối với quy trình hệ thống."</string>
<string name="permlab_movePackage" msgid="728454979946503926">"Chuyển tài nguyên của ứng dụng"</string>
<string name="permdesc_movePackage" msgid="6323049291923925277">"Cho phép ứng dụng di chuyển các tài nguyên của ứng dụng từ phương tiện truyền thông bên trong ra phương tiện bên ngoài và ngược lại."</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"đọc dữ liệu nhật ký nhạy cảm"</string>
@@ -305,7 +305,7 @@
<string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Cho phép ứng dụng sử dụng bất kỳ bộ giải mã phương tiện đã cài đặt nào để giải mã phát lại."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"đọc/ghi vào tài nguyên do chẩn đoán sở hữu"</string>
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Cho phép ứng dụng đọc và ghi vào bất kỳ tài nguyên nào do nhóm chẩn đoán sở hữu; ví dụ: các tệp trong /dev. Quyền này có thể ảnh hưởng đến sự ổn định và bảo mật của hệ thống. CHỈ nên sử dụng quyền này cho các chẩn đoán phần cứng cụ thể bởi nhà sản xuất hoặc nhà cung cấp dịch vụ."</string>
- <string name="permlab_changeComponentState" msgid="79425198834329406">"bật hoặc vô hiệu hoá các thành phần ứng dụng"</string>
+ <string name="permlab_changeComponentState" msgid="79425198834329406">"bật hoặc vô hiệu hóa các thành phần ứng dụng"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Cho phép ứng dụng thay đổi việc có nên bật thành phần của ứng dụng khác hay không. Các ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa các tính năng quan trọng của máy tính bảng. Phải cẩn thận khi sử dụng quyền này vì nó có thể khiến các thành phần rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
<string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Cho phép ứng dụng thay đổi việc có nên bật thành phần của ứng dụng khác hay không. Các ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa các tính năng quan trọng của điện thoại. Phải cẩn thận khi sử dụng quyền này vì quyền này có thể khiến các thành phần ứng dụng rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"đặt ứng dụng ưa thích"</string>
@@ -327,7 +327,7 @@
<string name="permdesc_readContacts" product="default" msgid="3371591512896545975">"Cho phép ứng dụng đọc tất cả dữ liệu liên hệ (địa chỉ) được lưu trữ trên điện thoại của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để gửi dữ liệu của bạn cho những người khác."</string>
<string name="permlab_writeContacts" msgid="644616215860933284">"ghi dữ liệu liên hệ"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="7782689510038568495">"Cho phép ứng dụng sửa đổi dữ liệu (địa chỉ) liên hệ được lưu trữ trên máy tính bảng của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi dữ liệu liên hệ của bạn."</string>
- <string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"Cho phép ứng dụng sửa đổi dữ liệu liên hệ (địa chỉ) được lưu trữ trên điện thoại của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để xoá hoặc sửa đổi dữ liệu liên hệ của bạn."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="3924383579108183601">"Cho phép ứng dụng sửa đổi dữ liệu liên hệ (địa chỉ) được lưu trữ trên điện thoại của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi dữ liệu liên hệ của bạn."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"đọc d.liệu t.sử của bạn"</string>
<string name="permdesc_readProfile" product="default" msgid="6335739730324727203">"Cho phép ứng dụng đọc thông tin tiểu sử cá nhân được lưu trên thiết bị của bạn, ví dụ như tên và thông tin liên hệ của bạn. Điều này nghĩa là ứng dụng có thể nhận dạng bạn và gửi thông tin tiểu sử của bạn cho những người khác."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"ghi dữ liệu t.sử của bạn"</string>
@@ -364,9 +364,9 @@
<string name="permlab_camera" msgid="3616391919559751192">"chụp ảnh và quay video"</string>
<string name="permdesc_camera" msgid="6004878235852154239">"Cho phép ứng dụng chụp ảnh và quay video bằng máy ảnh. Quyền này cho phép ứng dụng thu thập ảnh mà máy ảnh chụp vào bất kỳ thời điểm nào."</string>
<string name="permlab_brick" product="tablet" msgid="2961292205764488304">"vô hiệu hóa vĩnh viễn máy tính bảng"</string>
- <string name="permlab_brick" product="default" msgid="8337817093326370537">"vĩnh viễn vô hiệu hoá điện thoại"</string>
+ <string name="permlab_brick" product="default" msgid="8337817093326370537">"vĩnh viễn vô hiệu hóa điện thoại"</string>
<string name="permdesc_brick" product="tablet" msgid="7379164636920817963">"Cho phép ứng dụng vô hiệu hóa vĩnh viễn toàn bộ máy tính bảng. Việc này rất nguy hiểm."</string>
- <string name="permdesc_brick" product="default" msgid="5569526552607599221">"Cho phép ứng dụng vô hiệu hoá vĩnh viễn toàn bộ điện thoại. Việc này rất nguy hiểm."</string>
+ <string name="permdesc_brick" product="default" msgid="5569526552607599221">"Cho phép ứng dụng vô hiệu hóa vĩnh viễn toàn bộ điện thoại. Việc này rất nguy hiểm."</string>
<string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"buộc máy tính bảng khởi động lại"</string>
<string name="permlab_reboot" product="default" msgid="2898560872462638242">"buộc khởi động lại điện thoại"</string>
<string name="permdesc_reboot" product="tablet" msgid="4555793623560701557">"Cho phép ứng dụng buộc máy tính bảng khởi động lại."</string>
@@ -396,7 +396,7 @@
<string name="permlab_hardware_test" msgid="4148290860400659146">"kiểm tra phần cứng"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Cho phép ứng dụng kiểm soát các thiết bị ngoại vi khác nhau nhằm mục đích kiểm tra phần cứng."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"gọi trực tiếp số điện thoại"</string>
- <string name="permdesc_callPhone" msgid="3369867353692722456">"Cho phép ứng dụng gọi các số điện thoại mà không cần sự can thiệp của bạn. Các ứng dụng độc hại có thể dẫn đến các cuộc gọi không mong muốn trên hoá đơn điện thoại của bạn. Lưu ý rằng quyền này không cho phép ứng dụng gọi các số khẩn cấp."</string>
+ <string name="permdesc_callPhone" msgid="3369867353692722456">"Cho phép ứng dụng gọi các số điện thoại mà không cần sự can thiệp của bạn. Các ứng dụng độc hại có thể dẫn đến các cuộc gọi không mong muốn trên hóa đơn điện thoại của bạn. Lưu ý rằng quyền này không cho phép ứng dụng gọi các số khẩn cấp."</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"gọi trực tiếp số điện thoại bất kỳ"</string>
<string name="permdesc_callPrivileged" msgid="244405067160028452">"Cho phép ứng dụng gọi bất kỳ số điện thoại nào, kể cả số khẩn cấp mà không cần sự can thiệp của bạn. Các ứng dụng độc hại có thể thực hiện các cuộc gọi không cần thiết và bất hợp pháp vào dịch vụ khẩn cấp."</string>
<string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"trực tiếp bắt đầu thiết lập máy tính bảng CDMA"</string>
@@ -428,7 +428,7 @@
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"Đặt gợi ý kích thước hình nền"</string>
<string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"Cho phép ứng dụng đặt gợi ý kích thước hình nền của hệ thống."</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"đặt lại hệ thống về mặc định ban đầu"</string>
- <string name="permdesc_masterClear" msgid="5033465107545174514">"Cho phép ứng dụng đặt lại toàn bộ hệ thống về cài đặt ban đầu, xoá tất cả dữ liệu, cấu hình và ứng dụng đã cài đặt."</string>
+ <string name="permdesc_masterClear" msgid="5033465107545174514">"Cho phép ứng dụng đặt lại toàn bộ hệ thống về cài đặt ban đầu, xóa tất cả dữ liệu, cấu hình và ứng dụng đã cài đặt."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"đặt giờ"</string>
<string name="permdesc_setTime" product="tablet" msgid="209693136361006073">"Cho phép ứng dụng thay đổi giờ trên đồng hồ của máy tính bảng."</string>
<string name="permdesc_setTime" product="default" msgid="667294309287080045">"Cho phép ứng dụng thay đổi giờ trên đồng hồ của điện thoại."</string>
@@ -443,7 +443,7 @@
<string name="permlab_authenticateAccounts" msgid="3940505577982882450">"hoạt động như trình xác thực tài khoản"</string>
<string name="permdesc_authenticateAccounts" msgid="4006839406474208874">"Cho phép ứng dụng sử dụng các tính năng của trình xác thực tài khoản của AccountManager, bao gồm tạo tài khoản, nhận và đặt mật khẩu của các tài khoản đó."</string>
<string name="permlab_manageAccounts" msgid="4440380488312204365">"quản lý danh sách tài khoản"</string>
- <string name="permdesc_manageAccounts" msgid="8804114016661104517">"Cho phép ứng dụng thực hiện các thao tác như thêm và xoá tài khoản cũng như xoá mật khẩu của các tài khoản đó."</string>
+ <string name="permdesc_manageAccounts" msgid="8804114016661104517">"Cho phép ứng dụng thực hiện các thao tác như thêm và xóa tài khoản cũng như xóa mật khẩu của các tài khoản đó."</string>
<string name="permlab_useCredentials" msgid="6401886092818819856">"sử dụng thông tin xác thực tài khoản"</string>
<string name="permdesc_useCredentials" msgid="7416570544619546974">"Cho phép ứng dụng yêu cầu mã thông báo xác thực."</string>
<string name="permlab_accessNetworkState" msgid="6865575199464405769">"xem trạng thái mạng"</string>
@@ -476,24 +476,24 @@
<string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Cho phép ứng dụng xem cấu hình của điện thoại Bluetooth nội hạt cũng như tạo và chấp nhận các kết nối với các thiết bị được ghép nối."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"kiểm soát Liên lạc trường gần"</string>
<string name="permdesc_nfc" msgid="9171401851954407226">"Cho phép ứng dụng liên lạc với thẻ Liên lạc trường gần (NFC), thẻ và trình đọc."</string>
- <string name="permlab_disableKeyguard" msgid="4977406164311535092">"vô hiệu hoá khoá phím"</string>
- <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Cho phép ứng dụng vô hiệu hoá khoá phím và bất kỳ bảo mật mật khẩu được liên kết nào. Ví dụ thích hợp của việc này là điện thoại vô hiệu hoá khoá phím khi nhận được cuộc gọi đến sau đó bật lại khoá phím khi cuộc gọi kết thúc."</string>
- <string name="permlab_readSyncSettings" msgid="6201810008230503052">"đọc cài đặt đồng bộ hoá"</string>
- <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Cho phép ứng dụng đọc cài đặt đồng bộ hoá, chẳng hạn như liệu đồng bộ hoá đã được bật cho Danh bạ hay chưa."</string>
- <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"ghi cài đặt đồng bộ hoá"</string>
- <string name="permdesc_writeSyncSettings" msgid="2498201614431360044">"Cho phép ứng dụng sửa đổi cài đặt đồng bộ hoá, chẳng hạn như liệu đồng bộ hoá đã được bật cho Danh bạ chưa."</string>
- <string name="permlab_readSyncStats" msgid="7396577451360202448">"đọc thống kê đồng bộ hoá"</string>
- <string name="permdesc_readSyncStats" msgid="7511448343374465000">"Cho phép ứng dụng đọc thống kê đồng bộ hoá, ví dụ: lịch sử đồng bộ hoá đã diễn ra."</string>
+ <string name="permlab_disableKeyguard" msgid="4977406164311535092">"vô hiệu hóa khóa phím"</string>
+ <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Cho phép ứng dụng vô hiệu hóa khóa phím và bất kỳ bảo mật mật khẩu được liên kết nào. Ví dụ thích hợp của việc này là điện thoại vô hiệu hóa khóa phím khi nhận được cuộc gọi đến sau đó bật lại khóa phím khi cuộc gọi kết thúc."</string>
+ <string name="permlab_readSyncSettings" msgid="6201810008230503052">"đọc cài đặt đồng bộ hóa"</string>
+ <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Cho phép ứng dụng đọc cài đặt đồng bộ hóa, chẳng hạn như liệu đồng bộ hóa đã được bật cho Danh bạ hay chưa."</string>
+ <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"ghi cài đặt đồng bộ hóa"</string>
+ <string name="permdesc_writeSyncSettings" msgid="2498201614431360044">"Cho phép ứng dụng sửa đổi cài đặt đồng bộ hóa, chẳng hạn như liệu đồng bộ hóa đã được bật cho Danh bạ chưa."</string>
+ <string name="permlab_readSyncStats" msgid="7396577451360202448">"đọc thống kê đồng bộ hóa"</string>
+ <string name="permdesc_readSyncStats" msgid="7511448343374465000">"Cho phép ứng dụng đọc thống kê đồng bộ hóa, ví dụ: lịch sử đồng bộ hóa đã diễn ra."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"đọc nguồn cấp dữ liệu đã đăng ký"</string>
- <string name="permdesc_subscribedFeedsRead" msgid="3622200625634207660">"Cho phép ứng dụng nhận các chi tiết về nguồn cấp dữ liệu hiện đã được đồng bộ hoá."</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="3622200625634207660">"Cho phép ứng dụng nhận các chi tiết về nguồn cấp dữ liệu hiện đã được đồng bộ hóa."</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"ghi nguồn cấp dữ liệu đã đăng ký"</string>
- <string name="permdesc_subscribedFeedsWrite" msgid="8121607099326533878">"Cho phép ứng dụng sửa đổi nguồn cấp dữ liệu hiện đã được đồng bộ hoá. Quyền này có thể cho phép ứng dụng độc hại thay đổi nguồn cấp dữ liệu đã đồng bộ hoá của bạn."</string>
+ <string name="permdesc_subscribedFeedsWrite" msgid="8121607099326533878">"Cho phép ứng dụng sửa đổi nguồn cấp dữ liệu hiện đã được đồng bộ hóa. Quyền này có thể cho phép ứng dụng độc hại thay đổi nguồn cấp dữ liệu đã đồng bộ hóa của bạn."</string>
<string name="permlab_readDictionary" msgid="432535716804748781">"đọc từ điển do người dùng xác định"</string>
<string name="permdesc_readDictionary" msgid="1082972603576360690">"Cho phép ứng dụng đọc bất kỳ từ, tên và cụm từ riêng nào mà người dùng có thể đã lưu trữ trong từ điển của người dùng."</string>
<string name="permlab_writeDictionary" msgid="6703109511836343341">"ghi vào từ điển do người dùng xác định"</string>
<string name="permdesc_writeDictionary" msgid="2241256206524082880">"Cho phép ứng dụng ghi từ mới vào từ điển của người dùng."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"sửa đổi/xóa nội dung bộ nhớ USB"</string>
- <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"sửa đổi/xoá nội dung thẻ SD"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"sửa đổi/xóa nội dung thẻ SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"C.phép ứ.dụng ghi vào b.nhớ USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Cho phép ứng dụng ghi vào thẻ SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sửa đổi/xóa nội dung trên bộ nhớ phương tiện cục bộ"</string>
@@ -517,7 +517,7 @@
<string name="policydesc_resetPassword" msgid="5391240616981297361">"Thay đổi mật khẩu mở khóa màn hình"</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Khóa màn hình"</string>
<string name="policydesc_forceLock" msgid="5696964126226028442">"Kiểm tra cách và thời điểm khóa màn hình"</string>
- <string name="policylab_wipeData" msgid="3910545446758639713">"Xoá tất cả dữ liệu"</string>
+ <string name="policylab_wipeData" msgid="3910545446758639713">"Xóa tất cả dữ liệu"</string>
<string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"Xóa dữ liệu trên máy tính bảng mà không cần cảnh báo, bằng cách thực hiện đặt lại về dữ liệu gốc"</string>
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Xóa dữ liệu trên điện thoại mà không cần cảnh báo, bằng cách thực hiện đặt lại về dữ liệu gốc"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Đặt proxy chung của điện thoại"</string>
@@ -646,16 +646,16 @@
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Mã PUK"</string>
<string name="keyguard_password_enter_pin_prompt" msgid="2987350144349051286">"Mã Pin mới"</string>
<string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Chạm để nhập mật khẩu"</font></string>
- <string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Nhập mật khẩu để mở khoá"</string>
+ <string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Nhập mật khẩu để mở khóa"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Nhập PIN để mở khóa"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Mã PIN không chính xác!"</string>
- <string name="keyguard_label_text" msgid="861796461028298424">"Để mở khoá, hãy nhấn vào Trình đơn sau đó nhấn 0."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Để mở khóa, hãy nhấn vào Trình đơn sau đó nhấn 0."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Số khẩn cấp"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Không có dịch vụ nào."</string>
- <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Màn hình đã khoá."</string>
- <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Nhấn vào Trình đơn để mở khoá hoặc thực hiện cuộc gọi khẩn cấp."</string>
- <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Nhấn vào Trình đơn để mở khoá."</string>
- <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Vẽ hình để mở khoá"</string>
+ <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Màn hình đã khóa."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Nhấn vào Trình đơn để mở khóa hoặc thực hiện cuộc gọi khẩn cấp."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Nhấn vào Trình đơn để mở khóa."</string>
+ <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Vẽ hình để mở khóa"</string>
<string name="lockscreen_emergency_call" msgid="5347633784401285225">"Cuộc gọi khẩn cấp"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Quay lại cuộc gọi"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Chính xác!"</string>
@@ -677,32 +677,32 @@
<string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Nút phát"</string>
<string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Nút dừng"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Chỉ cuộc gọi khẩn cấp"</string>
- <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mạng đã khoá"</string>
- <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Thẻ SIM đã bị khoá PUK."</string>
+ <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mạng đã khóa"</string>
+ <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Thẻ SIM đã bị khóa PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="635967534992394321">"Vui lòng xem Hướng dẫn Người dùng hoặc liên hệ với Trung tâm Chăm sóc Khách hàng."</string>
- <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Thẻ SIM đã bị khoá."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Đang mở khoá thẻ SIM…"</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="3514742106066877476">"Bạn đã vẽ không chính xác hình mở khoá của mình <xliff:g id="NUMBER_0">%d</xliff:g> lần. "\n\n"Vui lòng thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+ <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Thẻ SIM đã bị khóa."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Đang mở khóa thẻ SIM…"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="3514742106066877476">"Bạn đã vẽ không chính xác hình mở khóa của mình <xliff:g id="NUMBER_0">%d</xliff:g> lần. "\n\n"Vui lòng thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="4906034376425175381">"Bạn đã nhập sai mật khẩu <xliff:g id="NUMBER_0">%d</xliff:g> lần. "\n\n"Vui lòng thử lại trong <xliff:g id="NUMBER_1">%d</xliff:g> giấy."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6827749231465145590">"Bạn đã nhập sai PIN <xliff:g id="NUMBER_0">%d</xliff:g> lần. "\n\n"Vui lòng thử lại trong <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="8687762517114904651">"Bạn đã vẽ không chính xác hình mở khóa của mình <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công khác, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng thông tin đăng nhập Google của mình."\n\n" Vui lòng thử lại trong <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="3351013842320127827">"Bạn đã vẽ không chính xác hình mở khoá của mình <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công khác, bạn sẽ được yêu cầu mở khoá điện thoại bằng thông tin đăng nhập Google của mình."\n\n" Vui lòng thử lại trong <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="3351013842320127827">"Bạn đã vẽ không chính xác hình mở khóa của mình <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công khác, bạn sẽ được yêu cầu mở khóa điện thoại bằng thông tin đăng nhập Google của mình."\n\n" Vui lòng thử lại trong <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Bạn đã mở khóa máy tính bảng không đúng cách <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Bạn đã mở khóa điện thoại không đúng cách <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Bạn đã mở khóa máy tính bảng không đúng cách <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, máy tính bảng sẽ được đặt lại về mặc định ban đầu."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Bạn đã mở khóa điện thoại không đúng cách <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Hãy thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Đã quên hình?"</string>
- <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Mở khoá tài khoản"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Mở khóa tài khoản"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Quá nhiều lần nhập hình!"</string>
- <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Để mở khoá, hãy đăng nhập bằng tài khoản Google của bạn"</string>
+ <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Để mở khóa, hãy đăng nhập bằng tài khoản Google của bạn"</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Tên người dùng (email)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mật khẩu"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Đăng nhập"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Bạn quên tên người dùng hoặc mật khẩu?"\n"Hãy truy cập "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Đang kiểm tra..."</string>
- <string name="lockscreen_unlock_label" msgid="737440483220667054">"Mở khoá"</string>
+ <string name="lockscreen_unlock_label" msgid="737440483220667054">"Mở khóa"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bật âm thanh"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Tắt âm thanh"</string>
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Đã bắt đầu vẽ hình"</string>
@@ -745,7 +745,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Cho phép ứng dụng đọc tất cả các URL mà Trình duyệt đã truy cập và tất cả các dấu trang của Trình duyệt."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"xem lịch sử và dấu trang của Trình duyệt"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"Cho phép ứng dụng sửa đổi lịch sử hoặc dấu trang của Trình duyệt được lưu trữ trên máy tính bảng của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi dữ liệu Trình duyệt của bạn."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Cho phép ứng dụng sửa đổi lịch sử hoặc dấu trang của Trình duyệt được lưu trữ trên điện thoại của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để xoá hoặc sửa đổi dữ liệu Trình duyệt của bạn."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"Cho phép ứng dụng sửa đổi lịch sử hoặc dấu trang của Trình duyệt được lưu trữ trên điện thoại của bạn. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi dữ liệu Trình duyệt của bạn."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"đặt báo thức trong đồng hồ báo thức"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"Cho phép ứng dụng đặt báo thức trong ứng dụng đồng hồ báo thức được cài đặt. Một số ứng dụng đồng hồ báo thức có thể không sử dụng tính năng này."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"thêm thư thoại"</string>
@@ -766,7 +766,7 @@
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Trình đơn+"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"dấu cách"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"nhập"</string>
- <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"xoá"</string>
+ <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"xóa"</string>
<string name="search_go" msgid="8298016669822141719">"Tìm kiếm"</string>
<string name="searchview_description_search" msgid="6749826639098512120">"Tìm kiếm"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"Truy vấn tìm kiếm"</string>
@@ -896,7 +896,7 @@
<string name="capital_off" msgid="6815870386972805832">"TẮT"</string>
<string name="whichApplication" msgid="4533185947064773386">"Hoàn tất tác vụ đang sử dụng"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Sử dụng theo mặc định đối với tác vụ này."</string>
- <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Xoá mặc định trong Cài đặt Màn hình trang chủ > Ứng dụng> Quản lý ứng dụng."</string>
+ <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Xóa mặc định trong Cài đặt Màn hình trang chủ > Ứng dụng> Quản lý ứng dụng."</string>
<string name="chooseActivity" msgid="1009246475582238425">"Chọn tác vụ"</string>
<string name="chooseUsbActivity" msgid="7892597146032121735">"Chọn ứng dụng cho thiết bị USB"</string>
<string name="noApplications" msgid="1691104391758345586">"Không ứng dụng nào có thể thực hiện tác vụ này."</string>
@@ -1019,7 +1019,7 @@
<string name="extmedia_format_message" product="default" msgid="3621369962433523619">"Bạn có chắc chắn muốn định dạng thẻ SD không? Tất cả dữ liệu trên thẻ của bạn sẽ bị mất."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Định dạng"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
- <string name="adb_active_notification_message" msgid="8470296818270110396">"Chọn để vô hiệu hoá gỡ lỗi USB."</string>
+ <string name="adb_active_notification_message" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Chọn phương thức nhập"</string>
<string name="configure_input_methods" msgid="6324843080254191535">"Định cấu hình phương thức nhập liệu"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1072,7 +1072,7 @@
<string name="permission_request_notification_title" msgid="5390555465778213840">"Yêu cầu Quyền"</string>
<string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Yêu cầu Quyền"\n"cho tài khoản <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"Phương thức nhập"</string>
- <string name="sync_binding_label" msgid="3687969138375092423">"Đồng bộ hoá"</string>
+ <string name="sync_binding_label" msgid="3687969138375092423">"Đồng bộ hóa"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Khả năng truy cập"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Hình nền"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Thay đổi hình nền"</string>
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"Chia sẻ với..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Thiết bị đã bị khóa."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"Đang gửi..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Khởi chạy trình duyệt?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"Chấp nhận cuộc gọi?"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b92008f..12b1784 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"分享方式..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"设备已锁定。"</string>
<string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"正在发送..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"要启动浏览器吗?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"要接听电话吗?"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 80c3ee5..1252ba1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1218,10 +1218,7 @@
<string name="share_action_provider_share_with" msgid="1791316789651185229">"分享活動..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"裝置已鎖定。"</string>
<string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
- <!-- no translation found for sending (8715108995741758718) -->
- <skip />
- <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
- <skip />
- <!-- no translation found for SetupCallDefault (6870275517518479651) -->
- <skip />
+ <string name="sending" msgid="8715108995741758718">"傳送中..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"要啟動「瀏覽器」嗎?"</string>
+ <string name="SetupCallDefault" msgid="6870275517518479651">"要接受通話嗎?"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index eadb0ea..eb9e660 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -73,11 +73,11 @@
<string name="RestrictedOnData" msgid="8653794784690065540">"Insizakalo yedatha ivaliwe."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Insizakalo ephuthumayo ivimbelwe."</string>
<string name="RestrictedOnNormal" msgid="4953867011389750673">"Insizakalo yezwi ivimbelwe."</string>
- <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Zonke izinsizakalo Zezwi zivimbelwe."</string>
+ <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Wonke amasevisi Wezwi avimbelwe."</string>
<string name="RestrictedOnSms" msgid="8314352327461638897">"Insizakalo ye-SMS ivaliwe."</string>
- <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Izinsizakalo Zezwi/Idatha zivimbelwe."</string>
- <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Izinsizakalo Zezwi/SMS zivimbelwe."</string>
- <string name="RestrictedOnAll" msgid="2714924667937117304">"Zonke izinsizakalo Zezwi/Idatha/SMS zivimbelwe."</string>
+ <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Amasevisi Wezwi/Idatha avimbelwe."</string>
+ <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Amasevisi Wezwi/SMS avimbelwe."</string>
+ <string name="RestrictedOnAll" msgid="2714924667937117304">"Wonke amasevisi Wezwi/Idatha/SMS avimbelwe."</string>
<string name="serviceClassVoice" msgid="1258393812335258019">"Izwi"</string>
<string name="serviceClassData" msgid="872456782077937893">"Idatha"</string>
<string name="serviceClassFAX" msgid="5566624998840486475">"Ifeksi"</string>
@@ -99,7 +99,7 @@
<string name="roamingText10" msgid="3992906999815316417">"Iyazulazula - Isici Sensizakalo Eyingxenye"</string>
<string name="roamingText11" msgid="4154476854426920970">"Ibhena Yokuzulazula Ivuliwe"</string>
<string name="roamingText12" msgid="1189071119992726320">"Ibhena yokuzulazula ivaliwe"</string>
- <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Izinsizakalo"</string>
+ <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Isevisi"</string>
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Akudlulisiwe"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> emuva kwamasekhondi angu-<xliff:g id="TIME_DELAY">{2}</xliff:g>"</string>
@@ -463,7 +463,7 @@
<string name="permlab_changeWifiState" msgid="7280632711057112137">"shintsha isimo se-WiFi"</string>
<string name="permdesc_changeWifiState" msgid="2950383153656873267">"Ivumela uhlelo lokusebena ukuxhuma futhi ingaxhumeki kumaphoyinti e-Wi-Fi, nokwenza izinguquko kumanethiwekhi e-Wi-Fi amisiwe."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ivumela isamukeli se-Wi-Fi Multicast"</string>
- <string name="permdesc_changeWifiMulticastState" msgid="8199464507656067553">"Ivumela uhlelo lokusebenza ukuthola amaphakhethe ngokungaqondile angeyona awedivaysi yakho. Lokhu kungaba usizo lapho uthola izinsizakalo ezinikezwa eduze. Kusebenzisa amandla amaninigi kunemodi yokungajikijeli okuningi."</string>
+ <string name="permdesc_changeWifiMulticastState" msgid="8199464507656067553">"Ivumela uhlelo lokusebenza ukuthola amaphakhethe ngokungaqondile angeyona awedivaysi yakho. Lokhu kungaba usizo lapho uthola amasevisi anikezwa eduze. Kusebenzisa amandla amaninigi kunemodi yokungajikijeli okuningi."</string>
<string name="permlab_accessWimaxState" msgid="2800410363171809280">"Buka isimo se-WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Ivumela uhlelo lokusebenza ukubuka ulwazi mayelana nesimo se-WiMAX."</string>
<string name="permlab_changeWimaxState" msgid="340465839241528618">"shintsha isimo se-WiMAX"</string>
@@ -852,7 +852,7 @@
<string name="hour" msgid="2126771916426189481">"ihora"</string>
<string name="hours" msgid="894424005266852993">"amahora"</string>
<string name="minute" msgid="9148878657703769868">"Okuncane"</string>
- <string name="minutes" msgid="5646001005827034509">"imizuzu"</string>
+ <string name="minutes" msgid="5646001005827034509">"amaminithi"</string>
<string name="second" msgid="3184235808021478">"isekhondi"</string>
<string name="seconds" msgid="3161515347216589235">"amasekhondi"</string>
<string name="week" msgid="5617961537173061583">"iviki"</string>
@@ -968,7 +968,7 @@
<string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Isethaphu yoheloxhumano oluqondile lwe-WiFi lwesicelo kusuka ku <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Faka i-pin ukuze uqhubeke"</string>
<string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"i-pin ye-WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> idinga ukufakiwa kudivayisi ye-peer <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> ukuze isethaphu yohleloxhumano iqhubeke"</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"I-Wi-Fi Direct ivulekile"</string>
- <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Thinta ze uthole izisetho"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Thinta ukuze uthole izilungiselelo"</string>
<string name="select_character" msgid="3365550120617701745">"Faka uhlamvu"</string>
<string name="sms_control_default_app_name" msgid="7630529934366549163">"Uhlelo lokusebenza olungaziwa"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Ithumela imiyalezo ye-SMS"</string>
diff --git a/docs/html/guide/topics/providers/calendar-provider.jd b/docs/html/guide/topics/providers/calendar-provider.jd
index 3ab5125..d30dda4 100644
--- a/docs/html/guide/topics/providers/calendar-provider.jd
+++ b/docs/html/guide/topics/providers/calendar-provider.jd
@@ -280,11 +280,9 @@
{@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE}
in the selection. That is because a given account is
only considered unique given both its <code>ACCOUNT_NAME</code> and its
-<code>ACCOUNT_TYPE</code>. The <code>ACCOUNT_TYPE</code> refers to the way that
-the account is being synced. It is often but not always the domain. For
-example, an account could be synced through a corporate pop3 sync adapter, in which
-case the <code>ACCOUNT_TYPE</code> would not be a domain. There is also a
-special type of account called {@link
+<code>ACCOUNT_TYPE</code>. The <code>ACCOUNT_TYPE</code> is the string corresponding to the
+account authenticator that was used when the account was registered with the
+{@link android.accounts.AccountManager}. There is also a special type of account called {@link
android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} for calendars not
associated with a device account. {@link
android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} accounts do not get
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 27d863d..15c2bab 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -202,6 +202,10 @@
// getCurrentScalingMode returns the scaling mode of the current buffer
uint32_t getCurrentScalingMode() const;
+ // isSynchronousMode returns whether the SurfaceTexture is currently in
+ // synchronous mode.
+ bool isSynchronousMode() const;
+
// abandon frees all the buffers and puts the SurfaceTexture into the
// 'abandoned' state. Once put in this state the SurfaceTexture can never
// leave it. When in the 'abandoned' state, all methods of the
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 8c1c593..446720b 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -153,6 +153,9 @@
bool mStarted;
int32_t mNumFramesEncoded;
+ // Time between capture of two frames.
+ int64_t mTimeBetweenFrameCaptureUs;
+
CameraSource(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId,
Size videoSize, int32_t frameRate,
diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h
index 0e264c7..b060691 100644
--- a/include/media/stagefright/CameraSourceTimeLapse.h
+++ b/include/media/stagefright/CameraSourceTimeLapse.h
@@ -57,10 +57,6 @@
int32_t mVideoWidth;
int32_t mVideoHeight;
- // Time between capture of two frames during time lapse recording
- // Negative value indicates that timelapse is disabled.
- int64_t mTimeBetweenTimeLapseFrameCaptureUs;
-
// Time between two frames in final video (1/frameRate)
int64_t mTimeBetweenTimeLapseVideoFramesUs;
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index c21d19d..84f8282 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -336,6 +336,10 @@
int64_t retrieveDecodingTimeUs(bool isCodecSpecific);
+ status_t parseAVCCodecSpecificData(
+ const void *data, size_t size,
+ unsigned *profile, unsigned *level);
+
OMXCodec(const OMXCodec &);
OMXCodec &operator=(const OMXCodec &);
};
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index ed319f5..9767568 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -32,6 +32,10 @@
LOCAL_MODULE:= libgui
+ifeq ($(TARGET_BOARD_PLATFORM), tegra)
+ LOCAL_CFLAGS += -DALLOW_DEQUEUE_CURRENT_BUFFER
+endif
+
include $(BUILD_SHARED_LIBRARY)
ifeq (,$(ONE_SHOT_MAKEFILE))
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 0561909..beb23f6 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -36,8 +36,12 @@
#include <utils/Log.h>
#include <utils/String8.h>
-
-#define ALLOW_DEQUEUE_CURRENT_BUFFER false
+#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
+#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true
+#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
+#else
+#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER false
+#endif
// Macros for including the SurfaceTexture name in log messages
#define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
@@ -325,7 +329,7 @@
LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
"dequeueBuffer: buffer %d is both FREE and current!", i);
- if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
+ if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
if (state == BufferSlot::FREE || i == mCurrentTexture) {
foundSync = i;
if (i != mCurrentTexture) {
@@ -642,8 +646,9 @@
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
- ST_LOGE("disconnect: SurfaceTexture has been abandoned!");
- return NO_INIT;
+ // it is not really an error to disconnect after the surface
+ // has been abandoned, it should just be a no-op.
+ return NO_ERROR;
}
int err = NO_ERROR;
@@ -1005,6 +1010,11 @@
return mCurrentScalingMode;
}
+bool SurfaceTexture::isSynchronousMode() const {
+ Mutex::Autolock lock(mMutex);
+ return mSynchronousMode;
+}
+
int SurfaceTexture::query(int what, int* outValue)
{
Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 93ebfb9..6d1b951 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -396,7 +396,8 @@
1.0f, 1.0f,
};
- glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices);
+ glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0,
+ triangleVertices);
ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
glEnableVertexAttribArray(mPositionHandle);
ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
@@ -410,13 +411,17 @@
// XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as
// they're setting the defautls for that target, but when hacking things
// to use GL_TEXTURE_2D they are needed to achieve the same behavior.
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR);
ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR);
ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE);
ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
- glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE);
ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
GLfloat texMatrix[16];
@@ -640,8 +645,8 @@
for (int i = 0; i < 5; i++) {
const android_native_rect_t& crop(crops[i]);
- SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", crop.left,
- crop.top, crop.right, crop.bottom).string());
+ SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }",
+ crop.left, crop.top, crop.right, crop.bottom).string());
ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
@@ -650,13 +655,15 @@
ASSERT_TRUE(anb != NULL);
sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+ ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
+ buf->getNativeBuffer()));
uint8_t* img = NULL;
buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop);
buf->unlock();
- ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+ ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
+ buf->getNativeBuffer()));
mST->updateTexImage();
@@ -708,7 +715,8 @@
class ProducerThread : public Thread {
public:
- ProducerThread(const sp<ANativeWindow>& anw, const TestPixel* testPixels):
+ ProducerThread(const sp<ANativeWindow>& anw,
+ const TestPixel* testPixels):
mANW(anw),
mTestPixels(testPixels) {
}
@@ -940,82 +948,6 @@
EXPECT_TRUE(checkPixel( 3, 52, 35, 231, 35, 35));
}
-TEST_F(SurfaceTextureGLTest, TexturingFromGLFilledRGBABufferPow2) {
- const int texWidth = 64;
- const int texHeight = 64;
-
- mST->setDefaultBufferSize(texWidth, texHeight);
-
- // Do the producer side of things
- EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
- mANW.get(), NULL);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
-
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- glClearColor(0.6, 0.6, 0.6, 0.6);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(4, 4, 4, 4);
- glClearColor(1.0, 0.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glScissor(24, 48, 4, 4);
- glClearColor(0.0, 1.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glScissor(37, 17, 4, 4);
- glClearColor(0.0, 0.0, 1.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- eglSwapBuffers(mEglDisplay, stcEglSurface);
-
- // Do the consumer side of things
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- glDisable(GL_SCISSOR_TEST);
-
- mST->updateTexImage();
-
- // We must wait until updateTexImage has been called to destroy the
- // EGLSurface because we're in synchronous mode.
- eglDestroySurface(mEglDisplay, stcEglSurface);
-
- glClearColor(0.2, 0.2, 0.2, 0.2);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glViewport(0, 0, texWidth, texHeight);
- drawTexture();
-
- EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
-
- EXPECT_TRUE(checkPixel( 4, 7, 255, 0, 0, 255));
- EXPECT_TRUE(checkPixel(25, 51, 0, 255, 0, 255));
- EXPECT_TRUE(checkPixel(40, 19, 0, 0, 255, 255));
- EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(13, 8, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(46, 3, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
- EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
-}
-
TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
class ProducerThread : public Thread {
public:
@@ -1093,13 +1025,284 @@
reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
}
+TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
+ int texHeight = 16;
+ ANativeWindowBuffer* anb;
+
+ GLint maxTextureSize;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+
+ // make sure it works with small textures
+ mST->setDefaultBufferSize(16, texHeight);
+ EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ EXPECT_EQ(16, anb->width);
+ EXPECT_EQ(texHeight, anb->height);
+ EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
+ EXPECT_EQ(NO_ERROR, mST->updateTexImage());
+
+ // make sure it works with GL_MAX_TEXTURE_SIZE
+ mST->setDefaultBufferSize(maxTextureSize, texHeight);
+ EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ EXPECT_EQ(maxTextureSize, anb->width);
+ EXPECT_EQ(texHeight, anb->height);
+ EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
+ EXPECT_EQ(NO_ERROR, mST->updateTexImage());
+
+ // make sure it fails with GL_MAX_TEXTURE_SIZE+1
+ mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
+ EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ EXPECT_EQ(maxTextureSize+1, anb->width);
+ EXPECT_EQ(texHeight, anb->height);
+ EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
+ ASSERT_NE(NO_ERROR, mST->updateTexImage());
+}
+
/*
- * This test is for testing GL -> GL texture streaming via SurfaceTexture. It
- * contains functionality to create a producer thread that will perform GL
- * rendering to an ANativeWindow that feeds frames to a SurfaceTexture.
- * Additionally it supports interlocking the producer and consumer threads so
- * that a specific sequence of calls can be deterministically created by the
- * test.
+ * This test fixture is for testing GL -> GL texture streaming. It creates an
+ * EGLSurface and an EGLContext for the image producer to use.
+ */
+class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
+protected:
+ SurfaceTextureGLToGLTest():
+ mProducerEglSurface(EGL_NO_SURFACE),
+ mProducerEglContext(EGL_NO_CONTEXT) {
+ }
+
+ virtual void SetUp() {
+ SurfaceTextureGLTest::SetUp();
+
+ EGLConfig myConfig = {0};
+ EGLint numConfigs = 0;
+ EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
+ 1, &numConfigs));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
+ mANW.get(), NULL);
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
+
+ mProducerEglContext = eglCreateContext(mEglDisplay, myConfig,
+ EGL_NO_CONTEXT, getContextAttribs());
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
+ }
+
+ virtual void TearDown() {
+ if (mProducerEglContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(mEglDisplay, mProducerEglContext);
+ }
+ if (mProducerEglSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(mEglDisplay, mProducerEglSurface);
+ }
+ SurfaceTextureGLTest::TearDown();
+ }
+
+ EGLSurface mProducerEglSurface;
+ EGLContext mProducerEglContext;
+};
+
+TEST_F(SurfaceTextureGLToGLTest, TexturingFromGLFilledRGBABufferPow2) {
+ const int texWidth = 64;
+ const int texHeight = 64;
+
+ mST->setDefaultBufferSize(texWidth, texHeight);
+
+ // Do the producer side of things
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ // This is needed to ensure we pick up a buffer of the correct size.
+ eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+ glClearColor(0.6, 0.6, 0.6, 0.6);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(4, 4, 4, 4);
+ glClearColor(1.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glScissor(24, 48, 4, 4);
+ glClearColor(0.0, 1.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glScissor(37, 17, 4, 4);
+ glClearColor(0.0, 0.0, 1.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+ // Do the consumer side of things
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+ mEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ glDisable(GL_SCISSOR_TEST);
+
+ mST->updateTexImage(); // Skip the first frame, which was empty
+ mST->updateTexImage();
+
+ glClearColor(0.2, 0.2, 0.2, 0.2);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glViewport(0, 0, texWidth, texHeight);
+ drawTexture();
+
+ EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153));
+
+ EXPECT_TRUE(checkPixel( 4, 7, 255, 0, 0, 255));
+ EXPECT_TRUE(checkPixel(25, 51, 0, 255, 0, 255));
+ EXPECT_TRUE(checkPixel(40, 19, 0, 0, 255, 255));
+ EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(13, 8, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(46, 3, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153));
+ EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceUnrefsBuffers) {
+ sp<GraphicBuffer> buffers[3];
+
+ // This test requires async mode to run on a single thread.
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ for (int i = 0; i < 3; i++) {
+ // Produce a frame
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(mEglDisplay, mProducerEglSurface);
+
+ // Consume a frame
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+ mEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ mST->updateTexImage();
+ buffers[i] = mST->getCurrentBuffer();
+ }
+
+ // Destroy the GL texture object to release its ref on buffers[2].
+ GLuint texID = TEX_ID;
+ glDeleteTextures(1, &texID);
+
+ // Destroy the EGLSurface
+ EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ // Release the ref that the SurfaceTexture has on buffers[2].
+ mST->abandon();
+
+ EXPECT_EQ(1, buffers[0]->getStrongCount());
+ EXPECT_EQ(1, buffers[1]->getStrongCount());
+
+ // Depending on how lazily the GL driver dequeues buffers, we may end up
+ // with either two or three total buffers. If there are three, make sure
+ // the last one was properly down-ref'd.
+ if (buffers[2] != buffers[0]) {
+ EXPECT_EQ(1, buffers[2]->getStrongCount());
+ }
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
+ sp<GraphicBuffer> buffers[3];
+
+ // This test requires async mode to run on a single thread.
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_TRUE(eglSwapInterval(mEglDisplay, 0));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ for (int i = 0; i < 3; i++) {
+ // Produce a frame
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ // Consume a frame
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+ mEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+ buffers[i] = mST->getCurrentBuffer();
+ }
+
+ // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
+ // on buffers[2].
+ mST->abandon();
+
+ // Destroy the GL texture object to release its ref on buffers[2].
+ GLuint texID = TEX_ID;
+ glDeleteTextures(1, &texID);
+
+ // Destroy the EGLSurface.
+ EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ EXPECT_EQ(1, buffers[0]->getStrongCount());
+ EXPECT_EQ(1, buffers[1]->getStrongCount());
+
+ // Depending on how lazily the GL driver dequeues buffers, we may end up
+ // with either two or three total buffers. If there are three, make sure
+ // the last one was properly down-ref'd.
+ if (buffers[2] != buffers[0]) {
+ EXPECT_EQ(1, buffers[2]->getStrongCount());
+ }
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
+ // This test requires 3 buffers to run on a single thread.
+ mST->setBufferCountServer(3);
+
+ ASSERT_TRUE(mST->isSynchronousMode());
+
+ for (int i = 0; i < 10; i++) {
+ // Produce a frame
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ // Consume a frame
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+ mEglContext));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+ }
+
+ ASSERT_TRUE(mST->isSynchronousMode());
+}
+
+/*
+ * This test fixture is for testing GL -> GL texture streaming from one thread
+ * to another. It contains functionality to create a producer thread that will
+ * perform GL rendering to an ANativeWindow that feeds frames to a
+ * SurfaceTexture. Additionally it supports interlocking the producer and
+ * consumer threads so that a specific sequence of calls can be
+ * deterministically created by the test.
*
* The intended usage is as follows:
*
@@ -1122,7 +1325,7 @@
* }
*
*/
-class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest {
+class SurfaceTextureGLThreadToGLTest : public SurfaceTextureGLToGLTest {
protected:
// ProducerThread is an abstract base class to simplify the creation of
@@ -1223,30 +1426,8 @@
Condition mFrameFinishCondition;
};
- SurfaceTextureGLToGLTest():
- mProducerEglSurface(EGL_NO_SURFACE),
- mProducerEglContext(EGL_NO_CONTEXT) {
- }
-
virtual void SetUp() {
- SurfaceTextureGLTest::SetUp();
-
- EGLConfig myConfig = {0};
- EGLint numConfigs = 0;
- EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig,
- 1, &numConfigs));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig,
- mANW.get(), NULL);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface);
-
- mProducerEglContext = eglCreateContext(mEglDisplay, myConfig,
- EGL_NO_CONTEXT, getContextAttribs());
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext);
-
+ SurfaceTextureGLToGLTest::SetUp();
mFC = new FrameCondition();
mST->setFrameAvailableListener(mFC);
}
@@ -1255,15 +1436,9 @@
if (mProducerThread != NULL) {
mProducerThread->requestExitAndWait();
}
- if (mProducerEglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(mEglDisplay, mProducerEglContext);
- }
- if (mProducerEglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mEglDisplay, mProducerEglSurface);
- }
mProducerThread.clear();
mFC.clear();
- SurfaceTextureGLTest::TearDown();
+ SurfaceTextureGLToGLTest::TearDown();
}
void runProducerThread(const sp<ProducerThread> producerThread) {
@@ -1274,13 +1449,12 @@
producerThread->run();
}
- EGLSurface mProducerEglSurface;
- EGLContext mProducerEglContext;
sp<ProducerThread> mProducerThread;
sp<FrameCondition> mFC;
};
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+ UpdateTexImageBeforeFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1298,7 +1472,8 @@
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+ UpdateTexImageAfterFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1316,7 +1491,8 @@
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+ RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@@ -1344,7 +1520,8 @@
}
}
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+ RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@@ -1373,7 +1550,8 @@
}
// XXX: This test is disabled because it is currently hanging on some devices.
-TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
+TEST_F(SurfaceTextureGLThreadToGLTest,
+ DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
enum { NUM_ITERATIONS = 64 };
class PT : public ProducerThread {
@@ -1438,118 +1616,4 @@
}
}
-TEST_F(SurfaceTextureGLTest, EglDestroySurfaceUnrefsBuffers) {
- EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
- mANW.get(), NULL);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
-
- sp<GraphicBuffer> buffers[3];
-
- for (int i = 0; i < 3; i++) {
- // Produce a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- glClear(GL_COLOR_BUFFER_BIT);
- eglSwapBuffers(mEglDisplay, stcEglSurface);
-
- // Consume a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- mST->updateTexImage();
- buffers[i] = mST->getCurrentBuffer();
- }
-
- // Destroy the GL texture object to release its ref on buffers[2].
- GLuint texID = TEX_ID;
- glDeleteTextures(1, &texID);
-
- // Destroy the EGLSurface
- EXPECT_TRUE(eglDestroySurface(mEglDisplay, stcEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Release the ref that the SurfaceTexture has on buffers[2].
- mST->abandon();
-
- EXPECT_EQ(1, buffers[0]->getStrongCount());
- EXPECT_EQ(1, buffers[1]->getStrongCount());
- EXPECT_EQ(1, buffers[2]->getStrongCount());
-}
-
-TEST_F(SurfaceTextureGLTest, EglDestroySurfaceAfterAbandonUnrefsBuffers) {
- EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,
- mANW.get(), NULL);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, stcEglSurface);
-
- sp<GraphicBuffer> buffers[3];
-
- for (int i = 0; i < 3; i++) {
- // Produce a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- glClear(GL_COLOR_BUFFER_BIT);
- EXPECT_TRUE(eglSwapBuffers(mEglDisplay, stcEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Consume a frame
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_EQ(NO_ERROR, mST->updateTexImage());
- buffers[i] = mST->getCurrentBuffer();
- }
-
- // Abandon the SurfaceTexture, releasing the ref that the SurfaceTexture has
- // on buffers[2].
- mST->abandon();
-
- // Destroy the GL texture object to release its ref on buffers[2].
- GLuint texID = TEX_ID;
- glDeleteTextures(1, &texID);
-
- // Destroy the EGLSurface.
- EXPECT_TRUE(eglDestroySurface(mEglDisplay, stcEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EXPECT_EQ(1, buffers[0]->getStrongCount());
- EXPECT_EQ(1, buffers[1]->getStrongCount());
- EXPECT_EQ(1, buffers[2]->getStrongCount());
-}
-
-TEST_F(SurfaceTextureGLTest, InvalidWidthOrHeightFails) {
- int texHeight = 16;
- ANativeWindowBuffer* anb;
-
- GLint maxTextureSize;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
-
- // make sure it works with small textures
- mST->setDefaultBufferSize(16, texHeight);
- EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- EXPECT_EQ(16, anb->width);
- EXPECT_EQ(texHeight, anb->height);
- EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
- EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
- // make sure it works with GL_MAX_TEXTURE_SIZE
- mST->setDefaultBufferSize(maxTextureSize, texHeight);
- EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- EXPECT_EQ(maxTextureSize, anb->width);
- EXPECT_EQ(texHeight, anb->height);
- EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
- EXPECT_EQ(NO_ERROR, mST->updateTexImage());
-
- // make sure it fails with GL_MAX_TEXTURE_SIZE+1
- mST->setDefaultBufferSize(maxTextureSize+1, texHeight);
- EXPECT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
- EXPECT_EQ(maxTextureSize+1, anb->width);
- EXPECT_EQ(texHeight, anb->height);
- EXPECT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), anb));
- ASSERT_NE(NO_ERROR, mST->updateTexImage());
-}
-
} // namespace android
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 32595e4..7561a47 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -208,7 +208,7 @@
glDisable(GL_DITHER);
- glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo());
+ glBindFramebuffer(GL_FRAMEBUFFER, mSnapshot->fbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
mCaches.blend = true;
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index d51154d..aff7b93 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -213,7 +213,8 @@
Layer* layer;
/**
- * Only set when the flag kFlagIsFboLayer is set.
+ * Target FBO used for rendering. Set to 0 when rendering directly
+ * into the framebuffer.
*/
GLuint fbo;
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
old mode 100644
new mode 100755
index 4e271c7..98617d2
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -38,6 +38,7 @@
import java.io.File;
import java.util.HashMap;
+import java.util.Locale;
/**
* {@hide}
@@ -120,6 +121,20 @@
mMediaStoragePath = storagePath;
mObjectsUri = Files.getMtpObjectsUri(volumeName);
mMediaScanner = new MediaScanner(context);
+
+ // Set locale to MediaScanner.
+ Locale locale = context.getResources().getConfiguration().locale;
+ if (locale != null) {
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ if (language != null) {
+ if (country != null) {
+ mMediaScanner.setLocale(language + "_" + country);
+ } else {
+ mMediaScanner.setLocale(language);
+ }
+ }
+ }
initDeviceProperties(context);
}
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 256f3ba..57989c5 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -33,6 +33,8 @@
namespace android {
+static const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
+
struct CameraSourceListener : public CameraListener {
CameraSourceListener(const sp<CameraSource> &source);
@@ -156,6 +158,7 @@
mLastFrameTimestampUs(0),
mStarted(false),
mNumFramesEncoded(0),
+ mTimeBetweenFrameCaptureUs(0),
mFirstFrameTimeUs(0),
mNumFramesDropped(0),
mNumGlitches(0),
@@ -644,7 +647,8 @@
releaseQueuedFrames();
while (!mFramesBeingEncoded.empty()) {
if (NO_ERROR !=
- mFrameCompleteCondition.waitRelative(mLock, 3000000000LL)) {
+ mFrameCompleteCondition.waitRelative(mLock,
+ mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
LOGW("Timed out waiting for outstanding frames being encoded: %d",
mFramesBeingEncoded.size());
}
@@ -736,7 +740,8 @@
Mutex::Autolock autoLock(mLock);
while (mStarted && mFramesReceived.empty()) {
if (NO_ERROR !=
- mFrameAvailableCondition.waitRelative(mLock, 1000000000LL)) {
+ mFrameAvailableCondition.waitRelative(mLock,
+ mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
if (mCameraRecordingProxy != 0 &&
!mCameraRecordingProxy->asBinder()->isBinderAlive()) {
LOGW("camera recording proxy is gone");
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index e4de20a..eb456f4 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -39,12 +39,12 @@
Size videoSize,
int32_t videoFrameRate,
const sp<Surface>& surface,
- int64_t timeBetweenTimeLapseFrameCaptureUs) {
+ int64_t timeBetweenFrameCaptureUs) {
CameraSourceTimeLapse *source = new
CameraSourceTimeLapse(camera, proxy, cameraId,
videoSize, videoFrameRate, surface,
- timeBetweenTimeLapseFrameCaptureUs);
+ timeBetweenFrameCaptureUs);
if (source != NULL) {
if (source->initCheck() != OK) {
@@ -62,15 +62,15 @@
Size videoSize,
int32_t videoFrameRate,
const sp<Surface>& surface,
- int64_t timeBetweenTimeLapseFrameCaptureUs)
+ int64_t timeBetweenFrameCaptureUs)
: CameraSource(camera, proxy, cameraId, videoSize, videoFrameRate, surface, true),
- mTimeBetweenTimeLapseFrameCaptureUs(timeBetweenTimeLapseFrameCaptureUs),
mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate),
mLastTimeLapseFrameRealTimestampUs(0),
mSkipCurrentFrame(false) {
+ mTimeBetweenFrameCaptureUs = timeBetweenFrameCaptureUs;
LOGD("starting time lapse mode: %lld us",
- mTimeBetweenTimeLapseFrameCaptureUs);
+ mTimeBetweenFrameCaptureUs);
mVideoWidth = videoSize.width;
mVideoHeight = videoSize.height;
@@ -271,14 +271,14 @@
// The first 2 output frames from the encoder are: decoder specific info and
// the compressed video frame data for the first input video frame.
if (mNumFramesEncoded >= 1 && *timestampUs <
- (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenTimeLapseFrameCaptureUs)) {
+ (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) {
// Skip all frames from last encoded frame until
- // sufficient time (mTimeBetweenTimeLapseFrameCaptureUs) has passed.
+ // sufficient time (mTimeBetweenFrameCaptureUs) has passed.
// Tell the camera to release its recording frame and return.
LOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
return true;
} else {
- // Desired frame has arrived after mTimeBetweenTimeLapseFrameCaptureUs time:
+ // Desired frame has arrived after mTimeBetweenFrameCaptureUs time:
// - Reset mLastTimeLapseFrameRealTimestampUs to current time.
// - Artificially modify timestampUs to be one frame time (1/framerate) ahead
// of the last encoded frame's time stamp.
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index dfd3f4a..86b3fe4 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -520,6 +520,85 @@
return NULL;
}
+status_t OMXCodec::parseAVCCodecSpecificData(
+ const void *data, size_t size,
+ unsigned *profile, unsigned *level) {
+ const uint8_t *ptr = (const uint8_t *)data;
+
+ // verify minimum size and configurationVersion == 1.
+ if (size < 7 || ptr[0] != 1) {
+ return ERROR_MALFORMED;
+ }
+
+ *profile = ptr[1];
+ *level = ptr[3];
+
+ // There is decodable content out there that fails the following
+ // assertion, let's be lenient for now...
+ // CHECK((ptr[4] >> 2) == 0x3f); // reserved
+
+ size_t lengthSize = 1 + (ptr[4] & 3);
+
+ // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
+ // violates it...
+ // CHECK((ptr[5] >> 5) == 7); // reserved
+
+ size_t numSeqParameterSets = ptr[5] & 31;
+
+ ptr += 6;
+ size -= 6;
+
+ for (size_t i = 0; i < numSeqParameterSets; ++i) {
+ if (size < 2) {
+ return ERROR_MALFORMED;
+ }
+
+ size_t length = U16_AT(ptr);
+
+ ptr += 2;
+ size -= 2;
+
+ if (size < length) {
+ return ERROR_MALFORMED;
+ }
+
+ addCodecSpecificData(ptr, length);
+
+ ptr += length;
+ size -= length;
+ }
+
+ if (size < 1) {
+ return ERROR_MALFORMED;
+ }
+
+ size_t numPictureParameterSets = *ptr;
+ ++ptr;
+ --size;
+
+ for (size_t i = 0; i < numPictureParameterSets; ++i) {
+ if (size < 2) {
+ return ERROR_MALFORMED;
+ }
+
+ size_t length = U16_AT(ptr);
+
+ ptr += 2;
+ size -= 2;
+
+ if (size < length) {
+ return ERROR_MALFORMED;
+ }
+
+ addCodecSpecificData(ptr, length);
+
+ ptr += length;
+ size -= length;
+ }
+
+ return OK;
+}
+
status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
LOGV("configureCodec protected=%d",
(mFlags & kEnableGrallocUsageProtected) ? 1 : 0);
@@ -542,66 +621,17 @@
} else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
// Parse the AVCDecoderConfigurationRecord
- const uint8_t *ptr = (const uint8_t *)data;
-
- CHECK(size >= 7);
- CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
- uint8_t profile = ptr[1];
- uint8_t level = ptr[3];
-
- // There is decodable content out there that fails the following
- // assertion, let's be lenient for now...
- // CHECK((ptr[4] >> 2) == 0x3f); // reserved
-
- size_t lengthSize = 1 + (ptr[4] & 3);
-
- // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
- // violates it...
- // CHECK((ptr[5] >> 5) == 7); // reserved
-
- size_t numSeqParameterSets = ptr[5] & 31;
-
- ptr += 6;
- size -= 6;
-
- for (size_t i = 0; i < numSeqParameterSets; ++i) {
- CHECK(size >= 2);
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- CHECK(size >= length);
-
- addCodecSpecificData(ptr, length);
-
- ptr += length;
- size -= length;
- }
-
- CHECK(size >= 1);
- size_t numPictureParameterSets = *ptr;
- ++ptr;
- --size;
-
- for (size_t i = 0; i < numPictureParameterSets; ++i) {
- CHECK(size >= 2);
- size_t length = U16_AT(ptr);
-
- ptr += 2;
- size -= 2;
-
- CHECK(size >= length);
-
- addCodecSpecificData(ptr, length);
-
- ptr += length;
- size -= length;
+ unsigned profile, level;
+ status_t err;
+ if ((err = parseAVCCodecSpecificData(
+ data, size, &profile, &level)) != OK) {
+ LOGE("Malformed AVC codec specific data.");
+ return err;
}
CODEC_LOGI(
- "AVC profile = %d (%s), level = %d",
- (int)profile, AVCProfileToString(profile), level);
+ "AVC profile = %u (%s), level = %u",
+ profile, AVCProfileToString(profile), level);
if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
&& (profile != kAVCProfileBaseline || level > 30)) {
diff --git a/opengl/java/android/opengl/ManagedEGLContext.java b/opengl/java/android/opengl/ManagedEGLContext.java
index d3a3662..61fa565 100644
--- a/opengl/java/android/opengl/ManagedEGLContext.java
+++ b/opengl/java/android/opengl/ManagedEGLContext.java
@@ -43,12 +43,13 @@
* of the currently created EGL contexts in the process are being managed
* through this class, then they will all be asked to terminate through the
* call to {@link #onTerminate}.
+ *
+ * @hide
*/
public abstract class ManagedEGLContext {
static final String TAG = "ManagedEGLContext";
- static final ArrayList<ManagedEGLContext> sActive
- = new ArrayList<ManagedEGLContext>();
+ static final ArrayList<ManagedEGLContext> sActive = new ArrayList<ManagedEGLContext>();
final EGLContext mContext;
@@ -127,7 +128,7 @@
sActive.clear();
}
- for (int i=0; i<active.size(); i++) {
+ for (int i = 0; i < active.size(); i++) {
active.get(i).execTerminate();
}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 5855b63..9c1a10e 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -44,10 +44,17 @@
LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
endif
+ifneq ($(MAX_EGL_CACHE_ENTRY_SIZE),)
+ LOCAL_CFLAGS += -DMAX_EGL_CACHE_ENTRY_SIZE=$(MAX_EGL_CACHE_ENTRY_SIZE)
+endif
+
+ifneq ($(MAX_EGL_CACHE_SIZE),)
+ LOCAL_CFLAGS += -DMAX_EGL_CACHE_SIZE=$(MAX_EGL_CACHE_SIZE)
+endif
+
include $(BUILD_SHARED_LIBRARY)
installed_libEGL := $(LOCAL_INSTALLED_MODULE)
-
# OpenGL drivers config file
ifneq ($(BOARD_EGL_CFG),)
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 2237eb6..a63d5b0 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -370,6 +370,11 @@
}
}
+ // the EGL spec requires that a new EGLSurface default to swap interval
+ // 1, so explicitly set that on the window here.
+ ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
+ anw->setSwapInterval(anw, 1);
+
EGLSurface surface = cnx->egl.eglCreateWindowSurface(
iDpy, iConfig, window, attrib_list);
if (surface != EGL_NO_SURFACE) {
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index fe32d43..c4a7466 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -25,10 +25,18 @@
#include <sys/types.h>
#include <unistd.h>
+#ifndef MAX_EGL_CACHE_ENTRY_SIZE
+#define MAX_EGL_CACHE_ENTRY_SIZE (16 * 1024);
+#endif
+
+#ifndef MAX_EGL_CACHE_SIZE
+#define MAX_EGL_CACHE_SIZE (64 * 1024);
+#endif
+
// Cache size limits.
static const size_t maxKeySize = 1024;
-static const size_t maxValueSize = 4096;
-static const size_t maxTotalSize = 64 * 1024;
+static const size_t maxValueSize = MAX_EGL_CACHE_ENTRY_SIZE;
+static const size_t maxTotalSize = MAX_EGL_CACHE_SIZE;
// Cache file header
static const char* cacheFileMagic = "EGL$";
diff --git a/packages/BackupRestoreConfirmation/res/values-af/strings.xml b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
index 8ee5550..fadd125 100644
--- a/packages/BackupRestoreConfirmation/res/values-af/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
@@ -18,10 +18,10 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="backup_confirm_title" msgid="827563724209303345">"Volledige rugsteun"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"Volledige herstel"</string>
- <string name="backup_confirm_text" msgid="1878021282758896593">"\'n Volledige rugsteun van al die data na \'n tafelrekenaar is aangevra. Wil jy dit toelaat? "\n\n"As jy nie self die rugsteun versoek het nie, moenie toelaat dat die aksie voortgaan nie."</string>
+ <string name="backup_confirm_text" msgid="1878021282758896593">"\'n Volledige rugsteun van al die data na \'n rekenaar is aangevra. Wil jy dit toelaat? "\n\n"As jy nie self die rugsteun versoek het nie, moenie toelaat dat die aksie voortgaan nie."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Rugsteun my data"</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"Moenie rugsteun nie"</string>
- <string name="restore_confirm_text" msgid="7499866728030461776">"\'n Volle teruglaai van alle data van \'n gekoppelde tafelrekenaar is versoek. Wil jy dit toelaat? "\n\n" As jy nie die teruglaai self versoek het nie, moenie die aksie toelaat nie. Dit sal enige data tans op die toestel vervang!"</string>
+ <string name="restore_confirm_text" msgid="7499866728030461776">"\'n Volle teruglaai van alle data van \'n gekoppelde rekenaar is versoek. Wil jy dit toelaat? "\n\n" As jy nie die teruglaai self versoek het nie, moenie die aksie toelaat nie. Dit sal enige data tans op die toestel vervang!"</string>
<string name="allow_restore_button_label" msgid="3081286752277127827">"Laai my data terug"</string>
<string name="deny_restore_button_label" msgid="1724367334453104378">"Moenie herstel nie"</string>
<string name="current_password_text" msgid="8268189555578298067">"Voer asseblief jou huidige rugsteunwagwoord hieronder in:"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 841f6e2..b518898 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -33,7 +33,7 @@
</plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen meddelelser"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"I gang"</string>
- <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelelser"</string>
+ <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Underretninger"</string>
<string name="battery_low_title" msgid="2783104807551211639">"Tilslut oplader"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er ved at være fladt."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tilbage"</string>
@@ -45,7 +45,7 @@
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Automatisk skærmrotation"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"LYDLØS"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
- <string name="status_bar_settings_notifications" msgid="397146176280905137">"Meddelelser"</string>
+ <string name="status_bar_settings_notifications" msgid="397146176280905137">"Underretninger"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inputmetoder"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Brug fysisk tastatur"</string>
@@ -119,7 +119,7 @@
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Flytilstand."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Systemindstillinger."</string>
- <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meddelelser."</string>
+ <string name="accessibility_notifications_button" msgid="4498000369779421892">"Underretninger."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Ryd meddelelse."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiveret."</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS samler data."</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ed62c10..a5bfb4a 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -106,7 +106,7 @@
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX-i on üks riba."</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-i on kaks riba."</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-i on kolm riba."</string>
- <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-i signaal on täis."</string>
+ <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-i signaal on tugev."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 54c8482..d9c9aa2 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -102,7 +102,7 @@
<string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi電波: レベル2"</string>
<string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi電波: レベル3"</string>
<string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi電波:フル"</string>
- <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX電波状態:レベル0"</string>
+ <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX電波状態:圏外"</string>
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX電波状態:レベル1"</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX電波状態:レベル2"</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX電波状態:レベル3"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index bc32081a..5f64f7b 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -102,7 +102,7 @@
<string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dua bar Wi-Fi."</string>
<string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tiga bar Wi-Fi."</string>
<string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Isyarat WiFi penuh."</string>
- <string name="accessibility_no_wimax" msgid="4329180129727630368">"No. WiMAX"</string>
+ <string name="accessibility_no_wimax" msgid="4329180129727630368">"Tiada WiMAX"</string>
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX satu bar."</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX dua bar."</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX tiga bar."</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 7320d6e..b90876a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -138,5 +138,5 @@
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Søker etter GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
- <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivér skjermbeskytter"</string>
+ <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiver skjermbeskytter"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 8996b2a..cf85c75 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -106,7 +106,7 @@
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX: één streepje."</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX: twee streepjes."</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX: drie streepjes."</string>
- <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-signaal is op volledige sterkte."</string>
+ <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-signaal is op volle sterkte."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index d623990..6e94cc5 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -102,7 +102,7 @@
<string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: два деления."</string>
<string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: три деления."</string>
<string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Надежный сигнал Wi-Fi."</string>
- <string name="accessibility_no_wimax" msgid="4329180129727630368">"Сигнал WiMAX отсутствует."</string>
+ <string name="accessibility_no_wimax" msgid="4329180129727630368">"Нет сигнала WiMAX."</string>
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Сигнал WiMAX: одно деление."</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Сигнал WiMAX: два деления."</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Сигнал WiMAX: три деления."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 70e29eb..3843ea9 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -26,7 +26,7 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ondoa kwenye orodha"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Taarifa za programu-matumizi"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Hakuna programu za sasa"</string>
- <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ondosha prog za hivi karibuni"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ondosha programu za hivi karibuni"</string>
<!-- String.format failed for translation -->
<!-- no translation found for status_bar_accessibility_recent_apps:other (1040784359794890744) -->
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Hakuna arifa"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 9cf90d2..34b84af 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="7164937344850004466">"Giao diện người dùng hệ thống"</string>
- <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Xoá"</string>
+ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Xóa"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Không làm phiền"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Hiển thị thông báo"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Xóa khỏi danh sách"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 52a44a3..39b428a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -68,7 +68,7 @@
<string name="screenshot_saved_title" msgid="6461865960961414961">"Umfanekiso weskrini uqoshiwe"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Thinta ukubona imifanekiso yakho yeskrini"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Yehlulekile ukulondoloza umfanekiso weskrini."</string>
- <string name="screenshot_failed_text" msgid="8134011269572415402">"Ayikwazanga ukulondoloza isithombe-skrini. Ukugcina kwangaphandle kungenzeka kuyasetshenziswa."</string>
+ <string name="screenshot_failed_text" msgid="8134011269572415402">"Ayikwazanga ukulondoloza isithombe-skrini. Isitoreji sangaphandle kungenzeka kuyasetshenziswa."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Okukhethwa kokudluliswa kwefayela ye-USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Lengisa njengesidlali semediya (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Lengisa ikhamera (PTP)"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
index 20a1c50..1db2a7f 100644
--- a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
+++ b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
@@ -30,12 +30,17 @@
com.android.internal.R.string.config_defaultDreamComponent);
}
if (component != null) {
+ // dismiss the notification shade, recents, etc.
+ context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+
ComponentName cn = ComponentName.unflattenFromString(component);
Intent zzz = new Intent(Intent.ACTION_MAIN)
.setComponent(cn)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_NO_USER_ACTION
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_NO_USER_ACTION
+ | Intent.FLAG_FROM_BACKGROUND
+ | Intent.FLAG_ACTIVITY_NO_HISTORY
);
Slog.v(TAG, "Starting screen saver on dock event: " + component);
context.startActivity(zzz);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e1676b8..fd9e095 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3475,12 +3475,17 @@
component = mContext.getResources().getString(R.string.config_defaultDreamComponent);
}
if (component != null) {
+ // dismiss the notification shade, recents, etc.
+ mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+
ComponentName cn = ComponentName.unflattenFromString(component);
Intent intent = new Intent(Intent.ACTION_MAIN)
.setComponent(cn)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_NO_USER_ACTION
+ | Intent.FLAG_FROM_BACKGROUND
+ | Intent.FLAG_ACTIVITY_NO_HISTORY
);
mContext.startActivity(intent);
} else {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 780c0d2..aea31a8 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -89,6 +89,12 @@
static const nsecs_t kSetParametersTimeout = seconds(2);
+// minimum sleep time for the mixer thread loop when tracks are active but in underrun
+static const uint32_t kMinThreadSleepTimeUs = 5000;
+// maximum divider applied to the active sleep time in the mixer thread loop
+static const uint32_t kMaxThreadSleepTimeShift = 2;
+
+
// ----------------------------------------------------------------------------
static bool recordingAllowed() {
@@ -1846,6 +1852,7 @@
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
+ uint32_t sleepTimeShift = 0;
Vector< sp<EffectChain> > effectChains;
#ifdef DEBUG_CPU_USAGE
ThreadCpuUsage cpu;
@@ -1937,6 +1944,7 @@
standbyTime = systemTime() + kStandbyTimeInNsecs;
sleepTime = idleSleepTime;
+ sleepTimeShift = 0;
continue;
}
}
@@ -1953,6 +1961,10 @@
// mix buffers...
mAudioMixer->process();
sleepTime = 0;
+ // increase sleep time progressively when application underrun condition clears
+ if (sleepTimeShift > 0) {
+ sleepTimeShift--;
+ }
standbyTime = systemTime() + kStandbyTimeInNsecs;
//TODO: delay standby when effects have a tail
} else {
@@ -1960,7 +1972,17 @@
// buffer size, then write 0s to the output
if (sleepTime == 0) {
if (mixerStatus == MIXER_TRACKS_ENABLED) {
- sleepTime = activeSleepTime;
+ sleepTime = activeSleepTime >> sleepTimeShift;
+ if (sleepTime < kMinThreadSleepTimeUs) {
+ sleepTime = kMinThreadSleepTimeUs;
+ }
+ // reduce sleep time in case of consecutive application underruns to avoid
+ // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
+ // duration we would end up writing less data than needed by the audio HAL if
+ // the condition persists.
+ if (sleepTimeShift < kMaxThreadSleepTimeShift) {
+ sleepTimeShift++;
+ }
} else {
sleepTime = idleSleepTime;
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index da960ae..75e5366 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -856,13 +856,17 @@
NetworkInterface internalNetworkInterface =
NetworkInterface.getByName(internalInterface);
- Collection<InterfaceAddress>interfaceAddresses =
- internalNetworkInterface.getInterfaceAddresses();
- cmd += " " + interfaceAddresses.size();
- for (InterfaceAddress ia : interfaceAddresses) {
- InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(),
- ia.getNetworkPrefixLength());
- cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength();
+ if (internalNetworkInterface == null) {
+ cmd += " 0";
+ } else {
+ Collection<InterfaceAddress>interfaceAddresses =
+ internalNetworkInterface.getInterfaceAddresses();
+ cmd += " " + interfaceAddresses.size();
+ for (InterfaceAddress ia : interfaceAddresses) {
+ InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(),
+ ia.getNetworkPrefixLength());
+ cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength();
+ }
}
mConnector.doCommand(cmd);
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index 6d8956f..efbf608 100644
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -126,6 +126,8 @@
// set link addresses
if (addresses != null && addresses.length > 0) {
for (String addr : addresses) {
+ addr = addr.trim();
+ if (addr.isEmpty()) continue;
LinkAddress la;
int addrPrefixLen;
@@ -159,6 +161,8 @@
// set dns servers
if (dnses != null && dnses.length > 0) {
for (String addr : dnses) {
+ addr = addr.trim();
+ if (addr.isEmpty()) continue;
InetAddress ia;
try {
ia = NetworkUtils.numericToInetAddress(addr);
@@ -174,6 +178,8 @@
dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
for (String dnsAddr : dnsServers) {
+ dnsAddr = dnsAddr.trim();
+ if (dnsAddr.isEmpty()) continue;
InetAddress ia;
try {
ia = NetworkUtils.numericToInetAddress(dnsAddr);
@@ -198,6 +204,8 @@
}
}
for (String addr : gateways) {
+ addr = addr.trim();
+ if (addr.isEmpty()) continue;
InetAddress ia;
try {
ia = NetworkUtils.numericToInetAddress(addr);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 7cd01a1..de09dfb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1848,8 +1848,14 @@
DataConnection dc = apnContext.getDataConnection();
if (DBG) {
- log(String.format("onDataSetupComplete: success apn=%s",
- apnContext.getWaitingApns().get(0).apn));
+ // TODO We may use apnContext.getApnSetting() directly
+ // instead of getWaitingApns().get(0)
+ String apnStr = "<unknown>";
+ if (apnContext.getWaitingApns() != null
+ && !apnContext.getWaitingApns().isEmpty()){
+ apnStr = apnContext.getWaitingApns().get(0).apn;
+ }
+ log("onDataSetupComplete: success apn=" + apnStr);
}
ApnSetting apn = apnContext.getApnSetting();
if (apn.proxy != null && apn.proxy.length() != 0) {
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index aadcaad..3ed9bd5 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -123,6 +123,8 @@
private final LruCache<String, ScanResult> mScanResultCache;
private String mInterfaceName;
+ /* Tethering interface could be seperate from wlan interface */
+ private String mTetherInterfaceName;
private int mLastSignalLevel = -1;
private String mLastBssid;
@@ -156,6 +158,14 @@
/* Tracks sequence number on stop failure message */
private int mSupplicantStopFailureToken = 0;
+ /**
+ * Tether state change notification time out
+ */
+ private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
+
+ /* Tracks sequence number on a tether notification time out */
+ private int mTetherToken = 0;
+
private LinkProperties mLinkProperties;
// Wakelock held during wifi start/stop and driver load/unload
@@ -240,10 +250,12 @@
static final int CMD_REQUEST_AP_CONFIG = BASE + 27;
/* Response to access point configuration request */
static final int CMD_RESPONSE_AP_CONFIG = BASE + 28;
- /* Set configuration on tether interface */
- static final int CMD_TETHER_INTERFACE = BASE + 29;
+ /* Invoked when getting a tether state change notification */
+ static final int CMD_TETHER_STATE_CHANGE = BASE + 29;
+ /* A delayed message sent to indicate tether state change failed to arrive */
+ static final int CMD_TETHER_NOTIFICATION_TIMED_OUT = BASE + 30;
- static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 30;
+ static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 31;
/* Supplicant commands */
/* Is supplicant alive ? */
@@ -455,12 +467,25 @@
private State mSoftApStartingState = new SoftApStartingState();
/* Soft ap is running */
private State mSoftApStartedState = new SoftApStartedState();
+ /* Soft ap is running and we are waiting for tether notification */
+ private State mTetheringState = new TetheringState();
/* Soft ap is running and we are tethered through connectivity service */
private State mTetheredState = new TetheredState();
+ /* Waiting for untether confirmation to stop soft Ap */
+ private State mSoftApStoppingState = new SoftApStoppingState();
/* Wait till p2p is disabled */
private State mWaitForP2pDisableState = new WaitForP2pDisableState();
+ private class TetherStateChange {
+ ArrayList<String> available;
+ ArrayList<String> active;
+ TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
+ available = av;
+ active = ac;
+ }
+ }
+
/**
* One of {@link WifiManager#WIFI_STATE_DISABLED},
@@ -562,7 +587,9 @@
public void onReceive(Context context, Intent intent) {
ArrayList<String> available = intent.getStringArrayListExtra(
ConnectivityManager.EXTRA_AVAILABLE_TETHER);
- sendMessage(CMD_TETHER_INTERFACE, available);
+ ArrayList<String> active = intent.getStringArrayListExtra(
+ ConnectivityManager.EXTRA_ACTIVE_TETHER);
+ sendMessage(CMD_TETHER_STATE_CHANGE, new TetherStateChange(available, active));
}
},new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
@@ -603,7 +630,9 @@
addState(mSupplicantStoppingState, mDefaultState);
addState(mSoftApStartingState, mDefaultState);
addState(mSoftApStartedState, mDefaultState);
+ addState(mTetheringState, mSoftApStartedState);
addState(mTetheredState, mSoftApStartedState);
+ addState(mSoftApStoppingState, mDefaultState);
addState(mWaitForP2pDisableState, mDefaultState);
setInitialState(mInitialState);
@@ -1139,6 +1168,7 @@
loge("Error tethering on " + intf);
return false;
}
+ mTetherInterfaceName = intf;
return true;
}
}
@@ -1165,11 +1195,27 @@
loge("Error resetting interface " + mInterfaceName + ", :" + e);
}
- if (mCm.untether(mInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
loge("Untether initiate failed!");
}
}
+ private boolean isWifiTethered(ArrayList<String> active) {
+
+ checkAndSetConnectivityInstance();
+
+ String[] wifiRegexs = mCm.getTetherableWifiRegexs();
+ for (String intf : active) {
+ for (String regex : wifiRegexs) {
+ if (intf.matches(regex)) {
+ return true;
+ }
+ }
+ }
+ // We found no interfaces that are tethered
+ return false;
+ }
+
/**
* Set the country code from the system setting value, if any.
*/
@@ -1800,7 +1846,8 @@
case CMD_START_AP_SUCCESS:
case CMD_START_AP_FAILURE:
case CMD_STOP_AP:
- case CMD_TETHER_INTERFACE:
+ case CMD_TETHER_STATE_CHANGE:
+ case CMD_TETHER_NOTIFICATION_TIMED_OUT:
case CMD_START_SCAN:
case CMD_DISCONNECT:
case CMD_RECONNECT:
@@ -3284,7 +3331,7 @@
case CMD_SET_FREQUENCY_BAND:
case CMD_START_PACKET_FILTERING:
case CMD_STOP_PACKET_FILTERING:
- case CMD_TETHER_INTERFACE:
+ case CMD_TETHER_STATE_CHANGE:
case WifiP2pService.P2P_ENABLE_PENDING:
deferMessage(message);
break;
@@ -3326,7 +3373,8 @@
case CMD_STOP_AP:
if (DBG) log("Stopping Soft AP");
setWifiApState(WIFI_AP_STATE_DISABLING);
- stopTethering();
+
+ /* We have not tethered at this point, so we just shutdown soft Ap */
try {
mNwService.stopAccessPoint(mInterfaceName);
} catch(Exception e) {
@@ -3342,10 +3390,10 @@
loge("Cannot start supplicant with a running soft AP");
setWifiState(WIFI_STATE_UNKNOWN);
break;
- case CMD_TETHER_INTERFACE:
- ArrayList<String> available = (ArrayList<String>) message.obj;
- if (startTethering(available)) {
- transitionTo(mTetheredState);
+ case CMD_TETHER_STATE_CHANGE:
+ TetherStateChange stateChange = (TetherStateChange) message.obj;
+ if (startTethering(stateChange.available)) {
+ transitionTo(mTetheringState);
}
break;
case WifiP2pService.P2P_ENABLE_PENDING:
@@ -3405,6 +3453,58 @@
}
}
+ class TetheringState extends State {
+ @Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+
+ /* Send ourselves a delayed message to shut down if tethering fails to notify */
+ sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
+ ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) log(getName() + message.toString() + "\n");
+ switch(message.what) {
+ case CMD_TETHER_STATE_CHANGE:
+ TetherStateChange stateChange = (TetherStateChange) message.obj;
+ if (isWifiTethered(stateChange.active)) {
+ transitionTo(mTetheredState);
+ }
+ return HANDLED;
+ case CMD_TETHER_NOTIFICATION_TIMED_OUT:
+ if (message.arg1 == mTetherToken) {
+ loge("Failed to get tether update, shutdown soft access point");
+ setWifiApEnabled(null, false);
+ }
+ break;
+ case CMD_LOAD_DRIVER:
+ case CMD_UNLOAD_DRIVER:
+ case CMD_START_SUPPLICANT:
+ case CMD_STOP_SUPPLICANT:
+ case CMD_START_AP:
+ case CMD_STOP_AP:
+ case CMD_START_DRIVER:
+ case CMD_STOP_DRIVER:
+ case CMD_SET_SCAN_MODE:
+ case CMD_SET_SCAN_TYPE:
+ case CMD_SET_HIGH_PERF_MODE:
+ case CMD_SET_COUNTRY_CODE:
+ case CMD_SET_FREQUENCY_BAND:
+ case CMD_START_PACKET_FILTERING:
+ case CMD_STOP_PACKET_FILTERING:
+ case WifiP2pService.P2P_ENABLE_PENDING:
+ deferMessage(message);
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+ return HANDLED;
+ }
+ }
+
class TetheredState extends State {
@Override
public void enter() {
@@ -3415,13 +3515,89 @@
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
- case CMD_TETHER_INTERFACE:
- // Ignore any duplicate interface available notifications
- // when in tethered state
+ case CMD_TETHER_STATE_CHANGE:
+ TetherStateChange stateChange = (TetherStateChange) message.obj;
+ if (!isWifiTethered(stateChange.active)) {
+ loge("Tethering reports wifi as untethered!, shut down soft Ap");
+ setWifiApEnabled(null, false);
+ }
return HANDLED;
+ case CMD_STOP_AP:
+ if (DBG) log("Untethering before stopping AP");
+ setWifiApState(WIFI_AP_STATE_DISABLING);
+ stopTethering();
+ transitionTo(mSoftApStoppingState);
+ break;
default:
return NOT_HANDLED;
}
+ EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+ return HANDLED;
+ }
+ }
+
+ class SoftApStoppingState extends State {
+ @Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+
+ /* Send ourselves a delayed message to shut down if tethering fails to notify */
+ sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
+ ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
+
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) log(getName() + message.toString() + "\n");
+ switch(message.what) {
+ case CMD_TETHER_STATE_CHANGE:
+ TetherStateChange stateChange = (TetherStateChange) message.obj;
+
+ /* Wait till wifi is untethered */
+ if (isWifiTethered(stateChange.active)) break;
+
+ try {
+ mNwService.stopAccessPoint(mInterfaceName);
+ } catch(Exception e) {
+ loge("Exception in stopAccessPoint()");
+ }
+ transitionTo(mDriverLoadedState);
+ break;
+ case CMD_TETHER_NOTIFICATION_TIMED_OUT:
+ if (message.arg1 == mTetherToken) {
+ loge("Failed to get tether update, force stop access point");
+ try {
+ mNwService.stopAccessPoint(mInterfaceName);
+ } catch(Exception e) {
+ loge("Exception in stopAccessPoint()");
+ }
+ transitionTo(mDriverLoadedState);
+ }
+ break;
+ case CMD_LOAD_DRIVER:
+ case CMD_UNLOAD_DRIVER:
+ case CMD_START_SUPPLICANT:
+ case CMD_STOP_SUPPLICANT:
+ case CMD_START_AP:
+ case CMD_STOP_AP:
+ case CMD_START_DRIVER:
+ case CMD_STOP_DRIVER:
+ case CMD_SET_SCAN_MODE:
+ case CMD_SET_SCAN_TYPE:
+ case CMD_SET_HIGH_PERF_MODE:
+ case CMD_SET_COUNTRY_CODE:
+ case CMD_SET_FREQUENCY_BAND:
+ case CMD_START_PACKET_FILTERING:
+ case CMD_STOP_PACKET_FILTERING:
+ case WifiP2pService.P2P_ENABLE_PENDING:
+ deferMessage(message);
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+ return HANDLED;
}
}