diff options
25 files changed, 622 insertions, 106 deletions
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index fb166097573c..2e70a569c095 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -1781,7 +1781,7 @@ public class AccountManagerService // will return a different value, but we *don't* erase the // passwords. We only erase them if it has a different // subscriber ID once it's provisioned. - if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { + if (telephonyManager.getCurrentPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { IBinder service = ServiceManager.checkService(Context.TELEPHONY_SERVICE); if (service == null) { Log.w(TAG, "call to checkService(TELEPHONY_SERVICE) failed"); diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java index f9920c77b8c4..a990ee98de51 100644 --- a/core/java/android/app/TimePickerDialog.java +++ b/core/java/android/app/TimePickerDialog.java @@ -107,9 +107,9 @@ public class TimePickerDialog extends AlertDialog mTimePicker = (TimePicker) view.findViewById(R.id.timePicker); // initialize state + mTimePicker.setIs24HourView(mIs24HourView); mTimePicker.setCurrentHour(mInitialHourOfDay); mTimePicker.setCurrentMinute(mInitialMinute); - mTimePicker.setIs24HourView(mIs24HourView); mTimePicker.setOnTimeChangedListener(this); } @@ -144,8 +144,8 @@ public class TimePickerDialog extends AlertDialog super.onRestoreInstanceState(savedInstanceState); int hour = savedInstanceState.getInt(HOUR); int minute = savedInstanceState.getInt(MINUTE); + mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR)); mTimePicker.setCurrentHour(hour); mTimePicker.setCurrentMinute(minute); - mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR)); } } diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index fb3744d530ca..4656e153915d 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -296,12 +296,12 @@ public final class BluetoothAdapter { * can use this intent. * * <p>This intent will have 3 extras: - * {@link #EXTRA_STATE} - The current state. - * {@link #EXTRA_PREVIOUS_STATE}- The previous. + * {@link #EXTRA_CONNECTION_STATE} - The current connection state. + * {@link #EXTRA_PREVIOUS_CONNECTION_STATE}- The previous connection state. * {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. * - * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of - * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, + * {@link #EXTRA_CONNECTION_STATE} or {@link #EXTRA_PREVIOUS_CONNECTION_STATE} + * can be any of {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 44887ede3c96..912a88d39759 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -36,6 +36,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.util.Log; import android.util.LogPrinter; @@ -206,8 +207,14 @@ public abstract class WallpaperService extends Service { @Override public void setFixedSize(int width, int height) { - throw new UnsupportedOperationException( - "Wallpapers currently only support sizing from layout"); + if (Process.myUid() != Process.SYSTEM_UID) { + // Regular apps can't do this. It can only work for + // certain designs of window animations, so you can't + // rely on it. + throw new UnsupportedOperationException( + "Wallpapers currently only support sizing from layout"); + } + super.setFixedSize(width, height); } public void setKeepScreenOn(boolean screenOn) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 6c5bdb69dff4..393412f0e6a0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -73,7 +73,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.WeakHashMap; /** @@ -2375,6 +2374,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility }) int mLayerType = LAYER_TYPE_NONE; Paint mLayerPaint; + Rect mLocalDirtyRect; /** * Simple constructor to use when creating a view from code. @@ -6910,7 +6910,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility * well. This is usually true for a full invalidate, but may be set to false if the * View's contents or dimensions have not changed. */ - private void invalidate(boolean invalidateCache) { + void invalidate(boolean invalidateCache) { if (ViewDebug.TRACE_HIERARCHY) { ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE); } @@ -8173,7 +8173,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } mLayerType = layerType; - mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : (paint == null ? new Paint() : paint); + final boolean layerDisabled = mLayerType == LAYER_TYPE_NONE; + mLayerPaint = layerDisabled ? null : (paint == null ? new Paint() : paint); + mLocalDirtyRect = layerDisabled ? null : new Rect(); invalidateParentCaches(); invalidate(true); @@ -8228,8 +8230,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mAttachInfo.mHardwareCanvas = canvas; try { canvas.setViewport(width, height); - // TODO: We should pass the dirty rect - canvas.onPreDraw(null); + canvas.onPreDraw(mLocalDirtyRect); final int restoreCount = canvas.save(); @@ -8251,6 +8252,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility canvas.onPostDraw(); mHardwareLayer.end(currentCanvas); mAttachInfo.mHardwareCanvas = currentCanvas; + mLocalDirtyRect.setEmpty(); } } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index f0aaf3fb36cc..09e1d89bb8a2 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -347,6 +347,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // views during a transition when they otherwise would have become gone/invisible private ArrayList<View> mVisibilityChangingChildren; + // Indicates whether this container will use its children layers to draw + @ViewDebug.ExportedProperty(category = "drawing") + private boolean mDrawLayers = true; + public ViewGroup(Context context) { super(context); initViewGroup(); @@ -2147,7 +2151,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager flags = mGroupFlags; if ((flags & FLAG_INVALIDATE_REQUIRED) == FLAG_INVALIDATE_REQUIRED) { - invalidate(); + invalidate(true); } if ((flags & FLAG_ANIMATION_DONE) == 0 && (flags & FLAG_NOTIFY_ANIMATION_LISTENER) == 0 && @@ -2203,7 +2207,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } - invalidate(); + invalidate(true); } /** @@ -2262,7 +2266,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager boolean scalingRequired = false; boolean caching; - int layerType = child.getLayerType(); + int layerType = mDrawLayers ? child.getLayerType() : LAYER_TYPE_NONE; final boolean hardwareAccelerated = canvas.isHardwareAccelerated(); if ((flags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE || @@ -2539,10 +2543,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // invalidation is the trigger to recreate display lists, so if we're using // display lists to render, force an invalidate to allow the animation to // continue drawing another frame - invalidate(); + invalidate(true); if (a instanceof AlphaAnimation) { // alpha animations should cause the child to recreate its display list - child.invalidate(); + child.invalidate(true); } } @@ -2552,6 +2556,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** + * + * @param enabled True if children should be drawn with layers, false otherwise. + * + * @hide + */ + public void setChildrenLayersEnabled(boolean enabled) { + mDrawLayers = enabled; + invalidate(true); + } + + /** * By default, children are clipped to their bounds before drawing. This * allows view groups to override this behavior for animations, etc. * @@ -2583,7 +2598,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View[] children = mChildren; final int count = mChildrenCount; for (int i = 0; i < count; i++) { - children[i].setSelected(selected); } } @@ -2596,7 +2610,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View[] children = mChildren; final int count = mChildrenCount; for (int i = 0; i < count; i++) { - children[i].setActivated(activated); } } @@ -2789,7 +2802,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // therefore, we call requestLayout() on ourselves before, so that the child's request // will be blocked at our level requestLayout(); - invalidate(); + invalidate(true); addViewInner(child, index, params, false); } @@ -3071,7 +3084,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public void removeView(View view) { removeViewInternal(view); requestLayout(); - invalidate(); + invalidate(true); } /** @@ -3103,7 +3116,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public void removeViewAt(int index) { removeViewInternal(index, getChildAt(index)); requestLayout(); - invalidate(); + invalidate(true); } /** @@ -3115,7 +3128,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public void removeViews(int start, int count) { removeViewsInternal(start, count); requestLayout(); - invalidate(); + invalidate(true); } private void removeViewInternal(View view) { @@ -3240,7 +3253,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager public void removeAllViews() { removeAllViewsInLayout(); requestLayout(); - invalidate(); + invalidate(true); } /** @@ -3474,16 +3487,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (child.mLayerType != LAYER_TYPE_NONE) { mPrivateFlags |= INVALIDATED; mPrivateFlags &= ~DRAWING_CACHE_VALID; + child.mLocalDirtyRect.setEmpty(); } do { View view = null; if (parent instanceof View) { view = (View) parent; - if (view.mLayerType != LAYER_TYPE_NONE && - view.getParent() instanceof View) { - final View grandParent = (View) view.getParent(); - grandParent.mPrivateFlags |= INVALIDATED; - grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID; + if (view.mLayerType != LAYER_TYPE_NONE) { + view.mLocalDirtyRect.setEmpty(); + if (view.getParent() instanceof View) { + final View grandParent = (View) view.getParent(); + grandParent.mPrivateFlags |= INVALIDATED; + grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID; + } } if ((view.mPrivateFlags & DIRTY_MASK) != 0) { // already marked dirty - we're done @@ -3521,6 +3537,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // Make sure we do not set both flags at the same time int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY; + if (child.mLayerType != LAYER_TYPE_NONE) { + mPrivateFlags |= INVALIDATED; + mPrivateFlags &= ~DRAWING_CACHE_VALID; + child.mLocalDirtyRect.union(dirty); + } + final int[] location = attachInfo.mInvalidateChildLocation; location[CHILD_LEFT_INDEX] = child.mLeft; location[CHILD_TOP_INDEX] = child.mTop; @@ -3534,10 +3556,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager (int) (boundingRect.bottom + 0.5f)); } - if (child.mLayerType != LAYER_TYPE_NONE) { - mPrivateFlags |= INVALIDATED; - mPrivateFlags &= ~DRAWING_CACHE_VALID; - } do { View view = null; if (parent instanceof View) { @@ -3618,6 +3636,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager location[CHILD_LEFT_INDEX] = left; location[CHILD_TOP_INDEX] = top; + if (mLayerType != LAYER_TYPE_NONE) { + mLocalDirtyRect.union(dirty); + } + return mParent; } } else { @@ -3626,8 +3648,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager location[CHILD_LEFT_INDEX] = mLeft; location[CHILD_TOP_INDEX] = mTop; - dirty.set(0, 0, mRight - location[CHILD_LEFT_INDEX], - mBottom - location[CHILD_TOP_INDEX]); + dirty.set(0, 0, mRight - mLeft, mBottom - mTop); + + if (mLayerType != LAYER_TYPE_NONE) { + mLocalDirtyRect.union(dirty); + } return mParent; } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index c84e314975ec..f91ae9f15736 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -8151,7 +8151,7 @@ public class WebView extends AbsoluteLayout * @hide only used by the Browser */ public void setExpandedTileBounds(boolean enabled) { - mWebViewCore.sendMessage(EventHub.SET_EXPANDED_TILE_BOUNDS, enabled ? 1 : 0, 0); + nativeSetExpandedTileBounds(enabled); } /** @@ -8310,6 +8310,8 @@ public class WebView extends AbsoluteLayout static final int NO_LEFTEDGE = -1; native int nativeGetBlockLeftEdge(int x, int y, float scale); + private native void nativeSetExpandedTileBounds(boolean enabled); + // Returns a pointer to the scrollable LayerAndroid at the given point. private native int nativeScrollableLayer(int x, int y, Rect scrollRect, Rect scrollBounds); diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 6536e457e0f0..b949a4165f6e 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -578,8 +578,6 @@ final class WebViewCore { private native void nativeSetJsFlags(String flags); - private native void nativeSetExpandedTileBounds(boolean enabled); - /** * Delete text from start to end in the focused textfield. If there is no * focus, or if start == end, silently fail. If start and end are out of @@ -1001,8 +999,6 @@ final class WebViewCore { static final int PROXY_CHANGED = 193; - static final int SET_EXPANDED_TILE_BOUNDS = 194; - // private message ids private static final int DESTROY = 200; @@ -1562,10 +1558,6 @@ final class WebViewCore { mWebView.mPrivateHandler.obtainMessage(WebView.AUTOFILL_COMPLETE, null) .sendToTarget(); break; - - case EventHub.SET_EXPANDED_TILE_BOUNDS: - nativeSetExpandedTileBounds(msg.arg1 == 1); - break; } } }; diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java index 595c6343b344..8fde247920f5 100644 --- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java +++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java @@ -117,7 +117,11 @@ public class ImageWallpaper extends WallpaperService { synchronized (mLock) { updateWallpaperLocked(); } - surfaceHolder.setSizeFromLayout(); + surfaceHolder.setFixedSize(getDesiredMinimumWidth(), getDesiredMinimumHeight()); + // Used a fixed size surface, because we are special. We can do + // this because we know the current design of window animations doesn't + // cause this to break. + //surfaceHolder.setSizeFromLayout(); } @Override diff --git a/core/res/res/drawable-hdpi/ic_emergency.png b/core/res/res/drawable-hdpi/ic_emergency.png Binary files differindex b4465ff12d27..89c05e360493 100644 --- a/core/res/res/drawable-hdpi/ic_emergency.png +++ b/core/res/res/drawable-hdpi/ic_emergency.png diff --git a/data/sounds/alarms/ogg/Cesium.ogg b/data/sounds/alarms/ogg/Cesium.ogg Binary files differindex 76eca088737b..a8c379ab04a8 100644 --- a/data/sounds/alarms/ogg/Cesium.ogg +++ b/data/sounds/alarms/ogg/Cesium.ogg diff --git a/data/sounds/effects/ogg/LowBattery.ogg b/data/sounds/effects/ogg/LowBattery.ogg Binary files differindex c21218cdfd3f..dfb5d889713e 100644 --- a/data/sounds/effects/ogg/LowBattery.ogg +++ b/data/sounds/effects/ogg/LowBattery.ogg diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 691f6497f641..7379b639eed1 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -16,8 +16,11 @@ #define LOG_TAG "OpenGLRenderer" +#include <ui/Rect.h> + #include "LayerRenderer.h" #include "Properties.h" +#include "Rect.h" namespace android { namespace uirenderer { @@ -30,12 +33,25 @@ void LayerRenderer::prepareDirty(float left, float top, float right, float botto LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo); #if RENDER_LAYERS_AS_REGIONS - mLayer->region.clear(); + Rect dirty(left, top, right, bottom); + if (dirty.isEmpty() || (dirty.left <= 0 && dirty.top <= 0 && + dirty.right >= mLayer->width && dirty.bottom >= mLayer->height)) { + mLayer->region.clear(); + dirty.set(0.0f, 0.0f, mLayer->width, mLayer->height); + } else { + dirty.intersect(0.0f, 0.0f, mLayer->width, mLayer->height); + android::Rect r(dirty.left, dirty.top, dirty.right, dirty.bottom); + mLayer->region.subtractSelf(r); + } #endif glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo); +#if RENDER_LAYERS_AS_REGIONS + OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque); +#else OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque); +#endif } void LayerRenderer::finish() { diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 29603955b30a..90d6ea1bc1f0 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -671,25 +671,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { finishDrawTexture(); #if DEBUG_LAYERS_AS_REGIONS - uint32_t colors[] = { - 0x7fff0000, 0x7f00ff00, - 0x7f0000ff, 0x7fff00ff, - }; - - int offset = 0; - int32_t top = rects[0].top; - int i = 0; - - for (size_t i = 0; i < count; i++) { - if (top != rects[i].top) { - offset ^= 0x2; - top = rects[i].top; - } - - Rect r(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom); - drawColorRect(r.left, r.top, r.right, r.bottom, colors[offset + (i & 0x1)], - SkXfermode::kSrcOver_Mode); - } + drawRegionRects(layer->region); #endif layer->region.clear(); @@ -699,6 +681,32 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { #endif } +void OpenGLRenderer::drawRegionRects(const Region& region) { +#if DEBUG_LAYERS_AS_REGIONS + size_t count; + const android::Rect* rects = region.getArray(&count); + + uint32_t colors[] = { + 0x7fff0000, 0x7f00ff00, + 0x7f0000ff, 0x7fff00ff, + }; + + int offset = 0; + int32_t top = rects[0].top; + + for (size_t i = 0; i < count; i++) { + if (top != rects[i].top) { + offset ^= 0x2; + top = rects[i].top; + } + + Rect r(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom); + drawColorRect(r.left, r.top, r.right, r.bottom, colors[offset + (i & 0x1)], + SkXfermode::kSrcOver_Mode); + } +#endif +} + void OpenGLRenderer::dirtyLayer(const float left, const float top, const float right, const float bottom, const mat4 transform) { #if RENDER_LAYERS_AS_REGIONS @@ -1626,6 +1634,10 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { GL_UNSIGNED_SHORT, layer->meshIndices); finishDrawTexture(); + +#if DEBUG_LAYERS_AS_REGIONS + drawRegionRects(layer->region); +#endif } } #else diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 64def03d9ede..7bbf034c8497 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -455,6 +455,8 @@ private: void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0); void finishDrawTexture(); + void drawRegionRects(const Region& region); + /** * Should be invoked every time the glScissor is modified. */ diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java index b8d1ca7a92b3..b9105cbf9569 100644 --- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java +++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java @@ -2064,6 +2064,20 @@ class MediaArtistNativeHelper { effectSettings.alphaBlendingFadeInTimePercent = 100; effectSettings.alphaBlendingFadeOutTimePercent = 100; effectSettings.framingBuffer = null; + + /* + * Set the resized RGB file dimensions + */ + effectSettings.width = overlay.getResizedRGBSizeWidth(); + if(effectSettings.width == 0) { + effectSettings.width = bitmap.getWidth(); + } + + effectSettings.height = overlay.getResizedRGBSizeHeight(); + if(effectSettings.height == 0) { + effectSettings.height = bitmap.getHeight(); + } + } effectSettings.topLeftX = 0; @@ -2098,6 +2112,11 @@ class MediaArtistNativeHelper { return effectSettings; } + /* get Video Editor aspect ratio */ + int nativeHelperGetAspectRatio() { + return mVideoEditor.getAspectRatio(); + } + /** * Sets the audio regenerate flag * diff --git a/media/java/android/media/videoeditor/MediaItem.java b/media/java/android/media/videoeditor/MediaItem.java index e3ef59908e40..dfe0baecd1e6 100755 --- a/media/java/android/media/videoeditor/MediaItem.java +++ b/media/java/android/media/videoeditor/MediaItem.java @@ -187,6 +187,10 @@ public abstract class MediaItem { if (mEndTransition != null) { mEndTransition.invalidate(); } + + for (Overlay overlay : mOverlays) { + ((OverlayFrame)overlay).invalidateGeneratedFiles(); + } } /** diff --git a/media/java/android/media/videoeditor/OverlayFrame.java b/media/java/android/media/videoeditor/OverlayFrame.java index 2bb9a1c0bbdf..131f5f0caf7a 100755 --- a/media/java/android/media/videoeditor/OverlayFrame.java +++ b/media/java/android/media/videoeditor/OverlayFrame.java @@ -21,14 +21,18 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.DataOutputStream; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; +import android.util.Pair; -import java.io.DataOutputStream; -import java.nio.ByteBuffer; -import java.nio.IntBuffer; /** * This class is used to overlay an image on top of a media item. @@ -46,6 +50,17 @@ public class OverlayFrame extends Overlay { private int mOFHeight; /** + * resized RGB Image dimensions + */ + private int mResizedRGBWidth; + private int mResizedRGBHeight; + + /** + * The resize paint + */ + private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG); + + /** * An object of this type cannot be instantiated by using the default * constructor */ @@ -74,6 +89,8 @@ public class OverlayFrame extends Overlay { mBitmap = bitmap; mFilename = null; mBitmapFileName = null; + mResizedRGBWidth = 0; + mResizedRGBHeight = 0; } /** @@ -95,6 +112,8 @@ public class OverlayFrame extends Overlay { mBitmapFileName = filename; mBitmap = BitmapFactory.decodeFile(mBitmapFileName); mFilename = null; + mResizedRGBWidth = 0; + mResizedRGBHeight = 0; } /** @@ -182,32 +201,23 @@ public class OverlayFrame extends Overlay { mOFHeight = mBitmap.getHeight(); mFilename = path + "/" + "Overlay" + getId() + ".rgb"; - if (!(new File(mFilename).exists())) { - /** - * Save the image to a file ; as a rgb - */ - final FileOutputStream fl = new FileOutputStream(mFilename); - final DataOutputStream dos = new DataOutputStream(fl); - /** - * populate the rgb file with bitmap data - */ - final int [] framingBuffer = new int[mOFWidth]; - ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4); - IntBuffer intBuffer; + /* resize and save rgb as per project aspect ratio */ + MediaArtistNativeHelper nativeHelper = (super.getMediaItem()).getNativeContext(); + + /* get height and width for story board aspect ratio */ + final Pair<Integer, Integer> maxResolution; + final Pair<Integer, Integer>[] resolutions; + resolutions = MediaProperties.getSupportedResolutions(nativeHelper.nativeHelperGetAspectRatio()); + + // Get the highest resolution + maxResolution = resolutions[resolutions.length - 1]; + + /* Generate the rgb file with rendering mode */ + generateOverlayWithRenderingMode (super.getMediaItem(), this, + maxResolution.second /* max Height */ , + maxResolution.first /* max Width */); - byte[] array = byteBuffer.array(); - int tmp = 0; - while(tmp < mOFHeight) { - mBitmap.getPixels(framingBuffer,0,mOFWidth,0,tmp,mOFWidth,1); - intBuffer = byteBuffer.asIntBuffer(); - intBuffer.put(framingBuffer,0,mOFWidth); - dos.write(array); - tmp += 1; - } - fl.flush(); - fl.close(); - } return mFilename; } @@ -238,6 +248,30 @@ public class OverlayFrame extends Overlay { void setOverlayFrameWidth(int width) { mOFWidth = width; } + + /* + * Set the resized RGB widht and height + */ + void setResizedRGBSize(int width, int height) { + mResizedRGBWidth = width; + mResizedRGBHeight = height; + } + + /* + * Get the resized RGB Height + */ + int getResizedRGBSizeHeight() { + return mResizedRGBHeight; + } + + /* + * Get the resized RGB Width + */ + int getResizedRGBSizeWidth() { + return mResizedRGBWidth; + } + + /** * Delete the overlay files */ @@ -257,4 +291,174 @@ public class OverlayFrame extends Overlay { mBitmapFileName = null; } } + + /** + * Delete the overlay related files + */ + void invalidateGeneratedFiles() { + if (mFilename != null) { + new File(mFilename).delete(); + mFilename = null; + } + + if (mBitmapFileName != null) { + new File(mBitmapFileName).delete(); + mBitmapFileName = null; + } + } + + void generateOverlayWithRenderingMode (MediaItem mediaItemsList, OverlayFrame overlay, int height , int width) + throws FileNotFoundException, IOException { + + final MediaItem t = mediaItemsList; + + /* get the rendering mode */ + int renderMode = t.getRenderingMode(); + + Bitmap overlayBitmap = ((OverlayFrame)overlay).getBitmap(); + + /* + * Check if the resize of Overlay is needed with rendering mode applied + * because of change in export dimensions + */ + int resizedRGBFileHeight = ((OverlayFrame)overlay).getResizedRGBSizeHeight(); + int resizedRGBFileWidth = ((OverlayFrame)overlay).getResizedRGBSizeWidth(); + + /* Get original bitmap width if it is not resized */ + if(resizedRGBFileWidth == 0) { + resizedRGBFileWidth = overlayBitmap.getWidth(); + } + /* Get original bitmap height if it is not resized */ + if(resizedRGBFileHeight == 0) { + resizedRGBFileHeight = overlayBitmap.getHeight(); + } + + if (resizedRGBFileWidth != width || resizedRGBFileHeight != height + || (!(new File(((OverlayFrame)overlay).getFilename()).exists()))) { + /* + * Create the canvas bitmap + */ + final Bitmap destBitmap = Bitmap.createBitmap((int)width, + (int)height, + Bitmap.Config.ARGB_8888); + final Canvas overlayCanvas = new Canvas(destBitmap); + final Rect destRect; + final Rect srcRect; + + switch (renderMode) { + case MediaItem.RENDERING_MODE_STRETCH: { + destRect = new Rect(0, 0, overlayCanvas.getWidth(), + overlayCanvas.getHeight()); + srcRect = new Rect(0, 0, overlayBitmap.getWidth(), + overlayBitmap.getHeight()); + break; + } + + case MediaItem.RENDERING_MODE_BLACK_BORDER: { + int left, right, top, bottom; + float aROverlayImage, aRCanvas; + aROverlayImage = (float)(overlayBitmap.getWidth()) / + (float)(overlayBitmap.getHeight()); + + aRCanvas = (float)(overlayCanvas.getWidth()) / + (float)(overlayCanvas.getHeight()); + + if (aROverlayImage > aRCanvas) { + int newHeight = ((overlayCanvas.getWidth() * overlayBitmap.getHeight()) + / overlayBitmap.getWidth()); + left = 0; + top = (overlayCanvas.getHeight() - newHeight) / 2; + right = overlayCanvas.getWidth(); + bottom = top + newHeight; + } else { + int newWidth = ((overlayCanvas.getHeight() * overlayBitmap.getWidth()) + / overlayBitmap.getHeight()); + left = (overlayCanvas.getWidth() - newWidth) / 2; + top = 0; + right = left + newWidth; + bottom = overlayCanvas.getHeight(); + } + + destRect = new Rect(left, top, right, bottom); + srcRect = new Rect(0, 0, overlayBitmap.getWidth(), overlayBitmap.getHeight()); + break; + } + + case MediaItem.RENDERING_MODE_CROPPING: { + // Calculate the source rect + int left, right, top, bottom; + float aROverlayImage, aRCanvas; + aROverlayImage = (float)(overlayBitmap.getWidth()) / + (float)(overlayBitmap.getHeight()); + aRCanvas = (float)(overlayCanvas.getWidth()) / + (float)(overlayCanvas.getHeight()); + if (aROverlayImage < aRCanvas) { + int newHeight = ((overlayBitmap.getWidth() * overlayCanvas.getHeight()) + / overlayCanvas.getWidth()); + + left = 0; + top = (overlayBitmap.getHeight() - newHeight) / 2; + right = overlayBitmap.getWidth(); + bottom = top + newHeight; + } else { + int newWidth = ((overlayBitmap.getHeight() * overlayCanvas.getWidth()) + / overlayCanvas.getHeight()); + left = (overlayBitmap.getWidth() - newWidth) / 2; + top = 0; + right = left + newWidth; + bottom = overlayBitmap.getHeight(); + } + + srcRect = new Rect(left, top, right, bottom); + destRect = new Rect(0, 0, overlayCanvas.getWidth(), overlayCanvas.getHeight()); + break; + } + + default: { + throw new IllegalStateException("Rendering mode: " + renderMode); + } + } + + overlayCanvas.drawBitmap(overlayBitmap, srcRect, destRect, sResizePaint); + + /* + * Write to the dest file + */ + String outFileName = ((OverlayFrame)overlay).getFilename(); + + /* + * Save the image to same rgb file + */ + if (outFileName != null) { + new File(outFileName).delete(); + } + + final FileOutputStream fl = new FileOutputStream(outFileName); + final DataOutputStream dos = new DataOutputStream(fl); + + /* + * Populate the rgb file with bitmap data + */ + final int [] framingBuffer = new int[width]; + ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4); + IntBuffer intBuffer; + + byte[] array = byteBuffer.array(); + int tmp = 0; + while(tmp < height) { + destBitmap.getPixels(framingBuffer,0,width,0,tmp,width,1); + intBuffer = byteBuffer.asIntBuffer(); + intBuffer.put(framingBuffer,0,width); + dos.write(array); + tmp += 1; + } + fl.flush(); + fl.close(); + + /* + * Set the resized RGB width and height + */ + ((OverlayFrame)overlay).setResizedRGBSize(width, height); + } + } } diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java index 8bbd8e8f752a..7608c059a4ab 100755 --- a/media/java/android/media/videoeditor/VideoEditorImpl.java +++ b/media/java/android/media/videoeditor/VideoEditorImpl.java @@ -109,6 +109,8 @@ public class VideoEditorImpl implements VideoEditor { private static final String ATTR_OVERLAY_RGB_FILENAME = "overlay_rgb_filename"; private static final String ATTR_OVERLAY_FRAME_WIDTH = "overlay_frame_width"; private static final String ATTR_OVERLAY_FRAME_HEIGHT = "overlay_frame_height"; + private static final String ATTR_OVERLAY_RESIZED_RGB_FRAME_WIDTH = "resized_RGBframe_width"; + private static final String ATTR_OVERLAY_RESIZED_RGB_FRAME_HEIGHT = "resized_RGBframe_height"; /* * Instance variables @@ -867,7 +869,6 @@ public class VideoEditorImpl implements VideoEditor { mMANativeHelper.unlock(); } } -Log.i("VE_IMPL","renderPreviewFrame <--"); return result; } @@ -1154,6 +1155,15 @@ Log.i("VE_IMPL","renderPreviewFrame <--"); ((OverlayFrame)overlay).setOverlayFrameWidth(overlayFrameWidth); ((OverlayFrame)overlay).setOverlayFrameHeight(overlayFrameHeight); + + final int resizedRGBFrameWidth = + Integer.parseInt(parser.getAttributeValue("", + ATTR_OVERLAY_RESIZED_RGB_FRAME_WIDTH)); + final int resizedRGBFrameHeight = + Integer.parseInt(parser.getAttributeValue("", + ATTR_OVERLAY_RESIZED_RGB_FRAME_HEIGHT)); + + ((OverlayFrame)overlay).setResizedRGBSize(resizedRGBFrameWidth, resizedRGBFrameHeight); } return overlay; @@ -1340,6 +1350,11 @@ Log.i("VE_IMPL","renderPreviewFrame <--"); Integer.toString(overlayFrame.getOverlayFrameWidth())); serializer.attribute("", ATTR_OVERLAY_FRAME_HEIGHT, Integer.toString(overlayFrame.getOverlayFrameHeight())); + serializer.attribute("", ATTR_OVERLAY_RESIZED_RGB_FRAME_WIDTH, + Integer.toString(overlayFrame.getResizedRGBSizeWidth())); + serializer.attribute("", ATTR_OVERLAY_RESIZED_RGB_FRAME_HEIGHT, + Integer.toString(overlayFrame.getResizedRGBSizeHeight())); + } } @@ -1524,6 +1539,17 @@ Log.i("VE_IMPL","renderPreviewFrame <--"); for (Transition transition : mTransitions) { transition.invalidate(); } + + final Iterator<MediaItem> it = mMediaItems.iterator(); + + while (it.hasNext()) { + final MediaItem t = it.next(); + List<Overlay> overlayList = t.getAllOverlays(); + for (Overlay overlay : overlayList) { + + ((OverlayFrame)overlay).invalidateGeneratedFiles(); + } + } } /* diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp index 221bfa1e93f0..204057d10d34 100755 --- a/media/jni/mediaeditor/VideoEditorMain.cpp +++ b/media/jni/mediaeditor/VideoEditorMain.cpp @@ -454,7 +454,7 @@ static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType, case MSG_TYPE_OVERLAY_CLEAR: isSendProgress = false; pContext->mOverlayFileName = NULL; - LOGI("MSG_TYPE_OVERLAY_CLEAR"); + LOGV("MSG_TYPE_OVERLAY_CLEAR"); //argc is not used pContext->mIsUpdateOverlay = true; break; @@ -1485,7 +1485,7 @@ videoEditor_populateSettings( if ( pContext->pEditSettings->nbEffects ) { pOverlayIndex - = (int*) M4OSA_malloc(pContext->pEditSettings->nbEffects, 0, + = (int*) M4OSA_malloc(pContext->pEditSettings->nbEffects * sizeof(int), 0, (M4OSA_Char*)"pOverlayIndex"); } @@ -1528,9 +1528,15 @@ videoEditor_populateSettings( result = M4xVSS_internalConvertARGB888toYUV420_FrammingEffect(pContext->engineContext, &(pContext->pEditSettings->Effects[j]),aFramingCtx, pContext->pEditSettings->Effects[j].xVSS.framingScaledSize); - if (result != M4NO_ERROR) - { + videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv, + (M4NO_ERROR != result), result); + if (needToBeLoaded == false) { M4OSA_TRACE1_1("M4xVSS_internalConvertARGB888toYUV420_FrammingEffect returned 0x%x", result); + if (aFramingCtx != M4OSA_NULL) { + M4OSA_free((M4OSA_MemAddr32)aFramingCtx); + aFramingCtx = M4OSA_NULL; + } + return; } //framing buffers are resized to fit the output video resolution. diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java index 2edfc23d8ac3..5eaa5a074114 100644 --- a/telephony/java/android/telephony/CellLocation.java +++ b/telephony/java/android/telephony/CellLocation.java @@ -61,9 +61,9 @@ public abstract class CellLocation { * @hide */ public static CellLocation newFromBundle(Bundle bundle) { - // TelephonyManager.getDefault().getPhoneType() handles the case when + // TelephonyManager.getDefault().getCurrentPhoneType() handles the case when // ITelephony interface is not up yet. - switch(TelephonyManager.getDefault().getPhoneType()) { + switch(TelephonyManager.getDefault().getCurrentPhoneType()) { case Phone.PHONE_TYPE_CDMA: return new CdmaCellLocation(bundle); case Phone.PHONE_TYPE_GSM: @@ -89,9 +89,9 @@ public abstract class CellLocation { * */ public static CellLocation getEmpty() { - // TelephonyManager.getDefault().getPhoneType() handles the case when + // TelephonyManager.getDefault().getCurrentPhoneType() handles the case when // ITelephony interface is not up yet. - switch(TelephonyManager.getDefault().getPhoneType()) { + switch(TelephonyManager.getDefault().getCurrentPhoneType()) { case Phone.PHONE_TYPE_CDMA: return new CdmaCellLocation(); case Phone.PHONE_TYPE_GSM: diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 88d943695c20..b0f0a4320cbe 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -276,15 +276,17 @@ public class TelephonyManager { public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP; /** - * Returns a constant indicating the device phone type. This - * indicates the type of radio used to transmit voice calls. + * Returns the current phone type. + * TODO: This is a last minute change and hence hidden. * * @see #PHONE_TYPE_NONE * @see #PHONE_TYPE_GSM * @see #PHONE_TYPE_CDMA * @see #PHONE_TYPE_SIP + * + * {@hide} */ - public int getPhoneType() { + public int getCurrentPhoneType() { try{ ITelephony telephony = getITelephony(); if (telephony != null) { @@ -304,6 +306,21 @@ public class TelephonyManager { } } + /** + * Returns a constant indicating the device phone type. This + * indicates the type of radio used to transmit voice calls. + * + * @see #PHONE_TYPE_NONE + * @see #PHONE_TYPE_GSM + * @see #PHONE_TYPE_CDMA + * @see #PHONE_TYPE_SIP + */ + public int getPhoneType() { + if (!isVoiceCapable()) { + return PHONE_TYPE_NONE; + } + return getCurrentPhoneType(); + } private int getPhoneTypeFromProperty() { int type = diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 2db44175a018..fc50334da73b 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -89,6 +89,15 @@ </activity> <activity + android:name="ViewLayersActivity5" + android:label="_ViewLayers5"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="AlphaLayersActivity" android:label="_αLayers"> <intent-filter> diff --git a/tests/HwAccelerationTest/res/layout/view_layers_5.xml b/tests/HwAccelerationTest/res/layout/view_layers_5.xml new file mode 100644 index 000000000000..653f3a8b2789 --- /dev/null +++ b/tests/HwAccelerationTest/res/layout/view_layers_5.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout + android:orientation="vertical" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1"> + + <Button + android:onClick="setLayerEnabled" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Enable layer" /> + + <Button + android:onClick="setLayerDisabled" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Disable layer" /> + + </LinearLayout> + + <ListView + android:id="@+id/list1" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" /> + +</LinearLayout> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java new file mode 100644 index 000000000000..95a5b0d8b36d --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; + +@SuppressWarnings({"UnusedDeclaration"}) +public class ViewLayersActivity5 extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.view_layers_5); + + setupList(R.id.list1); + } + + public void setLayerDisabled(View v) { + ((ViewGroup) findViewById(R.id.list1).getParent()).setChildrenLayersEnabled(false); + } + + public void setLayerEnabled(View v) { + ((ViewGroup) findViewById(R.id.list1).getParent()).setChildrenLayersEnabled(true); + } + + private void setupList(int listId) { + final Paint p = new Paint(); + p.setColorFilter(new PorterDuffColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY)); + + final ListView list = (ListView) findViewById(listId); + list.setAdapter(new SimpleListAdapter(this)); + list.setLayerType(View.LAYER_TYPE_HARDWARE, p); + } + + private static class SimpleListAdapter extends ArrayAdapter<String> { + public SimpleListAdapter(Context context) { + super(context, android.R.layout.simple_list_item_1, DATA_LIST); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView v = (TextView) super.getView(position, convertView, parent); + final Resources r = getContext().getResources(); + final DisplayMetrics metrics = r.getDisplayMetrics(); + v.setCompoundDrawablePadding((int) (6 * metrics.density + 0.5f)); + v.setCompoundDrawablesWithIntrinsicBounds(r.getDrawable(R.drawable.icon), + null, null, null); + return v; + } + } + + private static final String[] DATA_LIST = { + "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", + "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", + "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", + "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", + "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", + "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", + "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria", + "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde", + "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", + "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", + "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic", + "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic", + "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", + "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland", + "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia", + "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar", + "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", + "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary", + "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica", + "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos", + "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", + "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", + "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova", + "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", + "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", + "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas", + "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", + "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar", + "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena", + "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon", + "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal", + "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands", + "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea", + "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden", + "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas", + "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", + "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda", + "Ukraine", "United Arab Emirates", "United Kingdom", + "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", + "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara", + "Yemen", "Yugoslavia", "Zambia", "Zimbabwe" + }; +} |