Merge "Show the keyguard if unsecure window on top. DO NOT MERGE." into klp-dev
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c63e586..cce6fc4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1778,7 +1778,7 @@
RemoteViews button = new RemoteViews(mContext.getPackageName(),
tombstone ? R.layout.notification_action_tombstone
: R.layout.notification_action);
- button.setTextViewCompoundDrawables(R.id.action0, action.icon, 0, 0, 0);
+ button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
button.setTextViewText(R.id.action0, action.title);
if (!tombstone) {
button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bc0d7e3..d779628 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -232,8 +232,6 @@
InputStage mFirstInputStage;
InputStage mFirstPostImeInputStage;
- boolean mFlipControllerFallbackKeys;
-
boolean mWindowAttributesChanged = false;
int mWindowAttributesChangesFlag = 0;
@@ -370,8 +368,6 @@
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
mFallbackEventHandler = PolicyManager.makeNewFallbackEventHandler(context);
mChoreographer = Choreographer.getInstance();
- mFlipControllerFallbackKeys =
- context.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mAttachInfo.mScreenOn = powerManager.isScreenOn();
@@ -2912,11 +2908,8 @@
mView.dispatchConfigurationChanged(config);
}
}
-
- mFlipControllerFallbackKeys =
- mContext.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
}
-
+
/**
* Return true if child is an ancestor of parent, (or equal to the parent).
*/
@@ -3985,7 +3978,6 @@
private final SyntheticJoystickHandler mJoystick = new SyntheticJoystickHandler();
private final SyntheticTouchNavigationHandler mTouchNavigation =
new SyntheticTouchNavigationHandler();
- private final SyntheticKeyHandler mKeys = new SyntheticKeyHandler();
public SyntheticInputStage() {
super(null);
@@ -4008,12 +4000,7 @@
mTouchNavigation.process(event);
return FINISH_HANDLED;
}
- } else if (q.mEvent instanceof KeyEvent) {
- if (mKeys.process((KeyEvent) q.mEvent)) {
- return FINISH_HANDLED;
- }
}
-
return FORWARD;
}
@@ -4843,63 +4830,6 @@
};
}
- final class SyntheticKeyHandler {
-
- public boolean process(KeyEvent event) {
- // In some locales (like Japan) controllers use B for confirm and A for back, rather
- // than vice versa, so we need to special case this here since the input system itself
- // is not locale-aware.
- int keyCode;
- switch(event.getKeyCode()) {
- case KeyEvent.KEYCODE_BUTTON_A:
- case KeyEvent.KEYCODE_BUTTON_C:
- case KeyEvent.KEYCODE_BUTTON_X:
- case KeyEvent.KEYCODE_BUTTON_Z:
- keyCode = mFlipControllerFallbackKeys ?
- KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_DPAD_CENTER;
- break;
- case KeyEvent.KEYCODE_BUTTON_B:
- case KeyEvent.KEYCODE_BUTTON_Y:
- keyCode = mFlipControllerFallbackKeys ?
- KeyEvent.KEYCODE_DPAD_CENTER : KeyEvent.KEYCODE_BACK;
- break;
- case KeyEvent.KEYCODE_BUTTON_THUMBL:
- case KeyEvent.KEYCODE_BUTTON_THUMBR:
- case KeyEvent.KEYCODE_BUTTON_START:
- case KeyEvent.KEYCODE_BUTTON_1:
- case KeyEvent.KEYCODE_BUTTON_2:
- case KeyEvent.KEYCODE_BUTTON_3:
- case KeyEvent.KEYCODE_BUTTON_4:
- case KeyEvent.KEYCODE_BUTTON_5:
- case KeyEvent.KEYCODE_BUTTON_6:
- case KeyEvent.KEYCODE_BUTTON_7:
- case KeyEvent.KEYCODE_BUTTON_8:
- case KeyEvent.KEYCODE_BUTTON_9:
- case KeyEvent.KEYCODE_BUTTON_10:
- case KeyEvent.KEYCODE_BUTTON_11:
- case KeyEvent.KEYCODE_BUTTON_12:
- case KeyEvent.KEYCODE_BUTTON_13:
- case KeyEvent.KEYCODE_BUTTON_14:
- case KeyEvent.KEYCODE_BUTTON_15:
- case KeyEvent.KEYCODE_BUTTON_16:
- keyCode = KeyEvent.KEYCODE_DPAD_CENTER;
- break;
- case KeyEvent.KEYCODE_BUTTON_SELECT:
- case KeyEvent.KEYCODE_BUTTON_MODE:
- keyCode = KeyEvent.KEYCODE_MENU;
- default:
- return false;
- }
-
- enqueueInputEvent(new KeyEvent(event.getDownTime(), event.getEventTime(),
- event.getAction(), keyCode, event.getRepeatCount(), event.getMetaState(),
- event.getDeviceId(), event.getScanCode(),
- event.getFlags() | KeyEvent.FLAG_FALLBACK, event.getSource()));
- return true;
- }
-
- }
-
/**
* Returns true if the key is used for keyboard navigation.
* @param keyEvent The key event.
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index f0e6677..52f9c0b 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -311,7 +311,6 @@
lp.type = LayoutParams.TYPE_VOLUME_OVERLAY;
lp.width = LayoutParams.WRAP_CONTENT;
lp.height = LayoutParams.WRAP_CONTENT;
- lp.privateFlags |= LayoutParams.PRIVATE_FLAG_FORCE_SHOW_NAV_BAR;
window.setAttributes(lp);
window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCH_MODAL
| LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 0ce4da5..53a4c0d0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1063,13 +1063,6 @@
public static final int PRIVATE_FLAG_SHOW_FOR_ALL_USERS = 0x00000010;
/**
- * Special flag for the volume overlay: force the window manager out of "hide nav bar"
- * mode while the window is on screen.
- *
- * {@hide} */
- public static final int PRIVATE_FLAG_FORCE_SHOW_NAV_BAR = 0x00000020;
-
- /**
* Never animate position changes of the window.
*
* {@hide} */
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 0957ab4..e90b460 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -1210,35 +1210,38 @@
child = (WeekView) view.getChildAt(offset);
}
- // Find out which month we're moving into
- int month;
- if (mIsScrollingUp) {
- month = child.getMonthOfFirstWeekDay();
- } else {
- month = child.getMonthOfLastWeekDay();
- }
-
- // And how it relates to our current highlighted month
- int monthDiff;
- if (mCurrentMonthDisplayed == 11 && month == 0) {
- monthDiff = 1;
- } else if (mCurrentMonthDisplayed == 0 && month == 11) {
- monthDiff = -1;
- } else {
- monthDiff = month - mCurrentMonthDisplayed;
- }
-
- // Only switch months if we're scrolling away from the currently
- // selected month
- if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
- Calendar firstDay = child.getFirstDay();
+ if (child != null) {
+ // Find out which month we're moving into
+ int month;
if (mIsScrollingUp) {
- firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+ month = child.getMonthOfFirstWeekDay();
} else {
- firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+ month = child.getMonthOfLastWeekDay();
}
- setMonthDisplayed(firstDay);
+
+ // And how it relates to our current highlighted month
+ int monthDiff;
+ if (mCurrentMonthDisplayed == 11 && month == 0) {
+ monthDiff = 1;
+ } else if (mCurrentMonthDisplayed == 0 && month == 11) {
+ monthDiff = -1;
+ } else {
+ monthDiff = month - mCurrentMonthDisplayed;
+ }
+
+ // Only switch months if we're scrolling away from the currently
+ // selected month
+ if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
+ Calendar firstDay = child.getFirstDay();
+ if (mIsScrollingUp) {
+ firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
+ } else {
+ firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+ }
+ setMonthDisplayed(firstDay);
+ }
}
+
mPreviousScrollPosition = currScroll;
mPreviousScrollState = mCurrentScrollState;
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 5392a96..6a369a6 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -308,6 +308,11 @@
mMirrorForRtl = a.getBoolean(R.styleable.ProgressBar_mirrorForRtl, mMirrorForRtl);
a.recycle();
+
+ // If not explicitly specified this view is important for accessibility.
+ if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+ setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ }
}
/**
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index b204dfd..1cda631 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -731,10 +731,14 @@
}
}
- if (scheduleOtherSpellCheck) {
+ if (scheduleOtherSpellCheck && wordStart <= end) {
// Update range span: start new spell check from last wordStart
setRangeSpan(editable, wordStart, end);
} else {
+ if (DBG && scheduleOtherSpellCheck) {
+ Log.w(TAG, "Trying to schedule spellcheck for invalid region, from "
+ + wordStart + " to " + end);
+ }
removeRangeSpan(editable);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 7a9809f..37121e2 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8667,6 +8667,10 @@
super.onRtlPropertiesChanged(layoutDirection);
mTextDir = getTextDirectionHeuristic();
+
+ if (mLayout != null) {
+ checkForRelayout();
+ }
}
TextDirectionHeuristic getTextDirectionHeuristic() {
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index 0cad33c..0aad0b5 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1004,7 +1004,7 @@
for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
ProcessState ps = pkgState.mProcesses.valueAt(iproc);
if (ps.isInUse() || ps.mCommonProcess.isInUse()) {
- pkgState.mProcesses.valueAt(iproc).resetSafely(now);
+ ps.resetSafely(now);
} else {
pkgState.mProcesses.valueAt(iproc).makeDead();
pkgState.mProcesses.removeAt(iproc);
@@ -1013,7 +1013,7 @@
for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
ServiceState ss = pkgState.mServices.valueAt(isvc);
if (ss.isInUse()) {
- pkgState.mServices.valueAt(isvc).resetSafely(now);
+ ss.resetSafely(now);
} else {
pkgState.mServices.removeAt(isvc);
}
@@ -3014,7 +3014,7 @@
}
public boolean isInUse() {
- return mOwner != null;
+ return mOwner != null || mRestarting;
}
void add(ServiceState other) {
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index ab871fb..942995b 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -372,23 +372,25 @@
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
mAppearingPackages = pkgList;
- mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ mChangeType = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
+ ? PACKAGE_UPDATING : PACKAGE_TEMPORARY_CHANGE;
mSomePackagesChanged = true;
if (pkgList != null) {
onPackagesAvailable(pkgList);
for (int i=0; i<pkgList.length; i++) {
- onPackageAppeared(pkgList[i], PACKAGE_TEMPORARY_CHANGE);
+ onPackageAppeared(pkgList[i], mChangeType);
}
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
mDisappearingPackages = pkgList;
- mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ mChangeType = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
+ ? PACKAGE_UPDATING : PACKAGE_TEMPORARY_CHANGE;
mSomePackagesChanged = true;
if (pkgList != null) {
onPackagesUnavailable(pkgList);
for (int i=0; i<pkgList.length; i++) {
- onPackageDisappeared(pkgList[i], PACKAGE_TEMPORARY_CHANGE);
+ onPackageDisappeared(pkgList[i], mChangeType);
}
}
}
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index eea9ee1..2125763 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -227,7 +227,7 @@
do {
*dst++ = SkUnPreMultiply::PMColorToColor(colors[*s++]);
} while (--width != 0);
- ctable->unlockColors(false);
+ ctable->unlockColors();
}
static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,
@@ -240,7 +240,7 @@
*dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),
SkGetPackedG32(c), SkGetPackedB32(c));
} while (--width != 0);
- ctable->unlockColors(false);
+ ctable->unlockColors();
}
static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,
@@ -253,7 +253,7 @@
*dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
SkGetPackedB32(c));
} while (--width != 0);
- ctable->unlockColors(false);
+ ctable->unlockColors();
}
// can return NULL
@@ -442,9 +442,15 @@
return !bitmap->isOpaque();
}
-static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap,
- jboolean hasAlpha) {
- bitmap->setIsOpaque(!hasAlpha);
+static void Bitmap_setAlphaAndPremultiplied(JNIEnv* env, jobject, SkBitmap* bitmap,
+ jboolean hasAlpha, jboolean isPremul) {
+ if (!hasAlpha) {
+ bitmap->setAlphaType(kOpaque_SkAlphaType);
+ } else if (isPremul) {
+ bitmap->setAlphaType(kPremul_SkAlphaType);
+ } else {
+ bitmap->setAlphaType(kUnpremul_SkAlphaType);
+ }
}
static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
@@ -543,14 +549,14 @@
p->writeInt32(bitmap->rowBytes());
p->writeInt32(density);
- if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {
+ if (bitmap->config() == SkBitmap::kIndex8_Config) {
SkColorTable* ctable = bitmap->getColorTable();
if (ctable != NULL) {
int count = ctable->count();
p->writeInt32(count);
memcpy(p->writeInplace(count * sizeof(SkPMColor)),
ctable->lockColors(), count * sizeof(SkPMColor));
- ctable->unlockColors(false);
+ ctable->unlockColors();
} else {
p->writeInt32(0); // indicate no ctable
}
@@ -770,7 +776,7 @@
{ "nativeRowBytes", "(I)I", (void*)Bitmap_rowBytes },
{ "nativeConfig", "(I)I", (void*)Bitmap_config },
{ "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha },
- { "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha },
+ { "nativeSetAlphaAndPremultiplied", "(IZZ)V", (void*)Bitmap_setAlphaAndPremultiplied},
{ "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap },
{ "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap },
{ "nativeCreateFromParcel",
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index da6219f..709de5c 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -21,6 +21,7 @@
#include <androidfw/Asset.h>
#include <androidfw/ResourceTypes.h>
#include <netinet/in.h>
+#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -124,12 +125,18 @@
static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStreamRewindable* stream,
int sampleSize, bool ditherImage) {
+ SkImageInfo bitmapInfo;
+ if (!bitmap->asImageInfo(&bitmapInfo)) {
+ ALOGW("bitmap has unknown configuration so no memory has been allocated");
+ return NULL;
+ }
+
SkImageRef* pr;
// only use ashmem for large images, since mmaps come at a price
if (bitmap->getSize() >= 32 * 1024) {
- pr = new SkImageRef_ashmem(stream, bitmap->config(), sampleSize);
+ pr = new SkImageRef_ashmem(bitmapInfo, stream, sampleSize);
} else {
- pr = new SkImageRef_GlobalPool(stream, bitmap->config(), sampleSize);
+ pr = new SkImageRef_GlobalPool(bitmapInfo, stream, sampleSize);
}
pr->setDitherImage(ditherImage);
bitmap->setPixelRef(pr)->unref();
@@ -157,7 +164,7 @@
virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
// accounts for scale in final allocation, using eventual size and config
const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
- configForScaledOutput(bitmap->getConfig()));
+ configForScaledOutput(bitmap->config()));
const int requestedSize = bytesPerPixel *
int(bitmap->width() * mScale + 0.5f) *
int(bitmap->height() * mScale + 0.5f);
@@ -191,8 +198,15 @@
return false;
}
+ SkImageInfo bitmapInfo;
+ if (!bitmap->asImageInfo(&bitmapInfo)) {
+ ALOGW("unable to reuse a bitmap as the target has an unknown bitmap configuration");
+ return false;
+ }
+
// Create a new pixelref with the new ctable that wraps the previous pixelref
- SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable);
+ SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef),
+ bitmapInfo, bitmap->rowBytes(), ctable);
bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
@@ -401,8 +415,11 @@
// TODO: avoid copying when scaled size equals decodingBitmap size
SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
- outputBitmap->setConfig(config, scaledWidth, scaledHeight);
- outputBitmap->setIsOpaque(decodingBitmap.isOpaque());
+ // FIXME: If the alphaType is kUnpremul and the image has alpha, the
+ // colors may not be correct, since Skia does not yet support drawing
+ // to/from unpremultiplied bitmaps.
+ outputBitmap->setConfig(config, scaledWidth, scaledHeight, 0,
+ decodingBitmap.alphaType());
if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
return nullObjectReturn("allocation failed for scaled bitmap");
}
@@ -414,7 +431,7 @@
}
SkPaint paint;
- paint.setFilterBitmap(true);
+ paint.setFilterLevel(SkPaint::kLow_FilterLevel);
SkCanvas canvas(*outputBitmap);
canvas.scale(sx, sy);
@@ -470,6 +487,12 @@
bitmapCreateFlags, ninePatchChunk, layoutBounds, -1);
}
+// Need to buffer enough input to be able to rewind as much as might be read by a decoder
+// trying to determine the stream's format. Currently the most is 64, read by
+// SkImageDecoder_libwebp.
+// FIXME: Get this number from SkImageDecoder
+#define BYTES_TO_BUFFER 64
+
static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
jobject padding, jobject options) {
@@ -477,11 +500,8 @@
SkAutoTUnref<SkStream> stream(CreateJavaInputStreamAdaptor(env, is, storage));
if (stream.get()) {
- // Need to buffer enough input to be able to rewind as much as might be read by a decoder
- // trying to determine the stream's format. Currently the most is 64, read by
- // SkImageDecoder_libwebp.
- // FIXME: Get this number from SkImageDecoder
- SkAutoTUnref<SkStreamRewindable> bufferedStream(SkFrontBufferedStream::Create(stream, 64));
+ SkAutoTUnref<SkStreamRewindable> bufferedStream(
+ SkFrontBufferedStream::Create(stream, BYTES_TO_BUFFER));
SkASSERT(bufferedStream.get() != NULL);
// for now we don't allow purgeable with java inputstreams
bitmap = doDecode(env, bufferedStream, padding, options, false, false);
@@ -502,27 +522,48 @@
return nullObjectReturn("fstat return -1");
}
- bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions);
- bool isShareable = optionsShareable(env, bitmapFactoryOptions);
- bool weOwnTheFD = false;
- if (isPurgeable && isShareable) {
- int newFD = ::dup(descriptor);
- if (-1 != newFD) {
- weOwnTheFD = true;
- descriptor = newFD;
+ // Restore the descriptor's offset on exiting this function.
+ AutoFDSeek autoRestore(descriptor);
+
+ FILE* file = fdopen(descriptor, "r");
+ if (file == NULL) {
+ return nullObjectReturn("Could not open file");
+ }
+
+ SkAutoTUnref<SkFILEStream> fileStream(new SkFILEStream(file,
+ SkFILEStream::kCallerRetains_Ownership));
+
+ SkAutoTUnref<SkStreamRewindable> stream;
+
+ // Retain the old behavior of allowing purgeable if both purgeable and
+ // shareable are set to true.
+ bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions)
+ && optionsShareable(env, bitmapFactoryOptions);
+ if (isPurgeable) {
+ // Copy the stream, so the image can be decoded multiple times without
+ // continuing to modify the original file descriptor.
+ // Copy beginning from the current position.
+ const size_t fileSize = fileStream->getLength() - fileStream->getPosition();
+ void* buffer = sk_malloc_flags(fileSize, 0);
+ if (buffer == NULL) {
+ return nullObjectReturn("Could not make a copy for ashmem");
}
+
+ SkAutoTUnref<SkData> data(SkData::NewFromMalloc(buffer, fileSize));
+
+ if (fileStream->read(buffer, fileSize) != fileSize) {
+ return nullObjectReturn("Could not read the file.");
+ }
+
+ stream.reset(new SkMemoryStream(data));
+ } else {
+ // Use a buffered stream. Although an SkFILEStream can be rewound, this
+ // ensures that SkImageDecoder::Factory never rewinds beyond the
+ // current position of the file descriptor.
+ stream.reset(SkFrontBufferedStream::Create(fileStream, BYTES_TO_BUFFER));
}
- SkAutoTUnref<SkData> data(SkData::NewFromFD(descriptor));
- if (data.get() == NULL) {
- return nullObjectReturn("NewFromFD failed in nativeDecodeFileDescriptor");
- }
- SkAutoTUnref<SkMemoryStream> stream(new SkMemoryStream(data));
-
- /* Allow purgeable iff we own the FD, i.e., in the puregeable and
- shareable case.
- */
- return doDecode(env, stream, padding, bitmapFactoryOptions, weOwnTheFD);
+ return doDecode(env, stream, padding, bitmapFactoryOptions, isPurgeable);
}
static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset,
@@ -541,7 +582,9 @@
} else {
// since we know we'll be done with the asset when we return, we can
// just use a simple wrapper
- stream = new AssetStreamAdaptor(asset);
+ stream = new AssetStreamAdaptor(asset,
+ AssetStreamAdaptor::kNo_OwnAsset,
+ AssetStreamAdaptor::kNo_HasMemoryBase);
}
SkAutoUnref aur(stream);
return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index ee47ac4..1412a0e 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -29,7 +29,6 @@
#include "CreateJavaOutputStreamAdaptor.h"
#include "Utils.h"
#include "JNIHelp.h"
-#include "SkTScopedPtr.h"
#include <android_runtime/AndroidRuntime.h>
#include "android_util_Binder.h"
@@ -76,7 +75,7 @@
int fHeight;
};
-static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) {
+static jobject createBitmapRegionDecoder(JNIEnv* env, SkStreamRewindable* stream) {
SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
int width, height;
if (NULL == decoder) {
@@ -108,7 +107,7 @@
For now we just always copy the array's data if isShareable.
*/
AutoJavaByteArray ar(env, byteArray);
- SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
+ SkStreamRewindable* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
jobject brd = createBitmapRegionDecoder(env, stream);
SkSafeUnref(stream); // the decoder now holds a reference
@@ -215,7 +214,7 @@
region.fRight = start_x + width;
region.fBottom = start_y + height;
SkBitmap* bitmap = NULL;
- SkTScopedPtr<SkBitmap> adb;
+ SkAutoTDelete<SkBitmap> adb;
if (tileBitmap != NULL) {
// Re-use bitmap.
@@ -246,7 +245,7 @@
}
// detach bitmap from its autodeleter, since we want to own it now
- adb.release();
+ adb.detach();
JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
jbyteArray buff = allocator->getStorageObjAndReset();
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 813dd5a..edf3b4a 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -476,7 +476,7 @@
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterBitmap(true);
+ filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
} else {
canvas->drawBitmap(*bitmap, left_, top_, paint);
@@ -491,7 +491,7 @@
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterBitmap(true);
+ filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
@@ -514,7 +514,7 @@
if (paint) {
filteredPaint = *paint;
}
- filteredPaint.setFilterBitmap(true);
+ filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
} else {
canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 8cb152d..3090ad2 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -346,6 +346,18 @@
///////////////////////////////////////////////////////////////////////////////////////////
+// Assert that bitmap's SkAlphaType is consistent with isPremultiplied.
+static void assert_premultiplied(const SkBitmap& bitmap, bool isPremultiplied) {
+ // kOpaque_SkAlphaType and kIgnore_SkAlphaType mean that isPremultiplied is
+ // irrelevant. This just tests to ensure that the SkAlphaType is not
+ // opposite of isPremultiplied.
+ if (isPremultiplied) {
+ SkASSERT(bitmap.alphaType() != kUnpremul_SkAlphaType);
+ } else {
+ SkASSERT(bitmap.alphaType() != kPremul_SkAlphaType);
+ }
+}
+
jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density)
{
@@ -354,6 +366,10 @@
bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
+ // The caller needs to have already set the alpha type properly, so the
+ // native SkBitmap stays in sync with the Java Bitmap.
+ assert_premultiplied(*bitmap, isPremultiplied);
+
jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), buffer,
bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
@@ -371,6 +387,10 @@
void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
bool isPremultiplied)
{
+ // The caller needs to have already set the alpha type properly, so the
+ // native SkBitmap stays in sync with the Java Bitmap.
+ assert_premultiplied(*bitmap, isPremultiplied);
+
env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
bitmap->width(), bitmap->height(), isPremultiplied);
}
@@ -413,8 +433,9 @@
///////////////////////////////////////////////////////////////////////////////
-AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
- SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)),
+AndroidPixelRef::AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage,
+ size_t rowBytes, jbyteArray storageObj, SkColorTable* ctable) :
+ SkMallocPixelRef(info, storage, rowBytes, ctable, (storageObj == NULL)),
fWrappedPixelRef(NULL) {
SkASSERT(storage);
SkASSERT(env);
@@ -429,13 +450,13 @@
// If storageObj is NULL, the memory was NOT allocated on the Java heap
fOnJavaHeap = (storageObj != NULL);
-
}
-AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) :
- SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false),
+AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+ size_t rowBytes, SkColorTable* ctable) :
+ SkMallocPixelRef(info, wrappedPixelRef.getAddr(), rowBytes, ctable, false),
fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
- wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
+ wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
{
SkASSERT(fWrappedPixelRef);
SkSafeRef(fWrappedPixelRef);
@@ -540,13 +561,21 @@
return NULL;
}
+ SkImageInfo bitmapInfo;
+ if (!bitmap->asImageInfo(&bitmapInfo)) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "unknown bitmap configuration");
+ return NULL;
+ }
+
size_t size = size64.get32();
jbyteArray arrayObj = env->NewByteArray(size);
if (arrayObj) {
// TODO: make this work without jniGetNonMovableArrayElements
jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj);
if (addr) {
- SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
+ SkPixelRef* pr = new AndroidPixelRef(env, bitmapInfo, (void*) addr,
+ bitmap->rowBytes(), arrayObj, ctable);
bitmap->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
// HeapAllocator behaves this way too
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index f4590b9..cb154aa 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -57,6 +57,7 @@
/** Create a java Bitmap object given the native bitmap (required) and optional
storage array (may be null).
+ bitmap's SkAlphaType must already be in sync with bitmapCreateFlags.
*/
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1);
@@ -64,6 +65,9 @@
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags,
jbyteArray ninepatch, int density = -1);
+ /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
+ sync with isPremultiplied
+ */
static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
bool isPremultiplied);
@@ -88,15 +92,16 @@
class AndroidPixelRef : public SkMallocPixelRef {
public:
- AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
- SkColorTable* ctable);
+ AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes,
+ jbyteArray storageObj, SkColorTable* ctable);
/**
* Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
* the same storage and java byte array refcounting, yet have a different
* color table.
*/
- AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable);
+ AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
+ size_t rowBytes, SkColorTable* ctable);
virtual ~AndroidPixelRef();
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index feb2dec..55be7c1 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -85,7 +85,9 @@
static jobject movie_decodeAsset(JNIEnv* env, jobject clazz, jint native_asset) {
android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
if (asset == NULL) return NULL;
- SkAutoTUnref<SkStreamRewindable> stream (new android::AssetStreamAdaptor(asset));
+ SkAutoTUnref<SkStreamRewindable> stream (new android::AssetStreamAdaptor(asset,
+ android::AssetStreamAdaptor::kNo_OwnAsset,
+ android::AssetStreamAdaptor::kNo_HasMemoryBase));
SkMovie* moov = SkMovie::DecodeStream(stream.get());
return create_jmovie(env, moov);
}
diff --git a/core/jni/android/graphics/NinePatchPeeker.cpp b/core/jni/android/graphics/NinePatchPeeker.cpp
index df996af..d3482da 100644
--- a/core/jni/android/graphics/NinePatchPeeker.cpp
+++ b/core/jni/android/graphics/NinePatchPeeker.cpp
@@ -40,15 +40,14 @@
// now update our host to force index or 32bit config
// 'cause we don't want 565 predithered, since as a 9patch, we know
// we will be stretched, and therefore we want to dither afterwards.
- static const SkBitmap::Config gNo565Pref[] = {
- SkBitmap::kIndex8_Config,
- SkBitmap::kIndex8_Config,
- SkBitmap::kARGB_8888_Config,
- SkBitmap::kARGB_8888_Config,
- SkBitmap::kARGB_8888_Config,
- SkBitmap::kARGB_8888_Config,
- };
- fHost->setPrefConfigTable(gNo565Pref);
+ SkImageDecoder::PrefConfigTable table;
+ table.fPrefFor_8Index_NoAlpha_src = SkBitmap::kIndex8_Config;
+ table.fPrefFor_8Index_YesAlpha_src = SkBitmap::kIndex8_Config;
+ table.fPrefFor_8Gray_src = SkBitmap::kARGB_8888_Config;
+ table.fPrefFor_8bpc_NoAlpha_src = SkBitmap::kARGB_8888_Config;
+ table.fPrefFor_8bpc_YesAlpha_src = SkBitmap::kARGB_8888_Config;
+
+ fHost->setPrefConfigTable(table);
} else if (strcmp("npLb", tag) == 0 && length == sizeof(int) * 4) {
fLayoutBounds = new int[4];
memcpy(fLayoutBounds, data, sizeof(int) * 4);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 40e0731..4f6cc37 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -148,7 +148,8 @@
static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
NPE_CHECK_RETURN_VOID(env, paint);
- GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
+ GraphicsJNI::getNativePaint(env, paint)->setFilterLevel(
+ filterBitmap ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
}
static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index ded2186..f0a7baf 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -177,7 +177,7 @@
SkRegion* region = new SkRegion;
size_t size = p->readInt32();
- region->readFromMemory(p->readInplace(size));
+ region->readFromMemory(p->readInplace(size), size);
return region;
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 92d253f..144ac39 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -20,6 +20,7 @@
#include "TextLayoutCache.h"
#include "TextLayout.h"
+#include "SkGlyphCache.h"
#include "SkTypeface_android.h"
#include "HarfBuzzNGFaceSkia.h"
#include <unicode/unistr.h>
@@ -757,8 +758,8 @@
outPos->add(ypos);
totalAdvance += xAdvance;
- // TODO: consider using glyph cache
- const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL);
+ SkAutoGlyphCache autoCache(mShapingPaint, NULL, NULL);
+ const SkGlyph& metrics = autoCache.getCache()->getGlyphIDMetrics(glyphId);
outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index ccd75d5..d10a960 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -4,6 +4,7 @@
#include "GraphicsJNI.h"
#include "SkStream.h"
#include "SkTypeface.h"
+#include "Utils.h"
#include <android_runtime/android_util_AssetManager.h>
#include <androidfw/AssetManager.h>
@@ -73,65 +74,6 @@
return face->style();
}
-class AssetStream : public SkStream {
-public:
- AssetStream(Asset* asset, bool hasMemoryBase) : fAsset(asset)
- {
- fMemoryBase = hasMemoryBase ? fAsset->getBuffer(false) : NULL;
- }
-
- virtual ~AssetStream()
- {
- delete fAsset;
- }
-
- virtual const void* getMemoryBase()
- {
- return fMemoryBase;
- }
-
- virtual bool rewind()
- {
- off64_t pos = fAsset->seek(0, SEEK_SET);
- return pos != (off64_t)-1;
- }
-
- virtual size_t read(void* buffer, size_t size)
- {
- ssize_t amount;
-
- if (NULL == buffer)
- {
- if (0 == size) // caller is asking us for our total length
- return fAsset->getLength();
-
- // asset->seek returns new total offset
- // we want to return amount that was skipped
-
- off64_t oldOffset = fAsset->seek(0, SEEK_CUR);
- if (-1 == oldOffset)
- return 0;
- off64_t newOffset = fAsset->seek(size, SEEK_CUR);
- if (-1 == newOffset)
- return 0;
-
- amount = newOffset - oldOffset;
- }
- else
- {
- amount = fAsset->read(buffer, size);
- }
-
- if (amount < 0)
- amount = 0;
- return amount;
- }
-
-private:
- Asset* fAsset;
- const void* fMemoryBase;
-};
-
static SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject,
jobject jassetMgr,
jstring jpath) {
@@ -150,7 +92,9 @@
return NULL;
}
- SkStream* stream = new AssetStream(asset, true);
+ SkStream* stream = new AssetStreamAdaptor(asset,
+ AssetStreamAdaptor::kYes_OwnAsset,
+ AssetStreamAdaptor::kYes_HasMemoryBase);
SkTypeface* face = SkTypeface::CreateFromStream(stream);
// SkTypeFace::CreateFromStream calls ref() on the stream, so we
// need to unref it here or it won't be freed later on
diff --git a/core/jni/android/graphics/Utils.cpp b/core/jni/android/graphics/Utils.cpp
index b7d1f3a..eb416cb 100644
--- a/core/jni/android/graphics/Utils.cpp
+++ b/core/jni/android/graphics/Utils.cpp
@@ -19,6 +19,21 @@
using namespace android;
+AssetStreamAdaptor::AssetStreamAdaptor(Asset* asset, OwnAsset ownAsset,
+ HasMemoryBase hasMemoryBase)
+ : fAsset(asset)
+ , fMemoryBase(kYes_HasMemoryBase == hasMemoryBase ?
+ asset->getBuffer(false) : NULL)
+ , fOwnAsset(ownAsset)
+{
+}
+
+AssetStreamAdaptor::~AssetStreamAdaptor() {
+ if (kYes_OwnAsset == fOwnAsset) {
+ delete fAsset;
+ }
+}
+
bool AssetStreamAdaptor::rewind() {
off64_t pos = fAsset->seek(0, SEEK_SET);
if (pos == (off64_t)-1) {
diff --git a/core/jni/android/graphics/Utils.h b/core/jni/android/graphics/Utils.h
index a1ac72a..b90593c 100644
--- a/core/jni/android/graphics/Utils.h
+++ b/core/jni/android/graphics/Utils.h
@@ -28,16 +28,36 @@
class AssetStreamAdaptor : public SkStreamRewindable {
public:
- AssetStreamAdaptor(Asset* a) : fAsset(a) {}
+ // Enum passed to constructor. If set to kYes_OwnAsset,
+ // the passed in Asset will be deleted upon destruction.
+ enum OwnAsset {
+ kYes_OwnAsset,
+ kNo_OwnAsset,
+ };
+
+ // Enum passed to constructor. If set to kYes_HasMemoryBase,
+ // getMemoryBase will return the Asset's buffer.
+ enum HasMemoryBase {
+ kYes_HasMemoryBase,
+ kNo_HasMemoryBase,
+ };
+
+ AssetStreamAdaptor(Asset*, OwnAsset, HasMemoryBase);
+ ~AssetStreamAdaptor();
+
virtual bool rewind();
virtual size_t read(void* buffer, size_t size);
virtual bool hasLength() const { return true; }
virtual size_t getLength() const;
virtual bool isAtEnd() const;
+ virtual const void* getMemoryBase() { return fMemoryBase; }
+
virtual SkStreamRewindable* duplicate() const;
private:
- Asset* fAsset;
+ Asset* fAsset;
+ const void* const fMemoryBase;
+ const OwnAsset fOwnAsset;
};
/**
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 44af199..4bb091d 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -632,7 +632,7 @@
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
return getInternalFormat(config);
}
@@ -642,7 +642,7 @@
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
return getType(config);
}
@@ -653,7 +653,7 @@
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
if (internalformat < 0) {
internalformat = getInternalFormat(config);
}
@@ -681,7 +681,7 @@
SkColorTable* ctable = bitmap.getColorTable();
memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
memcpy(pixels, p, size);
- ctable->unlockColors(false);
+ ctable->unlockColors();
glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
free(data);
} else {
@@ -702,7 +702,7 @@
SkBitmap const * nativeBitmap =
(SkBitmap const *)env->GetIntField(jbitmap, nativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
- SkBitmap::Config config = bitmap.getConfig();
+ SkBitmap::Config config = bitmap.config();
if (format < 0) {
format = getInternalFormat(config);
if (format == GL_PALETTE8_RGBA8_OES)
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 1fe4b08..5b0a4b2 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -630,7 +630,7 @@
if (producer == NULL)
goto not_valid_surface;
- window = new android::Surface(producer);
+ window = new android::Surface(producer, true);
if (window == NULL)
goto not_valid_surface;
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 1868469..dd178d8 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -39,6 +39,7 @@
#include <SkCanvas.h>
#include <SkBitmap.h>
+#include <SkImage.h>
#include <SkRegion.h>
#include <utils/misc.h>
@@ -178,7 +179,8 @@
static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
/* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
we can map to SkBitmap::kARGB_8888_Config, and optionally call
- bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
+ bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap
+ (as an accelerator)
*/
switch (format) {
case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
@@ -234,7 +236,7 @@
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr);
if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
- bitmap.setIsOpaque(true);
+ bitmap.setAlphaType(kOpaque_SkAlphaType);
}
if (outBuffer.width > 0 && outBuffer.height > 0) {
bitmap.setPixels(outBuffer.bits);
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 67eade8..b8d3c20 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -61,51 +61,21 @@
class ScreenshotPixelRef : public SkPixelRef {
public:
- ScreenshotPixelRef(SkColorTable* ctable) {
- fCTable = ctable;
- SkSafeRef(ctable);
+ ScreenshotPixelRef(const SkImageInfo& info, ScreenshotClient* screenshot) :
+ SkPixelRef(info),
+ mScreenshot(screenshot) {
setImmutable();
}
virtual ~ScreenshotPixelRef() {
- SkSafeUnref(fCTable);
- }
-
- status_t update(const sp<IBinder>& display, int width, int height,
- int minLayer, int maxLayer, bool allLayers) {
- status_t res = (width > 0 && height > 0)
- ? (allLayers
- ? mScreenshot.update(display, width, height)
- : mScreenshot.update(display, width, height, minLayer, maxLayer))
- : mScreenshot.update(display);
- if (res != NO_ERROR) {
- return res;
- }
-
- return NO_ERROR;
- }
-
- uint32_t getWidth() const {
- return mScreenshot.getWidth();
- }
-
- uint32_t getHeight() const {
- return mScreenshot.getHeight();
- }
-
- uint32_t getStride() const {
- return mScreenshot.getStride();
- }
-
- uint32_t getFormat() const {
- return mScreenshot.getFormat();
+ delete mScreenshot;
}
protected:
// overrides from SkPixelRef
virtual void* onLockPixels(SkColorTable** ct) {
- *ct = fCTable;
- return (void*)mScreenshot.getPixels();
+ *ct = NULL;
+ return (void*)mScreenshot->getPixels();
}
virtual void onUnlockPixels() {
@@ -113,8 +83,7 @@
SK_DECLARE_UNFLATTENABLE_OBJECT()
private:
- ScreenshotClient mScreenshot;
- SkColorTable* fCTable;
+ ScreenshotClient* mScreenshot;
typedef SkPixelRef INHERITED;
};
@@ -147,19 +116,6 @@
ctrl->decStrong((void *)nativeCreate);
}
-static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
- /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
- we can map to SkBitmap::kARGB_8888_Config, and optionally call
- bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
- */
- switch (format) {
- case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
- case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config;
- case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config;
- default: return SkBitmap::kNo_Config;
- }
-}
-
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
@@ -167,26 +123,50 @@
return NULL;
}
- ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
- if (pixels->update(displayToken, width, height,
- minLayer, maxLayer, allLayers) != NO_ERROR) {
- delete pixels;
+ ScreenshotClient* screenshot = new ScreenshotClient();
+ status_t res = (width > 0 && height > 0)
+ ? (allLayers
+ ? screenshot->update(displayToken, width, height)
+ : screenshot->update(displayToken, width, height, minLayer, maxLayer))
+ : screenshot->update(displayToken);
+ if (res != NO_ERROR) {
+ delete screenshot;
return NULL;
}
- uint32_t w = pixels->getWidth();
- uint32_t h = pixels->getHeight();
- uint32_t s = pixels->getStride();
- uint32_t f = pixels->getFormat();
- ssize_t bpr = s * android::bytesPerPixel(f);
+ SkImageInfo screenshotInfo;
+ screenshotInfo.fWidth = screenshot->getWidth();
+ screenshotInfo.fHeight = screenshot->getHeight();
- SkBitmap* bitmap = new SkBitmap();
- bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
- if (f == PIXEL_FORMAT_RGBX_8888) {
- bitmap->setIsOpaque(true);
+ switch (screenshot->getFormat()) {
+ case PIXEL_FORMAT_RGBX_8888: {
+ screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+ screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+ break;
+ }
+ case PIXEL_FORMAT_RGBA_8888: {
+ screenshotInfo.fColorType = kRGBA_8888_SkColorType;
+ screenshotInfo.fAlphaType = kPremul_SkAlphaType;
+ break;
+ }
+ case PIXEL_FORMAT_RGB_565: {
+ screenshotInfo.fColorType = kRGB_565_SkColorType;
+ screenshotInfo.fAlphaType = kIgnore_SkAlphaType;
+ break;
+ }
+ default: {
+ delete screenshot;
+ return NULL;
+ }
}
- if (w > 0 && h > 0) {
+ // takes ownership of ScreenshotClient
+ ScreenshotPixelRef* pixels = new ScreenshotPixelRef(screenshotInfo, screenshot);
+ ssize_t rowBytes = screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
+
+ SkBitmap* bitmap = new SkBitmap();
+ bitmap->setConfig(screenshotInfo, rowBytes);
+ if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
bitmap->setPixelRef(pixels)->unref();
bitmap->lockPixels();
} else {
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 0f429005..7a4a20a 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -27,6 +27,7 @@
#include <SkBitmap.h>
#include <SkCanvas.h>
+#include <SkImage.h>
namespace android {
@@ -156,7 +157,7 @@
bitmap.setConfig(convertPixelFormat(buffer.format), buffer.width, buffer.height, bytesCount);
if (buffer.format == WINDOW_FORMAT_RGBX_8888) {
- bitmap.setIsOpaque(true);
+ bitmap.setAlphaType(kOpaque_SkAlphaType);
}
if (buffer.width > 0 && buffer.height > 0) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 69783bb..daff390 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1056,8 +1056,9 @@
android:permissionGroupFlags="personalInfo"
android:priority="370" />
- <!-- Allows an application to monitor, modify, or abort outgoing
- calls. -->
+ <!-- Allows an application to see the number being dialed during an outgoing
+ call with the option to redirect the call to a different number or
+ abort the call altogether. -->
<permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
android:permissionGroup="android.permission-group.PHONE_CALLS"
android:protectionLevel="dangerous"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0358de3..dde6da0 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Tuis"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Werk"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Ander"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Geen program gekry om hierdie kontak te bekyk nie."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Voer PIN-kode in"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Voer PUK en nuwe PIN-kode in"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index b649f5d..980465d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -46,7 +46,7 @@
<string name="badPin" msgid="9015277645546710014">"የተየበከው የድሮ ፒን ትክክል አይደለም።"</string>
<string name="badPuk" msgid="5487257647081132201">"የተየብከው PUK ትክክል አይደለም።"</string>
<string name="mismatchPin" msgid="609379054496863419">"ያስገባሃቸው ፒኖች አይዛመዱም"</string>
- <string name="invalidPin" msgid="3850018445187475377">"ከ4 እስከ 8 ቁጥሮች የያዘ PIN ተይብ"</string>
+ <string name="invalidPin" msgid="3850018445187475377">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን ተይብ"</string>
<string name="invalidPuk" msgid="8761456210898036513">"8 ወይም ከዛ በላይ የሆኑ ቁጥሮችንPUK ተይብ።"</string>
<string name="needPuk" msgid="919668385956251611">"SIM ካርድዎ PUK-የተቆለፈ ነው።የPUK ኮዱን በመተየብ ይክፈቱት።"</string>
<string name="needPuk2" msgid="4526033371987193070">" SIM ለመክፈት PUK2 ተይብ።"</string>
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"መነሻ"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"ስራ"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"ሌላ"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"ምንም መተግበሪያ ይህንን እውቂያ ለመመልከት አልተገኘም።"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ፒን ኮድ ተይብ"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK እና አዲስ ፒን ተይብ"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"የPUK ኮድ"</string>
@@ -823,7 +824,7 @@
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"የይለፍ ቃል ለመተየብ ንካ"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ለመክፈት የይለፍ ቃል ተይብ"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ለመክፈት ፒን ተይብ"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ PIN ኮድ።"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ ፒን ኮድ።"</string>
<string name="keyguard_label_text" msgid="861796461028298424">"ለመክፈት፣ምናሌ ተጫን ከዛ 0"</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"የአደጋ ጊዜቁጥር"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"ከአገልግሎት መስጫ ክልል ውጪ"</string>
@@ -985,8 +986,8 @@
<string name="searchview_description_submit" msgid="2688450133297983542">"ጥያቄ አስረክብ"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"የድምፅ ፍለጋ"</string>
<string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"በመንካት አስስ ይንቃ?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከጡባዊ ተኮው ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከስልኩ ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከጡባዊ ተኮው ጋር ለመግባባት ምን በጣትዎ ስር ወይም ምልክቶችን ማከናወን እንዳለብዎ ማብራሪያ ሊመለከቱ ወይም ሊሰሙ ይችላሉ።"</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከስልኩ ጋር ለመግባባት ምን በጣትዎ ስር ወይም ምልክቶችን ማከናወን እንዳለብዎ ማብራሪያ ሊመለከቱ ወይም ሊሰሙ ይችላሉ።"</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"ከ1 ወር በፊት"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"ከ1 ወር በፊት"</string>
<plurals name="num_seconds_ago">
@@ -1232,7 +1233,7 @@
<string name="time_picker_dialog_title" msgid="8349362623068819295">"ጊዜ አዘጋጅ"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"ውሂብ አዘጋጅ"</string>
<string name="date_time_set" msgid="5777075614321087758">"አዘጋጅ"</string>
- <string name="date_time_done" msgid="2507683751759308828">"ተጠናቋል"</string>
+ <string name="date_time_done" msgid="2507683751759308828">"ተከናውኗል"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"አዲስ፦ "</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"በ<xliff:g id="APP_NAME">%1$s</xliff:g> የቀረበ።"</string>
<string name="no_permissions" msgid="7283357728219338112">"ምንም ፍቃዶች አይጠየቁም"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 18296ea..2055c93 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"المنزل"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"العمل"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"غير ذلك"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"لم يتم العثور على تطبيق لعرض جهة الاتصال هذه."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"اكتب رمز رمز PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"اكتب رمز PUK ورمز رمز PIN الجديد"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"رمز PUK"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 0d1cdaf..0672cdf 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Домашен"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Служебен"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Друг"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Няма намерено приложение, с което да се отвори този контакт."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Въведете ПИН кода"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Въведете PUK и новия ПИН код"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK код"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index cf81367..b6c4762 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -675,8 +675,8 @@
<string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permet que l\'aplicació modifiqui les marques de sòcols per a l\'encaminament"</string>
<string name="permlab_accessNotifications" msgid="7673416487873432268">"accedeix a les notificacions"</string>
<string name="permdesc_accessNotifications" msgid="458457742683431387">"Permet que l\'aplicació recuperi, examini i esborri les notificacions, incloses les que han publicat altres aplicacions."</string>
- <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincula a un servei de processament de notificacions"</string>
- <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet que el titular vinculi la interfície de nivell superior d\'un servei de processament de notificacions. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+ <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincula a un servei oient de notificacions"</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet que el titular vinculi la interfície de nivell superior d\'un servei oient de notificacions. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoca l\'aplicació de configuració proporcionada per l\'operador"</string>
<string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet que el titular invoqui l\'aplicació de configuració proporcionada per l\'operador. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"conèixer les observacions sobre les condicions de la xarxa"</string>
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Feina"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Altres"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"No hem trobat cap aplicació per mostrar aquest contacte."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introdueix el codi PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introdueix el codi PUK i el codi PIN nou"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codi PUK"</string>
@@ -1335,7 +1336,7 @@
<string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilitat"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Fons de pantalla"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Canvia el fons de pantalla"</string>
- <string name="notification_listener_binding_label" msgid="2014162835481906429">"Processador de notificacions"</string>
+ <string name="notification_listener_binding_label" msgid="2014162835481906429">"Oient de notificacions"</string>
<string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
<string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ha activat VPN"</string>
<string name="vpn_text" msgid="3011306607126450322">"Toca per gestionar la xarxa."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 14d6dd5..da0dff4 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Domů"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Práce"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Jiné"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nebyla nalezena žádná aplikace, pomocí které by tento kontakt bylo možné zobrazit."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Zadejte kód PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Zadejte kód PUK a nový kód PIN."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kód PUK"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 1d394a8..27e1cfb 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Hjem"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbejde"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Andet"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Der blev ikke fundet nogen applikation, som kan vise denne kontaktperson."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Indtast pinkode"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Indtast PUK- og pinkode"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index dcd7671..d95bdca 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Privat"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Geschäftlich"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Sonstige"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Es wurde keine App zum Anzeigen dieses Kontakts gefunden."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN-Code eingeben"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK und neuen PIN-Code eingeben"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-Code"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ee98ceb..482a9fa 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Αρχική σελίδα"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Εργασία"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Άλλο"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Δεν βρέθηκε καμία εφαρμογή για την προβολή αυτής της επαφής."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Πληκτρολογήστε τον κωδικό αριθμό PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Πληκτρολογήστε τον κωδικό PUK και τον νέο κωδικό PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Κωδικός PUK"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d2c53cc..a66eeda 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"No application found to view this contact."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index d2c53cc..a66eeda 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"No application found to view this contact."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 114f6f5..c7df6e6 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabajo"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Otro"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"No se encontró ninguna aplicación para ver este contacto."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ingresa el código PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Escribe el código PUK y un nuevo código PIN."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f758989..95a623b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabajo"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Otro"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"No se ha encontrado ninguna aplicación para ver este contacto."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introduce el código PIN."</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introduce el código PUK y un nuevo código PIN."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 39523ef..1d24dea 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Kodu"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Töö"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Muu"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Selle kontakti kuvamiseks ei leitud ühtegi rakendust."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Sisestage PIN-kood"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Sisestage PUK-kood ja uus PIN-kood"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kood"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 14836c2..18cc89d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"صفحهٔ اصلی"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"محل کار"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"سایر موارد"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"هیچ برنامهای برای مشاهده این مخاطب پیدا نشد."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"پین کد را وارد کنید"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK و پین کد جدید را تایپ کنید"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"کد PUK"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index e4d4e3e..06e4fdd 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Koti"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Työ"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Muu"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Tämän kontaktin katselemiseen ei löydy sovellusta."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Anna PIN-koodi"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Anna PUK-koodi ja uusi PIN-koodi"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-koodi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2821897..b1a3f98 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Domicile"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Travail"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Autre"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Aucune application permettant d\'afficher ce contact n\'a été trouvée."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Saisissez le NIP."</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Saisissez la clé PUK et le nouveau NIP."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Clé PUK"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9944754..434b99b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Domicile"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Professionnelle"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Autre"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Aucune application permettant d\'afficher ce contact n\'a été trouvée."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Saisissez le code PIN."</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Saisissez la clé PUK et le nouveau code PIN."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Code PUK"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2650108..925ee36 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"घर"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"कार्यालय"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"अन्य"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"इस संपर्क को देखने के लिए कोई एप्लिकेशन नहीं मिला."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"पिन कोड लिखें"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK और नया पिन कोड लिखें"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 829c03d..8e06edd 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -627,7 +627,7 @@
<string name="permlab_bluetooth" msgid="6127769336339276828">"uparivanje s Bluetooth uređajima"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na tabletnom računalu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na telefonu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
- <string name="permlab_nfc" msgid="4423351274757876953">"upravljaj beskontaktnom (NFC) komunikacijom"</string>
+ <string name="permlab_nfc" msgid="4423351274757876953">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Aplikaciji omogućuje komunikaciju s oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja zaslona"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji omogućuje onemogućavanje zaključavanja tipkovnice i svih pripadajućih sigurnosnih zaporki. Na primjer, telefon onemogućuje zaključavanje tipkovnice kod primanja dolaznog telefonskog poziva, nakon kojeg se zaključavanje tipkovnice ponovo omogućuje."</string>
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Početna"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Posao"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Drugo"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nema aplikacije za prikazivanje tog kontakta."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Unesite PIN kôd"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Unesite PUK i novi PIN kôd"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kôd"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 5ed894e..005dcbe 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Otthoni"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Munkahely"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Egyéb"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nem található alkalmazás a névjegy megtekintéshez."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Írja be a PIN kódot"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Írja be a PUK kódot, majd az új PIN kódot"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kód"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 85eedba..5789e5f 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Տնային"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Աշխատանքային"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Այլ"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Այս կոնտակտը դիտելու համար համապատասխան ծրագիր չկա:"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Մուտքագրեք PIN կոդը"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Մուտքագրեք PUK-ը և նոր PIN կոդը"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK կոդ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 633621a..7acc02b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Beranda"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerjaan"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Lainnya"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Tidak ada aplikasi yang ditemukan untuk melihat kontak ini."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ketik kode PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ketik kode PUK dan PIN baru"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kode PUK"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 6bae95b..fdee440 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Lavoro"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Altro"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nessuna applicazione trovata per la visualizzazione di questo contatto."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Inserisci il codice PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Inserisci il PUK e il nuovo codice PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codice PUK"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 3d82fef..b3f5439 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"דף הבית"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"עבודה"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"אחר"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"לא נמצאה אפליקציה להצגת התוכן הזה."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"הקלד קוד PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"הקלד את קוד ה-PUK וקוד ה-PIN החדש"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"קוד PUK"</string>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/values-ja/bools.xml
deleted file mode 100644
index 59cf744..0000000
--- a/core/res/res/values-ja/bools.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <bool name="flip_controller_fallback_keys">true</bool>
-</resources>
-
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 559d53f..b7ccb6a 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"自宅"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"勤務先"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"その他"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"この連絡先を表示するアプリが見つかりません。"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PINコードを入力"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUKと新しいPINコードを入力"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUKコード"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 7f4dc90..ea36ab0 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"სახლი"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"სამსახური"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"სხვა"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"ამ კონტაქტის მნახველი აპლიკაცია ვერ მოიძებნა."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"აკრიფეთ PIN კოდი"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"დაბეჭდეთ PUK კოდი და ახალი PIN კოდი."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK კოდი"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index f03b5ed..f12b003 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"គេហទំព័រ"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"កន្លែងធ្វើការ"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"ផ្សេងៗ"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"រកមិនឃើញកម្មវិធី ដើម្បីមើលទំនាក់ទំនងនេះទេ។"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"បញ្ចូលកូដ PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"បញ្ចូលកូដ PUK និង PIN ថ្មី"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"កូដ PUK"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index cbfb1db..18c15a9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"집"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"직장"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"기타"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"이 주소록을 표시할 수 있는 애플리케이션이 없습니다."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN 코드 입력"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK 및 새 PIN 코드 입력"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 코드"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 8d88dfee9f..cd0d471 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"ເຮືອນ"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"ບ່ອນເຮັດວຽກ"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"ອື່ນໆ"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"ບໍ່ພົບແອັບຯທີ່ຕິດຕໍ່ນີ້."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ພິມລະຫັດ PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"ພິມລະຫັດ PUK ແລະລະຫັດ PIN ອັນໃໝ່"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"ລະຫັດ PUK"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 614bcd6..d11051f 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Pagrindinis"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Darbas"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Kita"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nerasta jokių programų šiam kontaktui peržiūrėti."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Įveskite PIN kodą"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Įveskite PUK ir naują PIN kodus"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kodas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9f3cb53..022917a 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Mājās"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Darbs"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Cits"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Netika atrasta neviena lietojumprogramma, ar kuru skatīt šo kontaktpersonu."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ievadiet PIN kodu."</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ievadiet PUK kodu un jaunu PIN kodu."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kods"</string>
diff --git a/core/res/res/values-mcc302-mnc500/config.xml b/core/res/res/values-mcc302-mnc500/config.xml
deleted file mode 100644
index 706570c..0000000
--- a/core/res/res/values-mcc302-mnc500/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Don't use roaming icon for considered operators -->
- <string-array translatable="false" name="config_operatorConsideredNonRoaming">
- <item>302</item>
- </string-array>
-</resources>
diff --git a/core/res/res/values-mcc302-mnc510/config.xml b/core/res/res/values-mcc302-mnc510/config.xml
deleted file mode 100644
index 706570c..0000000
--- a/core/res/res/values-mcc302-mnc510/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Don't use roaming icon for considered operators -->
- <string-array translatable="false" name="config_operatorConsideredNonRoaming">
- <item>302</item>
- </string-array>
-</resources>
diff --git a/core/res/res/values-mcc404-mnc17/config.xml b/core/res/res/values-mcc404-mnc17/config.xml
deleted file mode 100644
index 685d012..0000000
--- a/core/res/res/values-mcc404-mnc17/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Show roaming icon though same named operators. -->
- <string-array translatable="false" name="config_sameNamedOperatorConsideredRoaming">
- <item>40491</item>
- </string-array>
-</resources>
diff --git a/core/res/res/values-mcc404-mnc85/config.xml b/core/res/res/values-mcc404/config.xml
similarity index 94%
copy from core/res/res/values-mcc404-mnc85/config.xml
copy to core/res/res/values-mcc404/config.xml
index fd780ab..a106b0a 100644
--- a/core/res/res/values-mcc404-mnc85/config.xml
+++ b/core/res/res/values-mcc404/config.xml
@@ -20,6 +20,7 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Show roaming icon though same named operators. -->
<string-array translatable="false" name="config_sameNamedOperatorConsideredRoaming">
- <item>40483</item>
+ <item>404</item>
+ <item>405</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc404-mnc85/config.xml b/core/res/res/values-mcc405/config.xml
similarity index 94%
copy from core/res/res/values-mcc404-mnc85/config.xml
copy to core/res/res/values-mcc405/config.xml
index fd780ab..a106b0a 100644
--- a/core/res/res/values-mcc404-mnc85/config.xml
+++ b/core/res/res/values-mcc405/config.xml
@@ -20,6 +20,7 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Show roaming icon though same named operators. -->
<string-array translatable="false" name="config_sameNamedOperatorConsideredRoaming">
- <item>40483</item>
+ <item>404</item>
+ <item>405</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc404-mnc85/config.xml b/core/res/res/values-mcc520/config.xml
similarity index 96%
rename from core/res/res/values-mcc404-mnc85/config.xml
rename to core/res/res/values-mcc520/config.xml
index fd780ab..b2f3efa 100644
--- a/core/res/res/values-mcc404-mnc85/config.xml
+++ b/core/res/res/values-mcc520/config.xml
@@ -20,6 +20,6 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Show roaming icon though same named operators. -->
<string-array translatable="false" name="config_sameNamedOperatorConsideredRoaming">
- <item>40483</item>
+ <item>520</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 252a959..c58184d 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Гэрийн"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Ажлын"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Бусад"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Энэ харилцагчийг харах аппликешн олдсонгүй."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN кодыг бичнэ үү"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK-г бичээд шинэ PIN код оруулна уу"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK код"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 284837a..2f5769e 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Rumah"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerja"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Lain-lain"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Tiada aplikasi ditemui untuk melihat kenalan ini."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Taip kod PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Taip PUK dan kod PIN baharu"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 122bf1a..ff17815 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Hjem"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbeid"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Annen"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Du har ingen apper som kan åpne denne kontakten."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Skriv inn PIN-kode"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Skriv inn PUK-kode og ny personlig kode"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ba5ac11..27d6836 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Startpagina"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Werk"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Overig"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Er is geen app gevonden om dit contact te bekijken."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Pincode typen"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Geef de PUK-code en de nieuwe pincode op"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-code"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7e9a8c4..b8c20f5 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Domowy"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Służbowy"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Inny"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Brak aplikacji do wyświetlenia tego kontaktu."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Wpisz kod PIN."</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Wpisz kod PUK i nowy kod PIN."</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 2d69f9c..6fff221 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Emprego"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Outro"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Não foram encontradas aplicações para visualizar este contacto."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Escreva o código PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Escreva o PUK e o novo código PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f1ad4d7..b6e8fbc 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Página inicial"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Comercial"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Outros"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nenhum aplicativo encontrado para visualizar este contato."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Insira o código PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Insira o PUK e o novo código PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 6ea1e9e..45e6951 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1330,6 +1330,8 @@
<skip />
<!-- no translation found for sipAddressTypeOther (4408436162950119849) -->
<skip />
+ <!-- no translation found for quick_contacts_not_available (746098007828579688) -->
+ <skip />
<!-- no translation found for keyguard_password_enter_pin_code (3037685796058495017) -->
<skip />
<!-- no translation found for keyguard_password_enter_puk_code (4800725266925845333) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index c3f9157..fcd5809 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Ecran pornire"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Serviciu"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Altul"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nu s-a găsit nicio aplicație pentru a afișa această persoană de contact."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introduceţi codul PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introduceţi codul PUK şi noul cod PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codul PUK"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index b853e8d..0eab8e8 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Домашний"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Рабочий"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Другой"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Не найдено приложение для просмотра контакта"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Введите PIN-код"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Введите PUK-код и новый PIN-код"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-код"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d19d87a..30320b2 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -190,7 +190,7 @@
<string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Prístup k zariadeniam a sieťam prostredníctvom rozhrania Bluetooth."</string>
<string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Nastavenia zvuku"</string>
<string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Zmena nastavení zvuku."</string>
- <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Má vplyv na batériu"</string>
+ <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Vplyv na batériu"</string>
<string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Používanie funkcií, ktoré môžu rýchlo vyčerpať batériu."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string>
<string name="permgroupdesc_calendar" msgid="5777534316982184416">"Priamy prístup ku kalendáru a udalostiam."</string>
@@ -232,7 +232,7 @@
<string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Funkcie len pre vývojárov aplikácií."</string>
<string name="permgrouplab_display" msgid="4279909676036402636">"Používateľské rozhranie iných aplikácií"</string>
<string name="permgroupdesc_display" msgid="6051002031933013714">"Vplyv na používateľské rozhranie ďalších aplikácií."</string>
- <string name="permgrouplab_storage" msgid="1971118770546336966">"Ukladací priestor"</string>
+ <string name="permgrouplab_storage" msgid="1971118770546336966">"Úložisko"</string>
<string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Prístup do ukl. priestoru USB."</string>
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Prístup na kartu SD."</string>
<string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Funkcie zjednodušenia ovládania"</string>
@@ -558,7 +558,7 @@
<string name="permlab_readPhoneState" msgid="9178228524507610486">"čítať stav a identitu telefónu"</string>
<string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikácii pristupovať k telefónnym funkciám zariadenia. Aplikácia s týmto povolením môže určiť telefónne číslo a ID zariadenia, či práve prebieha hovor, a vzdialené číslo, s ktorým je prostredníctvom hovoru nadviazané spojenie."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zabránenie prechodu tabletu do režimu spánku"</string>
- <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zabránenie prechodu telefónu do režimu spánku"</string>
+ <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"deaktivácia režimu spánku"</string>
<string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikácii zabrániť prechodu tabletu do režimu spánku."</string>
<string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Umožňuje aplikácii zabrániť prechodu telefónu do režimu spánku."</string>
<string name="permlab_transmitIr" msgid="7545858504238530105">"infračervený prenos"</string>
@@ -629,7 +629,7 @@
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Umožňuje aplikácii zobraziť informácie o konfigurácii Bluetooth na telefóne. Taktiež jej umožňuje nadväzovať a akceptovať spojenia so spárovanými zariadeniami."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"ovládať technológiu Near Field Communication"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje aplikácii komunikovať so značkami, kartami a čítačkami s podporou technológie Near Field Communication (NFC)."</string>
- <string name="permlab_disableKeyguard" msgid="3598496301486439258">"zakázať uzamknutie obrazovky"</string>
+ <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivácia zámky obrazovky"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje aplikácii zakázať uzamknutie klávesnice a akékoľvek súvisiace zabezpečenie heslom. Príkladom je zakázanie uzamknutia klávesnice pri prichádzajúcom telefonickom hovore a jeho opätovné povolenie po skončení hovoru."</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čítanie nastavení synchronizácie"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikácii čítať nastavenia synchronizácie v účte. Môže napríklad určiť, či je s účtom synchronizovaná aplikácia Ľudia."</string>
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Domov"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Práca"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Iné"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Nebola nájdená žiadna aplikácia, pomocou ktorej by bolo možné zobraziť tento kontakt."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Zadajte kód PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Zadajte kód PUK a nový kód PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kód PUK"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0d76bbf..8972edf 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Domov"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Služba"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Drugo"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Ni aplikacije za ogled tega stika."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Vnesite kodo PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Vnesite kodo PUK in novo kodo PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Koda PUK"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 6fb9ea2..b9c7beb 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Почетна"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Посао"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Други"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Није пронађена ниједна апликација за приказ овог контакта."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Унесите PIN кôд"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Унесите PUK и нови PIN кôд"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK кôд"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 7123012..eb5e900 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Hem"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbete"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Övrigt"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Ingen app för att visa den här kontakten hittades."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ange PIN-kod"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ange PUK-koden och en ny PIN-kod"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kod"</string>
@@ -1459,7 +1460,7 @@
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Gränsen för data via Wi-Fi har överskridits"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> över angiven gräns."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Bakgrundsdata är begränsade"</string>
- <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att radera begränsning"</string>
+ <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att ta bort begränsning"</string>
<string name="ssl_certificate" msgid="6510040486049237639">"Säkerhetscertifikat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certifikatet är giltigt."</string>
<string name="issued_to" msgid="454239480274921032">"Utfärdad till:"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index c268476..c5f3f90 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Nyumbani"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Kazi"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Nyinginezo"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Hakuna programu iliyopatikana ili kuona anwani hii."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ingiza msimbo wa PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ingiza PUK na msimbo mpya wa PIN"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Msimbo wa PUK"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f298a8f..34c70e2 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"หน้าแรก"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"ที่ทำงาน"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"อื่นๆ"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"ไม่พบแอปพลิเคชันที่ใช้ดูที่อยู่ติดต่อนี้"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"พิมพ์รหัส PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"พิมพ์ PUK และรหัส PIN ใหม่"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"รหัส PUK"</string>
@@ -1352,7 +1353,7 @@
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"แตะเพื่อออกจากโหมดรถยนต์"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
<string name="tethered_notification_message" msgid="6857031760103062982">"แตะเพื่อตั้งค่า"</string>
- <string name="back_button_label" msgid="2300470004503343439">"ย้อนกลับ"</string>
+ <string name="back_button_label" msgid="2300470004503343439">"กลับ"</string>
<string name="next_button_label" msgid="1080555104677992408">"ถัดไป"</string>
<string name="skip_button_label" msgid="1275362299471631819">"ข้าม"</string>
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"การใช้งานข้อมูลมือถือในระดับสูง"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 85dd968..18d4759 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabaho"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Iba pa"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Walang nakitang application upang matingnan ang contact na ito."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"I-type ang PIN code"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"I-type ang PUK at bagong PIN code"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 9ca752e..6c0e81f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Ev"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"İş"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Diğer"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Bu kişiyi görüntüleyecek uygulama bulunamadı."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN kodunu yazın"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK ve yeni PIN kodunu yazın"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kodu"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 556b35b..3bfecc3 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Головна"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Робоча"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Інша"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Не знайдено програму для перегляду цього контакта."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Введіть PIN-код"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Введіть PUK-код і новий PIN-код"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-код"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index c8f5014..cfcc02e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Nhà riêng"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Cơ quan"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Khác"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Không tìm thấy ứng dụng nào để xem liên hệ này."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Nhập mã PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Nhập PUK và mã PIN mới"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Mã PUK"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index f65950e..adf2d4b 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -76,7 +76,7 @@
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"默认显示本机号码,在下一次通话中也显示"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"未提供服务。"</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"您无法更改来电显示设置。"</string>
- <string name="RestrictedChangedTitle" msgid="5592189398956187498">"访问受限情况已发生变化"</string>
+ <string name="RestrictedChangedTitle" msgid="5592189398956187498">"网络可用情况发生变化"</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"数据服务已禁用。"</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"紧急服务已禁用。"</string>
<string name="RestrictedOnNormal" msgid="4953867011389750673">"已禁用语音服务。"</string>
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"住宅"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"单位"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"找不到可用来查看此联系人的应用。"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"输入 PIN 码"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"请输入 PUK 码和新的 PIN 码"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 码"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index ab8ceed..f954c24 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"家用"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"工作"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"找不到可以查看這位聯絡人的應用程式。"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"輸入 PIN 碼"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"輸入 PUK 碼和新 PIN 碼"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 碼"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 40d6260..5eeea00 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"住家"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"公司"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"找不到可用來查看這位聯絡人的應用程式。"</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"輸入 PIN 碼"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"輸入 PUK 碼和新 PIN 碼"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 碼"</string>
@@ -1129,7 +1130,7 @@
<string name="chooseUsbActivity" msgid="6894748416073583509">"選取要以 USB 裝置存取的應用程式"</string>
<string name="noApplications" msgid="2991814273936504689">"沒有應用程式可執行這項操作。"</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="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 沒有回應。\n\n您要結束嗎?"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 563cb3f..0583640 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -816,6 +816,7 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Ekhaya"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Umsebenzi"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Okunye"</string>
+ <string name="quick_contacts_not_available" msgid="746098007828579688">"Alukho uhlelo lokusebenza olutholakele lokubuka lona oxhumana naye."</string>
<string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Faka ikhodi ye-PIN"</string>
<string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Faka i-PUK nephinikhodi entsha"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Ikhodi le-PUK"</string>
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 10a5d85..18e4f2f 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -26,5 +26,4 @@
<bool name="show_ongoing_ime_switcher">true</bool>
<bool name="action_bar_expanded_action_views_exclusive">true</bool>
<bool name="target_honeycomb_needs_options_menu">true</bool>
- <bool name="flip_controller_fallback_keys">false</bool>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4940f80..098fbbe 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -625,9 +625,9 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_processOutgoingCalls">reroute outgoing calls</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_processOutgoingCalls">Allows the app to process
- outgoing calls and change the number to be dialed. This permission allows
- the app to monitor, redirect, or prevent outgoing calls.</string>
+ <string name="permdesc_processOutgoingCalls">Allows the app to see the
+ number being dialed during an outgoing call with the option to redirect
+ the call to a different number or abort the call altogether.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_receiveSms">receive text messages (SMS)</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index bface57..b635039 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -288,7 +288,6 @@
<java-symbol type="bool" name="config_useFixedVolume" />
<java-symbol type="bool" name="config_forceDefaultOrientation" />
<java-symbol type="bool" name="config_wifi_batched_scan_supported" />
- <java-symbol type="bool" name="flip_controller_fallback_keys" />
<java-symbol type="integer" name="config_cursorWindowSize" />
<java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 695a74f..01d22ee 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -477,4 +477,128 @@
ctrl: fallback MENU
}
-### Gamepad buttons are handled by the view root ###
+### Gamepad buttons ###
+
+key BUTTON_A {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_B {
+ base: fallback BACK
+}
+
+key BUTTON_C {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_X {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_Y {
+ base: fallback BACK
+}
+
+key BUTTON_Z {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_L1 {
+ base: none
+}
+
+key BUTTON_R1 {
+ base: none
+}
+
+key BUTTON_L2 {
+ base: none
+}
+
+key BUTTON_R2 {
+ base: none
+}
+
+key BUTTON_THUMBL {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_THUMBR {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_START {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_SELECT {
+ base: fallback MENU
+}
+
+key BUTTON_MODE {
+ base: fallback MENU
+}
+
+key BUTTON_1 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_2 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_3 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_4 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_5 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_6 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_7 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_8 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_9 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_10 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_11 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_12 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_13 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_14 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_15 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_16 {
+ base: fallback DPAD_CENTER
+}
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 8c38d25..17727d3 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -67,6 +67,16 @@
* setPremultiplied() aren't order dependent, despite being setters.
*/
private boolean mIsPremultiplied;
+
+ /**
+ * Whether the Bitmap's content is expected to have alpha. Note that hasAlpha()
+ * does not directly return this value, because hasAlpha() may never return true
+ * for a 565 Bitmap.
+ *
+ * Any time this or mIsPremultiplied is changed, both are passed to native so they
+ * are not order dependent.
+ */
+ private boolean mHasAlpha;
private byte[] mNinePatchChunk; // may be null
private int[] mLayoutBounds; // may be null
private int mWidth;
@@ -390,7 +400,7 @@
* No color information is stored.
* With this configuration, each pixel requires 1 byte of memory.
*/
- ALPHA_8 (2),
+ ALPHA_8 (1),
/**
* Each pixel is stored on 2 bytes and only the RGB channels are
@@ -406,7 +416,7 @@
* This configuration may be useful when using opaque bitmaps
* that do not require high color fidelity.
*/
- RGB_565 (4),
+ RGB_565 (3),
/**
* Each pixel is stored on 2 bytes. The three RGB color channels
@@ -428,7 +438,7 @@
* it is advised to use {@link #ARGB_8888} instead.
*/
@Deprecated
- ARGB_4444 (5),
+ ARGB_4444 (4),
/**
* Each pixel is stored on 4 bytes. Each channel (RGB and alpha
@@ -438,13 +448,13 @@
* This configuration is very flexible and offers the best
* quality. It should be used whenever possible.
*/
- ARGB_8888 (6);
+ ARGB_8888 (5);
final int nativeInt;
@SuppressWarnings({"deprecation"})
private static Config sConfigs[] = {
- null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
+ null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
};
Config(int ni) {
@@ -554,7 +564,7 @@
checkRecycled("Can't copy a recycled bitmap");
Bitmap b = nativeCopy(mNativeBitmap, config.nativeInt, isMutable);
if (b != null) {
- b.mIsPremultiplied = mIsPremultiplied;
+ b.setAlphaAndPremultiplied(mHasAlpha, mIsPremultiplied);
b.mDensity = mDensity;
}
return b;
@@ -727,12 +737,12 @@
paint.setAntiAlias(true);
}
}
-
+
// The new bitmap was created from a known bitmap source so assume that
// they use the same density
bitmap.mDensity = source.mDensity;
- bitmap.mIsPremultiplied = source.mIsPremultiplied;
-
+ bitmap.setAlphaAndPremultiplied(source.mHasAlpha, source.mIsPremultiplied);
+
canvas.setBitmap(bitmap);
canvas.drawBitmap(source, srcR, dstR, paint);
canvas.setBitmap(null);
@@ -810,9 +820,9 @@
if (display != null) {
bm.mDensity = display.densityDpi;
}
+ bm.setHasAlpha(hasAlpha);
if (config == Config.ARGB_8888 && !hasAlpha) {
nativeErase(bm.mNativeBitmap, 0xff000000);
- nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha);
}
// No need to initialize the bitmap to zeroes with other configs;
// it is backed by a VM byte array which is by definition preinitialized
@@ -884,6 +894,7 @@
if (display != null) {
bm.mDensity = display.densityDpi;
}
+ bm.mHasAlpha = true;
return bm;
}
@@ -1041,11 +1052,24 @@
* <p>This method will not affect the behavior of a bitmap without an alpha
* channel, or if {@link #hasAlpha()} returns false.</p>
*
+ * <p>Calling createBitmap() or createScaledBitmap() with a source
+ * Bitmap whose colors are not pre-multiplied may result in a RuntimeException,
+ * since those functions require drawing the source, which is not supported for
+ * un-pre-multiplied Bitmaps.</p>
+ *
* @see Bitmap#isPremultiplied()
* @see BitmapFactory.Options#inPremultiplied
*/
public final void setPremultiplied(boolean premultiplied) {
mIsPremultiplied = premultiplied;
+ nativeSetAlphaAndPremultiplied(mNativeBitmap, mHasAlpha, premultiplied);
+ }
+
+ /** Helper function to set both alpha and premultiplied. **/
+ private final void setAlphaAndPremultiplied(boolean hasAlpha, boolean premultiplied) {
+ mHasAlpha = hasAlpha;
+ mIsPremultiplied = premultiplied;
+ nativeSetAlphaAndPremultiplied(mNativeBitmap, hasAlpha, premultiplied);
}
/** Returns the bitmap's width */
@@ -1206,7 +1230,8 @@
* non-opaque per-pixel alpha values.
*/
public void setHasAlpha(boolean hasAlpha) {
- nativeSetHasAlpha(mNativeBitmap, hasAlpha);
+ mHasAlpha = hasAlpha;
+ nativeSetAlphaAndPremultiplied(mNativeBitmap, hasAlpha, mIsPremultiplied);
}
/**
@@ -1611,7 +1636,8 @@
private static native void nativePrepareToDraw(int nativeBitmap);
private static native boolean nativeHasAlpha(int nativeBitmap);
- private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha);
+ private static native void nativeSetAlphaAndPremultiplied(int nBitmap, boolean hasAlpha,
+ boolean isPremul);
private static native boolean nativeHasMipMap(int nativeBitmap);
private static native void nativeSetHasMipMap(int nBitmap, boolean hasMipMap);
private static native boolean nativeSameAs(int nb0, int nb1);
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index b08ce09..9b07da9 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -153,8 +153,12 @@
*
* <p>This does not affect bitmaps without an alpha channel.</p>
*
+ * <p>Setting this flag to false while setting {@link #inScaled} to true
+ * may result in incorrect colors.</p>
+ *
* @see Bitmap#hasAlpha()
* @see Bitmap#isPremultiplied()
+ * @see #inScaled
*/
public boolean inPremultiplied;
@@ -249,6 +253,9 @@
* <p>This flag is turned on by default and should be turned off if you need
* a non-scaled version of the bitmap. Nine-patch bitmaps ignore this
* flag and are always scaled.
+ *
+ * <p>If {@link #inPremultiplied} is set to false, and the image has alpha,
+ * setting this flag to true may result in incorrect colors.
*/
public boolean inScaled;
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index ed0a79a..8d0874f 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -285,10 +285,9 @@
void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
uint32_t width, uint32_t height) {
SkBitmap rgbaBitmap;
- rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
+ rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0, bitmap->alphaType());
rgbaBitmap.allocPixels();
rgbaBitmap.eraseColor(0);
- rgbaBitmap.setIsOpaque(bitmap->isOpaque());
SkCanvas canvas(rgbaBitmap);
canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL);
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 18983d8..12a9c23 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -23,6 +23,7 @@
#include <utils/Trace.h>
#include <SkGlyph.h>
+#include <SkGlyphCache.h>
#include <SkUtils.h>
#include "FontUtil.h"
@@ -271,9 +272,9 @@
if (cachedGlyph) {
// Is the glyph still in texture cache?
if (!cachedGlyph->mIsValid) {
- const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit,
- &mDescription.mLookupTransform);
- updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching);
+ SkAutoGlyphCache autoCache(*paint, NULL, &mDescription.mLookupTransform);
+ const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), textUnit);
+ updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), cachedGlyph, precaching);
}
} else {
cachedGlyph = cacheGlyph(paint, textUnit, precaching);
@@ -415,8 +416,8 @@
}
}
-void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
- bool precaching) {
+void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
+ CachedGlyphInfo* glyph, bool precaching) {
glyph->mAdvanceX = skiaGlyph.fAdvanceX;
glyph->mAdvanceY = skiaGlyph.fAdvanceY;
glyph->mBitmapLeft = skiaGlyph.fLeft;
@@ -429,7 +430,7 @@
// Get the bitmap for the glyph
if (!skiaGlyph.fImage) {
- paint->findImage(skiaGlyph, &mDescription.mLookupTransform);
+ skiaGlyphCache->findImage(skiaGlyph);
}
mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
@@ -463,11 +464,12 @@
CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
mCachedGlyphs.add(glyph, newGlyph);
- const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph, &mDescription.mLookupTransform);
+ SkAutoGlyphCache autoCache(*paint, NULL, &mDescription.mLookupTransform);
+ const SkGlyph& skiaGlyph = GET_METRICS(autoCache.getCache(), glyph);
newGlyph->mIsValid = false;
newGlyph->mGlyphIndex = skiaGlyph.fID;
- updateGlyphCache(paint, skiaGlyph, newGlyph, precaching);
+ updateGlyphCache(paint, skiaGlyph, autoCache.getCache(), newGlyph, precaching);
return newGlyph;
}
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index 9e7ec2d..f68b430 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -19,6 +19,7 @@
#include <utils/KeyedVector.h>
+#include <SkGlyphCache.h>
#include <SkScalerContext.h>
#include <SkPaint.h>
#include <SkPathMeasure.h>
@@ -117,8 +118,8 @@
void invalidateTextureCache(CacheTexture* cacheTexture = NULL);
CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
- void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
- bool precaching);
+ void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
+ CachedGlyphInfo* glyph, bool precaching);
void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h
index cdcb23c..c2fd5f5 100644
--- a/libs/hwui/font/FontUtil.h
+++ b/libs/hwui/font/FontUtil.h
@@ -40,7 +40,7 @@
#if RENDER_TEXT_AS_GLYPHS
typedef uint16_t glyph_t;
#define TO_GLYPH(g) g
- #define GET_METRICS(paint, glyph, matrix) paint->getGlyphMetrics(glyph, matrix)
+ #define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph)
#define GET_GLYPH(text) nextGlyph((const uint16_t**) &text)
#define IS_END_OF_STRING(glyph) false
@@ -53,7 +53,7 @@
#else
typedef SkUnichar glyph_t;
#define TO_GLYPH(g) ((SkUnichar) g)
- #define GET_METRICS(paint, glyph, matrix) paint->getUnicharMetrics(glyph, matrix)
+ #define GET_METRICS(cache, glyph) cache->getUnicharMetrics(glyph)
#define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text)
#define IS_END_OF_STRING(glyph) glyph < 0
#endif
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 20eb356..9db35fc 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -98,7 +98,7 @@
private static SimpleDateFormat sFormatter;
static {
- System.loadLibrary("exif_jni");
+ System.loadLibrary("jhead_jni");
sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
}
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 6dbb3cd..910b24c 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -404,7 +404,7 @@
* @throws IllegalArgumentException
*/
public boolean setSynchronizationMode(int sync) throws IllegalArgumentException {
- if ((sync != POSITION_SYNCHRONIZATION_NONE) || (sync != POSITION_SYNCHRONIZATION_CHECK)) {
+ if ((sync != POSITION_SYNCHRONIZATION_NONE) && (sync != POSITION_SYNCHRONIZATION_CHECK)) {
throw new IllegalArgumentException("Unknown synchronization mode " + sync);
}
if (!mIsRegistered) {
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 63a61e2..dea971e 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -41,13 +41,13 @@
libstagefright_amrnb_common \
LOCAL_REQUIRED_MODULES := \
- libexif_jni
+ libjhead_jni
LOCAL_STATIC_LIBRARIES := \
libstagefright_amrnbenc
LOCAL_C_INCLUDES += \
- external/jhead \
+ external/libexif/ \
external/tremor/Tremor \
frameworks/base/core/jni \
frameworks/av/media/libmedia \
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 77c7966..067e7a6 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -37,7 +37,10 @@
#include "mtp.h"
extern "C" {
-#include "jhead.h"
+#include "libexif/exif-content.h"
+#include "libexif/exif-data.h"
+#include "libexif/exif-tag.h"
+#include "libexif/exif-utils.h"
}
using namespace android;
@@ -750,6 +753,22 @@
return result;
}
+static void foreachentry(ExifEntry *entry, void *user) {
+ char buf[1024];
+ ALOGI("entry %x, format %d, size %d: %s",
+ entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
+}
+
+static void foreachcontent(ExifContent *content, void *user) {
+ ALOGI("content %d", exif_content_get_ifd(content));
+ exif_content_foreach_entry(content, foreachentry, user);
+}
+
+static long getLongFromExifEntry(ExifEntry *e) {
+ ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
+ return exif_get_long(e->data, o);
+}
+
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
MtpObjectInfo& info) {
char date[20];
@@ -792,23 +811,22 @@
// read EXIF data for thumbnail information
if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
- ResetJpgfile();
- // Start with an empty image information structure.
- memset(&ImageInfo, 0, sizeof(ImageInfo));
- ImageInfo.FlashUsed = -1;
- ImageInfo.MeteringMode = -1;
- ImageInfo.Whitebalance = -1;
- strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
- if (ReadJpegFile((const char*)path, READ_METADATA)) {
- Section_t* section = FindSection(M_EXIF);
- if (section) {
- info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
- info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
- info.mImagePixWidth = ImageInfo.Width;
- info.mImagePixHeight = ImageInfo.Height;
- }
+
+ ExifData *exifdata = exif_data_new_from_file(path);
+ if (exifdata) {
+ //exif_data_foreach_content(exifdata, foreachcontent, NULL);
+
+ // XXX get this from exif, or parse jpeg header instead?
+ ExifEntry *w = exif_content_get_entry(
+ exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
+ ExifEntry *h = exif_content_get_entry(
+ exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
+ info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
+ info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
+ info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
+ info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
+ exif_data_unref(exifdata);
}
- DiscardData();
}
checkAndClearExceptionFromCallback(env, __FUNCTION__);
@@ -824,22 +842,16 @@
if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
&& (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
- ResetJpgfile();
- // Start with an empty image information structure.
- memset(&ImageInfo, 0, sizeof(ImageInfo));
- ImageInfo.FlashUsed = -1;
- ImageInfo.MeteringMode = -1;
- ImageInfo.Whitebalance = -1;
- strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
- if (ReadJpegFile((const char*)path, READ_METADATA)) {
- Section_t* section = FindSection(M_EXIF);
- if (section) {
- outThumbSize = ImageInfo.ThumbnailSize;
- result = malloc(outThumbSize);
- if (result)
- memcpy(result, section->Data + ImageInfo.ThumbnailOffset + 8, outThumbSize);
+
+ ExifData *exifdata = exif_data_new_from_file(path);
+ if (exifdata) {
+ if (exifdata->data) {
+ result = malloc(exifdata->size);
+ if (result) {
+ memcpy(result, exifdata->data, exifdata->size);
+ }
}
- DiscardData();
+ exif_data_unref(exifdata);
}
}
diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
index 6424744..53f04bc 100644
--- a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
+++ b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
@@ -30,6 +30,7 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
+#include <SkImage.h>
#include <SkMallocPixelRef.h>
#include "omx_jpeg_decoder.h"
@@ -184,8 +185,7 @@
void OmxJpegImageDecoder::configBitmapSize(SkBitmap* bm, SkBitmap::Config pref,
int width, int height) {
- bm->setConfig(getColorSpaceConfig(pref), width, height);
- bm->setIsOpaque(true);
+ bm->setConfig(getColorSpaceConfig(pref), width, height, 0, kOpaque_SkAlphaType);
}
SkBitmap::Config OmxJpegImageDecoder::getColorSpaceConfig(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index cb17ac6..eb63a54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -37,6 +37,8 @@
private static final boolean DEBUG = false;
private static final boolean DEBUG_COLORS = false;
+ public static final boolean HIGH_END = ActivityManager.isHighEndGfx();
+
public static final int MODE_OPAQUE = 0;
public static final int MODE_SEMI_TRANSPARENT = 1;
public static final int MODE_TRANSLUCENT = 2;
@@ -48,7 +50,6 @@
private final String mTag;
private final View mView;
- private final boolean mSupportsTransitions = ActivityManager.isHighEndGfx();
private final BarBackgroundDrawable mBarBackground;
private int mMode;
@@ -57,7 +58,7 @@
mTag = "BarTransitions." + view.getClass().getSimpleName();
mView = view;
mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
- if (mSupportsTransitions) {
+ if (HIGH_END) {
mView.setBackground(mBarBackground);
}
}
@@ -67,18 +68,22 @@
}
public void transitionTo(int mode, boolean animate) {
+ // low-end devices do not support translucent modes, fallback to opaque
+ if (!HIGH_END && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT)) {
+ mode = MODE_OPAQUE;
+ }
if (mMode == mode) return;
int oldMode = mMode;
mMode = mode;
if (DEBUG) Log.d(mTag, String.format("%s -> %s animate=%s",
modeToString(oldMode), modeToString(mode), animate));
- if (mSupportsTransitions) {
- onTransition(oldMode, mMode, animate);
- }
+ onTransition(oldMode, mMode, animate);
}
protected void onTransition(int oldMode, int newMode, boolean animate) {
- applyModeBackground(oldMode, newMode, animate);
+ if (HIGH_END) {
+ applyModeBackground(oldMode, newMode, animate);
+ }
}
protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
diff --git a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
index 3e57a77..b734c41 100644
--- a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
+++ b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
@@ -178,6 +178,7 @@
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
,
PixelFormat.TRANSLUCENT);
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
lp.setTitle("ImmersiveModeConfirmation");
lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
lp.gravity = Gravity.FILL;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index bea1c1f..a7e0114 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3278,8 +3278,9 @@
+ mRestrictedScreenWidth;
pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop
+ mRestrictedScreenHeight;
- } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT) {
- // Toasts are stable to interim decor changes.
+ } else if (attrs.type == TYPE_TOAST || attrs.type == TYPE_SYSTEM_ALERT
+ || attrs.type == TYPE_VOLUME_OVERLAY) {
+ // These dialogs are stable to interim decor changes.
pf.left = df.left = of.left = cf.left = mStableLeft;
pf.top = df.top = of.top = cf.top = mStableTop;
pf.right = df.right = of.right = cf.right = mStableRight;
@@ -3384,13 +3385,10 @@
WindowManager.LayoutParams attrs) {
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
+ win.isVisibleOrBehindKeyguardLw());
- if (mTopFullscreenOpaqueWindowState == null && (win.getAttrs().privateFlags
- &WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_NAV_BAR) != 0
- || (win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD)) {
- if (mForcingShowNavBarLayer < 0) {
- mForcingShowNavBar = true;
- mForcingShowNavBarLayer = win.getSurfaceLayer();
- }
+ if (mTopFullscreenOpaqueWindowState == null
+ && win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD) {
+ mForcingShowNavBar = true;
+ mForcingShowNavBarLayer = win.getSurfaceLayer();
}
if (mTopFullscreenOpaqueWindowState == null &&
win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 00bfee7..44cb019 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -82,7 +82,7 @@
import com.android.internal.backup.BackupConstants;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.backup.IObbBackupService;
-import com.android.internal.backup.LocalTransport;
+import com.android.server.EventLogTags;
import com.android.server.PackageManagerBackupAgent.Metadata;
import java.io.BufferedInputStream;
@@ -140,11 +140,16 @@
private static final boolean DEBUG = true;
private static final boolean MORE_DEBUG = false;
+ // Historical and current algorithm names
+ static final String PBKDF_CURRENT = "PBKDF2WithHmacSHA1";
+ static final String PBKDF_FALLBACK = "PBKDF2WithHmacSHA1And8bit";
+
// Name and current contents version of the full-backup manifest file
static final String BACKUP_MANIFEST_FILENAME = "_manifest";
static final int BACKUP_MANIFEST_VERSION = 1;
static final String BACKUP_FILE_HEADER_MAGIC = "ANDROID BACKUP\n";
- static final int BACKUP_FILE_VERSION = 1;
+ static final int BACKUP_FILE_VERSION = 2;
+ static final int BACKUP_PW_FILE_VERSION = 2;
static final boolean COMPRESS_FULL_BACKUPS = true; // should be true in production
static final String SHARED_BACKUP_AGENT_PACKAGE = "com.android.sharedstoragebackup";
@@ -450,6 +455,8 @@
private final SecureRandom mRng = new SecureRandom();
private String mPasswordHash;
private File mPasswordHashFile;
+ private int mPasswordVersion;
+ private File mPasswordVersionFile;
private byte[] mPasswordSalt;
// Configuration of PBKDF2 that we use for generating pw hashes and intermediate keys
@@ -810,6 +817,27 @@
}
mDataDir = Environment.getDownloadCacheDirectory();
+ mPasswordVersion = 1; // unless we hear otherwise
+ mPasswordVersionFile = new File(mBaseStateDir, "pwversion");
+ if (mPasswordVersionFile.exists()) {
+ FileInputStream fin = null;
+ DataInputStream in = null;
+ try {
+ fin = new FileInputStream(mPasswordVersionFile);
+ in = new DataInputStream(fin);
+ mPasswordVersion = in.readInt();
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to read backup pw version");
+ } finally {
+ try {
+ if (in != null) in.close();
+ if (fin != null) fin.close();
+ } catch (IOException e) {
+ Slog.w(TAG, "Error closing pw version files");
+ }
+ }
+ }
+
mPasswordHashFile = new File(mBaseStateDir, "pwhash");
if (mPasswordHashFile.exists()) {
FileInputStream fin = null;
@@ -1110,13 +1138,13 @@
}
}
- private SecretKey buildPasswordKey(String pw, byte[] salt, int rounds) {
- return buildCharArrayKey(pw.toCharArray(), salt, rounds);
+ private SecretKey buildPasswordKey(String algorithm, String pw, byte[] salt, int rounds) {
+ return buildCharArrayKey(algorithm, pw.toCharArray(), salt, rounds);
}
- private SecretKey buildCharArrayKey(char[] pwArray, byte[] salt, int rounds) {
+ private SecretKey buildCharArrayKey(String algorithm, char[] pwArray, byte[] salt, int rounds) {
try {
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
KeySpec ks = new PBEKeySpec(pwArray, salt, rounds, PBKDF2_KEY_SIZE);
return keyFactory.generateSecret(ks);
} catch (InvalidKeySpecException e) {
@@ -1127,8 +1155,8 @@
return null;
}
- private String buildPasswordHash(String pw, byte[] salt, int rounds) {
- SecretKey key = buildPasswordKey(pw, salt, rounds);
+ private String buildPasswordHash(String algorithm, String pw, byte[] salt, int rounds) {
+ SecretKey key = buildPasswordKey(algorithm, pw, salt, rounds);
if (key != null) {
return byteArrayToHex(key.getEncoded());
}
@@ -1156,13 +1184,13 @@
return result;
}
- private byte[] makeKeyChecksum(byte[] pwBytes, byte[] salt, int rounds) {
+ private byte[] makeKeyChecksum(String algorithm, byte[] pwBytes, byte[] salt, int rounds) {
char[] mkAsChar = new char[pwBytes.length];
for (int i = 0; i < pwBytes.length; i++) {
mkAsChar[i] = (char) pwBytes[i];
}
- Key checksum = buildCharArrayKey(mkAsChar, salt, rounds);
+ Key checksum = buildCharArrayKey(algorithm, mkAsChar, salt, rounds);
return checksum.getEncoded();
}
@@ -1174,7 +1202,7 @@
}
// Backup password management
- boolean passwordMatchesSaved(String candidatePw, int rounds) {
+ boolean passwordMatchesSaved(String algorithm, String candidatePw, int rounds) {
// First, on an encrypted device we require matching the device pw
final boolean isEncrypted;
try {
@@ -1217,7 +1245,7 @@
} else {
// hash the stated current pw and compare to the stored one
if (candidatePw != null && candidatePw.length() > 0) {
- String currentPwHash = buildPasswordHash(candidatePw, mPasswordSalt, rounds);
+ String currentPwHash = buildPasswordHash(algorithm, candidatePw, mPasswordSalt, rounds);
if (mPasswordHash.equalsIgnoreCase(currentPwHash)) {
// candidate hash matches the stored hash -- the password matches
return true;
@@ -1232,11 +1260,37 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"setBackupPassword");
- // If the supplied pw doesn't hash to the the saved one, fail
- if (!passwordMatchesSaved(currentPw, PBKDF2_HASH_ROUNDS)) {
+ // When processing v1 passwords we may need to try two different PBKDF2 checksum regimes
+ final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION);
+
+ // If the supplied pw doesn't hash to the the saved one, fail. The password
+ // might be caught in the legacy crypto mismatch; verify that too.
+ if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PBKDF2_HASH_ROUNDS)
+ && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK,
+ currentPw, PBKDF2_HASH_ROUNDS))) {
return false;
}
+ // Snap up to current on the pw file version
+ mPasswordVersion = BACKUP_PW_FILE_VERSION;
+ FileOutputStream pwFout = null;
+ DataOutputStream pwOut = null;
+ try {
+ pwFout = new FileOutputStream(mPasswordVersionFile);
+ pwOut = new DataOutputStream(pwFout);
+ pwOut.writeInt(mPasswordVersion);
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to write backup pw version; password not changed");
+ return false;
+ } finally {
+ try {
+ if (pwOut != null) pwOut.close();
+ if (pwFout != null) pwFout.close();
+ } catch (IOException e) {
+ Slog.w(TAG, "Unable to close pw version record");
+ }
+ }
+
// Clearing the password is okay
if (newPw == null || newPw.isEmpty()) {
if (mPasswordHashFile.exists()) {
@@ -1254,7 +1308,7 @@
try {
// Okay, build the hash of the new backup password
byte[] salt = randomBytes(PBKDF2_SALT_SIZE);
- String newPwHash = buildPasswordHash(newPw, salt, PBKDF2_HASH_ROUNDS);
+ String newPwHash = buildPasswordHash(PBKDF_CURRENT, newPw, salt, PBKDF2_HASH_ROUNDS);
OutputStream pwf = null, buffer = null;
DataOutputStream out = null;
@@ -1297,6 +1351,19 @@
}
}
+ private boolean backupPasswordMatches(String currentPw) {
+ if (hasBackupPassword()) {
+ final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION);
+ if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PBKDF2_HASH_ROUNDS)
+ && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK,
+ currentPw, PBKDF2_HASH_ROUNDS))) {
+ if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
+ return false;
+ }
+ }
+ return true;
+ }
+
// Maintain persistent state around whether need to do an initialize operation.
// Must be called with the queue lock held.
void recordInitPendingLocked(boolean isPending, String transportName) {
@@ -2717,11 +2784,9 @@
// Verify that the given password matches the currently-active
// backup password, if any
- if (hasBackupPassword()) {
- if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) {
- if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
- return;
- }
+ if (!backupPasswordMatches(mCurrentPassword)) {
+ if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
+ return;
}
// Write the global file header. All strings are UTF-8 encoded; lines end
@@ -2729,7 +2794,7 @@
// final '\n'.
//
// line 1: "ANDROID BACKUP"
- // line 2: backup file format version, currently "1"
+ // line 2: backup file format version, currently "2"
// line 3: compressed? "0" if not compressed, "1" if compressed.
// line 4: name of encryption algorithm [currently only "none" or "AES-256"]
//
@@ -2837,7 +2902,7 @@
OutputStream ofstream) throws Exception {
// User key will be used to encrypt the master key.
byte[] newUserSalt = randomBytes(PBKDF2_SALT_SIZE);
- SecretKey userKey = buildPasswordKey(mEncryptPassword, newUserSalt,
+ SecretKey userKey = buildPasswordKey(PBKDF_CURRENT, mEncryptPassword, newUserSalt,
PBKDF2_HASH_ROUNDS);
// the master key is random for each backup
@@ -2884,7 +2949,7 @@
// stated number of PBKDF2 rounds
IV = c.getIV();
byte[] mk = masterKeySpec.getEncoded();
- byte[] checksum = makeKeyChecksum(masterKeySpec.getEncoded(),
+ byte[] checksum = makeKeyChecksum(PBKDF_CURRENT, masterKeySpec.getEncoded(),
checksumSalt, PBKDF2_HASH_ROUNDS);
ByteArrayOutputStream blob = new ByteArrayOutputStream(IV.length + mk.length
@@ -3227,11 +3292,9 @@
FileInputStream rawInStream = null;
DataInputStream rawDataIn = null;
try {
- if (hasBackupPassword()) {
- if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) {
- if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
- return;
- }
+ if (!backupPasswordMatches(mCurrentPassword)) {
+ if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
+ return;
}
mBytes = 0;
@@ -3252,8 +3315,12 @@
if (Arrays.equals(magicBytes, streamHeader)) {
// okay, header looks good. now parse out the rest of the fields.
String s = readHeaderLine(rawInStream);
- if (Integer.parseInt(s) == BACKUP_FILE_VERSION) {
- // okay, it's a version we recognize
+ final int archiveVersion = Integer.parseInt(s);
+ if (archiveVersion <= BACKUP_FILE_VERSION) {
+ // okay, it's a version we recognize. if it's version 1, we may need
+ // to try two different PBKDF2 regimes to compare checksums.
+ final boolean pbkdf2Fallback = (archiveVersion == 1);
+
s = readHeaderLine(rawInStream);
compressed = (Integer.parseInt(s) != 0);
s = readHeaderLine(rawInStream);
@@ -3261,7 +3328,8 @@
// no more header to parse; we're good to go
okay = true;
} else if (mDecryptPassword != null && mDecryptPassword.length() > 0) {
- preCompressStream = decodeAesHeaderAndInitialize(s, rawInStream);
+ preCompressStream = decodeAesHeaderAndInitialize(s, pbkdf2Fallback,
+ rawInStream);
if (preCompressStream != null) {
okay = true;
}
@@ -3321,7 +3389,71 @@
return buffer.toString();
}
- InputStream decodeAesHeaderAndInitialize(String encryptionName, InputStream rawInStream) {
+ InputStream attemptMasterKeyDecryption(String algorithm, byte[] userSalt, byte[] ckSalt,
+ int rounds, String userIvHex, String masterKeyBlobHex, InputStream rawInStream,
+ boolean doLog) {
+ InputStream result = null;
+
+ try {
+ Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ SecretKey userKey = buildPasswordKey(algorithm, mDecryptPassword, userSalt,
+ rounds);
+ byte[] IV = hexToByteArray(userIvHex);
+ IvParameterSpec ivSpec = new IvParameterSpec(IV);
+ c.init(Cipher.DECRYPT_MODE,
+ new SecretKeySpec(userKey.getEncoded(), "AES"),
+ ivSpec);
+ byte[] mkCipher = hexToByteArray(masterKeyBlobHex);
+ byte[] mkBlob = c.doFinal(mkCipher);
+
+ // first, the master key IV
+ int offset = 0;
+ int len = mkBlob[offset++];
+ IV = Arrays.copyOfRange(mkBlob, offset, offset + len);
+ offset += len;
+ // then the master key itself
+ len = mkBlob[offset++];
+ byte[] mk = Arrays.copyOfRange(mkBlob,
+ offset, offset + len);
+ offset += len;
+ // and finally the master key checksum hash
+ len = mkBlob[offset++];
+ byte[] mkChecksum = Arrays.copyOfRange(mkBlob,
+ offset, offset + len);
+
+ // now validate the decrypted master key against the checksum
+ byte[] calculatedCk = makeKeyChecksum(algorithm, mk, ckSalt, rounds);
+ if (Arrays.equals(calculatedCk, mkChecksum)) {
+ ivSpec = new IvParameterSpec(IV);
+ c.init(Cipher.DECRYPT_MODE,
+ new SecretKeySpec(mk, "AES"),
+ ivSpec);
+ // Only if all of the above worked properly will 'result' be assigned
+ result = new CipherInputStream(rawInStream, c);
+ } else if (doLog) Slog.w(TAG, "Incorrect password");
+ } catch (InvalidAlgorithmParameterException e) {
+ if (doLog) Slog.e(TAG, "Needed parameter spec unavailable!", e);
+ } catch (BadPaddingException e) {
+ // This case frequently occurs when the wrong password is used to decrypt
+ // the master key. Use the identical "incorrect password" log text as is
+ // used in the checksum failure log in order to avoid providing additional
+ // information to an attacker.
+ if (doLog) Slog.w(TAG, "Incorrect password");
+ } catch (IllegalBlockSizeException e) {
+ if (doLog) Slog.w(TAG, "Invalid block size in master key");
+ } catch (NoSuchAlgorithmException e) {
+ if (doLog) Slog.e(TAG, "Needed decryption algorithm unavailable!");
+ } catch (NoSuchPaddingException e) {
+ if (doLog) Slog.e(TAG, "Needed padding mechanism unavailable!");
+ } catch (InvalidKeyException e) {
+ if (doLog) Slog.w(TAG, "Illegal password; aborting");
+ }
+
+ return result;
+ }
+
+ InputStream decodeAesHeaderAndInitialize(String encryptionName, boolean pbkdf2Fallback,
+ InputStream rawInStream) {
InputStream result = null;
try {
if (encryptionName.equals(ENCRYPTION_ALGORITHM_NAME)) {
@@ -3338,59 +3470,13 @@
String masterKeyBlobHex = readHeaderLine(rawInStream); // 9
// decrypt the master key blob
- Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
- SecretKey userKey = buildPasswordKey(mDecryptPassword, userSalt,
- rounds);
- byte[] IV = hexToByteArray(userIvHex);
- IvParameterSpec ivSpec = new IvParameterSpec(IV);
- c.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(userKey.getEncoded(), "AES"),
- ivSpec);
- byte[] mkCipher = hexToByteArray(masterKeyBlobHex);
- byte[] mkBlob = c.doFinal(mkCipher);
-
- // first, the master key IV
- int offset = 0;
- int len = mkBlob[offset++];
- IV = Arrays.copyOfRange(mkBlob, offset, offset + len);
- offset += len;
- // then the master key itself
- len = mkBlob[offset++];
- byte[] mk = Arrays.copyOfRange(mkBlob,
- offset, offset + len);
- offset += len;
- // and finally the master key checksum hash
- len = mkBlob[offset++];
- byte[] mkChecksum = Arrays.copyOfRange(mkBlob,
- offset, offset + len);
-
- // now validate the decrypted master key against the checksum
- byte[] calculatedCk = makeKeyChecksum(mk, ckSalt, rounds);
- if (Arrays.equals(calculatedCk, mkChecksum)) {
- ivSpec = new IvParameterSpec(IV);
- c.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(mk, "AES"),
- ivSpec);
- // Only if all of the above worked properly will 'result' be assigned
- result = new CipherInputStream(rawInStream, c);
- } else Slog.w(TAG, "Incorrect password");
+ result = attemptMasterKeyDecryption(PBKDF_CURRENT, userSalt, ckSalt,
+ rounds, userIvHex, masterKeyBlobHex, rawInStream, false);
+ if (result == null && pbkdf2Fallback) {
+ result = attemptMasterKeyDecryption(PBKDF_FALLBACK, userSalt, ckSalt,
+ rounds, userIvHex, masterKeyBlobHex, rawInStream, true);
+ }
} else Slog.w(TAG, "Unsupported encryption method: " + encryptionName);
- } catch (InvalidAlgorithmParameterException e) {
- Slog.e(TAG, "Needed parameter spec unavailable!", e);
- } catch (BadPaddingException e) {
- // This case frequently occurs when the wrong password is used to decrypt
- // the master key. Use the identical "incorrect password" log text as is
- // used in the checksum failure log in order to avoid providing additional
- // information to an attacker.
- Slog.w(TAG, "Incorrect password");
- } catch (IllegalBlockSizeException e) {
- Slog.w(TAG, "Invalid block size in master key");
- } catch (NoSuchAlgorithmException e) {
- Slog.e(TAG, "Needed decryption algorithm unavailable!");
- } catch (NoSuchPaddingException e) {
- Slog.e(TAG, "Needed padding mechanism unavailable!");
- } catch (InvalidKeyException e) {
- Slog.w(TAG, "Illegal password; aborting");
} catch (NumberFormatException e) {
Slog.w(TAG, "Can't parse restore data header");
} catch (IOException e) {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index baff661..2d0c285 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -2305,9 +2305,9 @@
mInetConditionChangeInFlight = false;
// Don't do this - if we never sign in stay, grey
//reportNetworkCondition(mActiveDefaultNetwork, 100);
+ updateNetworkSettings(thisNet);
}
thisNet.setTeardownRequested(false);
- updateNetworkSettings(thisNet);
updateMtuSizeSettings(thisNet);
handleConnectivityChange(newNetType, false);
sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
@@ -3034,7 +3034,7 @@
case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED: {
info = (NetworkInfo) msg.obj;
int type = info.getType();
- updateNetworkSettings(mNetTrackers[type]);
+ if (mNetConfigs[type].isDefault()) updateNetworkSettings(mNetTrackers[type]);
break;
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 9201b1d..e2050fc 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1328,7 +1328,7 @@
String pkg = bundle.getString("pkg");
String reason = bundle.getString("reason");
forceStopPackageLocked(pkg, appid, restart, false, true, false,
- UserHandle.USER_ALL, reason);
+ false, UserHandle.USER_ALL, reason);
}
} break;
case FINALIZE_PENDING_INTENT_MSG: {
@@ -4494,7 +4494,7 @@
private void forceStopPackageLocked(final String packageName, int uid, String reason) {
forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
- false, true, false, UserHandle.getUserId(uid), reason);
+ false, true, false, false, UserHandle.getUserId(uid), reason);
Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
Uri.fromParts("package", packageName, null));
if (!mProcessesReady) {
@@ -4510,7 +4510,7 @@
}
private void forceStopUserLocked(int userId, String reason) {
- forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
+ forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
@@ -4595,7 +4595,7 @@
private final boolean forceStopPackageLocked(String name, int appId,
boolean callerWillRestart, boolean purgeCache, boolean doit,
- boolean evenPersistent, int userId, String reason) {
+ boolean evenPersistent, boolean uninstalling, int userId, String reason) {
int i;
int N;
@@ -4687,7 +4687,7 @@
// Remove transient permissions granted from/to this package/user
removeUriPermissionsForPackageLocked(name, userId, false);
- if (name == null) {
+ if (name == null || uninstalling) {
// Remove pending intents. For now we only do this when force
// stopping users, because we have some problems when doing this
// for packages -- app widgets are not currently cleaned up for
@@ -5132,7 +5132,7 @@
if (pkgs != null) {
for (String pkg : pkgs) {
synchronized (ActivityManagerService.this) {
- if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
+ if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
"finished booting")) {
setResultCode(Activity.RESULT_OK);
return;
@@ -8445,7 +8445,7 @@
mDebugTransient = !persistent;
if (packageName != null) {
forceStopPackageLocked(packageName, -1, false, false, true, true,
- UserHandle.USER_ALL, "set debug app");
+ false, UserHandle.USER_ALL, "set debug app");
}
}
} finally {
@@ -9225,8 +9225,13 @@
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
if (lastDoneReceivers.contains(comp)) {
+ // We already did the pre boot receiver for this app with the current
+ // platform version, so don't do it again...
ris.remove(i);
i--;
+ // ...however, do keep it as one that has been done, so we don't
+ // forget about it when rewriting the file of last done receivers.
+ doneReceivers.add(comp);
}
}
@@ -13373,7 +13378,7 @@
String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
if (list != null && (list.length > 0)) {
for (String pkg : list) {
- forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
+ forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
"storage unmount");
}
sendPackageBroadcastLocked(
@@ -13385,10 +13390,13 @@
if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
intent.getAction());
+ boolean fullUninstall = removed &&
+ !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
forceStopPackageLocked(ssp, UserHandle.getAppId(
intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
- false, userId, removed ? "pkg removed" : "pkg changed");
+ false, fullUninstall, userId,
+ removed ? "pkg removed" : "pkg changed");
}
if (removed) {
sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
@@ -13866,7 +13874,7 @@
final long origId = Binder.clearCallingIdentity();
// Instrumentation can kill and relaunch even persistent processes
- forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
+ forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
"start instr");
ProcessRecord app = addAppLocked(ai, false);
app.instrumentationClass = className;
@@ -13934,7 +13942,7 @@
app.instrumentationProfileFile = null;
app.instrumentationArguments = null;
- forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
+ forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
"finished inst");
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 5450fd0..47476c0 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -867,7 +867,7 @@
int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
ArrayList<String> pkgList = new ArrayList<String>(1);
pkgList.add(res.pkg.applicationInfo.packageName);
- sendResourcesChangedBroadcast(true, false,
+ sendResourcesChangedBroadcast(true, true,
pkgList,uidArray, null);
}
}
@@ -10576,7 +10576,8 @@
DumpState dumpState = new DumpState();
boolean fullPreferred = false;
-
+ boolean checkin = false;
+
String packageName = null;
int opti = 0;
@@ -10590,7 +10591,8 @@
// Right now we only know how to print all.
} else if ("-h".equals(opt)) {
pw.println("Package manager dump options:");
- pw.println(" [-h] [-f] [cmd] ...");
+ pw.println(" [-h] [-f] [--checkin] [cmd] ...");
+ pw.println(" --checkin: dump for a checkin");
pw.println(" -f: print details of intent filters");
pw.println(" -h: print this help");
pw.println(" cmd may be one of:");
@@ -10608,13 +10610,15 @@
pw.println(" <package.name>: info about given package");
pw.println(" k[eysets]: print known keysets");
return;
+ } else if ("--checkin".equals(opt)) {
+ checkin = true;
} else if ("-f".equals(opt)) {
dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
} else {
pw.println("Unknown argument: " + opt + "; use -h for help");
}
}
-
+
// Is the caller requesting to dump a particular piece of data?
if (opti < args.length) {
String cmd = args[opti];
@@ -10656,17 +10660,26 @@
}
}
+ if (checkin) {
+ pw.println("vers,1");
+ }
+
// reader
synchronized (mPackages) {
if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
- if (dumpState.onTitlePrinted())
- pw.println();
- pw.println("Verifiers:");
- pw.print(" Required: ");
- pw.print(mRequiredVerifierPackage);
- pw.print(" (uid=");
- pw.print(getPackageUid(mRequiredVerifierPackage, 0));
- pw.println(")");
+ if (!checkin) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("Verifiers:");
+ pw.print(" Required: ");
+ pw.print(mRequiredVerifierPackage);
+ pw.print(" (uid=");
+ pw.print(getPackageUid(mRequiredVerifierPackage, 0));
+ pw.println(")");
+ } else if (mRequiredVerifierPackage != null) {
+ pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
+ pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
+ }
}
if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
@@ -10675,21 +10688,37 @@
while (it.hasNext()) {
String name = it.next();
SharedLibraryEntry ent = mSharedLibraries.get(name);
- if (!printedHeader) {
- if (dumpState.onTitlePrinted())
- pw.println();
- pw.println("Libraries:");
- printedHeader = true;
- }
- pw.print(" ");
- pw.print(name);
- pw.print(" -> ");
- if (ent.path != null) {
- pw.print("(jar) ");
- pw.print(ent.path);
+ if (!checkin) {
+ if (!printedHeader) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("Libraries:");
+ printedHeader = true;
+ }
+ pw.print(" ");
} else {
- pw.print("(apk) ");
- pw.print(ent.apk);
+ pw.print("lib,");
+ }
+ pw.print(name);
+ if (!checkin) {
+ pw.print(" -> ");
+ }
+ if (ent.path != null) {
+ if (!checkin) {
+ pw.print("(jar) ");
+ pw.print(ent.path);
+ } else {
+ pw.print(",jar,");
+ pw.print(ent.path);
+ }
+ } else {
+ if (!checkin) {
+ pw.print("(apk) ");
+ pw.print(ent.apk);
+ } else {
+ pw.print(",apk,");
+ pw.print(ent.apk);
+ }
}
pw.println();
}
@@ -10698,16 +10727,22 @@
if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
if (dumpState.onTitlePrinted())
pw.println();
- pw.println("Features:");
+ if (!checkin) {
+ pw.println("Features:");
+ }
Iterator<String> it = mAvailableFeatures.keySet().iterator();
while (it.hasNext()) {
String name = it.next();
- pw.print(" ");
+ if (!checkin) {
+ pw.print(" ");
+ } else {
+ pw.print("feat,");
+ }
pw.println(name);
}
}
- if (dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
: "Activity Resolver Table:", " ", packageName,
dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
@@ -10730,7 +10765,7 @@
}
}
- if (dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
int user = mSettings.mPreferredActivities.keyAt(i);
@@ -10744,7 +10779,7 @@
}
}
- if (dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
pw.flush();
FileOutputStream fout = new FileOutputStream(fd);
BufferedOutputStream str = new BufferedOutputStream(fout);
@@ -10766,11 +10801,11 @@
}
}
- if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
}
- if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
boolean printedSomething = false;
for (PackageParser.Provider p : mProviders.mProviders.values()) {
if (packageName != null && !packageName.equals(p.info.packageName)) {
@@ -10807,19 +10842,19 @@
}
}
- if (dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
mSettings.mKeySetManager.dump(pw, packageName, dumpState);
}
if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
- mSettings.dumpPackagesLPr(pw, packageName, dumpState);
+ mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
}
- if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
}
- if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
if (dumpState.onTitlePrinted())
pw.println();
mSettings.dumpReadMessagesLPr(pw, dumpState);
@@ -11058,7 +11093,7 @@
if (uidArr != null) {
extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
}
- if (replacing && !mediaStatus) {
+ if (replacing) {
extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
}
String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 0079b54..19bfe01 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -2891,8 +2891,44 @@
ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
};
- void dumpPackageLPr(PrintWriter pw, String prefix, PackageSetting ps, SimpleDateFormat sdf,
- Date date, List<UserInfo> users) {
+ void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
+ SimpleDateFormat sdf, Date date, List<UserInfo> users) {
+ if (checkinTag != null) {
+ pw.print(checkinTag);
+ pw.print(",");
+ pw.print(ps.realName != null ? ps.realName : ps.name);
+ pw.print(",");
+ pw.print(ps.appId);
+ pw.print(",");
+ pw.print(ps.versionCode);
+ pw.print(",");
+ pw.print(ps.firstInstallTime);
+ pw.print(",");
+ pw.print(ps.lastUpdateTime);
+ pw.print(",");
+ pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
+ pw.println();
+ for (UserInfo user : users) {
+ pw.print(checkinTag);
+ pw.print("-");
+ pw.print("usr");
+ pw.print(",");
+ pw.print(user.id);
+ pw.print(",");
+ pw.print(ps.getInstalled(user.id) ? "I" : "i");
+ pw.print(ps.getBlocked(user.id) ? "B" : "b");
+ pw.print(ps.getStopped(user.id) ? "S" : "s");
+ pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
+ pw.print(",");
+ pw.print(ps.getEnabled(user.id));
+ String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
+ pw.print(",");
+ pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
+ pw.println();
+ }
+ return;
+ }
+
pw.print(prefix); pw.print("Package [");
pw.print(ps.realName != null ? ps.realName : ps.name);
pw.print("] (");
@@ -3054,7 +3090,7 @@
}
}
- void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState) {
+ void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Date date = new Date();
boolean printedSomething = false;
@@ -3065,35 +3101,39 @@
continue;
}
- if (packageName != null) {
+ if (!checkin && packageName != null) {
dumpState.setSharedUser(ps.sharedUser);
}
- if (!printedSomething) {
+ if (!checkin && !printedSomething) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("Packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "pkg" : null, ps, sdf, date, users);
}
printedSomething = false;
- if (mRenamedPackages.size() > 0) {
+ if (!checkin && mRenamedPackages.size() > 0) {
for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
if (packageName != null && !packageName.equals(e.getKey())
&& !packageName.equals(e.getValue())) {
continue;
}
- if (!printedSomething) {
- if (dumpState.onTitlePrinted())
- pw.println();
- pw.println("Renamed packages:");
- printedSomething = true;
+ if (!checkin) {
+ if (!printedSomething) {
+ if (dumpState.onTitlePrinted())
+ pw.println();
+ pw.println("Renamed packages:");
+ printedSomething = true;
+ }
+ pw.print(" ");
+ } else {
+ pw.print("ren,");
}
- pw.print(" ");
pw.print(e.getKey());
- pw.print(" -> ");
+ pw.print(checkin ? " -> " : ",");
pw.println(e.getValue());
}
}
@@ -3105,13 +3145,13 @@
&& !packageName.equals(ps.name)) {
continue;
}
- if (!printedSomething) {
+ if (!checkin && !printedSomething) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("Hidden system packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "dis" : null, ps, sdf, date, users);
}
}
}
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 62f6aff..dfb8070 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -85,11 +85,13 @@
// do initial app launch, without force stopping
for (String app : mNameToResultKey.keySet()) {
long launchTime = startApp(app, false);
- if (launchTime <=0 ) {
+ if (launchTime <= 0) {
mNameToLaunchTime.put(app, -1L);
// simply pass the app if launch isn't successful
// error should have already been logged by startApp
continue;
+ } else {
+ mNameToLaunchTime.put(app, launchTime);
}
sleep(INITIAL_LAUNCH_IDLE_TIMEOUT);
closeApp(app, false);
@@ -98,9 +100,9 @@
// do the real app launch now
for (int i = 0; i < mLaunchIterations; i++) {
for (String app : mNameToResultKey.keySet()) {
- long totalLaunchTime = mNameToLaunchTime.get(app);
+ long prevLaunchTime = mNameToLaunchTime.get(app);
long launchTime = 0;
- if (totalLaunchTime < 0) {
+ if (prevLaunchTime < 0) {
// skip if the app has previous failures
continue;
}
@@ -110,18 +112,19 @@
mNameToLaunchTime.put(app, -1L);
continue;
}
- totalLaunchTime += launchTime;
- mNameToLaunchTime.put(app, totalLaunchTime);
+ // keep the min launch time
+ if (launchTime < prevLaunchTime) {
+ mNameToLaunchTime.put(app, launchTime);
+ }
sleep(POST_LAUNCH_IDLE_TIMEOUT);
closeApp(app, true);
sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT);
}
}
for (String app : mNameToResultKey.keySet()) {
- long totalLaunchTime = mNameToLaunchTime.get(app);
- if (totalLaunchTime != -1) {
- mResult.putDouble(mNameToResultKey.get(app),
- ((double) totalLaunchTime) / mLaunchIterations);
+ long launchTime = mNameToLaunchTime.get(app);
+ if (launchTime != -1) {
+ mResult.putLong(mNameToResultKey.get(app), launchTime);
}
}
instrumentation.sendStatus(0, mResult);
diff --git a/tests/LegacyRestoreTest/README b/tests/LegacyRestoreTest/README
new file mode 100644
index 0000000..cdd157e
--- /dev/null
+++ b/tests/LegacyRestoreTest/README
@@ -0,0 +1,18 @@
+The file "jbmr2-encrypted-settings-abcd.ab" in this directory is an encrypted
+"adb backup" archive of the settings provider package. It was generated on a
+Nexus 4 running Android 4.3 (API 18), and so predates the Android 4.4 changes
+to the PBKDF2 implementation. The archive's encryption password, entered on-screen,
+is "abcd" (with no quotation marks).
+
+'adb restore' decrypts and applies the restored archive successfully on a device
+running Android 4.3, but fails to restore correctly on a device running Android 4.4,
+reporting an invalid password in logcat. This is the situation reported in bug
+<https://code.google.com/p/android/issues/detail?id=63880>.
+
+The file "kk-fixed-encrypted-settings-abcd.ab" is a similar encrypted "adb backup"
+archive, using the same key, generated on a Nexus 4 running Android 4.4 with a fix
+to this bug in place. This archive should be successfully restorable on any
+version of Android which incorporates the fix.
+
+These archives can be used as an ongoing test to verify that historical encrypted
+archives from various points in Android's history can be successfully restored.
diff --git a/tests/LegacyRestoreTest/jbmr2-encrypted-settings-abcd.ab b/tests/LegacyRestoreTest/jbmr2-encrypted-settings-abcd.ab
new file mode 100644
index 0000000..192dcf5
--- /dev/null
+++ b/tests/LegacyRestoreTest/jbmr2-encrypted-settings-abcd.ab
Binary files differ
diff --git a/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab b/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab
new file mode 100644
index 0000000..bf2b558
--- /dev/null
+++ b/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab
Binary files differ