diff options
| -rw-r--r-- | cmds/installd/commands.c | 23 | ||||
| -rw-r--r-- | cmds/installd/installd.h | 5 | ||||
| -rw-r--r-- | cmds/installd/tests/installd_utils_test.cpp | 56 | ||||
| -rw-r--r-- | cmds/installd/utils.c | 18 | ||||
| -rwxr-xr-x | core/java/android/server/BluetoothService.java | 34 | ||||
| -rw-r--r-- | core/java/android/text/TextLine.java | 24 | ||||
| -rw-r--r-- | core/java/android/text/method/Touch.java | 40 | ||||
| -rw-r--r-- | core/java/android/widget/TextView.java | 89 | ||||
| -rw-r--r-- | docs/html/guide/practices/ui_guidelines/widget_design.jd | 12 | ||||
| -rw-r--r-- | docs/html/guide/topics/appwidgets/index.jd | 4 | ||||
| -rw-r--r-- | libs/rs/rsScriptC.cpp | 20 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java | 10 | ||||
| -rw-r--r-- | services/java/com/android/server/DeviceStorageMonitorService.java | 1 |
13 files changed, 251 insertions, 85 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index 26b911356699..4ede33f73daf 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -184,6 +184,7 @@ int free_cache(int64_t free_size) DIR *d; struct dirent *de; int64_t avail; + char datadir[PKG_PATH_MAX]; avail = disk_free(); if (avail < 0) return -1; @@ -191,9 +192,14 @@ int free_cache(int64_t free_size) LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail); if (avail >= free_size) return 0; - d = opendir(android_data_dir.path); + if (create_persona_path(datadir, 0)) { + LOGE("couldn't get directory for persona 0"); + return -1; + } + + d = opendir(datadir); if (d == NULL) { - LOGE("cannot open %s: %s\n", android_data_dir.path, strerror(errno)); + LOGE("cannot open %s: %s\n", datadir, strerror(errno)); return -1; } dfd = dirfd(d); @@ -578,19 +584,6 @@ fail: return -1; } -int create_move_path(char path[PKG_PATH_MAX], - const char* pkgname, - const char* leaf, - uid_t persona) -{ - if ((android_data_dir.len + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { - return -1; - } - - sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); - return 0; -} - void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid, struct stat* statbuf) { diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index c5872b8efa09..173cabfb77a7 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -105,6 +105,11 @@ int create_pkg_path(char path[PKG_PATH_MAX], int create_persona_path(char path[PKG_PATH_MAX], uid_t persona); +int create_move_path(char path[PKG_PATH_MAX], + const char* pkgname, + const char* leaf, + uid_t persona); + int is_valid_package_name(const char* pkgname); int create_cache_path(char path[PKG_PATH_MAX], const char *src); diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp index 1128fceca0af..7cb9b37fe038 100644 --- a/cmds/installd/tests/installd_utils_test.cpp +++ b/cmds/installd/tests/installd_utils_test.cpp @@ -34,6 +34,16 @@ extern "C" { #define TEST_SYSTEM_DIR1 "/system/app/" #define TEST_SYSTEM_DIR2 "/vendor/app/" +#define REALLY_LONG_APP_NAME "com.example." \ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +#define REALLY_LONG_LEAF_NAME "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \ + "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \ + "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \ + "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" + namespace android { class UtilsTest : public testing::Test { @@ -210,7 +220,7 @@ TEST_F(UtilsTest, CheckSystemApp_BadPathEscapeFail) { TEST_F(UtilsTest, GetPathFromString_NullPathFail) { dir_rec_t test1; - EXPECT_EQ(-1, get_path_from_string(&test1, NULL)) + EXPECT_EQ(-1, get_path_from_string(&test1, (const char *) NULL)) << "Should not allow NULL as a path."; } @@ -327,6 +337,50 @@ TEST_F(UtilsTest, CreatePkgPathInDir_ProtectedDir) { << "Package path should be in /data/app-private/"; } +TEST_F(UtilsTest, CreatePersonaPath_Primary) { + char path[PKG_PATH_MAX]; + + EXPECT_EQ(0, create_persona_path(path, 0)) + << "Should successfully build primary user path."; + + EXPECT_STREQ("/data/data/", path) + << "Primary user should have correct path"; +} + +TEST_F(UtilsTest, CreatePersonaPath_Secondary) { + char path[PKG_PATH_MAX]; + + EXPECT_EQ(0, create_persona_path(path, 1)) + << "Should successfully build primary user path."; + + EXPECT_STREQ("/data/user/1/", path) + << "Primary user should have correct path"; +} + +TEST_F(UtilsTest, CreateMovePath_Primary) { + char path[PKG_PATH_MAX]; + + EXPECT_EQ(0, create_move_path(path, "com.android.test", "shared_prefs", 0)) + << "Should be able to create move path for primary user"; + + EXPECT_STREQ("/data/data/com.android.test/shared_prefs", path) + << "Primary user package directory should be created correctly"; +} + +TEST_F(UtilsTest, CreateMovePath_Fail_AppTooLong) { + char path[PKG_PATH_MAX]; + + EXPECT_EQ(-1, create_move_path(path, REALLY_LONG_APP_NAME, "shared_prefs", 0)) + << "Should fail to create move path for primary user"; +} + +TEST_F(UtilsTest, CreateMovePath_Fail_LeafTooLong) { + char path[PKG_PATH_MAX]; + + EXPECT_EQ(-1, create_move_path(path, "com.android.test", REALLY_LONG_LEAF_NAME, 0)) + << "Should fail to create move path for primary user"; +} + TEST_F(UtilsTest, CopyAndAppend_Normal) { //int copy_and_append(dir_rec_t* dst, dir_rec_t* src, char* suffix) dir_rec_t dst; diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c index 3099b8341f6e..a53a93ce1073 100644 --- a/cmds/installd/utils.c +++ b/cmds/installd/utils.c @@ -109,7 +109,7 @@ int create_persona_path(char path[PKG_PATH_MAX], uid_len = 0; } else { persona_prefix = SECONDARY_USER_PREFIX; - uid_len = snprintf(NULL, 0, "%d", persona); + uid_len = snprintf(NULL, 0, "%d/", persona); } char *dst = path; @@ -126,7 +126,7 @@ int create_persona_path(char path[PKG_PATH_MAX], LOGE("Error building user path"); return -1; } - int ret = snprintf(dst, dst_size, "%d", persona); + int ret = snprintf(dst, dst_size, "%d/", persona); if (ret < 0 || (size_t) ret != uid_len) { LOGE("Error appending persona id to path"); return -1; @@ -135,6 +135,20 @@ int create_persona_path(char path[PKG_PATH_MAX], return 0; } +int create_move_path(char path[PKG_PATH_MAX], + const char* pkgname, + const char* leaf, + uid_t persona) +{ + if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1) + >= PKG_PATH_MAX) { + return -1; + } + + sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); + return 0; +} + /** * Checks whether the package name is valid. Returns -1 on error and * 0 on success. diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java index a7d8cace28e5..94fbbc8d33e2 100755 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -145,7 +145,12 @@ public class BluetoothService extends IBluetooth.Stub { private final ArrayList<String> mUuidIntentTracker; private final HashMap<RemoteService, IBluetoothCallback> mUuidCallbackTracker; - private final HashMap<Integer, Pair<Integer, IBinder>> mServiceRecordToPid; + private static class ServiceRecordClient { + int pid; + IBinder binder; + IBinder.DeathRecipient death; + } + private final HashMap<Integer, ServiceRecordClient> mServiceRecordToPid; private final HashMap<String, BluetoothDeviceProfileState> mDeviceProfileState; private final BluetoothProfileState mA2dpProfileState; @@ -221,7 +226,7 @@ public class BluetoothService extends IBluetooth.Stub { mDeviceOobData = new HashMap<String, Pair<byte[], byte[]>>(); mUuidIntentTracker = new ArrayList<String>(); mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>(); - mServiceRecordToPid = new HashMap<Integer, Pair<Integer, IBinder>>(); + mServiceRecordToPid = new HashMap<Integer, ServiceRecordClient>(); mDeviceProfileState = new HashMap<String, BluetoothDeviceProfileState>(); mA2dpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.A2DP); mHfpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.HFP); @@ -1528,11 +1533,17 @@ public class BluetoothService extends IBluetooth.Stub { return -1; } - int pid = Binder.getCallingPid(); - mServiceRecordToPid.put(new Integer(handle), new Pair<Integer, IBinder>(pid, b)); + ServiceRecordClient client = new ServiceRecordClient(); + client.pid = Binder.getCallingPid(); + client.binder = b; + client.death = new Reaper(handle, client.pid, RFCOMM_RECORD_REAPER); + mServiceRecordToPid.put(new Integer(handle), client); try { - b.linkToDeath(new Reaper(handle, pid, RFCOMM_RECORD_REAPER), 0); - } catch (RemoteException e) {Log.e(TAG, "", e);} + b.linkToDeath(client.death, 0); + } catch (RemoteException e) { + Log.e(TAG, "", e); + client.death = null; + } return handle; } @@ -1547,10 +1558,15 @@ public class BluetoothService extends IBluetooth.Stub { } private synchronized void checkAndRemoveRecord(int handle, int pid) { - Pair<Integer, IBinder> pidPair = mServiceRecordToPid.get(handle); - if (pidPair != null && pid == pidPair.first) { + ServiceRecordClient client = mServiceRecordToPid.get(handle); + if (client != null && pid == client.pid) { if (DBG) Log.d(TAG, "Removing service record " + Integer.toHexString(handle) + " for pid " + pid); + + if (client.death != null) { + client.binder.unlinkToDeath(client.death, 0); + } + mServiceRecordToPid.remove(handle); removeServiceRecordNative(handle); } @@ -1880,7 +1896,7 @@ public class BluetoothService extends IBluetooth.Stub { private void dumpApplicationServiceRecords(PrintWriter pw) { pw.println("\n--Application Service Records--"); for (Integer handle : mServiceRecordToPid.keySet()) { - Integer pid = mServiceRecordToPid.get(handle).first; + Integer pid = mServiceRecordToPid.get(handle).pid; pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle)); } } diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 68fea1907b87..b73d90046303 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -119,6 +119,7 @@ class TextLine { * @param hasTabs true if the line might contain tabs or emoji * @param tabStops the tabStops. Can be null. */ + @SuppressWarnings("null") void set(TextPaint paint, CharSequence text, int start, int limit, int dir, Directions directions, boolean hasTabs, TabStops tabStops) { mPaint = paint; @@ -134,11 +135,12 @@ class TextLine { mSpanned = null; boolean hasReplacement = false; + SpanSet<ReplacementSpan> replacementSpans = null; if (text instanceof Spanned) { mSpanned = (Spanned) text; - ReplacementSpan[] spans = mSpanned.getSpans(start, limit, ReplacementSpan.class); - spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class); - hasReplacement = spans.length > 0; + replacementSpans = new SpanSet<ReplacementSpan>(mSpanned, start, limit, + ReplacementSpan.class); + hasReplacement = replacementSpans.numberOfSpans > 0; } mCharsValid = hasReplacement || hasTabs || directions != Layout.DIRS_ALL_LEFT_TO_RIGHT; @@ -156,10 +158,9 @@ class TextLine { // zero-width characters. char[] chars = mChars; for (int i = start, inext; i < limit; i = inext) { - inext = mSpanned.nextSpanTransition(i, limit, ReplacementSpan.class); - ReplacementSpan[] spans = mSpanned.getSpans(i, inext, ReplacementSpan.class); - spans = TextUtils.removeEmptySpans(spans, mSpanned, ReplacementSpan.class); - if (spans.length > 0) { + // replacementSpans cannot be null if hasReplacement is true + inext = replacementSpans.getNextTransition(i, limit); + if (replacementSpans.hasSpansIntersecting(i, inext)) { // transition into a span chars[i - start] = '\ufffc'; for (int j = i - start + 1, e = inext - start; j < e; ++j) { @@ -908,6 +909,15 @@ class TextLine { numberOfSpans = count; } + public boolean hasSpansIntersecting(int start, int end) { + for (int i = 0; i < numberOfSpans; i++) { + // equal test is valid since both intervals are not empty by construction + if (spanStarts[i] >= end || spanEnds[i] <= start) continue; + return true; + } + return false; + } + int getNextTransition(int start, int limit) { for (int i = 0; i < numberOfSpans; i++) { final int spanStart = spanStarts[i]; diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java index 106a80190b36..3dfd44d90e4d 100644 --- a/core/java/android/text/method/Touch.java +++ b/core/java/android/text/method/Touch.java @@ -35,22 +35,30 @@ public class Touch { * Y position. */ public static void scrollTo(TextView widget, Layout layout, int x, int y) { - final int verticalPadding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); - final int top = layout.getLineForVertical(y); - final int bottom = layout.getLineForVertical(y + widget.getHeight() - verticalPadding); + final int horizontalPadding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight(); + final int availableWidth = widget.getWidth() - horizontalPadding; - int left = Integer.MAX_VALUE; - int right = 0; + final int top = layout.getLineForVertical(y); Alignment a = layout.getParagraphAlignment(top); boolean ltr = layout.getParagraphDirection(top) > 0; - for (int i = top; i <= bottom; i++) { - left = (int) Math.min(left, layout.getLineLeft(i)); - right = (int) Math.max(right, layout.getLineRight(i)); + int left, right; + if (widget.getHorizontallyScrolling()) { + final int verticalPadding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); + final int bottom = layout.getLineForVertical(y + widget.getHeight() - verticalPadding); + + left = Integer.MAX_VALUE; + right = 0; + + for (int i = top; i <= bottom; i++) { + left = (int) Math.min(left, layout.getLineLeft(i)); + right = (int) Math.max(right, layout.getLineRight(i)); + } + } else { + left = 0; + right = availableWidth; } - final int hoizontalPadding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight(); - final int availableWidth = widget.getWidth() - hoizontalPadding; final int actualWidth = right - left; if (actualWidth < availableWidth) { @@ -166,16 +174,24 @@ public class Touch { return false; } + /** + * @param widget The text view. + * @param buffer The text buffer. + */ public static int getInitialScrollX(TextView widget, Spannable buffer) { DragState[] ds = buffer.getSpans(0, buffer.length(), DragState.class); return ds.length > 0 ? ds[0].mScrollX : -1; } - + + /** + * @param widget The text view. + * @param buffer The text buffer. + */ public static int getInitialScrollY(TextView widget, Spannable buffer) { DragState[] ds = buffer.getSpans(0, buffer.length(), DragState.class); return ds.length > 0 ? ds[0].mScrollY : -1; } - + private static class DragState implements NoCopySpan { public float mX; public float mY; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index cbd08082d781..bd03fb908838 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -2581,6 +2581,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** + * Returns whether the text is allowed to be wider than the View is. + * If false, the text will be wrapped to the width of the View. + * + * @attr ref android.R.styleable#TextView_scrollHorizontally + * @hide + */ + public boolean getHorizontallyScrolling() { + return mHorizontallyScrolling; + } + + /** * Makes the TextView at least this many lines tall. * * Setting this value overrides any other (minimum) height setting. A single line TextView will @@ -9367,40 +9378,57 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mPositionY = mTempCoords[1]; } - public boolean isVisible(int positionX, int positionY) { - final TextView textView = TextView.this; + public void onScrollChanged() { + mScrollHasChanged = true; + } + } - if (mTempRect == null) mTempRect = new Rect(); - final Rect clip = mTempRect; - clip.left = getCompoundPaddingLeft(); - clip.top = getExtendedPaddingTop(); - clip.right = textView.getWidth() - getCompoundPaddingRight(); - clip.bottom = textView.getHeight() - getExtendedPaddingBottom(); - - final ViewParent parent = textView.getParent(); - if (parent == null || !parent.getChildVisibleRect(textView, clip, null)) { - return false; - } + private boolean isPositionVisible(int positionX, int positionY) { + synchronized (sTmpPosition) { + final float[] position = sTmpPosition; + position[0] = positionX; + position[1] = positionY; + View view = this; - int posX = mPositionX + positionX; - int posY = mPositionY + positionY; + while (view != null) { + if (view != this) { + // Local scroll is already taken into account in positionX/Y + position[0] -= view.getScrollX(); + position[1] -= view.getScrollY(); + } - // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal. - return posX >= clip.left - 1 && posX <= clip.right + 1 && - posY >= clip.top && posY <= clip.bottom; - } + if (position[0] < 0 || position[1] < 0 || + position[0] > view.getWidth() || position[1] > view.getHeight()) { + return false; + } - public boolean isOffsetVisible(int offset) { - final int line = mLayout.getLineForOffset(offset); - final int lineBottom = mLayout.getLineBottom(line); - final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset); - return isVisible(primaryHorizontal + viewportToContentHorizontalOffset(), - lineBottom + viewportToContentVerticalOffset()); - } + if (!view.getMatrix().isIdentity()) { + view.getMatrix().mapPoints(position); + } - public void onScrollChanged() { - mScrollHasChanged = true; + position[0] += view.getLeft(); + position[1] += view.getTop(); + + final ViewParent parent = view.getParent(); + if (parent instanceof View) { + view = (View) parent; + } else { + // We've reached the ViewRoot, stop iterating + view = null; + } + } } + + // We've been able to walk up the view hierarchy and the position was never clipped + return true; + } + + private boolean isOffsetVisible(int offset) { + final int line = mLayout.getLineForOffset(offset); + final int lineBottom = mLayout.getLineBottom(line); + final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset); + return isPositionVisible(primaryHorizontal + viewportToContentHorizontalOffset(), + lineBottom + viewportToContentVerticalOffset()); } @Override @@ -9501,7 +9529,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public void updatePosition(int parentPositionX, int parentPositionY, boolean parentPositionChanged, boolean parentScrolled) { // Either parentPositionChanged or parentScrolled is true, check if still visible - if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) { + if (isShowing() && isOffsetVisible(getTextOffset())) { if (parentScrolled) computeLocalPosition(); updatePosition(parentPositionX, parentPositionY); } else { @@ -10525,7 +10553,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return false; } - return getPositionListener().isVisible(mPositionX + mHotspotX, mPositionY); + return TextView.this.isPositionVisible(mPositionX + mHotspotX, mPositionY); } public abstract int getCurrentCursorOffset(); @@ -11507,6 +11535,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private Path mHighlightPath; private boolean mHighlightPathBogus = true; private static final RectF sTempRect = new RectF(); + private static final float[] sTmpPosition = new float[2]; // XXX should be much larger private static final int VERY_WIDE = 1024*1024; diff --git a/docs/html/guide/practices/ui_guidelines/widget_design.jd b/docs/html/guide/practices/ui_guidelines/widget_design.jd index de20e007f393..f63f3c4a8a76 100644 --- a/docs/html/guide/practices/ui_guidelines/widget_design.jd +++ b/docs/html/guide/practices/ui_guidelines/widget_design.jd @@ -250,13 +250,15 @@ android.widget.FrameLayout}. Just as your activity layouts must adapt to differe sizes, widget layouts must adapt to different Home screen grid cell sizes.</p> <p>Below is an example layout that a music widget showing text information and two buttons can use. -It builds upon the previous discussion of adding margins depending on OS version.</p> +It builds upon the previous discussion of adding margins depending on OS version. Note that the +most robust and resilient way to add margins to the widget is to wrap the widget frame and contents +in a padded {@link android.widget.FrameLayout}.</p> <pre> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_margin="@dimen/widget_margin"> + android:padding="@dimen/widget_margin"> <LinearLayout android:layout_width="match_parent" @@ -295,16 +297,16 @@ use flexible layouts attributes like so:</p> <p>When a user adds the widget to their home screen, on an example Android 4.0 device where each -grid cell is 80dp × 100dp in size and 16dp of margins are automatically applied on all sizes, +grid cell is 80dp × 100dp in size and 8dp of margins are automatically applied on all sizes, the widget will be stretched, like so:</p> <img src="{@docRoot}images/widget_design/music_example_stretched.png" - alt="Music widget sitting on an example 80dp x 100dp grid with 16dp of automatic margins + alt="Music widget sitting on an example 80dp x 100dp grid with 8dp of automatic margins added by the system" id="music_example_stretched"> <p class="img-caption"><strong>Figure 7.</strong> Music widget sitting on an example 80dp x 100dp -grid with 16dp of automatic margins added by the system.</p> +grid with 8dp of automatic margins added by the system.</p> <h2 id="templates">Using the App Widget Templates Pack</h2> diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd index 61337b782a75..2cb23c1cdbba 100644 --- a/docs/html/guide/topics/appwidgets/index.jd +++ b/docs/html/guide/topics/appwidgets/index.jd @@ -346,7 +346,7 @@ following layout classes:</p> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" - <strong>android:layout_margin="@dimen/widget_margin"></strong> + <strong>android:padding="@dimen/widget_margin"></strong> <LinearLayout android:layout_width="match_parent" @@ -363,7 +363,7 @@ following layout classes:</p> <li>Create two dimensions resources, one in <code>res/values/</code> to provide the pre-Android 4.0 custom margins, and one in <code>res/values-v14/</code> to provide no extra padding for Android 4.0 widgets: <p><strong>res/values/dimens.xml</strong>:<br> - <pre><dimen name="widget_margin">15dp</dimen></pre></p> + <pre><dimen name="widget_margin">8dp</dimen></pre></p> <p><strong>res/values-v14/dimens.xml</strong>:<br> <pre><dimen name="widget_margin">0dp</dimen></pre></p> diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index 2e7f2134fbaa..cd7b3a72ffef 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -21,6 +21,7 @@ #ifndef ANDROID_RS_SERIALIZE #include <bcinfo/BitcodeTranslator.h> +#include <bcinfo/BitcodeWrapper.h> #endif using namespace android; @@ -196,7 +197,24 @@ bool ScriptC::runCompiler(Context *rsc, //LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen); #ifndef ANDROID_RS_SERIALIZE - uint32_t sdkVersion = rsc->getTargetSdkVersion(); + uint32_t sdkVersion = 0; + bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeLen); + if (!bcWrapper.unwrap()) { + LOGE("Bitcode is not in proper container format (raw or wrapper)"); + return false; + } + + rsAssert(bcWrapper.getHeaderVersion() == 0); + if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) { + sdkVersion = bcWrapper.getTargetAPI(); + } + + if (sdkVersion == 0) { + // This signals that we didn't have a wrapper containing information + // about the bitcode. + sdkVersion = rsc->getTargetSdkVersion(); + } + if (BT) { delete BT; } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 2dcd80d74d1b..2232995c5c64 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -34,6 +34,7 @@ import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.PointF; +import android.hardware.CameraSound; import android.net.Uri; import android.os.AsyncTask; import android.os.Environment; @@ -49,6 +50,7 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.animation.Interpolator; import android.widget.ImageView; + import com.android.systemui.R; import java.io.File; @@ -254,6 +256,8 @@ class GlobalScreenshot { private float mBgPadding; private float mBgPaddingScale; + private CameraSound mCameraSound; + /** * @param context everything needs a context :( @@ -303,6 +307,9 @@ class GlobalScreenshot { // Scale has to account for both sides of the bg mBgPadding = (float) r.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding); mBgPaddingScale = mBgPadding / mDisplayMetrics.widthPixels; + + // Setup the Camera shutter sound + mCameraSound = new CameraSound(); } /** @@ -413,6 +420,9 @@ class GlobalScreenshot { mScreenshotLayout.post(new Runnable() { @Override public void run() { + // Play the shutter sound to notify that we've taken a screenshot + mCameraSound.playSound(CameraSound.SHUTTER_CLICK); + mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null); mScreenshotView.buildLayer(); mScreenshotAnimation.start(); diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java index d34087f959d0..16eeb7babb35 100644 --- a/services/java/com/android/server/DeviceStorageMonitorService.java +++ b/services/java/com/android/server/DeviceStorageMonitorService.java @@ -163,7 +163,6 @@ public class DeviceStorageMonitorService extends Binder { } catch (IllegalArgumentException e) { // ignore; report -1 } - mCacheFileStats.restat(CACHE_PATH); EventLog.writeEvent(EventLogTags.FREE_STORAGE_LEFT, mFreeMem, mFreeSystem, mFreeCache); } |