diff options
118 files changed, 996 insertions, 631 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c63e586a7127..cce6fc42da58 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1778,7 +1778,7 @@ public class Notification implements Parcelable 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 bc0d7e3c806b..d779628571bf 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -232,8 +232,6 @@ public final class ViewRootImpl implements ViewParent, InputStage mFirstInputStage; InputStage mFirstPostImeInputStage; - boolean mFlipControllerFallbackKeys; - boolean mWindowAttributesChanged = false; int mWindowAttributesChangesFlag = 0; @@ -370,8 +368,6 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, }; } - 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 f0e6677d016b..52f9c0b480ca 100644 --- a/core/java/android/view/VolumePanel.java +++ b/core/java/android/view/VolumePanel.java @@ -311,7 +311,6 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie 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 0ce4da5c4dc5..53a4c0d0df51 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1063,13 +1063,6 @@ public interface WindowManager extends ViewManager { 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 0957ab4670e6..e90b4608a888 100644 --- a/core/java/android/widget/CalendarView.java +++ b/core/java/android/widget/CalendarView.java @@ -1210,35 +1210,38 @@ public class CalendarView extends FrameLayout { 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(); + } + + // 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); } - setMonthDisplayed(firstDay); } + mPreviousScrollPosition = currScroll; mPreviousScrollState = mCurrentScrollState; } diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 5392a96715bf..6a369a60a324 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -308,6 +308,11 @@ public class ProgressBar extends View { 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 b204dfd0c032..1cda631a498a 100644 --- a/core/java/android/widget/SpellChecker.java +++ b/core/java/android/widget/SpellChecker.java @@ -731,10 +731,14 @@ public class SpellChecker implements SpellCheckerSessionListener { } } - 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 7a9809fda605..37121e210fd0 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8667,6 +8667,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 0cad33cff6b8..0aad0b541252 100644 --- a/core/java/com/android/internal/app/ProcessStats.java +++ b/core/java/com/android/internal/app/ProcessStats.java @@ -1004,7 +1004,7 @@ public final class ProcessStats implements Parcelable { 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 @@ public final class ProcessStats implements Parcelable { 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 final class ProcessStats implements Parcelable { } 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 ab871fb80a59..942995b51a83 100644 --- a/core/java/com/android/internal/content/PackageMonitor.java +++ b/core/java/com/android/internal/content/PackageMonitor.java @@ -372,23 +372,25 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { } 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 eea9ee14dd0f..212576328764 100644 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -227,7 +227,7 @@ static void ToColor_SI8_Alpha(SkColor dst[], const void* src, int width, 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 @@ static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width, *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 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),
SkGetPackedB32(c));
} while (--width != 0);
- ctable->unlockColors(false);
+ ctable->unlockColors();
}
// can return NULL
@@ -442,9 +442,15 @@ static jboolean Bitmap_hasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap) { 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 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, 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 @@ static JNINativeMethod gBitmapMethods[] = { { "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 da6219fcfeb1..709de5c7c070 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 void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) { 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 @@ public: 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 @@ public: 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 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding // 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 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } SkPaint paint; - paint.setFilterBitmap(true); + paint.setFilterLevel(SkPaint::kLow_FilterLevel); SkCanvas canvas(*outputBitmap); canvas.scale(sx, sy); @@ -470,6 +487,12 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding 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 @@ static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteA 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 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi 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<SkData> data(SkData::NewFromFD(descriptor)); - if (data.get() == NULL) { - return nullObjectReturn("NewFromFD failed in nativeDecodeFileDescriptor"); + 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<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 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset, } 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 ee47ac46ecd1..1412a0e900b3 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 @@ private: 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 @@ static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray b 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 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b 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 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b } // 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 813dd5af1e28..edf3b4a052a4 100644 --- a/core/jni/android/graphics/Canvas.cpp +++ b/core/jni/android/graphics/Canvas.cpp @@ -476,7 +476,7 @@ public: 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 @@ public: if (paint) { filteredPaint = *paint; } - filteredPaint.setFilterBitmap(true); + filteredPaint.setFilterLevel(SkPaint::kLow_FilterLevel); canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint); @@ -514,7 +514,7 @@ public: 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 8cb152db06e3..3090ad2ff711 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -346,6 +346,18 @@ SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region) /////////////////////////////////////////////////////////////////////////////////////////// +// 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 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buff 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 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreat 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 @@ static JNIEnv* vm2env(JavaVM* vm) /////////////////////////////////////////////////////////////////////////////// -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 @@ AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteA // 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 @@ jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, 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 f4590b956d78..cb154aaf28e5 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -57,6 +57,7 @@ public: /** 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 @@ public: 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 @@ public: 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 feb2decd3528..55be7c194f12 100644 --- a/core/jni/android/graphics/Movie.cpp +++ b/core/jni/android/graphics/Movie.cpp @@ -85,7 +85,9 @@ static void movie_draw(JNIEnv* env, jobject movie, jobject canvas, 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 df996afd0bf7..d3482da34fa2 100644 --- a/core/jni/android/graphics/NinePatchPeeker.cpp +++ b/core/jni/android/graphics/NinePatchPeeker.cpp @@ -40,15 +40,14 @@ bool NinePatchPeeker::peek(const char tag[], const void* data, size_t length) { // 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 40e0731cbee4..4f6cc37aaa0e 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -148,7 +148,8 @@ public: 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 ded21860b8b9..f0a7baf8cb04 100644 --- a/core/jni/android/graphics/Region.cpp +++ b/core/jni/android/graphics/Region.cpp @@ -177,7 +177,7 @@ static SkRegion* Region_createFromParcel(JNIEnv* env, jobject clazz, jobject par 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 92d253f0458e..144ac3990cd2 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 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte 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 ccd75d565ae5..d10a960049f1 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 @@ static int Typeface_getStyle(JNIEnv* env, jobject obj, SkTypeface* face) { 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 @@ static SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject, 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 b7d1f3ab220f..eb416cbe7ad2 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 a1ac72a0b92b..b90593cdc4b0 100644 --- a/core/jni/android/graphics/Utils.h +++ b/core/jni/android/graphics/Utils.h @@ -28,16 +28,36 @@ namespace android { 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 44af1993dc3d..4bb091d1ab6e 100644 --- a/core/jni/android/opengl/util.cpp +++ b/core/jni/android/opengl/util.cpp @@ -632,7 +632,7 @@ static jint util_getInternalFormat(JNIEnv *env, jclass clazz, 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 @@ static jint util_getType(JNIEnv *env, jclass clazz, 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 @@ static jint util_texImage2D(JNIEnv *env, jclass clazz, 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 @@ static jint util_texImage2D(JNIEnv *env, jclass clazz, 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 @@ static jint util_texSubImage2D(JNIEnv *env, jclass clazz, 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 1fe4b08d9721..5b0a4b2e4039 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -630,7 +630,7 @@ not_valid_surface: 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 1868469f8ebb..dd178d8297f3 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 jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jint na 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 @@ static jint nativeLockCanvas(JNIEnv* env, jclass clazz, 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 67eade83cdc4..b8d3c20fd899 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -61,51 +61,21 @@ static struct { 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 @@ protected: SK_DECLARE_UNFLATTENABLE_OBJECT() private: - ScreenshotClient mScreenshot; - SkColorTable* fCTable; + ScreenshotClient* mScreenshot; typedef SkPixelRef INHERITED; }; @@ -147,19 +116,6 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jint nativeObject) { 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 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display 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 0f4290059b89..7a4a20a97cab 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 @@ static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject, 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 69783bbc2701..daff390c93b1 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 0358de303717..dde6da0bed71 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 b649f5d32c7b..980465d9661a 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 18296ea97b6c..2055c935c063 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 0d1cdaf7b65d..0672cdfdc409 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 cf813679013b..b6c47629a5f5 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 14d6dd57fd48..da0dff41c0d0 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 1d394a818957..27e1cfb85416 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 dcd767183e3d..d95bdca8c67f 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 ee98cebc8d09..482a9fa3145e 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 d2c53cca4d8a..a66eedad04f4 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 d2c53cca4d8a..a66eedad04f4 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 114f6f5c04e6..c7df6e606778 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 f758989419fd..95a623b0dc6d 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 39523ef092cf..1d24dea00dac 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 14836c279705..18cc89dc9af7 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 e4d4e3e4a95b..06e4fdd5e422 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 28218973090c..b1a3f98b81cb 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 9944754a0aa0..434b99b98b77 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 2650108a7307..925ee367513e 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 829c03dd000b..8e06edd63445 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 5ed894ea4884..005dcbee6a93 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 85eedba3ba60..5789e5fcffd2 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 633621aedd52..7acc02b71be9 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 6bae95bc731f..fdee4400e9d4 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 3d82fefc0a54..b3f5439f6b5a 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 59cf744532eb..000000000000 --- 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 559d53f48b84..b7ccb6a5c7ee 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 7f4dc901da97..ea36ab0144fa 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 f03b5ed72bd6..f12b0038e2d9 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 cbfb1dbdf579..18c15a9b2ab4 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 8d88dfee9f1e..cd0d47156b7b 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 614bcd6d67d7..d11051f0c4f1 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 9f3cb533c5b3..022917ac40e3 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-mnc510/config.xml b/core/res/res/values-mcc302-mnc510/config.xml deleted file mode 100644 index 706570c0bd6b..000000000000 --- 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/config.xml index 685d0121931d..a106b0ae2cec 100644 --- a/core/res/res/values-mcc404-mnc17/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>40491</item> + <item>404</item> + <item>405</item> </string-array> </resources> diff --git a/core/res/res/values-mcc302-mnc500/config.xml b/core/res/res/values-mcc405/config.xml index 706570c0bd6b..a106b0ae2cec 100644 --- a/core/res/res/values-mcc302-mnc500/config.xml +++ b/core/res/res/values-mcc405/config.xml @@ -18,8 +18,9 @@ --> <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> + <!-- Show roaming icon though same named operators. --> + <string-array translatable="false" name="config_sameNamedOperatorConsideredRoaming"> + <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 index fd780abbf7dd..b2f3efa891ac 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 252a95900c6a..c58184dc9a47 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 284837a82efa..2f5769e7983d 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 122bf1a1b1e6..ff1781526c4e 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 ba5ac11a0ab4..27d683637b02 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 7e9a8c48e355..b8c20f5ef74e 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 2d69f9c5884c..6fff221d5b45 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 f1ad4d7d4689..b6e8fbc97e40 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 6ea1e9edc573..45e69512eb5f 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 c3f915714e4f..fcd580955c04 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 b853e8de6cd6..0eab8e886f35 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 d19d87a7ed0d..30320b24965b 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 0d76bbf153a8..8972edf326de 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 6fb9ea2ad1c3..b9c7bebad214 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 7123012d53cc..eb5e9008d348 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 c2684764d131..c5f3f902c586 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 f298a8f56216..34c70e2adc78 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 85dd968f56b3..18d475946ceb 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 9ca752ed298f..6c0e81f3c30f 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 556b35b78cf1..3bfecc3971c8 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 c8f5014e021d..cfcc02e72f7f 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 f65950e78777..adf2d4b19627 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 ab8ceed96511..f954c244b07b 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 40d626000504..5eeea0012972 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 563cb3f1d101..058364005591 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 10a5d851fac3..18e4f2f9b3a8 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 4940f80b32bc..098fbbe0c3c7 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 bface572a7d2..b635039a65c8 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 695a74f83810..01d22ee69178 100644 --- a/data/keyboards/Generic.kcm +++ b/data/keyboards/Generic.kcm @@ -477,4 +477,128 @@ key ESCAPE { 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 8c38d25d94e8..17727d3160f0 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -67,6 +67,16 @@ public final class Bitmap implements Parcelable { * 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 @@ public final class Bitmap implements Parcelable { * 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 @@ public final class Bitmap implements Parcelable { * 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 @@ public final class Bitmap implements Parcelable { * 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 @@ public final class Bitmap implements Parcelable { * 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 @@ public final class Bitmap implements Parcelable { 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 @@ public final class Bitmap implements Parcelable { 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 @@ public final class Bitmap implements Parcelable { 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 @@ public final class Bitmap implements Parcelable { if (display != null) { bm.mDensity = display.densityDpi; } + bm.mHasAlpha = true; return bm; } @@ -1041,11 +1052,24 @@ public final class Bitmap implements Parcelable { * <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 @@ public final class Bitmap implements Parcelable { * non-opaque per-pixel alpha values. */ public void setHasAlpha(boolean hasAlpha) { - nativeSetHasAlpha(mNativeBitmap, hasAlpha); + mHasAlpha = hasAlpha; + nativeSetAlphaAndPremultiplied(mNativeBitmap, hasAlpha, mIsPremultiplied); } /** @@ -1611,7 +1636,8 @@ public final class Bitmap implements Parcelable { 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 b08ce0974abe..9b07da98278a 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -153,8 +153,12 @@ public class BitmapFactory { * * <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 @@ public class BitmapFactory { * <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 ed0a79aac56a..8d0874f3e03b 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -285,10 +285,9 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege 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 18983d8b6d32..12a9c235c938 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 @@ CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool pre 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::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len } } -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 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp // 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* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching 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 9e7ec2dcfe4d..f68b43084187 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 @@ private: 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 cdcb23c488e7..c2fd5f58e02d 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 20eb35694146..9db35fce7db7 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -98,7 +98,7 @@ public class ExifInterface { 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 6dbb3cd1da61..910b24c20637 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -404,7 +404,7 @@ public final class RemoteController * @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 63a61e2edf22..dea971e4cfbc 100644 --- a/media/jni/Android.mk +++ b/media/jni/Android.mk @@ -41,13 +41,13 @@ LOCAL_SHARED_LIBRARIES := \ 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 77c796652442..067e7a6af8b0 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 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, 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 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, // 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 @@ void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) 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 6424744a4331..53f04bc6079c 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::installPixelRef(MediaBuffer *buffer, sp<MediaSource> d 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 cb17ac62439a..eb63a548ac42 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 @@ public class BarTransitions { 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 @@ public class BarTransitions { 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 @@ public class BarTransitions { 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 class BarTransitions { } 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 3e57a77807c4..b734c41c9a11 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 @@ public class ImmersiveModeConfirmation { | 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 bea1c1f9c4a8..a7e0114f4c92 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { + 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 00bfee78bfbb..44cb019aff03 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -82,7 +82,7 @@ import android.util.StringBuilderPrinter; 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { } 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 @@ class BackupManagerService extends IBackupManager.Stub { } } - 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { } // 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 @@ class BackupManagerService extends IBackupManager.Stub { } 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { } } + 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 @@ class BackupManagerService extends IBackupManager.Stub { // 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 @@ class BackupManagerService extends IBackupManager.Stub { // 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { // 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { // 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 @@ class BackupManagerService extends IBackupManager.Stub { 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 baff66117088..2d0c2856f81b 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -2305,9 +2305,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { 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 9201b1d3166c..e2050fc97fe1 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1328,7 +1328,7 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative } 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative // 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 @@ public final class ActivityManagerService extends ActivityManagerNative 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 5450fd071994..47476c0cb54b 100755 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -867,7 +867,7 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { DumpState dumpState = new DumpState(); boolean fullPreferred = false; - + boolean checkin = false; + String packageName = null; int opti = 0; @@ -10590,7 +10591,8 @@ public class PackageManagerService extends IPackageManager.Stub { // 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } + 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 @@ public class PackageManagerService extends IPackageManager.Stub { while (it.hasNext()) { String name = it.next(); SharedLibraryEntry ent = mSharedLibraries.get(name); - if (!printedHeader) { - if (dumpState.onTitlePrinted()) - pw.println(); - pw.println("Libraries:"); - printedHeader = true; + if (!checkin) { + if (!printedHeader) { + if (dumpState.onTitlePrinted()) + pw.println(); + pw.println("Libraries:"); + printedHeader = true; + } + pw.print(" "); + } else { + pw.print("lib,"); } - pw.print(" "); pw.print(name); - pw.print(" -> "); + if (!checkin) { + pw.print(" -> "); + } if (ent.path != null) { - pw.print("(jar) "); - pw.print(ent.path); + if (!checkin) { + pw.print("(jar) "); + pw.print(ent.path); + } else { + pw.print(",jar,"); + pw.print(ent.path); + } } else { - pw.print("(apk) "); - pw.print(ent.apk); + if (!checkin) { + pw.print("(apk) "); + pw.print(ent.apk); + } else { + pw.print(",apk,"); + pw.print(ent.apk); + } } pw.println(); } @@ -10698,16 +10727,22 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } - 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } - 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } - 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } - 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 0079b546788a..19bfe01600fd 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -2891,8 +2891,44 @@ final class Settings { 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 @@ final class Settings { } } - 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 @@ final class Settings { 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 @@ final class Settings { && !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 62f6affd9b3a..dfb80707f14c 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 @@ public class AppLaunch extends InstrumentationTestCase { // 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 @@ public class AppLaunch extends InstrumentationTestCase { // 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 @@ public class AppLaunch extends InstrumentationTestCase { 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 000000000000..cdd157e58295 --- /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 Binary files differnew file mode 100644 index 000000000000..192dcf5d4c52 --- /dev/null +++ b/tests/LegacyRestoreTest/jbmr2-encrypted-settings-abcd.ab diff --git a/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab b/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab Binary files differnew file mode 100644 index 000000000000..bf2b558d49b9 --- /dev/null +++ b/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab |