diff options
49 files changed, 469 insertions, 224 deletions
diff --git a/api/11.xml b/api/11.xml index 20337875a7ab..6a672d16611b 100644 --- a/api/11.xml +++ b/api/11.xml @@ -70101,7 +70101,7 @@ </parameter> </method> <method name="getAttachedDbs" - return="java.util.ArrayList<android.util.Pair<java.lang.String, java.lang.String>>" + return="java.util.List<android.util.Pair<java.lang.String, java.lang.String>>" abstract="false" native="false" synchronized="false" diff --git a/api/current.xml b/api/current.xml index 248a1e2c4e99..28efc7edaa0f 100644 --- a/api/current.xml +++ b/api/current.xml @@ -70123,7 +70123,7 @@ </parameter> </method> <method name="getAttachedDbs" - return="java.util.ArrayList<android.util.Pair<java.lang.String, java.lang.String>>" + return="java.util.List<android.util.Pair<java.lang.String, java.lang.String>>" abstract="false" native="false" synchronized="false" diff --git a/core/java/android/database/DefaultDatabaseErrorHandler.java b/core/java/android/database/DefaultDatabaseErrorHandler.java index 61337dde6c3a..a9e39c321ac2 100644 --- a/core/java/android/database/DefaultDatabaseErrorHandler.java +++ b/core/java/android/database/DefaultDatabaseErrorHandler.java @@ -16,7 +16,7 @@ package android.database; import java.io.File; -import java.util.ArrayList; +import java.util.List; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; @@ -65,7 +65,7 @@ public final class DefaultDatabaseErrorHandler implements DatabaseErrorHandler { return; } - ArrayList<Pair<String, String>> attachedDbs = null; + List<Pair<String, String>> attachedDbs = null; try { // Close the database, which will cause subsequent operations to fail. // before that, get the attached database list first. diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 1a43b300f25d..b3fd9147f23c 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -40,6 +40,7 @@ import dalvik.system.BlockGuard; import java.io.File; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.List; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -2504,7 +2505,7 @@ public class SQLiteDatabase extends SQLiteClosable { String lastnode = path.substring((indx != -1) ? ++indx : 0); // get list of attached dbs and for each db, get its size and pagesize - ArrayList<Pair<String, String>> attachedDbs = db.getAttachedDbs(); + List<Pair<String, String>> attachedDbs = db.getAttachedDbs(); if (attachedDbs == null) { continue; } @@ -2560,7 +2561,7 @@ public class SQLiteDatabase extends SQLiteClosable { * @return ArrayList of pairs of (database name, database file path) or null if the database * is not open. */ - public ArrayList<Pair<String, String>> getAttachedDbs() { + public List<Pair<String, String>> getAttachedDbs() { if (!isOpen()) { return null; } @@ -2613,7 +2614,7 @@ public class SQLiteDatabase extends SQLiteClosable { */ public boolean isDatabaseIntegrityOk() { verifyDbIsOpen(); - ArrayList<Pair<String, String>> attachedDbs = null; + List<Pair<String, String>> attachedDbs = null; try { attachedDbs = getAttachedDbs(); if (attachedDbs == null) { diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 41fc6c6e33d0..b21af410b306 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -1537,6 +1537,7 @@ public final class ViewRoot extends Handler implements ViewParent, int top = dirty.top; int right = dirty.right; int bottom = dirty.bottom; + canvas = surface.lockCanvas(dirty); if (left != dirty.left || top != dirty.top || right != dirty.right || diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index ec3c32971c26..b7ffd14cf72a 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -88,6 +88,9 @@ class BrowserFrame extends Handler { // Attached Javascript interfaces private Map<String, Object> mJSInterfaceMap; + // Key store handler when Chromium HTTP stack is used. + private KeyStoreHandler mKeyStoreHandler = null; + // message ids // a message posted when a frame loading is completed static final int FRAME_COMPLETED = 1001; @@ -1173,8 +1176,27 @@ class BrowserFrame extends Handler { } mimeType = MimeTypeMap.getSingleton().remapGenericMimeType( mimeType, url, contentDisposition); - mCallbackProxy.onDownloadStart(url, userAgent, + + if (CertTool.getCertType(mimeType) != null) { + mKeyStoreHandler = new KeyStoreHandler(mimeType); + } else { + mCallbackProxy.onDownloadStart(url, userAgent, contentDisposition, mimeType, contentLength); + } + } + + /** + * Called by JNI for Chrome HTTP stack when the Java side needs to access the data. + */ + private void didReceiveData(byte data[], int size) { + if (mKeyStoreHandler != null) mKeyStoreHandler.didReceiveData(data, size); + } + + private void didFinishLoading() { + if (mKeyStoreHandler != null) { + mKeyStoreHandler.installCert(mContext); + mKeyStoreHandler = null; + } } /** diff --git a/core/java/android/webkit/CertTool.java b/core/java/android/webkit/CertTool.java index d25d970eea88..4c534f93cd26 100644 --- a/core/java/android/webkit/CertTool.java +++ b/core/java/android/webkit/CertTool.java @@ -29,6 +29,7 @@ import android.util.Log; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.util.HashMap; class CertTool { private static final String LOGTAG = "CertTool"; @@ -39,6 +40,14 @@ class CertTool { static final String CERT = Credentials.CERTIFICATE; static final String PKCS12 = Credentials.PKCS12; + private static HashMap<String, String> sCertificateTypeMap; + static { + sCertificateTypeMap = new HashMap<String, String>(); + sCertificateTypeMap.put("application/x-x509-ca-cert", CertTool.CERT); + sCertificateTypeMap.put("application/x-x509-user-cert", CertTool.CERT); + sCertificateTypeMap.put("application/x-pkcs12", CertTool.PKCS12); + } + static String[] getKeyStrengthList() { return new String[] {"High Grade", "Medium Grade"}; } @@ -66,5 +75,9 @@ class CertTool { Credentials.getInstance().install(context, type, value); } + static String getCertType(String mimeType) { + return sCertificateTypeMap.get(mimeType); + } + private CertTool() {} } diff --git a/core/java/android/webkit/KeyStoreHandler.java b/core/java/android/webkit/KeyStoreHandler.java new file mode 100644 index 000000000000..849007e9d547 --- /dev/null +++ b/core/java/android/webkit/KeyStoreHandler.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.webkit; + +import android.content.Context; +import android.os.Handler; +import android.util.Log; + +/** + * KeyStoreHandler: class responsible for certificate installation to + * the system key store. It reads the certificates file from network + * then pass the bytes to class CertTool. + * This class is only needed if the Chromium HTTP stack is used. + */ +class KeyStoreHandler extends Handler { + private static final String LOGTAG = "KeyStoreHandler"; + + private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(); + + private String mMimeType; + + public KeyStoreHandler(String mimeType) { + mMimeType = mimeType; + } + + /** + * Add data to the internal collection of data. + * @param data A byte array containing the content. + * @param length The length of data. + */ + public void didReceiveData(byte[] data, int length) { + synchronized (mDataBuilder) { + mDataBuilder.append(data, 0, length); + } + } + + public void installCert(Context context) { + String type = CertTool.getCertType(mMimeType); + if (type == null) return; + + // This must be synchronized so that no more data can be added + // after getByteSize returns. + synchronized (mDataBuilder) { + // In the case of downloading certificate, we will save it + // to the KeyStore and stop the current loading so that it + // will not generate a new history page + byte[] cert = new byte[mDataBuilder.getByteSize()]; + int offset = 0; + while (true) { + ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk(); + if (c == null) break; + + if (c.mLength != 0) { + System.arraycopy(c.mArray, 0, cert, offset, c.mLength); + offset += c.mLength; + } + c.release(); + } + CertTool.addCertificate(context, type, cert); + return; + } + } +} diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index 6d1d39ac034f..04af73877cce 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -75,14 +75,6 @@ class LoadListener extends Handler implements EventHandler { private static final int HTTP_NOT_FOUND = 404; private static final int HTTP_PROXY_AUTH = 407; - private static HashMap<String, String> sCertificateTypeMap; - static { - sCertificateTypeMap = new HashMap<String, String>(); - sCertificateTypeMap.put("application/x-x509-ca-cert", CertTool.CERT); - sCertificateTypeMap.put("application/x-x509-user-cert", CertTool.CERT); - sCertificateTypeMap.put("application/x-pkcs12", CertTool.PKCS12); - } - private static int sNativeLoaderCount; private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(); @@ -1053,7 +1045,7 @@ class LoadListener extends Handler implements EventHandler { // This commits the headers without checking the response status code. private void commitHeaders() { - if (mIsMainPageLoader && sCertificateTypeMap.containsKey(mMimeType)) { + if (mIsMainPageLoader && CertTool.getCertType(mMimeType) != null) { // In the case of downloading certificate, we will save it to the // KeyStore in commitLoad. Do not call webcore. return; @@ -1114,7 +1106,7 @@ class LoadListener extends Handler implements EventHandler { } if (mIsMainPageLoader) { - String type = sCertificateTypeMap.get(mMimeType); + String type = CertTool.getCertType(mMimeType); if (type != null) { // This must be synchronized so that no more data can be added // after getByteSize returns. diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 2a2b3af05a3f..63632996bc99 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -673,6 +673,7 @@ public class WebView extends AbsoluteLayout static final int AUTOFILL_COMPLETE = 134; static final int SELECT_AT = 135; + static final int SCREEN_ON = 136; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int LAST_PACKAGE_MSG_ID = SET_TOUCH_HIGHLIGHT_RECTS; @@ -726,7 +727,8 @@ public class WebView extends AbsoluteLayout "SAVE_WEBARCHIVE_FINISHED", // = 132; "SET_AUTOFILLABLE", // = 133; "AUTOFILL_COMPLETE", // = 134; - "SELECT_AT" // = 135; + "SELECT_AT", // = 135; + "SCREEN_ON" // = 136; }; // If the site doesn't use the viewport meta tag to specify the viewport, @@ -7454,6 +7456,10 @@ public class WebView extends AbsoluteLayout doMotionUp(msg.arg1, msg.arg2); break; + case SCREEN_ON: + setKeepScreenOn(msg.arg1 == 1); + break; + case SHOW_FULLSCREEN: { View view = (View) msg.obj; int npp = msg.arg1; diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 27bf51c9442f..3bde0002e3aa 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -2549,6 +2549,15 @@ final class WebViewCore { } // called by JNI + private void keepScreenOn(boolean screenOn) { + if (mWebView != null) { + Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SCREEN_ON); + message.arg1 = screenOn ? 1 : 0; + message.sendToTarget(); + } + } + + // called by JNI private Class<?> getPluginClass(String libName, String clsName) { if (mWebView == null) { diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 5dc42e44ae9f..8116a1237112 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -190,6 +190,7 @@ public class ListPopupWindow { public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { mContext = context; mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); + mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); } /** @@ -576,7 +577,6 @@ public class ListPopupWindow { } mPopup.setWindowLayoutMode(widthSpec, heightSpec); - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); mPopup.setClipToScreenEnabled(true); // use outside touchable to dismiss drop down when touching outside of it, so diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 0baddcb97501..a92272ce1ce4 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -665,6 +665,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { @Override public void show() { setWidth(Spinner.this.getWidth()); + setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); super.show(); getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); setSelection(Spinner.this.getSelectedItemPosition()); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b024dcb2bb0f..b2170521a97f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -3320,7 +3320,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } else if (actionCode == EditorInfo.IME_ACTION_DONE) { InputMethodManager imm = InputMethodManager.peekInstance(); - if (imm != null) { + if (imm != null && imm.isActive(this)) { imm.hideSoftInputFromWindow(getWindowToken(), 0); } return; @@ -4822,9 +4822,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mOnClickListener == null) { if (mMovement != null && mText instanceof Editable && mLayout != null && onCheckIsTextEditor()) { - InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(this, 0); + InputMethodManager imm = InputMethodManager.peekInstance(); + if (imm != null) imm.showSoftInput(this, 0); } } } @@ -4877,7 +4876,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // No target for next focus, but make sure the IME // if this came from it. InputMethodManager imm = InputMethodManager.peekInstance(); - if (imm != null) { + if (imm != null && imm.isActive(this)) { imm.hideSoftInputFromWindow(getWindowToken(), 0); } } @@ -7149,10 +7148,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // the IME. Showing the IME while focus is moved using the D-Pad is a bad idea, however this // does not happen in that case (using the arrows on a bluetooth keyboard). if (focused && isTextEditable()) { - final InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - - imm.showSoftInput(this, 0, null); + final InputMethodManager imm = InputMethodManager.peekInstance(); + if (imm != null) imm.showSoftInput(this, 0, null); } } @@ -7346,10 +7343,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Show the IME, except when selecting in read-only text. if (!mTextIsSelectable) { - final InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - - handled |= imm.showSoftInput(this, 0, csr) && (csr != null); + final InputMethodManager imm = InputMethodManager.peekInstance(); + handled |= imm != null && imm.showSoftInput(this, 0, csr) && (csr != null); } stopSelectionActionMode(); @@ -8247,16 +8242,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener selectCurrentWord(); } - if (!mTextIsSelectable) { - // Show the IME, except when selection non editable text. - final InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(this, 0, null); - } - ActionMode.Callback actionModeCallback = new SelectionActionModeCallback(); mSelectionActionMode = startActionMode(actionModeCallback); - return mSelectionActionMode != null; + final boolean selectionStarted = mSelectionActionMode != null; + + if (selectionStarted && !mTextIsSelectable) { + // Show the IME to be able to replace text, except when selecting non editable text. + final InputMethodManager imm = InputMethodManager.peekInstance(); + if (imm != null) imm.showSoftInput(this, 0, null); + } + + return selectionStarted; } /** diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index e4af33f1e885..aa9c1078363b 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -296,8 +296,10 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) { const sp<Surface>& surface(getSurface(env, clazz)); - if (!Surface::isValid(surface)) + if (!Surface::isValid(surface)) { + doThrow(env, "java/lang/IllegalArgumentException", NULL); return 0; + } // get dirty region Region dirtyRegion; diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim0.png b/core/res/res/drawable-hdpi/stat_sys_download_anim0.png Binary files differindex 8858a75b72ae..943e62020335 100644 --- a/core/res/res/drawable-hdpi/stat_sys_download_anim0.png +++ b/core/res/res/drawable-hdpi/stat_sys_download_anim0.png diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png Binary files differindex 5418785a1431..28edae120cca 100644 --- a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png +++ b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim2.png b/core/res/res/drawable-hdpi/stat_sys_download_anim2.png Binary files differindex f55887ed22fc..556a46f228cb 100644 --- a/core/res/res/drawable-hdpi/stat_sys_download_anim2.png +++ b/core/res/res/drawable-hdpi/stat_sys_download_anim2.png diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim3.png b/core/res/res/drawable-hdpi/stat_sys_download_anim3.png Binary files differindex 50fcc3662b52..422d72b0b4cb 100644 --- a/core/res/res/drawable-hdpi/stat_sys_download_anim3.png +++ b/core/res/res/drawable-hdpi/stat_sys_download_anim3.png diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim4.png b/core/res/res/drawable-hdpi/stat_sys_download_anim4.png Binary files differindex 65ac698e928f..24a0db5582d6 100644 --- a/core/res/res/drawable-hdpi/stat_sys_download_anim4.png +++ b/core/res/res/drawable-hdpi/stat_sys_download_anim4.png diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim5.png b/core/res/res/drawable-hdpi/stat_sys_download_anim5.png Binary files differindex 7fb60324452f..97e5a6b37673 100644 --- a/core/res/res/drawable-hdpi/stat_sys_download_anim5.png +++ b/core/res/res/drawable-hdpi/stat_sys_download_anim5.png diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim0.png b/core/res/res/drawable-mdpi/stat_sys_download_anim0.png Binary files differindex a326868b46a6..39e4ccb8d207 100644 --- a/core/res/res/drawable-mdpi/stat_sys_download_anim0.png +++ b/core/res/res/drawable-mdpi/stat_sys_download_anim0.png diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim1.png b/core/res/res/drawable-mdpi/stat_sys_download_anim1.png Binary files differindex 42e5c2a98954..429ebd7c9c1f 100644 --- a/core/res/res/drawable-mdpi/stat_sys_download_anim1.png +++ b/core/res/res/drawable-mdpi/stat_sys_download_anim1.png diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim2.png b/core/res/res/drawable-mdpi/stat_sys_download_anim2.png Binary files differindex 0c27622c125b..b3de461f4a90 100644 --- a/core/res/res/drawable-mdpi/stat_sys_download_anim2.png +++ b/core/res/res/drawable-mdpi/stat_sys_download_anim2.png diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim3.png b/core/res/res/drawable-mdpi/stat_sys_download_anim3.png Binary files differindex b1b84d4490b2..195498e19b5e 100644 --- a/core/res/res/drawable-mdpi/stat_sys_download_anim3.png +++ b/core/res/res/drawable-mdpi/stat_sys_download_anim3.png diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim4.png b/core/res/res/drawable-mdpi/stat_sys_download_anim4.png Binary files differindex 75cc99c21d86..8fc3e8669138 100644 --- a/core/res/res/drawable-mdpi/stat_sys_download_anim4.png +++ b/core/res/res/drawable-mdpi/stat_sys_download_anim4.png diff --git a/core/res/res/drawable-mdpi/stat_sys_download_anim5.png b/core/res/res/drawable-mdpi/stat_sys_download_anim5.png Binary files differindex c21b6acbd418..c6f2f4e06f34 100644 --- a/core/res/res/drawable-mdpi/stat_sys_download_anim5.png +++ b/core/res/res/drawable-mdpi/stat_sys_download_anim5.png diff --git a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java index cd38bf0788ea..6786700d3228 100644 --- a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java +++ b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java @@ -37,6 +37,7 @@ import junit.framework.Assert; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Locale; public class DatabaseGeneralTest extends AndroidTestCase implements PerformanceTestCase { @@ -1130,7 +1131,7 @@ public class DatabaseGeneralTest extends AndroidTestCase implements PerformanceT assertTrue(new File(attachedDb1File).exists()); assertNotNull(dbObj); assertTrue(dbObj.isOpen()); - ArrayList<Pair<String, String>> attachedDbs = dbObj.getAttachedDbs(); + List<Pair<String, String>> attachedDbs = dbObj.getAttachedDbs(); try { errorHandler.onCorruption(dbObj); assertFalse(dbfile.exists()); diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java index a977b8ed63ca..f1315c042b55 100755 --- a/media/java/android/media/videoeditor/MediaImageItem.java +++ b/media/java/android/media/videoeditor/MediaImageItem.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * 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. @@ -71,6 +71,7 @@ public class MediaImageItem extends MediaItem { private String mDecodedFilename; private int mGeneratedClipHeight; private int mGeneratedClipWidth; + private String mFileName; private final MediaArtistNativeHelper mMANativeHelper; @@ -116,7 +117,7 @@ public class MediaImageItem extends MediaItem { } catch (Exception e) { throw new IllegalArgumentException("Unsupported file or file not found: " + filename); } - + mFileName = filename; /** * Determine the dimensions of the image */ @@ -149,108 +150,53 @@ public class MediaImageItem extends MediaItem { /** * Get the highest resolution */ - final FileOutputStream fl = new FileOutputStream(mDecodedFilename); - final DataOutputStream dos = new DataOutputStream(fl); final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1]; + + final Bitmap imageBitmap; + if (mHeight > maxResolution.second) { /** * We need to scale the image */ - final Bitmap scaledImage = scaleImage(filename, maxResolution.first, - maxResolution.second); + imageBitmap = scaleImage(filename, maxResolution.first, + maxResolution.second); mScaledFilename = String.format(mMANativeHelper.getProjectPath() + "/" + "scaled" + getId()+ ".JPG"); if (!((new File(mScaledFilename)).exists())) { super.mRegenerateClip = true; final FileOutputStream f1 = new FileOutputStream(mScaledFilename); - scaledImage.compress(Bitmap.CompressFormat.JPEG, 50,f1); + imageBitmap.compress(Bitmap.CompressFormat.JPEG, 50,f1); f1.close(); } - mScaledWidth = scaledImage.getWidth(); - mScaledHeight = scaledImage.getHeight(); - - int mNewWidth = 0; - int mNewHeight = 0; - if ((mScaledWidth % 2 ) != 0) { - mNewWidth = mScaledWidth - 1; - } else { - mNewWidth = mScaledWidth; - } - - if ((mScaledHeight % 2 ) != 0) { - mNewHeight = mScaledHeight - 1; - } else { - mNewHeight = mScaledHeight; - } - - final int [] framingBuffer = new int[mNewWidth]; + mScaledWidth = (imageBitmap.getWidth() >> 1) << 1; + mScaledHeight = (imageBitmap.getHeight() >> 1) << 1; + } else { + mScaledFilename = filename; + mScaledWidth = (mWidth >> 1) << 1; + mScaledHeight = (mHeight >> 1) << 1; + imageBitmap = BitmapFactory.decodeFile(mScaledFilename); + } + int newWidth = mScaledWidth; + int newHeight = mScaledHeight; + if (!((new File(mDecodedFilename)).exists())) { + final FileOutputStream fl = new FileOutputStream(mDecodedFilename); + final DataOutputStream dos = new DataOutputStream(fl); + final int [] framingBuffer = new int[newWidth]; final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4); IntBuffer intBuffer; - final byte[] array = byteBuffer.array(); int tmp = 0; - while (tmp < mNewHeight) { - scaledImage.getPixels(framingBuffer,0,mScaledWidth,0, - tmp,mNewWidth,1); - intBuffer = byteBuffer.asIntBuffer(); - intBuffer.put(framingBuffer,0,mNewWidth); - dos.write(array); - tmp += 1; - } - - mScaledWidth = mNewWidth; - mScaledHeight = mNewHeight; - scaledImage.recycle(); - } else { - final Bitmap scaledImage = BitmapFactory.decodeFile(filename); - mScaledFilename = String.format(mMANativeHelper.getProjectPath() - + "/" + "scaled" + getId()+ ".JPG"); - if (!((new File(mScaledFilename)).exists())) { - super.mRegenerateClip = true; - final FileOutputStream f1 = new FileOutputStream(mScaledFilename); - scaledImage.compress(Bitmap.CompressFormat.JPEG, 50,f1); - f1.close(); - } - - mScaledWidth = scaledImage.getWidth(); - mScaledHeight = scaledImage.getHeight(); - - int mNewWidth = 0; - int mNewheight = 0; - if ((mScaledWidth % 2 ) != 0) { - mNewWidth = mScaledWidth - 1; - } else { - mNewWidth = mScaledWidth; - } - - if ((mScaledHeight % 2 ) != 0) { - mNewheight = mScaledHeight - 1; - } else { - mNewheight = mScaledHeight; - } - - final Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename); - final int [] framingBuffer = new int[mNewWidth]; - ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4); - IntBuffer intBuffer; - - byte[] array = byteBuffer.array(); - int tmp = 0; - while (tmp < mNewheight) { - imageBitmap.getPixels(framingBuffer,0,mScaledWidth,0, - tmp,mNewWidth,1); + while (tmp < newHeight) { + imageBitmap.getPixels(framingBuffer, 0, mScaledWidth, 0, + tmp, newWidth, 1); intBuffer = byteBuffer.asIntBuffer(); - intBuffer.put(framingBuffer,0,mNewWidth); + intBuffer.put(framingBuffer, 0, newWidth); dos.write(array); tmp += 1; } - - mScaledWidth = mNewWidth; - mScaledHeight = mNewheight; - imageBitmap.recycle(); + fl.close(); } - - fl.close(); + imageBitmap.recycle(); System.gc(); } @@ -772,7 +718,9 @@ public class MediaImageItem extends MediaItem { } if (mScaledFilename != null) { - new File(mScaledFilename).delete(); + if(mFileName != mScaledFilename) { + new File(mScaledFilename).delete(); + } mScaledFilename = null; } diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket.png Binary files differdeleted file mode 100644 index 12b6ceaa4af0..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_drag.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_drag.png Binary files differdeleted file mode 100644 index 28590bca66fc..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_drag.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_hidden.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_hidden.png Binary files differdeleted file mode 100644 index c66ad777a1c1..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_hidden.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_holding.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_holding.png Binary files differdeleted file mode 100644 index 6416969748b4..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_pocket_holding.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/scrubber_control_disabled_holo.png b/packages/SystemUI/res/drawable-hdpi/scrubber_control_disabled_holo.png Binary files differnew file mode 100644 index 000000000000..18bd8b49978d --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/scrubber_control_disabled_holo.png diff --git a/packages/SystemUI/res/drawable-hdpi/scrubber_control_holo.png b/packages/SystemUI/res/drawable-hdpi/scrubber_control_holo.png Binary files differnew file mode 100644 index 000000000000..993ccf4c3e54 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/scrubber_control_holo.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket.png Binary files differdeleted file mode 100644 index 90dffa973c2d..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_drag.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_drag.png Binary files differdeleted file mode 100644 index dcce49574465..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_drag.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_hidden.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_hidden.png Binary files differdeleted file mode 100644 index 93b0d238fb0c..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_hidden.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_holding.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_holding.png Binary files differdeleted file mode 100644 index 9eb9dc62d7b3..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_pocket_holding.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/scrubber_control_disabled_holo.png b/packages/SystemUI/res/drawable-mdpi/scrubber_control_disabled_holo.png Binary files differindex b8adc97a4c33..7e679edd4bb1 100644 --- a/packages/SystemUI/res/drawable-mdpi/scrubber_control_disabled_holo.png +++ b/packages/SystemUI/res/drawable-mdpi/scrubber_control_disabled_holo.png diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java index 1004e18ee064..372aa90410eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java @@ -60,6 +60,9 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, View mSettingsView; ViewGroup mContentParent; + // amount to slide mContentParent down by when mContentFrame is missing + float mContentFrameMissingTranslation; + Choreographer mChoreo = new Choreographer(); public NotificationPanel(Context context, AttributeSet attrs) { @@ -87,11 +90,17 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, mNotificationScroller = findViewById(R.id.notification_scroller); mContentFrame = (ViewGroup)findViewById(R.id.content_frame); + mContentFrameMissingTranslation = + mContentFrame.getBackground().getMinimumHeight() + 10; + + mShowing = false; + + setContentFrameVisible(mNotificationCount > 0, false); } public void show(boolean show, boolean animate) { if (show && !mShowing) { - setContentFrameVisible(mNotificationCount > 0, false); + setContentFrameVisible(mSettingsView != null || mNotificationCount > 0, false); } if (animate) { @@ -120,7 +129,7 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, public void onVisibilityChanged(View v, int vis) { super.onVisibilityChanged(v, vis); // when we hide, put back the notifications - if (!isShown()) { + if (vis != View.VISIBLE) { if (mSettingsView != null) removeSettingsView(); mNotificationScroller.setVisibility(View.VISIBLE); mNotificationScroller.setAlpha(1f); @@ -161,10 +170,8 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, setContentFrameVisible(n > 0, false); } else if (mSettingsView == null) { // we're looking at the notifications; time to maybe make some changes - if (mNotificationCount == 0 && n > 0) { - setContentFrameVisible(true, true); - } else if (mNotificationCount > 0 && n == 0) { - setContentFrameVisible(false, true); + if (mNotificationCount != n) { + setContentFrameVisible(n > 0, true); } } mNotificationCount = n; @@ -173,22 +180,35 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, public void setContentFrameVisible(final boolean showing, boolean animate) { if (!animate) { mContentFrame.setVisibility(showing ? View.VISIBLE : View.GONE); - mContentParent.setTranslationY(showing ? 0f : 100f); + mContentFrame.setAlpha(1f); + // the translation will be patched up when the window is slid into place return; } - mContentFrame.setVisibility(showing ? View.VISIBLE : View.GONE); + if (showing) { + mContentFrame.setVisibility(View.VISIBLE); + } AnimatorSet set = new AnimatorSet(); - float adjust = mContentFrame.getBackground().getMinimumHeight() + 8; // fudge factor set.play(ObjectAnimator.ofFloat( mContentFrame, "alpha", showing ? 0f : 1f, showing ? 1f : 0f)) .with(ObjectAnimator.ofFloat( mContentParent, "translationY", - showing ? adjust : 0f, - showing ? 0f : adjust)); + showing ? mContentFrameMissingTranslation : 0f, + showing ? 0f : mContentFrameMissingTranslation)) + ; + set.setDuration(200); + if (!showing) { + set.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator _a) { + mContentFrame.setVisibility(View.GONE); + mContentFrame.setAlpha(1f); + } + }); + } set.start(); } @@ -238,10 +258,15 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, } public boolean isInContentArea(int x, int y) { - mContentArea.left = mContentFrame.getLeft() + mContentFrame.getPaddingLeft(); - mContentArea.top = mTitleArea.getTop() + mTitleArea.getPaddingTop(); - mContentArea.right = mContentFrame.getRight() - mContentFrame.getPaddingRight(); - mContentArea.bottom = mContentFrame.getBottom() - mContentFrame.getPaddingBottom(); + mContentArea.left = mTitleArea.getLeft() + mTitleArea.getPaddingLeft(); + mContentArea.top = mTitleArea.getTop() + mTitleArea.getPaddingTop() + + (int)mContentParent.getTranslationY(); // account for any adjustment + mContentArea.right = mTitleArea.getRight() - mTitleArea.getPaddingRight(); + + View theBottom = (mContentFrame.getVisibility() == View.VISIBLE) + ? mContentFrame : mTitleArea; + mContentArea.bottom = theBottom.getBottom() - theBottom.getPaddingBottom(); + offsetDescendantRectToMyCoords(mContentParent, mContentArea); return mContentArea.contains(x, y); } @@ -291,12 +316,16 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, if (appearing) { // we want to go from near-the-top to the top, unless we're half-open in the right // general vicinity - start = (y < HYPERSPACE_OFFRAMP) ? y : HYPERSPACE_OFFRAMP; end = 0; + if (mNotificationCount == 0) { + end += mContentFrameMissingTranslation; + } + start = (y < (HYPERSPACE_OFFRAMP+end)) ? y : (HYPERSPACE_OFFRAMP+end); } else { start = y; end = y + HYPERSPACE_OFFRAMP; } + Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY", start, end); posAnim.setInterpolator(appearing diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath index 2102eb196b0c..64c1fb543074 100644 --- a/tools/layoutlib/bridge/.classpath +++ b/tools/layoutlib/bridge/.classpath @@ -8,5 +8,6 @@ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/> <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/> + <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/resources/resources-prebuilt.jar"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk index a0a7307a8cc0..57dd7aee49f0 100644 --- a/tools/layoutlib/bridge/Android.mk +++ b/tools/layoutlib/bridge/Android.mk @@ -20,7 +20,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under,src) LOCAL_JAVA_LIBRARIES := \ kxml2-2.3.0 \ - layoutlib_api-prebuilt + layoutlib_api-prebuilt \ + resources-prebuilt LOCAL_STATIC_JAVA_LIBRARIES := \ temp_layoutlib \ diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java index db3cf44d89c8..993c30543e32 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java +++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java @@ -17,8 +17,8 @@ package android.graphics; import com.android.ide.common.rendering.api.LayoutLog; -import com.android.ide.common.rendering.api.ResourceDensity; import com.android.layoutlib.bridge.Bridge; +import com.android.resources.Density; import android.content.res.AssetManager; import android.content.res.Resources; @@ -462,9 +462,9 @@ public class BitmapFactory { // into is.read(...) This number is not related to the value passed // to mark(...) above. try { - ResourceDensity density = ResourceDensity.MEDIUM; + Density density = Density.MEDIUM; if (opts != null) { - density = ResourceDensity.getEnum(opts.inDensity); + density = Density.getEnum(opts.inDensity); } bm = Bitmap_Delegate.createBitmap(is, true, density); } catch (IOException e) { diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java index 108d1838db7b..efe69552118f 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java @@ -17,9 +17,9 @@ package android.graphics; import com.android.ide.common.rendering.api.LayoutLog; -import com.android.ide.common.rendering.api.ResourceDensity; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; +import com.android.resources.Density; import android.graphics.Bitmap.Config; import android.os.Parcel; @@ -89,12 +89,12 @@ public final class Bitmap_Delegate { * @see Bitmap#isMutable() * @see Bitmap#getDensity() */ - public static Bitmap createBitmap(File input, boolean isMutable, ResourceDensity density) + public static Bitmap createBitmap(File input, boolean isMutable, Density density) throws IOException { // create a delegate with the content of the file. Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888); - return createBitmap(delegate, isMutable, density.getDpi()); + return createBitmap(delegate, isMutable, density.getDpiValue()); } /** @@ -107,12 +107,12 @@ public final class Bitmap_Delegate { * @see Bitmap#isMutable() * @see Bitmap#getDensity() */ - public static Bitmap createBitmap(InputStream input, boolean isMutable, ResourceDensity density) + public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density) throws IOException { // create a delegate with the content of the stream. Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888); - return createBitmap(delegate, isMutable, density.getDpi()); + return createBitmap(delegate, isMutable, density.getDpiValue()); } /** @@ -126,11 +126,11 @@ public final class Bitmap_Delegate { * @see Bitmap#getDensity() */ public static Bitmap createBitmap(BufferedImage image, boolean isMutable, - ResourceDensity density) throws IOException { + Density density) throws IOException { // create a delegate with the given image. Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888); - return createBitmap(delegate, isMutable, density.getDpi()); + return createBitmap(delegate, isMutable, density.getDpiValue()); } /** @@ -425,7 +425,7 @@ public final class Bitmap_Delegate { // the density doesn't matter, it's set by the Java method. return createBitmap(delegate, false /*isMutable*/, - ResourceDensity.DEFAULT_DENSITY /*density*/); + Density.DEFAULT_DENSITY /*density*/); } /*package*/ static void nativePrepareToDraw(int nativeBitmap) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java index 963dc4d74a88..0c6fa20fc977 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java @@ -56,6 +56,11 @@ public class BridgeRenderSession extends RenderSession { } @Override + public boolean isAlphaChannelImage() { + return mSession.isAlphaChannelImage(); + } + + @Override public List<ViewInfo> getRootViews() { return mSession.getViewInfos(); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index 8d194925652d..79264d0bfa7a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -267,7 +267,7 @@ public final class BridgeContext extends Activity { @Override public final TypedArray obtainStyledAttributes(int[] attrs) { - return createStyleBasedTypedArray(mRenderResources.getTheme(), attrs); + return createStyleBasedTypedArray(mRenderResources.getCurrentTheme(), attrs); } @Override diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index 8b064529b9ab..978832ff41dd 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -32,7 +32,6 @@ import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.Params; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.RenderSession; -import com.android.ide.common.rendering.api.ResourceDensity; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.StyleResourceValue; @@ -48,6 +47,8 @@ import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; import com.android.layoutlib.bridge.android.BridgeWindow; import com.android.layoutlib.bridge.android.BridgeWindowSession; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; +import com.android.resources.Density; +import com.android.resources.ScreenSize; import android.animation.Animator; import android.animation.AnimatorInflater; @@ -109,12 +110,19 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { private BridgeContext mContext; private BridgeXmlBlockParser mBlockParser; private BridgeInflater mInflater; - private int mScreenOffset; private ResourceValue mWindowBackground; private FrameLayout mViewRoot; private Canvas mCanvas; private int mMeasuredScreenWidth = -1; private int mMeasuredScreenHeight = -1; + private boolean mIsAlphaChannelImage = true; + + private int mStatusBarSize; + private int mTopBarSize; + private int mSystemBarSize; + private int mTopOffset; + private int mTotalBarSize; + // information being returned through the API private BufferedImage mImage; @@ -176,19 +184,20 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, mParams.getProjectCallback(), mParams.getTargetSdkVersion()); + // use default of true in case it's not found to use alpha by default + mIsAlphaChannelImage = getBooleanThemeValue(resources, + "windowIsFloating", true /*defaultValue*/); + setUp(); - // get the screen offset and window-background resource - mWindowBackground = null; - mScreenOffset = 0; - StyleResourceValue theme = resources.getTheme(); - if (theme != null && mParams.isBgColorOverridden() == false) { - mWindowBackground = resources.findItemInTheme("windowBackground"); - mWindowBackground = resources.resolveResValue(mWindowBackground); + findBackground(resources); + findStatusBar(resources, metrics); + findTopBar(resources, metrics); + findSystemBar(resources, metrics); - mScreenOffset = getScreenOffset(resources, metrics); - } + mTopOffset = mStatusBarSize + mTopBarSize; + mTotalBarSize = mTopOffset + mSystemBarSize; // build the inflater and parser. mInflater = new BridgeInflater(mContext, mParams.getProjectCallback()); @@ -414,7 +423,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { if (mMeasuredScreenWidth == -1) { newRenderSize = true; mMeasuredScreenWidth = mParams.getScreenWidth(); - mMeasuredScreenHeight = mParams.getScreenHeight(); + mMeasuredScreenHeight = mParams.getScreenHeight() - mTotalBarSize; if (renderingMode != RenderingMode.NORMAL) { // measure the full size needed by the layout. @@ -422,7 +431,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { renderingMode.isHorizExpand() ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY); - h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight - mScreenOffset, + h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight, renderingMode.isVertExpand() ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY); @@ -437,8 +446,8 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { if (renderingMode.isVertExpand()) { int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight(); - if (neededHeight > mMeasuredScreenHeight - mScreenOffset) { - mMeasuredScreenHeight = neededHeight + mScreenOffset; + if (neededHeight > mMeasuredScreenHeight) { + mMeasuredScreenHeight = neededHeight; } } } @@ -447,23 +456,26 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { // remeasure with the size we need // This must always be done before the call to layout w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, MeasureSpec.EXACTLY); - h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight - mScreenOffset, + h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight, MeasureSpec.EXACTLY); mViewRoot.measure(w_spec, h_spec); // now do the layout. - mViewRoot.layout(0, mScreenOffset, mMeasuredScreenWidth, mMeasuredScreenHeight); + mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); // draw the views // create the BufferedImage into which the layout will be rendered. boolean newImage = false; if (newRenderSize || mCanvas == null) { if (mParams.getImageFactory() != null) { - mImage = mParams.getImageFactory().getImage(mMeasuredScreenWidth, - mMeasuredScreenHeight - mScreenOffset); + mImage = mParams.getImageFactory().getImage( + mMeasuredScreenWidth, + mMeasuredScreenHeight + mTotalBarSize); } else { - mImage = new BufferedImage(mMeasuredScreenWidth, - mMeasuredScreenHeight - mScreenOffset, BufferedImage.TYPE_INT_ARGB); + mImage = new BufferedImage( + mMeasuredScreenWidth, + mMeasuredScreenHeight + mTotalBarSize, + BufferedImage.TYPE_INT_ARGB); newImage = true; } @@ -473,31 +485,54 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { Graphics2D gc = mImage.createGraphics(); gc.setColor(new Color(mParams.getOverrideBgColor(), true)); gc.setComposite(AlphaComposite.Src); - gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset); + gc.fillRect(0, 0, mMeasuredScreenWidth, + mMeasuredScreenHeight + mTotalBarSize); gc.dispose(); } // create an Android bitmap around the BufferedImage Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, true /*isMutable*/, - ResourceDensity.getEnum(mParams.getDensity())); + Density.getEnum(mParams.getDensity())); // create a Canvas around the Android bitmap mCanvas = new Canvas(bitmap); mCanvas.setDensity(mParams.getDensity()); + mCanvas.translate(0, mTopOffset); } if (freshRender && newImage == false) { Graphics2D gc = mImage.createGraphics(); - gc.setColor(new Color(0x00000000, true)); gc.setComposite(AlphaComposite.Src); - gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset); + + if (mStatusBarSize > 0) { + gc.setColor(new Color(0xFF3C3C3C, true)); + gc.fillRect(0, 0, mMeasuredScreenWidth, mStatusBarSize); + } + + if (mTopBarSize > 0) { + gc.setColor(new Color(0xFF7F7F7F, true)); + gc.fillRect(0, mStatusBarSize, mMeasuredScreenWidth, mTopOffset); + } + + // erase the rest + gc.setColor(new Color(0x00000000, true)); + gc.fillRect(0, mTopOffset, + mMeasuredScreenWidth, mMeasuredScreenHeight + mTopOffset); + + if (mSystemBarSize > 0) { + gc.setColor(new Color(0xFF3C3C3C, true)); + gc.fillRect(0, mMeasuredScreenHeight + mTopOffset, + mMeasuredScreenWidth, mMeasuredScreenHeight + mTotalBarSize); + } + + // done gc.dispose(); } mViewRoot.draw(mCanvas); - mViewInfoList = visitAllChildren((ViewGroup)mViewRoot, mContext); + mViewInfoList = visitAllChildren((ViewGroup)mViewRoot, mContext, mTopOffset); // success! return SUCCESS.createResult(); @@ -936,73 +971,173 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { } } - /** - * Returns the top screen offset. This depends on whether the current theme defines the user - * of the title and status bars. - * @param resolver The {@link RenderResources} - * @param metrics The display metrics - * @return the pixel height offset - */ - private int getScreenOffset(RenderResources resolver, DisplayMetrics metrics) { - int offset = 0; + private void findBackground(RenderResources resources) { + if (mParams.isBgColorOverridden() == false) { + mWindowBackground = resources.findItemInTheme("windowBackground"); + if (mWindowBackground != null) { + mWindowBackground = resources.resolveResValue(mWindowBackground); + } + } + } - // get the title bar flag from the current theme. - ResourceValue value = resolver.findItemInTheme("windowNoTitle"); + private boolean isTabletUi() { + return mParams.getConfigScreenSize() == ScreenSize.XLARGE; + } - // because it may reference something else, we resolve it. - value = resolver.resolveResValue(value); + private boolean isHCApp() { + RenderResources resources = mContext.getRenderResources(); + + // the app must say it targets 11+ and the theme name must extend Theme.Holo or + // Theme.Holo.Light (which does not extend Theme.Holo, but Theme.Light) + if (mParams.getTargetSdkVersion() < 11) { + return false; + } + + StyleResourceValue currentTheme = resources.getCurrentTheme(); + StyleResourceValue holoTheme = resources.getTheme("Theme.Holo", true /*frameworkTheme*/); + + if (currentTheme == holoTheme || + resources.themeIsParentOf(holoTheme, currentTheme)) { + return true; + } + + StyleResourceValue holoLightTheme = resources.getTheme("Theme.Holo.Light", + true /*frameworkTheme*/); + + if (currentTheme == holoLightTheme || + resources.themeIsParentOf(holoLightTheme, currentTheme)) { + return true; + } + + return false; + } + + private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { + if (isTabletUi() == false) { + boolean windowFullscreen = getBooleanThemeValue(resources, + "windowFullscreen", false /*defaultValue*/); + + if (windowFullscreen == false) { + // default value + mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; + + // get the real value + ResourceValue value = resources.getFrameworkResource(RenderResources.RES_DIMEN, + "status_bar_height"); + + if (value != null) { + TypedValue typedValue = ResourceHelper.getValue(value.getValue()); + if (typedValue != null) { + // compute the pixel value based on the display metrics + mStatusBarSize = (int)typedValue.getDimension(metrics); + } + } + } + } + } + + private void findTopBar(RenderResources resources, DisplayMetrics metrics) { + boolean windowIsFloating = getBooleanThemeValue(resources, + "windowIsFloating", true /*defaultValue*/); + + if (windowIsFloating == false) { + if (isHCApp()) { + findActionBar(resources, metrics); + } else { + findTitleBar(resources, metrics); + } + } + } + + private void findActionBar(RenderResources resources, DisplayMetrics metrics) { + boolean windowActionBar = getBooleanThemeValue(resources, + "windowActionBar", true /*defaultValue*/); + + // if there's a value and it's false (default is true) + if (windowActionBar) { - // if there's a value and it's true (default is false) - if (value == null || value.getValue() == null || - XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) { // default size of the window title bar - int defaultOffset = DEFAULT_TITLE_BAR_HEIGHT; + mTopBarSize = DEFAULT_TITLE_BAR_HEIGHT; // get value from the theme. - value = resolver.findItemInTheme("windowTitleSize"); + ResourceValue value = resources.findItemInTheme("actionBarSize"); // resolve it - value = resolver.resolveResValue(value); + value = resources.resolveResValue(value); if (value != null) { // get the numerical value, if available TypedValue typedValue = ResourceHelper.getValue(value.getValue()); if (typedValue != null) { // compute the pixel value based on the display metrics - defaultOffset = (int)typedValue.getDimension(metrics); + mTopBarSize = (int)typedValue.getDimension(metrics); } } - - offset += defaultOffset; } + } - // get the fullscreen flag from the current theme. - value = resolver.findItemInTheme("windowFullscreen"); + private void findTitleBar(RenderResources resources, DisplayMetrics metrics) { + boolean windowNoTitle = getBooleanThemeValue(resources, + "windowNoTitle", false /*defaultValue*/); - // because it may reference something else, we resolve it. - value = resolver.resolveResValue(value); + if (windowNoTitle == false) { + + // default size of the window title bar + mTopBarSize = DEFAULT_TITLE_BAR_HEIGHT; + + // get value from the theme. + ResourceValue value = resources.findItemInTheme("windowTitleSize"); + + // resolve it + value = resources.resolveResValue(value); - if (value == null || value.getValue() == null || - XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) { + if (value != null) { + // get the numerical value, if available + TypedValue typedValue = ResourceHelper.getValue(value.getValue()); + if (typedValue != null) { + // compute the pixel value based on the display metrics + mTopBarSize = (int)typedValue.getDimension(metrics); + } + } + } + } + + private void findSystemBar(RenderResources resources, DisplayMetrics metrics) { + if (isTabletUi() && getBooleanThemeValue( + resources, "windowIsFloating", true /*defaultValue*/) == false) { // default value - int defaultOffset = DEFAULT_STATUS_BAR_HEIGHT; + mSystemBarSize = 56; // ?? // get the real value - value = resolver.getFrameworkResource(RenderResources.RES_DIMEN, "status_bar_height"); + ResourceValue value = resources.getFrameworkResource(RenderResources.RES_DIMEN, + "status_bar_height"); + if (value != null) { TypedValue typedValue = ResourceHelper.getValue(value.getValue()); if (typedValue != null) { // compute the pixel value based on the display metrics - defaultOffset = (int)typedValue.getDimension(metrics); + mSystemBarSize = (int)typedValue.getDimension(metrics); } } + } + } + + private boolean getBooleanThemeValue(RenderResources resources, + String name, boolean defaultValue) { + + // get the title bar flag from the current theme. + ResourceValue value = resources.findItemInTheme(name); + + // because it may reference something else, we resolve it. + value = resources.resolveResValue(value); - // add the computed offset. - offset += defaultOffset; + // if there's no value, return the default. + if (value == null || value.getValue() == null) { + return defaultValue; } - return offset; + return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); } /** @@ -1111,32 +1246,33 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { * @param view the root View * @param context the context. */ - private ViewInfo visit(View view, BridgeContext context) { + private ViewInfo visit(View view, BridgeContext context, int offset) { if (view == null) { return null; } ViewInfo result = new ViewInfo(view.getClass().getName(), context.getViewKey(view), - view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), + view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset, view, view.getLayoutParams()); if (view instanceof ViewGroup) { ViewGroup group = ((ViewGroup) view); - result.setChildren(visitAllChildren(group, context)); + result.setChildren(visitAllChildren(group, context, 0 /*offset*/)); } return result; } - private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, BridgeContext context) { + private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, BridgeContext context, + int offset) { if (viewGroup == null) { return null; } List<ViewInfo> children = new ArrayList<ViewInfo>(); for (int i = 0; i < viewGroup.getChildCount(); i++) { - children.add(visit(viewGroup.getChildAt(i), context)); + children.add(visit(viewGroup.getChildAt(i), context, offset)); } return children; } @@ -1150,6 +1286,10 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider { return mImage; } + public boolean isAlphaChannelImage() { + return mIsAlphaChannelImage; + } + public List<ViewInfo> getViewInfos() { return mViewInfoList; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index 475b4be25314..119dfb1f71f3 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -18,13 +18,13 @@ package com.android.layoutlib.bridge.impl; import com.android.ide.common.rendering.api.DensityBasedResourceValue; import com.android.ide.common.rendering.api.LayoutLog; -import com.android.ide.common.rendering.api.ResourceDensity; import com.android.ide.common.rendering.api.ResourceValue; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; import com.android.ninepatch.NinePatch; import com.android.ninepatch.NinePatchChunk; +import com.android.resources.Density; import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; @@ -147,7 +147,7 @@ public final class ResourceHelper { } if (bitmap == null) { - ResourceDensity density = ResourceDensity.MEDIUM; + Density density = Density.MEDIUM; if (value instanceof DensityBasedResourceValue) { density = ((DensityBasedResourceValue)value).getResourceDensity(); @@ -214,7 +214,7 @@ public final class ResourceHelper { isFramework ? null : context.getProjectKey()); if (bitmap == null) { - ResourceDensity density = ResourceDensity.MEDIUM; + Density density = Density.MEDIUM; if (value instanceof DensityBasedResourceValue) { density = ((DensityBasedResourceValue)value).getResourceDensity(); } |