Merge "SurfaceTexture: fix queues-to-composer"
diff --git a/Android.mk b/Android.mk
index 752a5f8..fdf0933 100644
--- a/Android.mk
+++ b/Android.mk
@@ -183,7 +183,7 @@
media/java/android/media/IAudioFocusDispatcher.aidl \
media/java/android/media/IMediaScannerListener.aidl \
media/java/android/media/IMediaScannerService.aidl \
- media/java/android/media/IRemoteControlClient.aidl \
+ media/java/android/media/IRemoteControlClientDispatcher.aidl \
telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \
@@ -319,6 +319,9 @@
# include definition of libcore_to_document
include $(LOCAL_PATH)/../../libcore/Docs.mk
+# include definition of libfilterfw_to_document
+include $(LOCAL_PATH)/../../system/media/mca/Docs.mk
+
non_base_dirs := \
../../external/apache-http/src/org/apache/http
@@ -335,7 +338,8 @@
framework_docs_LOCAL_SRC_FILES := \
$(call find-other-java-files, $(dirs_to_document)) \
$(call find-other-html-files, $(html_dirs)) \
- $(addprefix ../../libcore/, $(call libcore_to_document, $(LOCAL_PATH)/../../libcore))
+ $(addprefix ../../libcore/, $(call libcore_to_document, $(LOCAL_PATH)/../../libcore)) \
+ $(addprefix ../../system/media/mca/, $(call libfilterfw_to_document, $(LOCAL_PATH)/../../system/media/mca))
# This is used by ide.mk as the list of source files that are
# always included.
diff --git a/CleanSpec.mk b/CleanSpec.mk
index bf47314..2593065 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -104,6 +104,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/SystemUI_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/R/com/android/systemui/R.java)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index 3ea70b7..d377109 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11267,6 +11267,37 @@
}
+package android.media.effect {
+
+ public abstract class Effect {
+ ctor public Effect();
+ method public abstract void apply(int, int, int, int);
+ method public abstract java.lang.String getName();
+ method public abstract void release();
+ method public abstract void setParameter(java.lang.String, java.lang.Object);
+ method public void setUpdateListener(android.media.effect.EffectUpdateListener);
+ }
+
+ public class EffectContext {
+ method public static android.media.effect.EffectContext createWithCurrentGlContext();
+ method public android.media.effect.EffectFactory getFactory();
+ method public void release();
+ }
+
+ public class EffectFactory {
+ method public android.media.effect.Effect createEffect(java.lang.String);
+ method public static boolean isEffectSupported(java.lang.String);
+ field public static final java.lang.String EFFECT_BRIGHTNESS = "BrightnessEffect";
+ field public static final java.lang.String EFFECT_CONTRAST = "ContrastEffect";
+ field public static final java.lang.String EFFECT_FISHEYE = "FisheyeEffect";
+ }
+
+ public abstract interface EffectUpdateListener {
+ method public abstract void onEffectUpdated(android.media.effect.Effect, java.lang.Object);
+ }
+
+}
+
package android.mtp {
public final class MtpConstants {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index cab8457..d3dbb8d 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1613,17 +1613,34 @@
/**
* Continuous auto focus mode intended for video recording. The camera
- * continuously tries to focus. This is ideal for shooting video.
- * Applications still can call {@link
- * #takePicture(Camera.ShutterCallback, Camera.PictureCallback,
- * Camera.PictureCallback)} in this mode but the subject may not be in
- * focus. Auto focus starts when the parameter is set. Applications
- * should not call {@link #autoFocus(AutoFocusCallback)} in this mode.
- * To stop continuous focus, applications should change the focus mode
- * to other modes.
+ * continuously tries to focus. This is the best choice for video
+ * recording because the focus changes smoothly . Applications still can
+ * call {@link #takePicture(Camera.ShutterCallback,
+ * Camera.PictureCallback, Camera.PictureCallback)} in this mode but the
+ * subject may not be in focus. Auto focus starts when the parameter is
+ * set. Applications should not call {@link
+ * #autoFocus(AutoFocusCallback)} in this mode. To stop continuous
+ * focus, applications should change the focus mode to other modes.
*/
public static final String FOCUS_MODE_CONTINUOUS_VIDEO = "continuous-video";
+ /**
+ * Continuous auto focus mode intended for taking pictures. The camera
+ * continuously tries to focus. The speed of focus change is more
+ * aggressive than {@link #FOCUS_MODE_CONTINUOUS_VIDEO}. Auto focus
+ * starts when the parameter is set. If applications call {@link
+ * #autoFocus(AutoFocusCallback)} in this mode, the focus callback will
+ * immediately return with a boolean that indicates whether the focus is
+ * sharp or not. The apps can then decide if they want to take a picture
+ * immediately or to change the focus mode to auto, and run a full
+ * autofocus cycle. To stop continuous focus, applications should change
+ * the focus mode to other modes.
+ *
+ * @see #FOCUS_MODE_CONTINUOUS_VIDEO
+ * @hide
+ */
+ public static final String FOCUS_MODE_CONTINUOUS_PICTURE = "continuous-picture";
+
// Indices for focus distance array.
/**
* The array index of near focus distance for use with
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 78c9010..1029161 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -589,8 +589,6 @@
mPreferenceManager.setOnPreferenceTreeClickListener(this);
}
- getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
-
// see if we should show Back/Next buttons
Intent intent = getIntent();
if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index f6ba7f7..bdd858b 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -159,7 +159,6 @@
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
if (mHavePrefs) {
bindPreferences();
diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java
index 5a244f1..77cd71e 100644
--- a/core/java/android/text/BoringLayout.java
+++ b/core/java/android/text/BoringLayout.java
@@ -280,7 +280,7 @@
}
}
- if (textDir.isRtl(temp, 0, n)) {
+ if (textDir != null && textDir.isRtl(temp, 0, n)) {
boring = false;
break outer;
}
diff --git a/core/java/android/text/TextDirectionHeuristic.java b/core/java/android/text/TextDirectionHeuristic.java
index 130f879..0bf64e4 100644
--- a/core/java/android/text/TextDirectionHeuristic.java
+++ b/core/java/android/text/TextDirectionHeuristic.java
@@ -1,4 +1,18 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * 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.text;
@@ -8,6 +22,5 @@
* @hide
*/
public interface TextDirectionHeuristic {
- /** @hide */ boolean isRtl(CharSequence text, int start, int end);
/** @hide */ boolean isRtl(char[] text, int start, int count);
}
diff --git a/core/java/android/text/TextDirectionHeuristics.java b/core/java/android/text/TextDirectionHeuristics.java
index 5f9ffc5..5ed2df4 100644
--- a/core/java/android/text/TextDirectionHeuristics.java
+++ b/core/java/android/text/TextDirectionHeuristics.java
@@ -1,4 +1,18 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * 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.text;
@@ -36,12 +50,12 @@
new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, true);
/**
- * If the text contains any strong right to left non-format character, determines
- * that the direction is right to left, falling back to left to right if it
+ * If the text contains any strong left to right non-format character, determines
+ * that the direction is left to right, falling back to left to right if it
* finds none.
*/
- public static final TextDirectionHeuristic ANYRTL_LTR =
- new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false);
+ public static final TextDirectionHeuristic ANYLTR_LTR =
+ new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_LTR, false);
/**
* If the text contains any strong left to right non-format character, determines
@@ -52,6 +66,22 @@
new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_LTR, true);
/**
+ * If the text contains any strong right to left non-format character, determines
+ * that the direction is right to left, falling back to left to right if it
+ * finds none.
+ */
+ public static final TextDirectionHeuristic ANYRTL_LTR =
+ new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false);
+
+ /**
+ * If the text contains any strong right to left non-format character, determines
+ * that the direction is right to left, falling back to right to left if it
+ * finds none.
+ */
+ public static final TextDirectionHeuristic ANYRTL_RTL =
+ new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, true);
+
+ /**
* Examines only the strong directional non-format characters, and if either
* left to right or right to left characters are 60% or more of this total,
* determines that the direction follows the majority of characters. Falls
@@ -92,19 +122,6 @@
abstract protected boolean defaultIsRtl();
@Override
- public boolean isRtl(CharSequence text, int start, int end) {
- if (text == null || start < 0 || end < start || text.length() < end) {
- throw new IllegalArgumentException();
- }
- if (mAlgorithm == null) {
- return defaultIsRtl();
- }
- text = text.subSequence(start, end);
- char[] chars = text.toString().toCharArray();
- return doCheck(chars, 0, chars.length);
- }
-
- @Override
public boolean isRtl(char[] chars, int start, int count) {
if (chars == null || start < 0 || count < 0 || chars.length - count < start) {
throw new IllegalArgumentException();
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 29c9853..83ef6ce 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -259,6 +259,17 @@
}
/**
+ * Returns list of multiple {@link CharSequence} joined into a single
+ * {@link CharSequence} separated by localized delimiter such as ", ".
+ *
+ * @hide
+ */
+ public static CharSequence join(Iterable<CharSequence> list) {
+ final CharSequence delimiter = Resources.getSystem().getText(R.string.list_delimeter);
+ return join(delimiter, list);
+ }
+
+ /**
* Returns a string containing the tokens joined by delimiters.
* @param tokens an array objects to be joined. Strings will be formed from
* the objects by calling object.toString().
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6627bf6..abd9ad6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9165,6 +9165,7 @@
mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH;
}
jumpDrawablesToCurrentState();
+ // Order is important here: LayoutDirection should be resolved before Padding and TextDirection
resolveLayoutDirectionIfNeeded();
resolvePadding();
resolveTextDirection();
@@ -9185,6 +9186,10 @@
// Clear any previous layout direction resolution
mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_RTL;
+ // Reset also TextDirection as a change into LayoutDirection may impact the selected
+ // TextDirectionHeuristic
+ resetResolvedTextDirection();
+
// Set resolved depending on layout direction
switch (getLayoutDirection()) {
case LAYOUT_DIRECTION_INHERIT:
@@ -12663,13 +12668,15 @@
* Request that the visibility of the status bar be changed.
* @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
* {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
+ *
+ * This value will be re-applied immediately, even if the flags have not changed, so a view may
+ * easily reassert a particular SystemUiVisibility condition even if the system UI itself has
+ * since countermanded the original request.
*/
public void setSystemUiVisibility(int visibility) {
- if (visibility != mSystemUiVisibility) {
- mSystemUiVisibility = visibility;
- if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
- mParent.recomputeViewAttributes(this);
- }
+ mSystemUiVisibility = visibility;
+ if (mParent != null && mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
+ mParent.recomputeViewAttributes(this);
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 08cb270..8fa1922 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5012,7 +5012,9 @@
*/
public void requestTransitionStart(LayoutTransition transition) {
ViewRootImpl viewAncestor = getViewRootImpl();
- viewAncestor.requestTransitionStart(transition);
+ if (viewAncestor != null) {
+ viewAncestor.requestTransitionStart(transition);
+ }
}
@Override
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6374b47..17dfbe05 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -9036,15 +9036,6 @@
}
/**
- * Enable expanded tiles bound for smoother scrolling.
- *
- * @hide only used by the Browser
- */
- public void setExpandedTileBounds(boolean enabled) {
- nativeSetExpandedTileBounds(enabled);
- }
-
- /**
* Set the time to wait between passing touches to WebCore. See also the
* TOUCH_SENT_INTERVAL member for further discussion.
*
@@ -9273,7 +9264,6 @@
static final int NO_LEFTEDGE = -1;
native int nativeGetBlockLeftEdge(int x, int y, float scale);
- private native void nativeSetExpandedTileBounds(boolean enabled);
private native void nativeUseHardwareAccelSkia(boolean enabled);
// Returns a pointer to the scrollable LayerAndroid at the given point.
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index fc60949..b92130d 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -83,7 +83,6 @@
// Avoid allocations...
private RectF mTempSrc = new RectF();
private RectF mTempDst = new RectF();
- private float[] mTempPoints;
private boolean mCropToPadding;
@@ -347,29 +346,13 @@
if (mDrawable != drawable) {
mResource = 0;
mUri = null;
+
int oldWidth = mDrawableWidth;
int oldHeight = mDrawableHeight;
+
updateDrawable(drawable);
- boolean needsLayout;
- if (mScaleType == ScaleType.CENTER) {
- needsLayout = mDrawableWidth != oldWidth || mDrawableHeight != oldHeight;
- } else {
- if (mTempPoints == null) {
- mTempPoints = new float[4];
- }
- float[] points = mTempPoints;
- points[0] = oldWidth;
- points[1] = oldHeight;
- points[2] = mDrawableWidth;
- points[3] = mDrawableHeight;
- if (!mMatrix.isIdentity()) {
- mMatrix.mapPoints(points);
- }
- needsLayout = points[0] != points[2] || points[1] != points[3];
- }
-
- if (needsLayout) {
+ if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
requestLayout();
}
invalidate();
@@ -621,6 +604,8 @@
mDrawableHeight = d.getIntrinsicHeight();
applyColorMod();
configureBounds();
+ } else {
+ mDrawableWidth = mDrawableHeight = -1;
}
}
@@ -679,14 +664,14 @@
h = mDrawableHeight;
if (w <= 0) w = 1;
if (h <= 0) h = 1;
-
+
// We are supposed to adjust view bounds to match the aspect
// ratio of our drawable. See if that is possible.
if (mAdjustViewBounds) {
resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
- desiredAspect = (float)w/(float)h;
+ desiredAspect = (float) w / (float) h;
}
}
@@ -705,13 +690,11 @@
*/
// Get the max possible width given our constraints
- widthSize = resolveAdjustedSize(w + pleft + pright,
- mMaxWidth, widthMeasureSpec);
-
+ widthSize = resolveAdjustedSize(w + pleft + pright, mMaxWidth, widthMeasureSpec);
+
// Get the max possible height given our constraints
- heightSize = resolveAdjustedSize(h + ptop + pbottom,
- mMaxHeight, heightMeasureSpec);
-
+ heightSize = resolveAdjustedSize(h + ptop + pbottom, mMaxHeight, heightMeasureSpec);
+
if (desiredAspect != 0.0f) {
// See what our actual aspect ratio is
float actualAspect = (float)(widthSize - pleft - pright) /
@@ -723,9 +706,8 @@
// Try adjusting width to be proportional to height
if (resizeWidth) {
- int newWidth = (int)(desiredAspect *
- (heightSize - ptop - pbottom))
- + pleft + pright;
+ int newWidth = (int)(desiredAspect * (heightSize - ptop - pbottom)) +
+ pleft + pright;
if (newWidth <= widthSize) {
widthSize = newWidth;
done = true;
@@ -734,8 +716,8 @@
// Try adjusting height to be proportional to width
if (!done && resizeHeight) {
- int newHeight = (int)((widthSize - pleft - pright)
- / desiredAspect) + ptop + pbottom;
+ int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) +
+ ptop + pbottom;
if (newHeight <= heightSize) {
heightSize = newHeight;
}
@@ -859,7 +841,7 @@
if (dwidth <= vwidth && dheight <= vheight) {
scale = 1.0f;
} else {
- scale = Math.min((float) vwidth / (float) dwidth,
+ scale = Math.min((float) vwidth / (float) dwidth,
(float) vheight / (float) dheight);
}
@@ -874,8 +856,7 @@
mTempDst.set(0, 0, vwidth, vheight);
mDrawMatrix = mMatrix;
- mDrawMatrix.setRectToRect(mTempSrc, mTempDst,
- scaleTypeToScaleToFit(mScaleType));
+ mDrawMatrix.setRectToRect(mTempSrc, mTempDst, scaleTypeToScaleToFit(mScaleType));
}
}
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index aa23ad0..2a299bd 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1208,7 +1208,10 @@
float textGapCount = selectorIndices.length - 1;
int selectorTextGapHeight = (int) (totalTextGapHeight / textGapCount + 0.5f);
mSelectorElementHeight = mTextSize + selectorTextGapHeight;
- mInitialScrollOffset = mTextSize - 3 * (mSelectorElementHeight % 2);
+ // Ensure that the middle item is positioned the same as the text in mInputText
+ int editTextTextPosition = mInputText.getBaseline() + mInputText.getTop();
+ mInitialScrollOffset = editTextTextPosition -
+ (mSelectorElementHeight * SELECTOR_MIDDLE_ITEM_INDEX);
mCurrentScrollOffset = mInitialScrollOffset;
updateInputTextView();
}
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index aba6834..99f2765 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -35,6 +35,7 @@
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.speech.RecognizerIntent;
import android.text.Editable;
import android.text.InputType;
@@ -138,6 +139,12 @@
}
};
+ private Runnable mUpdateDrawableStateRunnable = new Runnable() {
+ public void run() {
+ updateFocusedState();
+ }
+ };
+
// For voice searching
private final Intent mVoiceWebSearchIntent;
private final Intent mVoiceAppSearchIntent;
@@ -624,6 +631,12 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Let the standard measurements take effect in iconified state.
+ if (isIconified()) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
+
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
@@ -720,9 +733,21 @@
mCloseButton.getDrawable().setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET);
}
- private void updateFocusedState(boolean focused) {
+ private void postUpdateFocusedState() {
+ post(mUpdateDrawableStateRunnable);
+ }
+
+ private void updateFocusedState() {
+ boolean focused = mQueryTextView.hasFocus();
mSearchPlate.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET);
mSubmitArea.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET);
+ invalidate();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ removeCallbacks(mUpdateDrawableStateRunnable);
+ super.onDetachedFromWindow();
}
private void setImeVisibility(final boolean visible) {
@@ -1118,15 +1143,19 @@
void onTextFocusChanged() {
updateViewsVisibility(isIconified());
- updateFocusedState(mQueryTextView.hasFocus());
+ // Delayed update to make sure that the focus has settled down and window focus changes
+ // don't affect it. A synchronous update was not working.
+ postUpdateFocusedState();
if (mQueryTextView.hasFocus()) {
forceSuggestionQuery();
}
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ super.onWindowFocusChanged(hasWindowFocus);
+
+ postUpdateFocusedState();
}
/**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d6cb61d..7a5a091 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9499,8 +9499,7 @@
public boolean isSuggestionsEnabled() {
if (!mSuggestionsEnabled) return false;
if ((mInputType & InputType.TYPE_MASK_CLASS) != InputType.TYPE_CLASS_TEXT) return false;
- final int variation =
- mInputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION);
+ final int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_VARIATION_NORMAL ||
variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT ||
variation == EditorInfo.TYPE_TEXT_VARIATION_LONG_MESSAGE ||
@@ -10729,42 +10728,29 @@
return mInBatchEditControllers;
}
- private class TextViewDirectionHeuristic extends TextDirectionHeuristicImpl {
- private TextViewDirectionHeuristic(TextDirectionAlgorithm algorithm) {
- super(algorithm);
- }
- @Override
- protected boolean defaultIsRtl() {
- return getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL;
- }
- }
-
- /**
- * Resolve the text direction.
- *
- * Text direction of paragraphs in a TextView is determined using a heuristic. If the correct
- * text direction cannot be determined by the heuristic, the view's resolved layout direction
- * determines the direction.
- *
- * This heuristic and result is applied individually to each paragraph in a TextView, based on
- * the text and style content of that paragraph. Paragraph text styles can also be used to force
- * a particular direction.
- */
@Override
protected void resolveTextDirection() {
+ // Always need to resolve layout direction first
+ final boolean defaultIsRtl = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL);
+
+ // Then resolve text direction on the parent
super.resolveTextDirection();
+ // Now, we can select the heuristic
int textDir = getResolvedTextDirection();
switch (textDir) {
default:
case TEXT_DIRECTION_FIRST_STRONG:
- mTextDir = new TextViewDirectionHeuristic(FirstStrong.INSTANCE);
+ mTextDir = (defaultIsRtl ? TextDirectionHeuristics.FIRSTSTRONG_RTL :
+ TextDirectionHeuristics.FIRSTSTRONG_LTR);
break;
case TEXT_DIRECTION_ANY_RTL:
- mTextDir = new TextViewDirectionHeuristic(AnyStrong.INSTANCE_RTL);
+ mTextDir = (defaultIsRtl ? TextDirectionHeuristics.ANYRTL_RTL:
+ TextDirectionHeuristics.ANYRTL_LTR);
break;
case TEXT_DIRECTION_CHAR_COUNT:
- mTextDir = new TextViewDirectionHeuristic(CharCount.INSTANCE_DEFAULT);
+ mTextDir = (defaultIsRtl ? TextDirectionHeuristics.CHARCOUNT_RTL:
+ TextDirectionHeuristics.CHARCOUNT_LTR);
break;
case TEXT_DIRECTION_LTR:
mTextDir = TextDirectionHeuristics.LTR;
@@ -10773,7 +10759,6 @@
mTextDir = TextDirectionHeuristics.RTL;
break;
}
-
}
/**
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 7b65964..df5071f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -67,12 +67,13 @@
private static final String TAG = "BatteryStatsImpl";
private static final boolean DEBUG = false;
private static final boolean DEBUG_HISTORY = false;
+ private static final boolean USE_OLD_HISTORY = false; // for debugging.
// In-memory Parcel magic number, used to detect attempts to unmarshall bad data
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 60;
+ private static final int VERSION = 61 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -1285,6 +1286,10 @@
void addHistoryRecordLocked(long curTime) {
addHistoryBufferLocked(curTime);
+ if (!USE_OLD_HISTORY) {
+ return;
+ }
+
if (!mHaveBatteryLevel || !mRecordingHistory) {
return;
}
@@ -1363,12 +1368,15 @@
void clearHistoryLocked() {
if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
- if (mHistory != null) {
- mHistoryEnd.next = mHistoryCache;
- mHistoryCache = mHistory;
- mHistory = mHistoryLastEnd = mHistoryEnd = null;
+ if (USE_OLD_HISTORY) {
+ if (mHistory != null) {
+ mHistoryEnd.next = mHistoryCache;
+ mHistoryCache = mHistory;
+ mHistory = mHistoryLastEnd = mHistoryEnd = null;
+ }
+ mNumHistoryItems = 0;
}
- mNumHistoryItems = 0;
+
mHistoryBaseTime = 0;
mLastHistoryTime = 0;
@@ -4863,7 +4871,9 @@
}
long now = SystemClock.elapsedRealtime();
- addHistoryRecordLocked(now, HistoryItem.CMD_START);
+ if (USE_OLD_HISTORY) {
+ addHistoryRecordLocked(now, HistoryItem.CMD_START);
+ }
addHistoryBufferLocked(now, HistoryItem.CMD_START);
}
@@ -4923,6 +4933,9 @@
}
void readOldHistory(Parcel in) {
+ if (!USE_OLD_HISTORY) {
+ return;
+ }
mHistory = mHistoryEnd = mHistoryCache = null;
long time;
while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
@@ -4952,6 +4965,9 @@
}
void writeOldHistory(Parcel out) {
+ if (!USE_OLD_HISTORY) {
+ return;
+ }
HistoryItem rec = mHistory;
while (rec != null) {
if (rec.time >= 0) rec.writeToParcel(out, 0);
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index aaae691..5c42579 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -173,7 +173,8 @@
public void updateMenuView(boolean cleared) {
super.updateMenuView(cleared);
- final boolean hasOverflow = mReserveOverflow && mMenu.getNonActionItems().size() > 0;
+ final boolean hasOverflow = mReserveOverflow && mMenu != null &&
+ mMenu.getNonActionItems().size() > 0;
if (hasOverflow) {
if (mOverflowButton == null) {
mOverflowButton = new OverflowMenuButton(mContext);
diff --git a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java
index ed9d34a..bec437a 100644
--- a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java
@@ -74,20 +74,24 @@
* Reuses item views when it can
*/
public void updateMenuView(boolean cleared) {
- mMenu.flagActionItems();
- ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
- final int itemCount = visibleItems.size();
final ViewGroup parent = (ViewGroup) mMenuView;
+ if (parent == null) return;
+
int childIndex = 0;
- for (int i = 0; i < itemCount; i++) {
- MenuItemImpl item = visibleItems.get(i);
- if (shouldIncludeItem(childIndex, item)) {
- final View convertView = parent.getChildAt(childIndex);
- final View itemView = getItemView(item, convertView, parent);
- if (itemView != convertView) {
- addItemView(itemView, childIndex);
+ if (mMenu != null) {
+ mMenu.flagActionItems();
+ ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
+ final int itemCount = visibleItems.size();
+ for (int i = 0; i < itemCount; i++) {
+ MenuItemImpl item = visibleItems.get(i);
+ if (shouldIncludeItem(childIndex, item)) {
+ final View convertView = parent.getChildAt(childIndex);
+ final View itemView = getItemView(item, convertView, parent);
+ if (itemView != convertView) {
+ addItemView(itemView, childIndex);
+ }
+ childIndex++;
}
- childIndex++;
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 6b5ea60..792766b 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -52,6 +52,7 @@
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.Window;
+import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -373,8 +374,7 @@
mActionMenuPresenter.setExpandedActionViewsExclusive(
getResources().getBoolean(
com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
- builder.addMenuPresenter(mActionMenuPresenter);
- builder.addMenuPresenter(mExpandedMenuPresenter);
+ configPresenters(builder);
menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
final ViewGroup oldParent = (ViewGroup) menuView.getParent();
if (oldParent != null && oldParent != this) {
@@ -390,8 +390,7 @@
mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
// Span the whole width
layoutParams.width = LayoutParams.MATCH_PARENT;
- builder.addMenuPresenter(mActionMenuPresenter);
- builder.addMenuPresenter(mExpandedMenuPresenter);
+ configPresenters(builder);
menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
if (mSplitView != null) {
final ViewGroup oldParent = (ViewGroup) menuView.getParent();
@@ -407,6 +406,18 @@
mMenuView = menuView;
}
+ private void configPresenters(MenuBuilder builder) {
+ if (builder != null) {
+ builder.addMenuPresenter(mActionMenuPresenter);
+ builder.addMenuPresenter(mExpandedMenuPresenter);
+ } else {
+ mActionMenuPresenter.initForMenu(mContext, null);
+ mExpandedMenuPresenter.initForMenu(mContext, null);
+ mActionMenuPresenter.updateMenuView(true);
+ mExpandedMenuPresenter.updateMenuView(true);
+ }
+ }
+
public boolean hasExpandedActionView() {
return mExpandedMenuPresenter != null &&
mExpandedMenuPresenter.mCurrentExpandedItem != null;
@@ -1025,6 +1036,8 @@
} else if (centeredLeft + navWidth > menuLeft) {
hgravity = Gravity.RIGHT;
}
+ } else if (gravity == -1) {
+ hgravity = Gravity.LEFT;
}
int xpos = 0;
@@ -1040,8 +1053,14 @@
break;
}
+ int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+ if (gravity == -1) {
+ vgravity = Gravity.CENTER_VERTICAL;
+ }
+
int ypos = 0;
- switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
+ switch (vgravity) {
case Gravity.CENTER_VERTICAL:
final int paddedTop = getPaddingTop();
final int paddedBottom = mBottom - mTop - getPaddingBottom();
@@ -1070,6 +1089,11 @@
}
@Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new ActionBar.LayoutParams(getContext(), attrs);
+ }
+
+ @Override
public LayoutParams generateLayoutParams(LayoutParams lp) {
if (lp == null) {
lp = generateDefaultLayoutParams();
@@ -1263,12 +1287,15 @@
// Make sure the expanded item we have is still there.
if (mCurrentExpandedItem != null) {
boolean found = false;
- final int count = mMenu.size();
- for (int i = 0; i < count; i++) {
- final MenuItem item = mMenu.getItem(i);
- if (item == mCurrentExpandedItem) {
- found = true;
- break;
+
+ if (mMenu != null) {
+ final int count = mMenu.size();
+ for (int i = 0; i < count; i++) {
+ final MenuItem item = mMenu.getItem(i);
+ if (item == mCurrentExpandedItem) {
+ found = true;
+ break;
+ }
}
}
diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java
index 23af37e..9f6ab31 100644
--- a/core/java/com/android/server/NetworkManagementSocketTagger.java
+++ b/core/java/com/android/server/NetworkManagementSocketTagger.java
@@ -115,7 +115,8 @@
private void unTagSocketFd(FileDescriptor fd) throws IOException {
int fdNum = fd.getInt$();
- if (fdNum == -1) return;
+ final SocketTags options = threadSocketTags.get();
+ if (fdNum == -1 || (options.statsTag == -1 && options.statsUid == -1)) return;
String cmd = "u " + fdNum;
internalModuleCtrl(cmd);
}
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 45b7f27..b369efb 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -507,6 +507,7 @@
#define EVENT_LOOP_EXIT 1
#define EVENT_LOOP_ADD 2
#define EVENT_LOOP_REMOVE 3
+#define EVENT_LOOP_WAKEUP 4
dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) {
native_data_t *nat = (native_data_t *)data;
@@ -551,6 +552,13 @@
}
}
+void dbusWakeup(void *data) {
+ native_data_t *nat = (native_data_t *)data;
+
+ char control = EVENT_LOOP_WAKEUP;
+ write(nat->controlFdW, &control, sizeof(char));
+}
+
static void handleWatchAdd(native_data_t *nat) {
DBusWatch *watch;
int newFD;
@@ -634,6 +642,7 @@
dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
+ dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL);
nat->running = true;
@@ -669,6 +678,11 @@
handleWatchRemove(nat);
break;
}
+ case EVENT_LOOP_WAKEUP:
+ {
+ // noop
+ break;
+ }
}
}
} else {
diff --git a/core/res/res/layout-sw600dp/preference_list_content.xml b/core/res/res/layout-sw600dp/preference_list_content.xml
index 5b67d71..08f6453 100644
--- a/core/res/res/layout-sw600dp/preference_list_content.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content.xml
@@ -44,8 +44,11 @@
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
+ android:paddingLeft="@dimen/preference_screen_header_padding_side"
+ android:paddingRight="@dimen/preference_screen_header_padding_side"
+ android:paddingTop="@dimen/preference_screen_header_vertical_padding"
+ android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
+ android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
android:drawSelectorOnTop="false"
android:cacheColorHint="@android:color/transparent"
android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/breadcrumbs_in_fragment.xml b/core/res/res/layout/breadcrumbs_in_fragment.xml
index 98fffb7..9c12618 100644
--- a/core/res/res/layout/breadcrumbs_in_fragment.xml
+++ b/core/res/res/layout/breadcrumbs_in_fragment.xml
@@ -13,10 +13,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<!-- This layout disables breadcrumbs in the fragment area and causes PreferenceActivity to
put the breadcrumbs in the action bar. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_height="@dimen/preference_fragment_padding_side"
- android:layout_width="match_parent">
-</LinearLayout>
\ No newline at end of file
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:visibility="gone" />
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 4e7981a..62181b5 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -44,8 +44,11 @@
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
+ android:paddingLeft="@dimen/preference_screen_header_padding_side"
+ android:paddingRight="@dimen/preference_screen_header_padding_side"
android:paddingTop="@dimen/preference_screen_header_vertical_padding"
android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
+ android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
android:drawSelectorOnTop="false"
android:cacheColorHint="@android:color/transparent"
android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index 315f708..fdef4fc 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -32,11 +32,19 @@
android:paddingBottom="@dimen/preference_fragment_padding_bottom"
android:paddingLeft="@dimen/preference_fragment_padding_side"
android:paddingRight="@dimen/preference_fragment_padding_side"
+ android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
android:clipToPadding="false"
android:drawSelectorOnTop="false"
android:cacheColorHint="@android:color/transparent"
android:scrollbarAlwaysDrawVerticalTrack="true" />
+ <TextView android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="@dimen/preference_fragment_padding_side"
+ android:gravity="center"
+ android:visibility="gone" />
+
<RelativeLayout android:id="@+id/button_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml
index 0ffd571..f699a46 100644
--- a/core/res/res/layout/search_view.xml
+++ b/core/res/res/layout/search_view.xml
@@ -40,12 +40,11 @@
<ImageView
android:id="@+id/search_button"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
- android:src="?android:attr/searchViewSearchIcon"
style="?android:attr/actionButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:src="?android:attr/searchViewSearchIcon"
android:contentDescription="@string/searchview_description_search"
/>
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index 37dee8e..7efe322 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -25,4 +25,10 @@
<dimen name="preference_screen_top_margin">16dp</dimen>
<!-- Preference activity bottom margin -->
<dimen name="preference_screen_bottom_margin">16dp</dimen>
+
+ <dimen name="preference_screen_header_padding_side">0dip</dimen>
+
+ <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+ <integer name="preference_fragment_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+
</resources>
diff --git a/core/res/res/values-w720dp/dimens.xml b/core/res/res/values-w720dp/dimens.xml
index 3d10103..c62c3f5 100644
--- a/core/res/res/values-w720dp/dimens.xml
+++ b/core/res/res/values-w720dp/dimens.xml
@@ -29,4 +29,9 @@
This helps in aligning titles when some items have icons and some don't. When space is
at a premium, we don't pre-allocate any space. -->
<dimen name="preference_icon_minWidth">56dp</dimen>
+
+ <dimen name="preference_screen_header_padding_side">0dip</dimen>
+
+ <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+ <integer name="preference_fragment_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 8855645..83e86939 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -76,9 +76,9 @@
<dimen name="multiwaveview_hit_radius">60dip</dimen>
<!-- Preference activity side margins -->
- <dimen name="preference_screen_side_margin">16dp</dimen>
+ <dimen name="preference_screen_side_margin">0dp</dimen>
<!-- Preference activity side margins negative-->
- <dimen name="preference_screen_side_margin_negative">16dp</dimen>
+ <dimen name="preference_screen_side_margin_negative">0dp</dimen>
<!-- Preference activity top margin -->
<dimen name="preference_screen_top_margin">0dp</dimen>
<!-- Preference activity bottom margin -->
@@ -88,7 +88,7 @@
<!-- Preference fragment padding, bottom -->
<dimen name="preference_fragment_padding_bottom">0dp</dimen>
<!-- Preference fragment padding, sides -->
- <dimen name="preference_fragment_padding_side">0dp</dimen>
+ <dimen name="preference_fragment_padding_side">16dp</dimen>
<!-- Weight of the left pane in a multi-pane preference layout. -->
<integer name="preferences_left_pane_weight">4</integer>
<!-- Weight of the right pane in a multi-pane preference layout. So the split is 40:60 -->
@@ -108,6 +108,11 @@
<!-- Preference activity, vertical padding for the header list -->
<dimen name="preference_screen_header_vertical_padding">0dp</dimen>
+ <dimen name="preference_screen_header_padding_side">16dip</dimen>
+ <integer name="preference_screen_header_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
+
+ <integer name="preference_fragment_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
+
<dimen name="preference_item_padding_side">8dip</dimen>
<dimen name="preference_item_padding_inner">8dip</dimen>
<dimen name="preference_child_padding_side">16dip</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index feb7846..128889c 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -225,7 +225,7 @@
<!-- Displayed when a web request failed because there was a connection error. -->
<string name="httpErrorConnect">The connection to the server was unsuccessful.</string>
<!-- Displayed when a web request failed because there was an input or output error. -->
- <string name="httpErrorIO">The server failed to communicate. Try again later.</string>
+ <string name="httpErrorIO">The server couldn\'t communicate. Try again later.</string>
<!-- Displayed when a web request failed because the request timed out -->
<string name="httpErrorTimeout">The connection to the server timed out.</string>
<!-- Displayed when a web request failed because the site tried to redirect us one too many times -->
@@ -2500,10 +2500,10 @@
<!-- Title of the alert when an application has crashed. -->
<string name="aerr_title"></string>
<!-- Text of the alert that is displayed when an application has crashed. -->
- <string name="aerr_application"><xliff:g id="application">%1$s</xliff:g> has stopped by mistake.</string>
+ <string name="aerr_application">Unfortunately, <xliff:g id="application">%1$s</xliff:g> has stopped.</string>
<!-- Text of the alert that is displayed when an application has crashed. -->
- <string name="aerr_process">The process <xliff:g id="process">%1$s</xliff:g> has
- stopped by mistake.</string>
+ <string name="aerr_process">Unfortunately, the process <xliff:g id="process">%1$s</xliff:g> has
+ stopped.</string>
<!-- Title of the alert when an application is not responding. -->
<string name="anr_title"></string>
<!-- Text of the alert that is displayed when an application is not responding. -->
@@ -2629,7 +2629,7 @@
<!-- Wi-Fi p2p dialog title-->
<string name="wifi_p2p_dialog_title">Wi-Fi Direct</string>
<string name="wifi_p2p_turnon_message">Start Wi-Fi Direct operation. This will turn off Wi-Fi client/hotspot operation.</string>
- <string name="wifi_p2p_failed_message">Failed to start Wi-Fi Direct</string>
+ <string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct</string>
<string name="wifi_p2p_pbc_go_negotiation_request_message">Wi-Fi Direct connection setup request from <xliff:g id="p2p_device_address">%1$s</xliff:g>. Click OK to accept. </string>
<string name="wifi_p2p_pin_go_negotiation_request_message">Wi-Fi Direct connection setup request from <xliff:g id="p2p_device_address">%1$s</xliff:g>. Enter pin to proceed. </string>
<string name="wifi_p2p_pin_display_message">WPS pin <xliff:g id="p2p_wps_pin">%1$s</xliff:g> needs to be entered on the peer device <xliff:g id="p2p_client_address">%2$s</xliff:g> for connection setup to proceed </string>
@@ -2728,7 +2728,7 @@
<!-- USB_STORAGE_KILL_STORAGE_USERS dialog message text -->
<string name="dlg_confirm_kill_storage_users_text">If you turn on USB storage, some applications you are using will stop and may be unavailable until you turn off USB storage.</string>
<!-- USB_STORAGE_ERROR dialog dialog-->
- <string name="dlg_error_title">USB operation failed</string>
+ <string name="dlg_error_title">USB operation unsuccessful</string>
<!-- USB_STORAGE_ERROR dialog ok button-->
<string name="dlg_ok">OK</string>
@@ -2982,9 +2982,9 @@
<!-- Text for progress dialog while erasing SD card [CHAR LIMIT=NONE] -->
<string name="progress_erasing" product="default">Erasing SD card...</string>
<!-- Text for message to user that an error happened when formatting USB storage [CHAR LIMIT=NONE] -->
- <string name="format_error" product="nosdcard">Failed to erase USB storage.</string>
+ <string name="format_error" product="nosdcard">Couldn\'t erase USB storage.</string>
<!-- Text for message to user that an error happened when formatting SD card [CHAR LIMIT=NONE] -->
- <string name="format_error" product="default">Failed to erase SD card.</string>
+ <string name="format_error" product="default">Couldn\'t erase SD card.</string>
<!-- Text for message to user that SD card has been removed while in use [CHAR LIMIT=NONE] -->
<string name="media_bad_removal">SD card was removed before being unmounted.</string>
<!-- Text for message to user USB storage is currently being checked [CHAR LIMIT=NONE] -->
@@ -3153,4 +3153,7 @@
<!-- Description of for the status bar's icon that the device is locked for accessibility. [CHAR LIMIT=NONE] -->
<string name="status_bar_device_locked">Device locked.</string>
+ <!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
+ <string name="list_delimeter">", "</string>
+
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 6f2f1e5..94c6e41 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2363,7 +2363,7 @@
<style name="Widget.Holo.PreferenceFrameLayout">
<item name="android:borderTop">0dip</item>
- <item name="android:borderBottom">@dimen/preference_fragment_padding_side</item>
+ <item name="android:borderBottom">@dimen/preference_fragment_padding_bottom</item>
<item name="android:borderLeft">@dimen/preference_fragment_padding_side</item>
<item name="android:borderRight">@dimen/preference_fragment_padding_side</item>
</style>
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index b82e698..3e96dc4 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -20,11 +20,16 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.List;
/** Unit test for SettingsProvider. */
public class SettingsProviderTest extends AndroidTestCase {
@@ -191,4 +196,49 @@
assertEquals("test1,test2",
Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
}
+
+ @SmallTest
+ public void testSettings() {
+ assertCanBeHandled(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_ADD_ACCOUNT));
+ assertCanBeHandled(new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_APN_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ .setData(Uri.parse("package:" + getContext().getPackageName())));
+ assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DATE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_DISPLAY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_LOCALE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_QUICK_LAUNCH_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SEARCH_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SECURITY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SOUND_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SYNC_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_SYSTEM_UPDATE_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_USER_DICTIONARY_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_WIFI_IP_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SETTINGS));
+ assertCanBeHandled(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
+ }
+
+ private void assertCanBeHandled(final Intent intent) {
+ PackageManager packageManager = mContext.getPackageManager();
+ List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
+ assertNotNull(resolveInfoList);
+ // one or more activity can handle this intent.
+ assertTrue(resolveInfoList.size() > 0);
+ }
}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 05bd626..0353a47 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -155,6 +155,7 @@
<assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
<assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
<assign-permission name="android.permission.BACKUP" uid="shell" />
+ <assign-permission name="android.permission.FORCE_STOP_PACKAGES" uid="shell" />
<assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
<assign-permission name="android.permission.ACCESS_DRM" uid="media" />
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 49dbbca..6698d31 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -277,10 +277,19 @@
*/
public boolean setDrawableByLayerId(int id, Drawable drawable) {
final ChildDrawable[] layers = mLayerState.mChildren;
- drawable.setCallback(this);
for (int i = mLayerState.mNum - 1; i >= 0; i--) {
if (layers[i].mId == id) {
+ if (layers[i].mDrawable != null) {
+ if (drawable != null) {
+ Rect bounds = layers[i].mDrawable.getBounds();
+ drawable.setBounds(bounds);
+ }
+ layers[i].mDrawable.setCallback(null);
+ }
+ if (drawable != null) {
+ drawable.setCallback(this);
+ }
layers[i].mDrawable = drawable;
return true;
}
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index b661496..6c91dfc 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -597,13 +597,24 @@
// CameraHardwareInterface.autoFocus in this mode.
static const char FOCUS_MODE_EDOF[];
// Continuous auto focus mode intended for video recording. The camera
- // continuously tries to focus. This is ideal for shooting video.
- // Applications still can call CameraHardwareInterface.takePicture in this
- // mode but the subject may not be in focus. Auto focus starts when the
- // parameter is set. Applications should not call
- // CameraHardwareInterface.autoFocus in this mode. To stop continuous focus,
- // applications should change the focus mode to other modes.
+ // continuously tries to focus. This is the best choice for video
+ // recording because the focus changes smoothly . Applications still can
+ // call CameraHardwareInterface.takePicture in this mode but the subject may
+ // not be in focus. Auto focus starts when the parameter is set.
+ // Applications should not call CameraHardwareInterface.autoFocus in this
+ // mode. To stop continuous focus, applications should change the focus mode
+ // to other modes.
static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
+ // Continuous auto focus mode intended for taking pictures. The camera
+ // continuously tries to focus. The speed of focus change is more aggressive
+ // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
+ // set. If applications call autoFocus in this mode, the focus callback will
+ // immediately return with a boolean that indicates the focus is sharp or
+ // not. The apps can then decide if they want to take a picture immediately
+ // or to change the focus mode to auto, and run a full autofocus cycle. To
+ // stop continuous focus, applications should change the focus mode to other
+ // modes.
+ static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
private:
DefaultKeyedVector<String8,String8> mMap;
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index a6fb12e..493993d 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -275,7 +275,7 @@
enum BufferState {
// FREE indicates that the buffer is not currently being used and
// will not be used in the future until it gets dequeued and
- // subseqently queued by the client.
+ // subsequently queued by the client.
FREE = 0,
// DEQUEUED indicates that the buffer has been dequeued by the
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 584f53f..360f407 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -156,7 +156,7 @@
inline String16 String16::operator+(const String16& other) const
{
- String16 tmp;
+ String16 tmp(*this);
tmp += other;
return tmp;
}
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index 51b96c1..0eb5d50 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -160,6 +160,7 @@
const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video";
+const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture";
CameraParameters::CameraParameters()
: mMap()
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 7ac4343..ac9b33b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -36,6 +36,10 @@
#include <utils/Log.h>
#include <utils/String8.h>
+
+#define ALLOW_DEQUEUE_CURRENT_BUFFER false
+
+
namespace android {
// Transform matrices
@@ -294,9 +298,22 @@
if (state == BufferSlot::DEQUEUED) {
dequeuedCount++;
}
- if (state == BufferSlot::FREE /*|| i == mCurrentTexture*/) {
- foundSync = i;
- if (i != mCurrentTexture) {
+
+ // if buffer is FREE it CANNOT be current
+ LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
+ "dequeueBuffer: buffer %d is both FREE and current!", i);
+
+ if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
+ if (state == BufferSlot::FREE || i == mCurrentTexture) {
+ foundSync = i;
+ if (i != mCurrentTexture) {
+ found = i;
+ break;
+ }
+ }
+ } else {
+ if (state == BufferSlot::FREE) {
+ foundSync = i;
found = i;
break;
}
@@ -325,7 +342,7 @@
}
// we're in synchronous mode and didn't find a buffer, we need to wait
- // for for some buffers to be consumed
+ // for some buffers to be consumed
tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
if (tryAgain) {
mDequeueCondition.wait(mMutex);
@@ -482,17 +499,16 @@
mSlots[buf].mScalingMode = mNextScalingMode;
mSlots[buf].mTimestamp = timestamp;
mDequeueCondition.signal();
+
+ *outWidth = mDefaultWidth;
+ *outHeight = mDefaultHeight;
+ *outTransform = 0;
} // scope for the lock
// call back without lock held
if (listener != 0) {
listener->onFrameAvailable();
}
-
- *outWidth = mDefaultWidth;
- *outHeight = mDefaultHeight;
- *outTransform = 0;
-
return OK;
}
@@ -847,6 +863,7 @@
void SurfaceTexture::freeAllBuffersLocked() {
LOGW_IF(!mQueue.isEmpty(),
"freeAllBuffersLocked called but mQueue is not empty");
+ mCurrentTexture = INVALID_BUFFER_SLOT;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
freeBufferLocked(i);
}
@@ -860,6 +877,7 @@
Fifo::iterator front(mQueue.begin());
head = *front;
}
+ mCurrentTexture = INVALID_BUFFER_SLOT;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (i != head) {
freeBufferLocked(i);
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index fb2df37..176dd18 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -182,6 +182,7 @@
const Allocation * ain;
Allocation * aout;
const void * usr;
+ size_t usrLen;
uint32_t mSliceSize;
volatile int mSliceNum;
@@ -209,6 +210,10 @@
static void wc_xy(void *usr, uint32_t idx) {
MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+ RsForEachStubParamStruct p;
+ memset(&p, 0, sizeof(p));
+ p.usr = mtls->usr;
+ p.usr_len = mtls->usrLen;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
@@ -221,13 +226,15 @@
//LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
//LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
- for (uint32_t y = yStart; y < yEnd; y++) {
- uint32_t offset = mtls->dimX * y;
+ for (p.y = yStart; p.y < yEnd; p.y++) {
+ uint32_t offset = mtls->dimX * p.y;
uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset);
const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset);
- for (uint32_t x = mtls->xStart; x < mtls->xEnd; x++) {
- ((rs_t)mtls->script->mHal.info.root) (xPtrIn, xPtrOut, mtls->usr, x, y, 0, 0);
+ for (p.x = mtls->xStart; p.x < mtls->xEnd; p.x++) {
+ p.in = xPtrIn;
+ p.out = xPtrOut;
+ ((rs_t)mtls->script->mHal.info.root) (p.in, p.out, p.usr, p.x, p.y, 0, 0);
xPtrIn += mtls->eStrideIn;
xPtrOut += mtls->eStrideOut;
}
@@ -237,6 +244,10 @@
static void wc_x(void *usr, uint32_t idx) {
MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+ RsForEachStubParamStruct p;
+ memset(&p, 0, sizeof(p));
+ p.usr = mtls->usr;
+ p.usr_len = mtls->usrLen;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
@@ -251,8 +262,10 @@
//LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * xStart);
const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * xStart);
- for (uint32_t x = xStart; x < xEnd; x++) {
- ((rs_t)mtls->script->mHal.info.root) (xPtrIn, xPtrOut, mtls->usr, x, 0, 0, 0);
+ for (p.x = xStart; p.x < xEnd; p.x++) {
+ p.in = xPtrIn;
+ p.out = xPtrOut;
+ ((rs_t)mtls->script->mHal.info.root) (p.in, p.out, p.usr, p.x, 0, 0, 0);
xPtrIn += mtls->eStrideIn;
xPtrOut += mtls->eStrideOut;
}
@@ -325,6 +338,7 @@
mtls.aout = aout;
mtls.script = s;
mtls.usr = usr;
+ mtls.usrLen = usrLen;
mtls.mSliceSize = 10;
mtls.mSliceNum = 0;
@@ -351,18 +365,25 @@
//LOGE("launch 1");
} else {
+ RsForEachStubParamStruct p;
+ memset(&p, 0, sizeof(p));
+ p.usr = mtls.usr;
+ p.usr_len = mtls.usrLen;
+
//LOGE("launch 3");
- for (uint32_t ar = mtls.arrayStart; ar < mtls.arrayEnd; ar++) {
- for (uint32_t z = mtls.zStart; z < mtls.zEnd; z++) {
- for (uint32_t y = mtls.yStart; y < mtls.yEnd; y++) {
- uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * ar +
- mtls.dimX * mtls.dimY * z +
- mtls.dimX * y;
+ for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) {
+ for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) {
+ for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) {
+ uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * p.ar[0] +
+ mtls.dimX * mtls.dimY * p.z +
+ mtls.dimX * p.y;
uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset);
const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset);
- for (uint32_t x = mtls.xStart; x < mtls.xEnd; x++) {
- ((rs_t)s->mHal.info.root) (xPtrIn, xPtrOut, usr, x, y, z, ar);
+ for (p.x = mtls.xStart; p.x < mtls.xEnd; p.x++) {
+ p.in = xPtrIn;
+ p.out = xPtrOut;
+ ((rs_t)s->mHal.info.root) (p.in, p.out, p.usr, p.x, p.y, p.z, p.ar[0]);
xPtrIn += mtls.eStrideIn;
xPtrOut += mtls.eStrideOut;
}
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 0dea971..f277582 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -127,6 +127,7 @@
}
ElementCreate {
+ direct
param RsDataType mType
param RsDataKind mKind
param bool mNormalized
@@ -135,6 +136,7 @@
}
ElementCreate2 {
+ direct
param const RsElement * elements
param const char ** names
param const uint32_t * arraySize
@@ -226,6 +228,7 @@
}
SamplerCreate {
+ direct
param RsSamplerValue magFilter
param RsSamplerValue minFilter
param RsSamplerValue wrapS
@@ -311,6 +314,7 @@
ProgramStoreCreate {
+ direct
param bool colorMaskR
param bool colorMaskG
param bool colorMaskB
@@ -324,6 +328,7 @@
}
ProgramRasterCreate {
+ direct
param bool pointSmooth
param bool lineSmooth
param bool pointSprite
@@ -352,12 +357,14 @@
}
ProgramFragmentCreate {
+ direct
param const char * shaderText
param const uint32_t * params
ret RsProgramFragment
}
ProgramVertexCreate {
+ direct
param const char * shaderText
param const uint32_t * params
ret RsProgramVertex
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index b59ade8..a366d49 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -252,6 +252,7 @@
Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
alloc->setName(name.string(), name.size());
+ type->decUserRef();
uint32_t count = dataSize / type->getElementSizeBytes();
@@ -307,12 +308,12 @@
return;
}
- Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
+ ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX);
if (dimX < oldDimX) {
decRefs(getPtr(), oldDimX - dimX, dimX);
}
- rsc->mHal.funcs.allocation.resize(rsc, this, t, mHal.state.hasReferences);
- mHal.state.type.set(t);
+ rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
+ mHal.state.type.set(t.get());
updateCache();
}
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index e65febb..ce06306 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -176,36 +176,6 @@
return (mType >= RS_TYPE_ELEMENT);
}
-String8 Component::getGLSLType() const {
- if (mType == RS_TYPE_SIGNED_32) {
- switch (mVectorSize) {
- case 1: return String8("int");
- case 2: return String8("ivec2");
- case 3: return String8("ivec3");
- case 4: return String8("ivec4");
- }
- }
- if (mType == RS_TYPE_FLOAT_32) {
- switch (mVectorSize) {
- case 1: return String8("float");
- case 2: return String8("vec2");
- case 3: return String8("vec3");
- case 4: return String8("vec4");
- }
- }
- if ((mType == RS_TYPE_MATRIX_4X4) && (mVectorSize == 1)) {
- return String8("mat4");
- }
- if ((mType == RS_TYPE_MATRIX_3X3) && (mVectorSize == 1)) {
- return String8("mat3");
- }
- if ((mType == RS_TYPE_MATRIX_2X2) && (mVectorSize == 1)) {
- return String8("mat2");
- }
- return String8();
-}
-
-
static const char * gTypeBasicStrings[] = {
"NONE",
"F16",
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index a448f0e..6ddc990 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -32,10 +32,8 @@
void set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize=1);
- String8 getGLSLType() const;
void dumpLOGV(const char *prefix) const;
-
RsDataType getType() const {return mType;}
RsDataKind getKind() const {return mKind;}
bool getIsNormalized() const {return mNormalized;}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index bffe3c0..8996ad1 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -240,6 +240,7 @@
rsc->setProgramStore(NULL);
rsc->mStateFont.init(rsc);
rsc->setFont(NULL);
+ rsc->mStateSampler.init(rsc);
rsc->mFBOCache.init(rsc);
}
@@ -251,10 +252,11 @@
while (!rsc->mExit) {
uint64_t waitTime = 0;
uint64_t now = rsc->getTime();
- if (now < targetTime) {
- waitTime = targetTime - now;
- } else {
- doWait = false;
+ if (!doWait) {
+ if (now < targetTime) {
+ waitTime = targetTime - now;
+ doWait = true;
+ }
}
mDraw |= rsc->mIO.playCoreCommands(rsc, doWait, waitTime);
@@ -264,7 +266,7 @@
if (mDraw && rsc->mIsGraphicsContext) {
uint64_t delay = rsc->runRootScript() * 1000000;
targetTime = rsc->getTime() + delay;
- doWait = delay != 0;
+ doWait = (delay == 0);
if (rsc->props.mLogVisual) {
rsc->displayDebugStats();
@@ -307,6 +309,7 @@
mStateFragment.deinit(this);
mStateFragmentStore.deinit(this);
mStateFont.deinit(this);
+ mStateSampler.deinit(this);
mFBOCache.deinit(this);
}
//LOGV("destroyWorkerThreadResources 2");
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index b77b18a..36bbdf0 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -29,13 +29,16 @@
}
Element::~Element() {
+ clear();
+}
+
+void Element::preDestroy() const {
for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
if (mRSC->mStateElement.mElements[ct] == this) {
mRSC->mStateElement.mElements.removeAt(ct);
break;
}
}
- clear();
}
void Element::clear() {
@@ -60,6 +63,7 @@
void Element::dumpLOGV(const char *prefix) const {
ObjectBase::dumpLOGV(prefix);
LOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes());
+ mComponent.dumpLOGV(prefix);
for (uint32_t ct = 0; ct < mFieldCount; ct++) {
LOGV("%s Element field index: %u ------------------", prefix, ct);
LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
@@ -97,60 +101,46 @@
String8 name;
stream->loadString(&name);
- Element *elem = new Element(rsc);
- elem->mComponent.loadFromStream(stream);
+ Component component;
+ component.loadFromStream(stream);
- elem->mFieldCount = stream->loadU32();
- if (elem->mFieldCount) {
- elem->mFields = new ElementField_t [elem->mFieldCount];
- for (uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
- stream->loadString(&elem->mFields[ct].name);
- elem->mFields[ct].arraySize = stream->loadU32();
- Element *fieldElem = Element::createFromStream(rsc, stream);
- elem->mFields[ct].e.set(fieldElem);
- }
+ uint32_t fieldCount = stream->loadU32();
+ if (!fieldCount) {
+ return (Element *)Element::create(rsc,
+ component.getType(),
+ component.getKind(),
+ component.getIsNormalized(),
+ component.getVectorSize());;
}
- // We need to check if this already exists
- for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
- Element *ee = rsc->mStateElement.mElements[ct];
- if (ee->isEqual(elem)) {
- ObjectBase::checkDelete(elem);
- ee->incUserRef();
- return ee;
- }
+ const Element **subElems = new const Element *[fieldCount];
+ const char **subElemNames = new const char *[fieldCount];
+ size_t *subElemNamesLengths = new size_t[fieldCount];
+ uint32_t *arraySizes = new uint32_t[fieldCount];
+
+ String8 elemName;
+ for (uint32_t ct = 0; ct < fieldCount; ct ++) {
+ stream->loadString(&elemName);
+ subElemNamesLengths[ct] = elemName.length();
+ char *tmpName = new char[subElemNamesLengths[ct]];
+ memcpy(tmpName, elemName.string(), subElemNamesLengths[ct]);
+ subElemNames[ct] = tmpName;
+ arraySizes[ct] = stream->loadU32();
+ subElems[ct] = Element::createFromStream(rsc, stream);
}
- elem->compute();
- rsc->mStateElement.mElements.push(elem);
- return elem;
-}
+ const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames,
+ subElemNamesLengths, arraySizes);
+ for (uint32_t ct = 0; ct < fieldCount; ct ++) {
+ delete [] subElemNames[ct];
+ subElems[ct]->decUserRef();
+ }
+ delete[] subElems;
+ delete[] subElemNames;
+ delete[] subElemNamesLengths;
+ delete[] arraySizes;
-bool Element::isEqual(const Element *other) const {
- if (other == NULL) {
- return false;
- }
- if (!other->getFieldCount() && !mFieldCount) {
- if ((other->getType() == getType()) &&
- (other->getKind() == getKind()) &&
- (other->getComponent().getIsNormalized() == getComponent().getIsNormalized()) &&
- (other->getComponent().getVectorSize() == getComponent().getVectorSize())) {
- return true;
- }
- return false;
- }
- if (other->getFieldCount() == mFieldCount) {
- for (uint32_t i=0; i < mFieldCount; i++) {
- if ((!other->mFields[i].e->isEqual(mFields[i].e.get())) ||
- (other->mFields[i].name.length() != mFields[i].name.length()) ||
- (other->mFields[i].name != mFields[i].name) ||
- (other->mFields[i].arraySize != mFields[i].arraySize)) {
- return false;
- }
- }
- return true;
- }
- return false;
+ return (Element *)elem;
}
void Element::compute() {
@@ -172,9 +162,11 @@
}
-const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
+ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk,
bool isNorm, uint32_t vecSize) {
+ ObjectBaseRef<const Element> returnRef;
// Look for an existing match.
+ ObjectBase::asyncLock();
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
const Element *ee = rsc->mStateElement.mElements[ct];
if (!ee->getFieldCount() &&
@@ -183,21 +175,31 @@
(ee->getComponent().getIsNormalized() == isNorm) &&
(ee->getComponent().getVectorSize() == vecSize)) {
// Match
- ee->incUserRef();
+ returnRef.set(ee);
+ ObjectBase::asyncUnlock();
return ee;
}
}
+ ObjectBase::asyncUnlock();
Element *e = new Element(rsc);
+ returnRef.set(e);
e->mComponent.set(dt, dk, isNorm, vecSize);
e->compute();
+
+ ObjectBase::asyncLock();
rsc->mStateElement.mElements.push(e);
- return e;
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
}
-const Element * Element::create(Context *rsc, size_t count, const Element **ein,
+ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein,
const char **nin, const size_t * lengths, const uint32_t *asin) {
+
+ ObjectBaseRef<const Element> returnRef;
// Look for an existing match.
+ ObjectBase::asyncLock();
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
const Element *ee = rsc->mStateElement.mElements[ct];
if (ee->getFieldCount() == count) {
@@ -212,13 +214,16 @@
}
}
if (match) {
- ee->incUserRef();
- return ee;
+ returnRef.set(ee);
+ ObjectBase::asyncUnlock();
+ return returnRef;
}
}
}
+ ObjectBase::asyncUnlock();
Element *e = new Element(rsc);
+ returnRef.set(e);
e->mFields = new ElementField_t [count];
e->mFieldCount = count;
for (size_t ct=0; ct < count; ct++) {
@@ -228,26 +233,11 @@
}
e->compute();
+ ObjectBase::asyncLock();
rsc->mStateElement.mElements.push(e);
- return e;
-}
+ ObjectBase::asyncUnlock();
-String8 Element::getGLSLType(uint32_t indent) const {
- String8 s;
- for (uint32_t ct=0; ct < indent; ct++) {
- s.append(" ");
- }
-
- if (!mFieldCount) {
- // Basic component.
- s.append(mComponent.getGLSLType());
- } else {
- rsAssert(0);
- //s.append("struct ");
- //s.append(getCStructBody(indent));
- }
-
- return s;
+ return returnRef;
}
void Element::incRefs(const void *ptr) const {
@@ -294,6 +284,23 @@
}
}
+void Element::Builder::add(const Element *e, const char *nameStr, uint32_t arraySize) {
+ mBuilderElementRefs.push(ObjectBaseRef<const Element>(e));
+ mBuilderElements.push(e);
+ mBuilderNameStrings.push(nameStr);
+ mBuilderNameLengths.push(strlen(nameStr));
+ mBuilderArrays.push(arraySize);
+
+}
+
+ObjectBaseRef<const Element> Element::Builder::create(Context *rsc) {
+ return Element::createRef(rsc, mBuilderElements.size(),
+ &(mBuilderElements.editArray()[0]),
+ &(mBuilderNameStrings.editArray()[0]),
+ mBuilderNameLengths.editArray(),
+ mBuilderArrays.editArray());
+}
+
ElementState::ElementState() {
const uint32_t initialCapacity = 32;
@@ -324,10 +331,10 @@
const Element *ElementState::elementBuilderCreate(Context *rsc) {
return Element::create(rsc, mBuilderElements.size(),
- &(mBuilderElements.editArray()[0]),
- &(mBuilderNameStrings.editArray()[0]),
- mBuilderNameLengths.editArray(),
- mBuilderArrays.editArray());
+ &(mBuilderElements.editArray()[0]),
+ &(mBuilderNameStrings.editArray()[0]),
+ mBuilderNameLengths.editArray(),
+ mBuilderArrays.editArray());
}
@@ -342,9 +349,7 @@
RsDataKind dk,
bool norm,
uint32_t vecSize) {
- const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
- e->incUserRef();
- return (RsElement)e;
+ return (RsElement)Element::create(rsc, dt, dk, norm, vecSize);
}
@@ -358,15 +363,15 @@
const uint32_t * arraySizes,
size_t arraySizes_length) {
- const Element *e = Element::create(rsc, ein_length, (const Element **)ein, names, nameLengths, arraySizes);
- e->incUserRef();
- return (RsElement)e;
+ return (RsElement)Element::create(rsc, ein_length, (const Element **)ein,
+ names, nameLengths, arraySizes);
}
}
}
-void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) {
+void rsaElementGetNativeData(RsContext con, RsElement elem,
+ uint32_t *elemData, uint32_t elemDataSize) {
rsAssert(elemDataSize == 5);
// we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
Element *e = static_cast<Element *>(elem);
@@ -378,7 +383,8 @@
(*elemData++) = e->getFieldCount();
}
-void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) {
+void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids,
+ const char **names, uint32_t dataSize) {
Element *e = static_cast<Element *>(elem);
rsAssert(e->getFieldCount() == dataSize);
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 26e2760..c3ef250 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -28,8 +28,17 @@
// An element is a group of Components that occupies one cell in a structure.
class Element : public ObjectBase {
public:
- ~Element();
-
+ class Builder {
+ public:
+ void add(const Element *e, const char *nameStr, uint32_t arraySize);
+ ObjectBaseRef<const Element> create(Context *rsc);
+ private:
+ Vector<ObjectBaseRef<const Element> > mBuilderElementRefs;
+ Vector<const Element *> mBuilderElements;
+ Vector<const char*> mBuilderNameStrings;
+ Vector<size_t> mBuilderNameLengths;
+ Vector<uint32_t> mBuilderArrays;
+ };
uint32_t getGLType() const;
uint32_t getGLFormat() const;
@@ -55,24 +64,45 @@
RsDataKind getKind() const {return mComponent.getKind();}
uint32_t getBits() const {return mBits;}
- String8 getGLSLType(uint32_t indent=0) const;
-
void dumpLOGV(const char *prefix) const;
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_ELEMENT; }
static Element *createFromStream(Context *rsc, IStream *stream);
- static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
- bool isNorm, uint32_t vecSize);
- static const Element * create(Context *rsc, size_t count, const Element **,
- const char **, const size_t * lengths, const uint32_t *asin);
+ static ObjectBaseRef<const Element> createRef(Context *rsc,
+ RsDataType dt,
+ RsDataKind dk,
+ bool isNorm,
+ uint32_t vecSize);
+ static ObjectBaseRef<const Element> createRef(Context *rsc, size_t count,
+ const Element **,
+ const char **,
+ const size_t * lengths,
+ const uint32_t *asin);
+
+ static const Element* create(Context *rsc,
+ RsDataType dt,
+ RsDataKind dk,
+ bool isNorm,
+ uint32_t vecSize) {
+ ObjectBaseRef<const Element> elem = createRef(rsc, dt, dk, isNorm, vecSize);
+ elem->incUserRef();
+ return elem.get();
+ }
+ static const Element* create(Context *rsc, size_t count,
+ const Element **ein,
+ const char **nin,
+ const size_t * lengths,
+ const uint32_t *asin) {
+ ObjectBaseRef<const Element> elem = createRef(rsc, count, ein, nin, lengths, asin);
+ elem->incUserRef();
+ return elem.get();
+ }
void incRefs(const void *) const;
void decRefs(const void *) const;
bool getHasReferences() const {return mHasReference;}
- bool isEqual(const Element *other) const;
-
protected:
// deallocate any components that are part of this element.
void clear();
@@ -88,12 +118,15 @@
bool mHasReference;
+ virtual ~Element();
Element(Context *);
Component mComponent;
uint32_t mBits;
void compute();
+
+ virtual void preDestroy() const;
};
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index cd02c24..df5dc12 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -68,7 +68,7 @@
for (uint32_t i = 0; i < numIndexEntries; i ++) {
A3DIndexEntry *entry = new A3DIndexEntry();
headerStream->loadString(&entry->mObjectName);
- LOGV("Header data, entry name = %s", entry->mObjectName.string());
+ //LOGV("Header data, entry name = %s", entry->mObjectName.string());
entry->mType = (RsA3DClassID)headerStream->loadU32();
if (mUse64BitOffsets){
entry->mOffset = headerStream->loadOffset();
@@ -369,7 +369,7 @@
}
ObjectBase *obj = fa3d->initializeFromEntry(index);
- LOGV("Returning object with name %s", obj->getName());
+ //LOGV("Returning object with name %s", obj->getName());
return obj;
}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 3917ca1..7efed9d 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -490,49 +490,47 @@
shaderString.append(" gl_FragColor = col;\n");
shaderString.append("}\n");
- const Element *colorElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
- const Element *gammaElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
- mRSC->mStateElement.elementBuilderBegin();
- mRSC->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
- mRSC->mStateElement.elementBuilderAdd(gammaElem, "Gamma", 1);
- const Element *constInput = mRSC->mStateElement.elementBuilderCreate(mRSC);
+ ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
+ Element::Builder builder;
+ builder.add(colorElem.get(), "Color", 1);
+ builder.add(gammaElem.get(), "Gamma", 1);
+ ObjectBaseRef<const Element> constInput = builder.create(mRSC);
- Type *inputType = Type::getType(mRSC, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(mRSC, constInput.get(), 1, 0, 0, false, false);
uint32_t tmp[4];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
tmp[2] = RS_PROGRAM_PARAM_TEXTURE_TYPE;
tmp[3] = RS_TEXTURE_2D;
- mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType,
+ mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS));
ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(),
shaderString.length(), tmp, 4);
mFontShaderF.set(pf);
mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0);
- Sampler *sampler = new Sampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
- RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP);
- mFontSampler.set(sampler);
- mFontShaderF->bindSampler(mRSC, 0, sampler);
+ mFontSampler.set(Sampler::getSampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
+ RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP).get());
+ mFontShaderF->bindSampler(mRSC, 0, mFontSampler.get());
- ProgramStore *fontStore = new ProgramStore(mRSC, true, true, true, true,
- false, false,
- RS_BLEND_SRC_SRC_ALPHA,
- RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
- RS_DEPTH_FUNC_ALWAYS);
- mFontProgramStore.set(fontStore);
+ mFontProgramStore.set(ProgramStore::getProgramStore(mRSC, true, true, true, true,
+ false, false,
+ RS_BLEND_SRC_SRC_ALPHA,
+ RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
+ RS_DEPTH_FUNC_ALWAYS).get());
mFontProgramStore->init();
}
void FontState::initTextTexture() {
- const Element *alphaElem = Element::create(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
+ ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
// We will allocate a texture to initially hold 32 character bitmaps
- Type *texType = Type::getType(mRSC, alphaElem, 1024, 256, 0, false, false);
+ ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), 1024, 256, 0, false, false);
- Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType,
+ Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE);
mTextTexture.set(cacheAlloc);
mTextTexture->syncAll(mRSC, RS_ALLOCATION_USAGE_SCRIPT);
@@ -557,11 +555,11 @@
// Avoid having to reallocate memory and render quad by quad
void FontState::initVertexArrayBuffers() {
// Now lets write index data
- const Element *indexElem = Element::create(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
+ ObjectBaseRef<const Element> indexElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
uint32_t numIndicies = mMaxNumberOfQuads * 6;
- Type *indexType = Type::getType(mRSC, indexElem, numIndicies, 0, 0, false, false);
+ ObjectBaseRef<Type> indexType = Type::getTypeRef(mRSC, indexElem.get(), numIndicies, 0, 0, false, false);
- Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType,
+ Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType.get(),
RS_ALLOCATION_USAGE_SCRIPT |
RS_ALLOCATION_USAGE_GRAPHICS_VERTEX);
uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr();
@@ -582,19 +580,19 @@
indexAlloc->sendDirty(mRSC);
- const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
- const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
+ ObjectBaseRef<const Element> posElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
+ ObjectBaseRef<const Element> texElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
- mRSC->mStateElement.elementBuilderBegin();
- mRSC->mStateElement.elementBuilderAdd(posElem, "position", 1);
- mRSC->mStateElement.elementBuilderAdd(texElem, "texture0", 1);
- const Element *vertexDataElem = mRSC->mStateElement.elementBuilderCreate(mRSC);
+ Element::Builder builder;
+ builder.add(posElem.get(), "position", 1);
+ builder.add(texElem.get(), "texture0", 1);
+ ObjectBaseRef<const Element> vertexDataElem = builder.create(mRSC);
- Type *vertexDataType = Type::getType(mRSC, vertexDataElem,
- mMaxNumberOfQuads * 4,
- 0, 0, false, false);
+ ObjectBaseRef<Type> vertexDataType = Type::getTypeRef(mRSC, vertexDataElem.get(),
+ mMaxNumberOfQuads * 4,
+ 0, 0, false, false);
- Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType,
+ Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType.get(),
RS_ALLOCATION_USAGE_SCRIPT);
mTextMeshPtr = (float*)vertexAlloc->getPtr();
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index b0e1430..679591c 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -146,7 +146,6 @@
void deinit(Context *rsc);
ObjectBaseRef<Font> mDefault;
- ObjectBaseRef<Font> mLast;
void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
uint32_t startIndex = 0, int numGlyphs = -1,
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index 01850f1..c7cfb0e 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -114,7 +114,10 @@
}
ObjectBaseRef & operator= (const ObjectBaseRef &ref) {
- return ObjectBaseRef(ref);
+ if (&ref != this) {
+ set(ref);
+ }
+ return *this;
}
~ObjectBaseRef() {
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index b1d8f48..33eb422e 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -116,7 +116,7 @@
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
return;
}
- if (!alloc->getType()->isEqual(mHal.state.constantTypes[slot].get())) {
+ if (alloc->getType() != mHal.state.constantTypes[slot].get()) {
LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
slot, (uint32_t)this);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 356ff77..ff29520 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -97,18 +97,18 @@
shaderString.append(" gl_FragColor = col;\n");
shaderString.append("}\n");
- const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
- const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
+ ObjectBaseRef<const Element> colorElem = Element::createRef(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ Element::Builder builder;
+ builder.add(colorElem.get(), "Color", 1);
+ ObjectBaseRef<const Element> constInput = builder.create(rsc);
- Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false);
uint32_t tmp[2];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
- Allocation *constAlloc = Allocation::createAllocation(rsc, inputType,
+ Allocation *constAlloc = Allocation::createAllocation(rsc, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
shaderString.length(), tmp, 2);
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
index 435561d..945b5ec 100644
--- a/libs/rs/rsProgramRaster.cpp
+++ b/libs/rs/rsProgramRaster.cpp
@@ -37,6 +37,15 @@
rsc->mHal.funcs.raster.init(rsc, this);
}
+void ProgramRaster::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateRaster.mRasterPrograms.size(); ct++) {
+ if (mRSC->mStateRaster.mRasterPrograms[ct] == this) {
+ mRSC->mStateRaster.mRasterPrograms.removeAt(ct);
+ break;
+ }
+ }
+}
+
ProgramRaster::~ProgramRaster() {
mRSC->mHal.funcs.raster.destroy(mRSC, this);
}
@@ -65,8 +74,8 @@
}
void ProgramRasterState::init(Context *rsc) {
- ProgramRaster *pr = new ProgramRaster(rsc, false, false, false, 1.f, RS_CULL_BACK);
- mDefault.set(pr);
+ mDefault.set(ProgramRaster::getProgramRaster(rsc, false, false,
+ false, 1.f, RS_CULL_BACK).get());
}
void ProgramRasterState::deinit(Context *rsc) {
@@ -74,19 +83,47 @@
mLast.clear();
}
+ObjectBaseRef<ProgramRaster> ProgramRaster::getProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull) {
+ ObjectBaseRef<ProgramRaster> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateRaster.mRasterPrograms.size(); ct++) {
+ ProgramRaster *existing = rsc->mStateRaster.mRasterPrograms[ct];
+ if (existing->mHal.state.pointSmooth != pointSmooth) continue;
+ if (existing->mHal.state.lineSmooth != lineSmooth) continue;
+ if (existing->mHal.state.pointSprite != pointSprite) continue;
+ if (existing->mHal.state.lineWidth != lineWidth) continue;
+ if (existing->mHal.state.cull != cull) continue;
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
+
+ ProgramRaster *pr = new ProgramRaster(rsc, pointSmooth,
+ lineSmooth, pointSprite, lineWidth, cull);
+ returnRef.set(pr);
+
+ ObjectBase::asyncLock();
+ rsc->mStateRaster.mRasterPrograms.push(pr);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
namespace android {
namespace renderscript {
-RsProgramRaster rsi_ProgramRasterCreate(Context * rsc,
- bool pointSmooth,
- bool lineSmooth,
- bool pointSprite,
- float lineWidth,
- RsCullMode cull) {
- ProgramRaster *pr = new ProgramRaster(rsc, pointSmooth,
- lineSmooth, pointSprite, lineWidth, cull);
+RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, bool pointSmooth, bool lineSmooth,
+ bool pointSprite, float lineWidth, RsCullMode cull) {
+ ObjectBaseRef<ProgramRaster> pr = ProgramRaster::getProgramRaster(rsc, pointSmooth, lineSmooth,
+ pointSprite, lineWidth, cull);
pr->incUserRef();
- return pr;
+ return pr.get();
}
}
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
index efdb948..09d7d54 100644
--- a/libs/rs/rsProgramRaster.h
+++ b/libs/rs/rsProgramRaster.h
@@ -27,19 +27,17 @@
class ProgramRaster : public ProgramBase {
public:
- ProgramRaster(Context *rsc,
- bool pointSmooth,
- bool lineSmooth,
- bool pointSprite,
- float lineWidth,
- RsCullMode cull);
- virtual ~ProgramRaster();
-
virtual void setup(const Context *, ProgramRasterState *);
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_RASTER; }
static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
+ static ObjectBaseRef<ProgramRaster> getProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull);
struct Hal {
mutable void *drv;
@@ -55,6 +53,17 @@
Hal mHal;
protected:
+ virtual void preDestroy() const;
+ virtual ~ProgramRaster();
+
+private:
+ ProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull);
+
};
class ProgramRasterState {
@@ -66,6 +75,9 @@
ObjectBaseRef<ProgramRaster> mDefault;
ObjectBaseRef<ProgramRaster> mLast;
+
+ // Cache of all existing raster programs.
+ Vector<ProgramRaster *> mRasterPrograms;
};
diff --git a/libs/rs/rsProgramStore.cpp b/libs/rs/rsProgramStore.cpp
index 8fe890b..7e25a22 100644
--- a/libs/rs/rsProgramStore.cpp
+++ b/libs/rs/rsProgramStore.cpp
@@ -41,6 +41,15 @@
mHal.state.depthFunc = depthFunc;
}
+void ProgramStore::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateFragmentStore.mStorePrograms.size(); ct++) {
+ if (mRSC->mStateFragmentStore.mStorePrograms[ct] == this) {
+ mRSC->mStateFragmentStore.mStorePrograms.removeAt(ct);
+ break;
+ }
+ }
+}
+
ProgramStore::~ProgramStore() {
mRSC->mHal.funcs.store.destroy(mRSC, this);
}
@@ -71,14 +80,58 @@
ProgramStoreState::~ProgramStoreState() {
}
+ObjectBaseRef<ProgramStore> ProgramStore::getProgramStore(Context *rsc,
+ bool colorMaskR,
+ bool colorMaskG,
+ bool colorMaskB,
+ bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc,
+ RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc) {
+ ObjectBaseRef<ProgramStore> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateFragmentStore.mStorePrograms.size(); ct++) {
+ ProgramStore *existing = rsc->mStateFragmentStore.mStorePrograms[ct];
+ if (existing->mHal.state.ditherEnable != ditherEnable) continue;
+ if (existing->mHal.state.colorRWriteEnable != colorMaskR) continue;
+ if (existing->mHal.state.colorGWriteEnable != colorMaskG) continue;
+ if (existing->mHal.state.colorBWriteEnable != colorMaskB) continue;
+ if (existing->mHal.state.colorAWriteEnable != colorMaskA) continue;
+ if (existing->mHal.state.blendSrc != srcFunc) continue;
+ if (existing->mHal.state.blendDst != destFunc) continue;
+ if (existing->mHal.state.depthWriteEnable != depthMask) continue;
+ if (existing->mHal.state.depthFunc != depthFunc) continue;
+
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
+
+ ProgramStore *pfs = new ProgramStore(rsc,
+ colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+ depthMask, ditherEnable,
+ srcFunc, destFunc, depthFunc);
+ returnRef.set(pfs);
+
+ pfs->init();
+
+ ObjectBase::asyncLock();
+ rsc->mStateFragmentStore.mStorePrograms.push(pfs);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
+
+
void ProgramStoreState::init(Context *rsc) {
- ProgramStore *ps = new ProgramStore(rsc,
- true, true, true, true,
- true, true,
- RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
- RS_DEPTH_FUNC_LESS);
- ps->init();
- mDefault.set(ps);
+ mDefault.set(ProgramStore::getProgramStore(rsc,
+ true, true, true, true,
+ true, true,
+ RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
+ RS_DEPTH_FUNC_LESS).get());
}
void ProgramStoreState::deinit(Context *rsc) {
@@ -96,13 +149,14 @@
RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
RsDepthFunc depthFunc) {
- ProgramStore *pfs = new ProgramStore(rsc,
- colorMaskR, colorMaskG, colorMaskB, colorMaskA,
- depthMask, ditherEnable,
- srcFunc, destFunc, depthFunc);
- pfs->init();
- pfs->incUserRef();
- return pfs;
+
+ ObjectBaseRef<ProgramStore> ps = ProgramStore::getProgramStore(rsc,
+ colorMaskR, colorMaskG,
+ colorMaskB, colorMaskA,
+ depthMask, ditherEnable,
+ srcFunc, destFunc, depthFunc);
+ ps->incUserRef();
+ return ps.get();
}
}
diff --git a/libs/rs/rsProgramStore.h b/libs/rs/rsProgramStore.h
index 77b3881..e21f039 100644
--- a/libs/rs/rsProgramStore.h
+++ b/libs/rs/rsProgramStore.h
@@ -28,18 +28,17 @@
class ProgramStore : public ProgramBase {
public:
- ProgramStore(Context *,
- bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
- bool depthMask, bool ditherEnable,
- RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
- RsDepthFunc depthFunc);
- virtual ~ProgramStore();
-
virtual void setup(const Context *, ProgramStoreState *);
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_STORE; }
static ProgramStore *createFromStream(Context *rsc, IStream *stream);
+ static ObjectBaseRef<ProgramStore> getProgramStore(Context *,
+ bool colorMaskR, bool colorMaskG,
+ bool colorMaskB, bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc);
void init();
@@ -66,6 +65,15 @@
Hal mHal;
protected:
+ virtual void preDestroy() const;
+ virtual ~ProgramStore();
+
+private:
+ ProgramStore(Context *,
+ bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc);
};
class ProgramStoreState {
@@ -77,6 +85,9 @@
ObjectBaseRef<ProgramStore> mDefault;
ObjectBaseRef<ProgramStore> mLast;
+
+ // Cache of all existing store programs.
+ Vector<ProgramStore *> mStorePrograms;
};
}
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 058a456..51cb2a8a 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -150,26 +150,30 @@
}
void ProgramVertexState::init(Context *rsc) {
- const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1);
- const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
- const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
- const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ ObjectBaseRef<const Element> matrixElem = Element::createRef(rsc, RS_TYPE_MATRIX_4X4,
+ RS_KIND_USER, false, 1);
+ ObjectBaseRef<const Element> f2Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 2);
+ ObjectBaseRef<const Element> f3Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 3);
+ ObjectBaseRef<const Element> f4Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 4);
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1);
- const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
+ Element::Builder constBuilder;
+ constBuilder.add(matrixElem.get(), "MV", 1);
+ constBuilder.add(matrixElem.get(), "P", 1);
+ constBuilder.add(matrixElem.get(), "TexMatrix", 1);
+ constBuilder.add(matrixElem.get(), "MVP", 1);
+ ObjectBaseRef<const Element> constInput = constBuilder.create(rsc);
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1);
- rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1);
- rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1);
- rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1);
- const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc);
+ Element::Builder inputBuilder;
+ inputBuilder.add(f4Elem.get(), "position", 1);
+ inputBuilder.add(f4Elem.get(), "color", 1);
+ inputBuilder.add(f3Elem.get(), "normal", 1);
+ inputBuilder.add(f2Elem.get(), "texture0", 1);
+ ObjectBaseRef<const Element> attrElem = inputBuilder.create(rsc);
- Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false);
String8 shaderString(RS_SHADER_INTERNAL);
shaderString.append("varying vec4 varColor;\n");
@@ -183,13 +187,13 @@
uint32_t tmp[4];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
tmp[2] = RS_PROGRAM_PARAM_INPUT;
- tmp[3] = (uint32_t)attrElem;
+ tmp[3] = (uint32_t)attrElem.get();
ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
shaderString.length(), tmp, 4);
- Allocation *alloc = Allocation::createAllocation(rsc, inputType,
+ Allocation *alloc = Allocation::createAllocation(rsc, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
pv->bindAllocation(rsc, alloc, 0);
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 2a05d16..5fc64a4 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -48,6 +48,15 @@
mRSC->mHal.funcs.sampler.destroy(mRSC, this);
}
+void Sampler::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateSampler.mAllSamplers.size(); ct++) {
+ if (mRSC->mStateSampler.mAllSamplers[ct] == this) {
+ mRSC->mStateSampler.mAllSamplers.removeAt(ct);
+ break;
+ }
+ }
+}
+
void Sampler::bindToContext(SamplerState *ss, uint32_t slot) {
ss->mSamplers[slot].set(this);
mBoundSlot = slot;
@@ -66,6 +75,39 @@
return NULL;
}
+ObjectBaseRef<Sampler> Sampler::getSampler(Context *rsc,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso) {
+ ObjectBaseRef<Sampler> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateSampler.mAllSamplers.size(); ct++) {
+ Sampler *existing = rsc->mStateSampler.mAllSamplers[ct];
+ if (existing->mHal.state.magFilter != magFilter) continue;
+ if (existing->mHal.state.minFilter != minFilter ) continue;
+ if (existing->mHal.state.wrapS != wrapS) continue;
+ if (existing->mHal.state.wrapT != wrapT) continue;
+ if (existing->mHal.state.wrapR != wrapR) continue;
+ if (existing->mHal.state.aniso != aniso) continue;
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
+
+ Sampler *s = new Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+ returnRef.set(s);
+
+ ObjectBase::asyncLock();
+ rsc->mStateSampler.mAllSamplers.push(s);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
////////////////////////////////
namespace android {
@@ -78,9 +120,10 @@
RsSamplerValue wrapT,
RsSamplerValue wrapR,
float aniso) {
- Sampler * s = new Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+ ObjectBaseRef<Sampler> s = Sampler::getSampler(rsc, magFilter, minFilter,
+ wrapS, wrapT, wrapR, aniso);
s->incUserRef();
- return s;
+ return s.get();
}
}}
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index 90b6082..e698132 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -30,16 +30,13 @@
class Sampler : public ObjectBase {
public:
- Sampler(Context *,
- RsSamplerValue magFilter,
- RsSamplerValue minFilter,
- RsSamplerValue wrapS,
- RsSamplerValue wrapT,
- RsSamplerValue wrapR,
- float aniso = 1.0f);
-
- virtual ~Sampler();
-
+ static ObjectBaseRef<Sampler> getSampler(Context *,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso = 1.0f);
void bindToContext(SamplerState *, uint32_t slot);
void unbindFromContext(SamplerState *);
@@ -65,14 +62,33 @@
protected:
int32_t mBoundSlot;
+ virtual void preDestroy() const;
+ virtual ~Sampler();
+
private:
Sampler(Context *);
+ Sampler(Context *,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso = 1.0f);
};
class SamplerState {
public:
ObjectBaseRef<Sampler> mSamplers[RS_MAX_SAMPLER_SLOT];
+ void init(Context *rsc) {
+ }
+ void deinit(Context *rsc) {
+ for (uint32_t i = 0; i < RS_MAX_SAMPLER_SLOT; i ++) {
+ mSamplers[i].clear();
+ }
+ }
+ // Cache of all existing raster programs.
+ Vector<Sampler *> mAllSamplers;
};
}
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 10e3182..9a6a31b 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -25,7 +25,7 @@
clear();
}
-void Type::preDestroy() {
+void Type::preDestroy() const {
for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
if (mRSC->mStateType.mTypes[ct] == this) {
mRSC->mStateType.mTypes.removeAt(ct);
@@ -58,6 +58,7 @@
}
TypeState::~TypeState() {
+ rsAssert(!mTypes.size());
}
size_t Type::getOffsetForFace(uint32_t face) const {
@@ -183,7 +184,9 @@
uint32_t z = stream->loadU32();
uint8_t lod = stream->loadU8();
uint8_t faces = stream->loadU8();
- return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
+ Type *type = Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
+ elem->decUserRef();
+ return type;
}
bool Type::getIsNp2() const {
@@ -203,24 +206,11 @@
return false;
}
-bool Type::isEqual(const Type *other) const {
- if (other == NULL) {
- return false;
- }
- if (other->getElement()->isEqual(getElement()) &&
- other->getDimX() == mDimX &&
- other->getDimY() == mDimY &&
- other->getDimZ() == mDimZ &&
- other->getDimLOD() == mDimLOD &&
- other->getDimFaces() == mFaces) {
- return true;
- }
- return false;
-}
+ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces) {
+ ObjectBaseRef<Type> returnRef;
-Type * Type::getType(Context *rsc, const Element *e,
- uint32_t dimX, uint32_t dimY, uint32_t dimZ,
- bool dimLOD, bool dimFaces) {
TypeState * stc = &rsc->mStateType;
ObjectBase::asyncLock();
@@ -232,14 +222,15 @@
if (t->getDimZ() != dimZ) continue;
if (t->getDimLOD() != dimLOD) continue;
if (t->getDimFaces() != dimFaces) continue;
- t->incUserRef();
+ returnRef.set(t);
ObjectBase::asyncUnlock();
- return t;
+ return returnRef;
}
ObjectBase::asyncUnlock();
Type *nt = new Type(rsc);
+ returnRef.set(nt);
nt->mElement.set(e);
nt->mDimX = dimX;
nt->mDimY = dimY;
@@ -247,25 +238,24 @@
nt->mDimLOD = dimLOD;
nt->mFaces = dimFaces;
nt->compute();
- nt->incUserRef();
ObjectBase::asyncLock();
stc->mTypes.push(nt);
ObjectBase::asyncUnlock();
- return nt;
+ return returnRef;
}
-Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
- return getType(rsc, mElement.get(), dimX,
- mDimY, mDimZ, mDimLOD, mFaces);
+ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
+ return getTypeRef(rsc, mElement.get(), dimX,
+ mDimY, mDimZ, mDimLOD, mFaces);
}
-Type * Type::cloneAndResize2D(Context *rsc,
+ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
uint32_t dimX,
uint32_t dimY) const {
- return getType(rsc, mElement.get(), dimX, dimY,
- mDimZ, mDimLOD, mFaces);
+ return getTypeRef(rsc, mElement.get(), dimX, dimY,
+ mDimZ, mDimLOD, mFaces);
}
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 086db33..bc0d9ff 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -62,14 +62,20 @@
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_TYPE; }
static Type *createFromStream(Context *rsc, IStream *stream);
- bool isEqual(const Type *other) const;
+ ObjectBaseRef<Type> cloneAndResize1D(Context *rsc, uint32_t dimX) const;
+ ObjectBaseRef<Type> cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
- Type * cloneAndResize1D(Context *rsc, uint32_t dimX) const;
- Type * cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
+ static ObjectBaseRef<Type> getTypeRef(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces);
- static Type * getType(Context *rsc, const Element *e,
- uint32_t dimX, uint32_t dimY, uint32_t dimZ,
- bool dimLOD, bool dimFaces);
+ static Type* getType(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces) {
+ ObjectBaseRef<Type> type = getTypeRef(rsc, e, dimX, dimY, dimZ, dimLOD, dimFaces);
+ type->incUserRef();
+ return type.get();
+ }
protected:
struct LOD {
@@ -105,7 +111,7 @@
uint32_t mLODCount;
protected:
- virtual void preDestroy();
+ virtual void preDestroy() const;
virtual ~Type();
private:
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index 6a4537b..21dff218 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -40,6 +40,19 @@
typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
+typedef struct {
+ const void *in;
+ void *out;
+ const void *usr;
+ size_t usr_len;
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+ uint32_t lod;
+ RsAllocationCubemapFace face;
+ uint32_t ar[16];
+} RsForEachStubParamStruct;
+
/**
* Script management functions
*/
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 7a92b35..f9efd3c 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -21,6 +21,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.database.ContentObserver;
+import android.graphics.Bitmap;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -1715,29 +1716,103 @@
}
/**
+ * Acts as a proxy between AudioService and the RemoteControlClient
+ */
+ private IRemoteControlClientDispatcher mRcClientDispatcher =
+ new IRemoteControlClientDispatcher.Stub() {
+
+ public String getMetadataStringForClient(String clientName, int field) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getMetadataString(field);
+ } else {
+ return null;
+ }
+ }
+
+ public int getPlaybackStateForClient(String clientName) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getPlaybackState();
+ } else {
+ return 0;
+ }
+ }
+
+ public int getTransportControlFlagsForClient(String clientName) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getTransportControlFlags();
+ } else {
+ return 0;
+ }
+ }
+
+ public Bitmap getAlbumArtForClient(String clientName, int maxWidth, int maxHeight) {
+ RemoteControlClient realClient;
+ synchronized(mRcClientMap) {
+ realClient = mRcClientMap.get(clientName);
+ }
+ if (realClient != null) {
+ return realClient.getAlbumArt(maxWidth, maxHeight);
+ } else {
+ return null;
+ }
+ }
+ };
+
+ private HashMap<String, RemoteControlClient> mRcClientMap =
+ new HashMap<String, RemoteControlClient>();
+
+ private String getIdForRcClient(RemoteControlClient client) {
+ // client is guaranteed to be non-null
+ return client.toString();
+ }
+
+ /**
* @hide
- * Registers the remote control client for providing information to display on the remotes.
+ * Registers the remote control client for providing information to display on the remote
+ * controls.
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
* that will receive the media button intent, and associated with the remote control
* client. This method has no effect if
* {@link #registerMediaButtonEventReceiver(ComponentName)} hasn't been called
* with the same eventReceiver, or if
* {@link #unregisterMediaButtonEventReceiver(ComponentName)} has been called.
- * @param rcClient the client associated with the event receiver, responsible for providing
- * the information to display on the remote control.
+ * @param rcClient the remote control client associated with the event receiver, responsible
+ * for providing the information to display on the remote control.
*/
public void registerRemoteControlClient(ComponentName eventReceiver,
- IRemoteControlClient rcClient) {
- if (eventReceiver == null) {
+ RemoteControlClient rcClient) {
+ if ((eventReceiver == null) || (rcClient == null)) {
return;
}
+ String clientKey = getIdForRcClient(rcClient);
+ synchronized(mRcClientMap) {
+ if (mRcClientMap.containsKey(clientKey)) {
+ return;
+ }
+ mRcClientMap.put(clientKey, rcClient);
+ }
IAudioService service = getService();
try {
- service.registerRemoteControlClient(eventReceiver, rcClient,
+ service.registerRemoteControlClient(eventReceiver, mRcClientDispatcher, clientKey,
// used to match media button event receiver and audio focus
mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerRemoteControlClient"+e);
+ synchronized(mRcClientMap) {
+ mRcClientMap.remove(clientKey);
+ }
}
}
@@ -1748,17 +1823,28 @@
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
* that receives the media button intent, and associated with the remote control
* client.
- * @see #registerRemoteControlClient(ComponentName)
-
+ * @param rcClient the remote control client to unregister
+ * @see #registerRemoteControlClient(ComponentName, RemoteControlClient)
*/
- public void unregisterRemoteControlClient(ComponentName eventReceiver) {
- if (eventReceiver == null) {
+ public void unregisterRemoteControlClient(ComponentName eventReceiver,
+ RemoteControlClient rcClient) {
+ if ((eventReceiver == null) || (rcClient == null)) {
return;
}
IAudioService service = getService();
try {
- // unregistering a IRemoteControlClient is equivalent to setting it to null
- service.registerRemoteControlClient(eventReceiver, null, mContext.getPackageName());
+ // remove locally
+ boolean unregister = true;
+ synchronized(mRcClientMap) {
+ if (mRcClientMap.remove(getIdForRcClient(rcClient)) == null) {
+ unregister = false;
+ }
+ }
+ if (unregister) {
+ // unregistering a RemoteControlClient is equivalent to setting it to null
+ service.registerRemoteControlClient(eventReceiver, null, null,
+ mContext.getPackageName());
+ }
} catch (RemoteException e) {
Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e);
}
@@ -1767,17 +1853,17 @@
/**
* @hide
* Returns the current remote control client.
- * @param rcClientId the counter value that matches the extra
- * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the
+ * @param rcClientId the generation counter that matches the extra
+ * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT_GENERATION} in the
* {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event
- * @return the current IRemoteControlClient from which information to display on the remote
+ * @return the current RemoteControlClient from which information to display on the remote
* control can be retrieved, or null if rcClientId doesn't match the current generation
* counter.
*/
- public IRemoteControlClient getRemoteControlClient(int rcClientId) {
+ public IRemoteControlClientDispatcher getRemoteControlClientDispatcher(int rcClientId) {
IAudioService service = getService();
try {
- return service.getRemoteControlClient(rcClientId);
+ return service.getRemoteControlClientDispatcher(rcClientId);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in getRemoteControlClient "+e);
return null;
@@ -1786,160 +1872,6 @@
/**
* @hide
- * Definitions of constants to be used in {@link android.media.IRemoteControlClient}.
- */
- public final class RemoteControlParameters {
- /**
- * Playback state of an IRemoteControlClient which is stopped.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_STOPPED = 1;
- /**
- * Playback state of an IRemoteControlClient which is paused.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_PAUSED = 2;
- /**
- * Playback state of an IRemoteControlClient which is playing media.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_PLAYING = 3;
- /**
- * Playback state of an IRemoteControlClient which is fast forwarding in the media
- * it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_FAST_FORWARDING = 4;
- /**
- * Playback state of an IRemoteControlClient which is fast rewinding in the media
- * it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_REWINDING = 5;
- /**
- * Playback state of an IRemoteControlClient which is skipping to the next
- * logical chapter (such as a song in a playlist) in the media it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_SKIPPING_FORWARDS = 6;
- /**
- * Playback state of an IRemoteControlClient which is skipping back to the previous
- * logical chapter (such as a song in a playlist) in the media it is currently playing.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
- /**
- * Playback state of an IRemoteControlClient which is buffering data to play before it can
- * start or resume playback.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_BUFFERING = 8;
- /**
- * Playback state of an IRemoteControlClient which cannot perform any playback related
- * operation because of an internal error. Examples of such situations are no network
- * connectivity when attempting to stream data from a server, or expired user credentials
- * when trying to play subscription-based content.
- *
- * @see android.media.IRemoteControlClient#getPlaybackState()
- */
- public final static int PLAYSTATE_ERROR = 9;
-
- /**
- * Flag indicating an IRemoteControlClient makes use of the "previous" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS
- */
- public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "rewing" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
- */
- public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "play" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY
- */
- public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "play/pause" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE
- */
- public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "pause" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE
- */
- public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "stop" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP
- */
- public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "fast forward" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD
- */
- public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
- /**
- * Flag indicating an IRemoteControlClient makes use of the "next" media key.
- *
- * @see android.media.IRemoteControlClient#getTransportControlFlags()
- * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
- */
- public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
-
- /**
- * Flag used to signal that the metadata exposed by the IRemoteControlClient has changed.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_METADATA = 1 << 0;
- /**
- * Flag used to signal that the transport control buttons supported by the
- * IRemoteControlClient have changed.
- * This can for instance happen when playback is at the end of a playlist, and the "next"
- * operation is not supported anymore.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_KEY_MEDIA = 1 << 1;
- /**
- * Flag used to signal that the playback state of the IRemoteControlClient has changed.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_PLAYSTATE = 1 << 2;
- /**
- * Flag used to signal that the album art for the IRemoteControlClient has changed.
- *
- * @see #notifyRemoteControlInformationChanged(ComponentName, int)
- */
- public final static int FLAG_INFORMATION_CHANGED_ALBUM_ART = 1 << 3;
- }
-
- /**
- * @hide
* Broadcast intent action indicating that the displays on the remote controls
* should be updated because a new remote control client is now active. If there is no
* {@link #EXTRA_REMOTE_CONTROL_CLIENT}, the remote control display should be cleared
@@ -1952,16 +1884,27 @@
/**
* @hide
- * The IRemoteControlClient monotonically increasing generation counter.
+ * The IRemoteControlClientDispatcher monotonically increasing generation counter.
*
* @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION
*/
- public static final String EXTRA_REMOTE_CONTROL_CLIENT =
- "android.media.EXTRA_REMOTE_CONTROL_CLIENT";
+ public static final String EXTRA_REMOTE_CONTROL_CLIENT_GENERATION =
+ "android.media.EXTRA_REMOTE_CONTROL_CLIENT_GENERATION";
/**
* @hide
- * The media button event receiver associated with the IRemoteControlClient.
+ * The name of the RemoteControlClient.
+ * This String is passed as the client name when calling methods from the
+ * IRemoteControlClientDispatcher interface.
+ *
+ * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION
+ */
+ public static final String EXTRA_REMOTE_CONTROL_CLIENT_NAME =
+ "android.media.EXTRA_REMOTE_CONTROL_CLIENT_NAME";
+
+ /**
+ * @hide
+ * The media button event receiver associated with the RemoteControlClient.
* The {@link android.content.ComponentName} value of the event receiver can be retrieved with
* {@link android.content.ComponentName#unflattenFromString(String)}
*
@@ -1992,10 +1935,10 @@
* @param infoFlag the type of information that has changed since this method was last called,
* or the event receiver was registered. Use one or multiple of the following flags to
* describe what changed:
- * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_METADATA},
- * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_KEY_MEDIA},
- * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_PLAYSTATE},
- * {@link RemoteControlParameters#FLAG_INFORMATION_CHANGED_ALBUM_ART}.
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_METADATA},
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_KEY_MEDIA},
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_PLAYSTATE},
+ * {@link RemoteControlClient#FLAG_INFORMATION_CHANGED_ALBUM_ART}.
*/
public void notifyRemoteControlInformationChanged(ComponentName eventReceiver, int infoFlag) {
IAudioService service = getService();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 179b8a4..85c7dba 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -34,6 +34,7 @@
import android.database.ContentObserver;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
+import android.media.IRemoteControlClientDispatcher;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
@@ -521,6 +522,10 @@
(!mVoiceCapable && streamType != AudioSystem.STREAM_VOICE_CALL &&
streamType != AudioSystem.STREAM_BLUETOOTH_SCO) ||
(mVoiceCapable && streamType == AudioSystem.STREAM_RING)) {
+ // do not vibrate if already in silent mode
+ if (mRingerMode != AudioManager.RINGER_MODE_NORMAL) {
+ flags &= ~AudioManager.FLAG_VIBRATE;
+ }
// Check if the ringer mode changes with this volume adjustment. If
// it does, it will handle adjusting the volume, so we won't below
adjustVolume = checkForRingerModeChange(oldIndex, direction);
@@ -2168,7 +2173,7 @@
// TODO remove log before release
Log.i(TAG, "Clear remote control display");
Intent clearIntent = new Intent(AudioManager.REMOTE_CONTROL_CLIENT_CHANGED);
- // no extra means no IRemoteControlClient, which is a request to clear
+ // no extra means no IRemoteControlClientDispatcher, which is a request to clear
clearIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(clearIntent);
break;
@@ -2188,7 +2193,8 @@
Log.i(TAG, "Display/update remote control ");
Intent rcClientIntent = new Intent(
AudioManager.REMOTE_CONTROL_CLIENT_CHANGED);
- rcClientIntent.putExtra(AudioManager.EXTRA_REMOTE_CONTROL_CLIENT,
+ rcClientIntent.putExtra(
+ AudioManager.EXTRA_REMOTE_CONTROL_CLIENT_GENERATION,
mCurrentRcClientGen);
rcClientIntent.putExtra(
AudioManager.EXTRA_REMOTE_CONTROL_CLIENT_INFO_CHANGED,
@@ -2196,6 +2202,9 @@
rcClientIntent.putExtra(
AudioManager.EXTRA_REMOTE_CONTROL_EVENT_RECEIVER,
rcse.mReceiverComponent.flattenToString());
+ rcClientIntent.putExtra(
+ AudioManager.EXTRA_REMOTE_CONTROL_CLIENT_NAME,
+ rcse.mRcClientName);
rcClientIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(rcClientIntent);
}
@@ -2891,14 +2900,14 @@
* This object may be null.
* Access protected by mCurrentRcLock.
*/
- private IRemoteControlClient mCurrentRcClient = null;
+ private IRemoteControlClientDispatcher mCurrentRcClient = null;
private final static int RC_INFO_NONE = 0;
private final static int RC_INFO_ALL =
- AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_ALBUM_ART |
- AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_KEY_MEDIA |
- AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_METADATA |
- AudioManager.RemoteControlParameters.FLAG_INFORMATION_CHANGED_PLAYSTATE;
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_ALBUM_ART |
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_KEY_MEDIA |
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_METADATA |
+ RemoteControlClient.FLAG_INFORMATION_CHANGED_PLAYSTATE;
/**
* A monotonically increasing generation counter for mCurrentRcClient.
@@ -2910,13 +2919,13 @@
/**
* Returns the current remote control client.
* @param rcClientId the counter value that matches the extra
- * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT} in the
+ * {@link AudioManager#EXTRA_REMOTE_CONTROL_CLIENT_GENERATION} in the
* {@link AudioManager#REMOTE_CONTROL_CLIENT_CHANGED} event
- * @return the current IRemoteControlClient from which information to display on the remote
- * control can be retrieved, or null if rcClientId doesn't match the current generation
- * counter.
+ * @return the current IRemoteControlClientDispatcher from which information to display on the
+ * remote control can be retrieved, or null if rcClientId doesn't match the current
+ * generation counter.
*/
- public IRemoteControlClient getRemoteControlClient(int rcClientId) {
+ public IRemoteControlClientDispatcher getRemoteControlClientDispatcher(int rcClientId) {
synchronized(mCurrentRcLock) {
if (rcClientId == mCurrentRcClientGen) {
return mCurrentRcClient;
@@ -2943,7 +2952,7 @@
Log.w(TAG, " RemoteControlClient died");
// remote control client died, make sure the displays don't use it anymore
// by setting its remote control client to null
- registerRemoteControlClient(mRcEventReceiver, null, null/*ignored*/);
+ registerRemoteControlClient(mRcEventReceiver, null, null, null/*ignored*/);
}
public IBinder getBinder() {
@@ -2955,10 +2964,11 @@
/** the target for the ACTION_MEDIA_BUTTON events */
public ComponentName mReceiverComponent;// always non null
public String mCallingPackageName;
+ public String mRcClientName;
public int mCallingUid;
/** provides access to the information to display on the remote control */
- public IRemoteControlClient mRcClient;
+ public IRemoteControlClientDispatcher mRcClient;
public RcClientDeathHandler mRcClientDeathHandler;
public RemoteControlStackEntry(ComponentName r) {
@@ -3213,7 +3223,7 @@
/** see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...) */
public void registerRemoteControlClient(ComponentName eventReceiver,
- IRemoteControlClient rcClient, String callingPackageName) {
+ IRemoteControlClientDispatcher rcClient, String clientName, String callingPackageName) {
synchronized(mAudioFocusLock) {
synchronized(mRCStack) {
// store the new display information
@@ -3229,8 +3239,10 @@
// save the new remote control client
rcse.mRcClient = rcClient;
rcse.mCallingPackageName = callingPackageName;
+ rcse.mRcClientName = clientName;
rcse.mCallingUid = Binder.getCallingUid();
if (rcClient == null) {
+ rcse.mRcClientDeathHandler = null;
break;
}
// monitor the new client's death
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index c259aa3..7f9ced9 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -18,9 +18,7 @@
import android.content.ComponentName;
import android.media.IAudioFocusDispatcher;
-import android.media.IRemoteControlClient;
-import android.net.Uri;
-import android.os.Bundle;
+import android.media.IRemoteControlClientDispatcher;
/**
* {@hide}
@@ -91,9 +89,10 @@
void unregisterMediaButtonEventReceiver(in ComponentName eventReceiver);
void registerRemoteControlClient(in ComponentName eventReceiver,
- in IRemoteControlClient rcClient, in String callingPackageName);
+ in IRemoteControlClientDispatcher rcClient, in String clientName,
+ in String callingPackageName);
- IRemoteControlClient getRemoteControlClient(in int rcClientId);
+ IRemoteControlClientDispatcher getRemoteControlClientDispatcher(in int rcClientId);
void notifyRemoteControlInformationChanged(in ComponentName eventReceiver, int infoFlag);
diff --git a/media/java/android/media/IRemoteControlClient.aidl b/media/java/android/media/IRemoteControlClientDispatcher.aidl
similarity index 88%
rename from media/java/android/media/IRemoteControlClient.aidl
rename to media/java/android/media/IRemoteControlClientDispatcher.aidl
index 76d178c..98142cc 100644
--- a/media/java/android/media/IRemoteControlClient.aidl
+++ b/media/java/android/media/IRemoteControlClientDispatcher.aidl
@@ -20,13 +20,11 @@
/**
* @hide
- * Interface for an object that exposes information meant to be consumed by remote controls
- * capable of displaying metadata, album art and media transport control buttons.
- * Such a remote control client object is associated with a media button event receiver
- * when registered through
- * {@link AudioManager#registerRemoteControlClient(ComponentName, IRemoteControlClient)}.
+ * Interface registered by AudioManager to dispatch remote control information requests
+ * to the RemoteControlClient implementation. This is used by AudioService.
+ * {@see AudioManager#registerRemoteControlClient(ComponentName, RemoteControlClient)}.
*/
-interface IRemoteControlClient
+interface IRemoteControlClientDispatcher
{
/**
* Called by a remote control to retrieve a String of information to display.
@@ -49,7 +47,7 @@
* @return null if the requested field is not supported, or the String matching the
* metadata field.
*/
- String getMetadataString(int field);
+ String getMetadataStringForClient(String clientName, int field);
/**
* Called by a remote control to retrieve the current playback state.
@@ -64,7 +62,7 @@
* {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_BUFFERING},
* {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_ERROR}.
*/
- int getPlaybackState();
+ int getPlaybackStateForClient(String clientName);
/**
* Called by a remote control to retrieve the flags for the media transport control buttons
@@ -78,7 +76,7 @@
* {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_FAST_FORWARD},
* {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_NEXT}
*/
- int getTransportControlFlags();
+ int getTransportControlFlagsForClient(String clientName);
/**
* Called by a remote control to retrieve the album art picture at the requested size.
@@ -90,5 +88,5 @@
* @return the bitmap for the album art, or null if there isn't any.
* @see android.graphics.Bitmap
*/
- Bitmap getAlbumArt(int maxWidth, int maxHeight);
+ Bitmap getAlbumArtForClient(String clientName, int maxWidth, int maxHeight);
}
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
new file mode 100644
index 0000000..c384636
--- /dev/null
+++ b/media/java/android/media/RemoteControlClient.java
@@ -0,0 +1,243 @@
+/*
+ * 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.media;
+
+import android.content.ComponentName;
+import android.graphics.Bitmap;
+
+/**
+ * @hide
+ * Interface for an object that exposes information meant to be consumed by remote controls
+ * capable of displaying metadata, album art and media transport control buttons.
+ * Such a remote control client object is associated with a media button event receiver
+ * when registered through
+ * {@link AudioManager#registerRemoteControlClient(ComponentName, RemoteControlClient)}.
+ */
+public interface RemoteControlClient
+{
+ /**
+ * Playback state of a RemoteControlClient which is stopped.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_STOPPED = 1;
+ /**
+ * Playback state of a RemoteControlClient which is paused.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_PAUSED = 2;
+ /**
+ * Playback state of a RemoteControlClient which is playing media.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_PLAYING = 3;
+ /**
+ * Playback state of a RemoteControlClient which is fast forwarding in the media
+ * it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_FAST_FORWARDING = 4;
+ /**
+ * Playback state of a RemoteControlClient which is fast rewinding in the media
+ * it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_REWINDING = 5;
+ /**
+ * Playback state of a RemoteControlClient which is skipping to the next
+ * logical chapter (such as a song in a playlist) in the media it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_SKIPPING_FORWARDS = 6;
+ /**
+ * Playback state of a RemoteControlClient which is skipping back to the previous
+ * logical chapter (such as a song in a playlist) in the media it is currently playing.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
+ /**
+ * Playback state of a RemoteControlClient which is buffering data to play before it can
+ * start or resume playback.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_BUFFERING = 8;
+ /**
+ * Playback state of a RemoteControlClient which cannot perform any playback related
+ * operation because of an internal error. Examples of such situations are no network
+ * connectivity when attempting to stream data from a server, or expired user credentials
+ * when trying to play subscription-based content.
+ *
+ * @see android.media.RemoteControlClient#getPlaybackState()
+ */
+ public final static int PLAYSTATE_ERROR = 9;
+
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "previous" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS
+ */
+ public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "rewing" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
+ */
+ public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "play" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY
+ */
+ public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "play/pause" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE
+ */
+ public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "pause" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE
+ */
+ public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "stop" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP
+ */
+ public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "fast forward" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD
+ */
+ public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
+ /**
+ * Flag indicating a RemoteControlClient makes use of the "next" media key.
+ *
+ * @see android.media.RemoteControlClient#getTransportControlFlags()
+ * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
+ */
+ public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
+
+ /**
+ * Flag used to signal that the metadata exposed by the RemoteControlClient has changed.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_METADATA = 1 << 0;
+ /**
+ * Flag used to signal that the transport control buttons supported by the
+ * RemoteControlClient have changed.
+ * This can for instance happen when playback is at the end of a playlist, and the "next"
+ * operation is not supported anymore.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_KEY_MEDIA = 1 << 1;
+ /**
+ * Flag used to signal that the playback state of the RemoteControlClient has changed.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_PLAYSTATE = 1 << 2;
+ /**
+ * Flag used to signal that the album art for the RemoteControlClient has changed.
+ *
+ * @see #notifyRemoteControlInformationChanged(ComponentName, int)
+ */
+ public final static int FLAG_INFORMATION_CHANGED_ALBUM_ART = 1 << 3;
+
+ /**
+ * Called by a remote control to retrieve a String of information to display.
+ * @param field the identifier for a metadata field to retrieve. Valid values are
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER},
+ * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
+ * @return null if the requested field is not supported, or the String matching the
+ * metadata field.
+ */
+ String getMetadataString(int field);
+
+ /**
+ * Called by a remote control to retrieve the current playback state.
+ * @return one of the following values:
+ * {@link #PLAYSTATE_STOPPED},
+ * {@link #PLAYSTATE_PAUSED},
+ * {@link #PLAYSTATE_PLAYING},
+ * {@link #PLAYSTATE_FAST_FORWARDING},
+ * {@link #PLAYSTATE_REWINDING},
+ * {@link #PLAYSTATE_SKIPPING_FORWARDS},
+ * {@link #PLAYSTATE_SKIPPING_BACKWARDS},
+ * {@link #PLAYSTATE_BUFFERING},
+ * {@link #PLAYSTATE_ERROR}.
+ */
+ int getPlaybackState();
+
+ /**
+ * Called by a remote control to retrieve the flags for the media transport control buttons
+ * that this client supports.
+ * @see {@link #FLAG_KEY_MEDIA_PREVIOUS},
+ * {@link #FLAG_KEY_MEDIA_REWIND},
+ * {@link #FLAG_KEY_MEDIA_PLAY},
+ * {@link #FLAG_KEY_MEDIA_PLAY_PAUSE},
+ * {@link #FLAG_KEY_MEDIA_PAUSE},
+ * {@link #FLAG_KEY_MEDIA_STOP},
+ * {@link #FLAG_KEY_MEDIA_FAST_FORWARD},
+ * {@link #FLAG_KEY_MEDIA_NEXT}
+ */
+ int getTransportControlFlags();
+
+ /**
+ * Called by a remote control to retrieve the album art picture at the requested size.
+ * Note that returning a bitmap smaller than the maximum requested dimension is accepted
+ * and it will be scaled as needed, but exceeding the maximum dimensions may produce
+ * unspecified results, such as the image being cropped or simply not being displayed.
+ * @param maxWidth the maximum width of the requested bitmap expressed in pixels.
+ * @param maxHeight the maximum height of the requested bitmap expressed in pixels.
+ * @return the bitmap for the album art, or null if there isn't any.
+ * @see android.graphics.Bitmap
+ */
+ Bitmap getAlbumArt(int maxWidth, int maxHeight);
+}
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 7d0f56f..5dda8d3 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -2499,7 +2499,7 @@
//initialize the first char. so that strcat works.
M4OSA_Char *ptmpChar = (M4OSA_Char*)pContext->initParams.pTempPath;
ptmpChar[0] = 0x00;
- strncat((char *)pContext->initParams.pTempPath, (const char *)tmpString,
+ strncat((char *)pContext->initParams.pTempPath, (const char *)tmpString,
(size_t)strlen((const char *)tmpString));
strncat((char *)pContext->initParams.pTempPath, (const char *)"/", (size_t)1);
free(tmpString);
@@ -2631,7 +2631,8 @@
ManualEditState completionState = ManualEditState_OPENED;
ManualEditState errorState = ManualEditState_ANALYZING_ERROR;
- // While analyzing progress goes from 0 to 50
+ // While analyzing progress goes from 0 to 10 (except Kenburn clip
+ // generation, which goes from 0 to 50)
progressBase = 0;
// Set the text rendering function.
@@ -2667,6 +2668,7 @@
// Check if a task is being performed.
// ??? ADD STOPPING MECHANISM
LOGV("videoEditor_processClip Entering processing loop");
+ M4OSA_UInt8 prevReportedProgress = 0;
while((result == M4NO_ERROR)
&&(pContext->state!=ManualEditState_SAVED)
&&(pContext->state!=ManualEditState_STOPPING)) {
@@ -2674,19 +2676,35 @@
// Perform the next processing step.
//LOGV("LVME_processClip Entering M4xVSS_Step()");
result = M4xVSS_Step(pContext->engineContext, &progress);
- //LOGV("LVME_processClip M4xVSS_Step() returned 0x%x", (unsigned int)result);
- // Log the the 1 % .. 100 % progress after processing.
- progress = progressBase + progress/2;
- if (progress != lastProgress)
- {
- // Send a progress notification.
- LOGV("videoEditor_processClip ITEM %d Progress indication %d",
- unuseditemID, progress);
- pEnv->CallVoidMethod(pContext->engine,
- pContext->onProgressUpdateMethodId,
- unuseditemID, progress);
- lastProgress = progress;
+ if (progress != prevReportedProgress) {
+ prevReportedProgress = progress;
+ // Log the 1 % .. 100 % progress after processing.
+ if (M4OSA_TRUE ==
+ pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) {
+ // For KenBurn clip generation, return 0 to 50
+ // for Analysis phase and 50 to 100 for Saving phase
+ progress = progressBase + progress/2;
+ } else {
+ // For export/transition clips, 0 to 10 for Analysis phase
+ // and 10 to 100 for Saving phase
+ if (ManualEditState_INITIALIZED == pContext->state) {
+ progress = 0.1*progress;
+ } else {
+ progress = progressBase + 0.9*progress;
+ }
+ }
+
+ if (progress > lastProgress)
+ {
+ // Send a progress notification.
+ LOGV("videoEditor_processClip ITEM %d Progress indication %d",
+ unuseditemID, progress);
+ pEnv->CallVoidMethod(pContext->engine,
+ pContext->onProgressUpdateMethodId,
+ unuseditemID, progress);
+ lastProgress = progress;
+ }
}
// Check if processing has been completed.
@@ -2719,20 +2737,26 @@
completionResult = M4VSS3GPP_WAR_SAVING_DONE;
errorState = ManualEditState_SAVING_ERROR;
- // While saving progress goes from 50 to 100
- progressBase = 50;
+ // While saving, progress goes from 10 to 100
+ // except for Kenburn clip which goes from 50 to 100
+ if (M4OSA_TRUE ==
+ pContext->pEditSettings->pClipList[0]->xVSS.isPanZoom) {
+ progressBase = 50;
+ } else {
+ progressBase = 10;
+ }
}
// Check if we encoding is ongoing
else if (pContext->state == ManualEditState_SAVED) {
- if (progress != 100) {
- // Send a progress notification.
- progress = 100;
- LOGI("videoEditor_processClip ITEM %d Last progress indication %d",
- unuseditemID, progress);
- pEnv->CallVoidMethod(pContext->engine,
- pContext->onProgressUpdateMethodId,
- unuseditemID, progress);
- }
+
+ // Send a progress notification.
+ progress = 100;
+ LOGV("videoEditor_processClip ITEM %d Last progress indication %d",
+ unuseditemID, progress);
+ pEnv->CallVoidMethod(pContext->engine,
+ pContext->onProgressUpdateMethodId,
+ unuseditemID, progress);
+
// Stop the encoding.
LOGV("videoEditor_processClip Calling M4xVSS_SaveStop()");
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 99242ab..8b23da7 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -59,6 +59,7 @@
#include <cutils/properties.h>
#define USE_SURFACE_ALLOC 1
+#define FRAME_DROP_FREQ 0
namespace android {
@@ -820,7 +821,12 @@
return;
}
- if (mFlags & (LOOPING | AUTO_LOOPING)) {
+ if ((mFlags & LOOPING)
+ || ((mFlags & AUTO_LOOPING)
+ && (mAudioSink == NULL || mAudioSink->realtime()))) {
+ // Don't AUTO_LOOP if we're being recorded, since that cannot be
+ // turned off and recording would go on indefinitely.
+
seekTo_l(0);
if (mVideoSource != NULL) {
@@ -1518,14 +1524,29 @@
}
if (mVideoSource != NULL) {
- Mutex::Autolock autoLock(mStatsLock);
- TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
-
- const char *component;
+ const char *componentName;
CHECK(mVideoSource->getFormat()
- ->findCString(kKeyDecoderComponent, &component));
+ ->findCString(kKeyDecoderComponent, &componentName));
- stat->mDecoderName = component;
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
+
+ stat->mDecoderName = componentName;
+ }
+
+ static const char *kPrefix = "OMX.Nvidia.";
+ static const char *kSuffix = ".decode";
+ static const size_t kSuffixLength = strlen(kSuffix);
+
+ size_t componentNameLength = strlen(componentName);
+
+ if (!strncmp(componentName, kPrefix, strlen(kPrefix))
+ && componentNameLength >= kSuffixLength
+ && !strcmp(&componentName[
+ componentNameLength - kSuffixLength], kSuffix)) {
+ modifyFlags(SLOW_DECODER_HACK, SET);
+ }
}
return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
@@ -1705,6 +1726,7 @@
if (mFlags & FIRST_FRAME) {
modifyFlags(FIRST_FRAME, CLEAR);
+ mSinceLastDropped = 0;
mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
}
@@ -1751,18 +1773,28 @@
if (latenessUs > 40000) {
// We're more than 40ms late.
- LOGV("we're late by %lld us (%.2f secs), dropping frame",
+ LOGV("we're late by %lld us (%.2f secs)",
latenessUs, latenessUs / 1E6);
- mVideoBuffer->release();
- mVideoBuffer = NULL;
+ if (!(mFlags & SLOW_DECODER_HACK)
+ || mSinceLastDropped > FRAME_DROP_FREQ)
{
- Mutex::Autolock autoLock(mStatsLock);
- ++mStats.mNumVideoFramesDropped;
- }
+ LOGV("we're late by %lld us (%.2f secs) dropping "
+ "one after %d frames",
+ latenessUs, latenessUs / 1E6, mSinceLastDropped);
- postVideoEvent_l();
- return;
+ mSinceLastDropped = 0;
+ mVideoBuffer->release();
+ mVideoBuffer = NULL;
+
+ {
+ Mutex::Autolock autoLock(mStatsLock);
+ ++mStats.mNumVideoFramesDropped;
+ }
+
+ postVideoEvent_l();
+ return;
+ }
}
if (latenessUs < -10000) {
@@ -1781,6 +1813,7 @@
}
if (mVideoRenderer != NULL) {
+ mSinceLastDropped++;
mVideoRenderer->render(mVideoBuffer);
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 73a05a5..3b79f06 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1687,6 +1687,11 @@
}
}
+ if (!track->sampleTable->isValid()) {
+ // Make sure we have all the metadata we need.
+ return ERROR_MALFORMED;
+ }
+
return OK;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index a8a094e..2b9d99b 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -84,6 +84,13 @@
mSampleIterator = NULL;
}
+bool SampleTable::isValid() const {
+ return mChunkOffsetOffset >= 0
+ && mSampleToChunkOffset >= 0
+ && mSampleSizeOffset >= 0
+ && mTimeToSample != NULL;
+}
+
status_t SampleTable::setChunkOffsetParams(
uint32_t type, off64_t data_offset, size_t data_size) {
if (mChunkOffsetOffset >= 0) {
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 95f2ae8..14476d3 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -141,6 +141,8 @@
TEXT_RUNNING = 0x10000,
TEXTPLAYER_STARTED = 0x20000,
+
+ SLOW_DECODER_HACK = 0x40000,
};
mutable Mutex mLock;
@@ -181,6 +183,7 @@
uint32_t mFlags;
uint32_t mExtractorFlags;
+ uint32_t mSinceLastDropped;
int64_t mTimeSourceDeltaUs;
int64_t mVideoTimeUs;
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index f44e0a2..a6a6524 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -34,6 +34,8 @@
public:
SampleTable(const sp<DataSource> &source);
+ bool isValid() const;
+
// type can be 'stco' or 'co64'.
status_t setChunkOffsetParams(
uint32_t type, off64_t data_offset, size_t data_size);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 2080fad..d10911f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -29,6 +29,7 @@
<!-- started from PhoneWindowManager
TODO: Should have an android:permission attribute -->
<service android:name=".screenshot.TakeScreenshotService"
+ android:process=":screenshot"
android:exported="false" />
<service android:name=".LoadAverageService"
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_layers.xml b/packages/SystemUI/res/anim/recent_appear.xml
similarity index 64%
rename from packages/SystemUI/res/drawable/recents_thumbnail_layers.xml
rename to packages/SystemUI/res/anim/recent_appear.xml
index 6cae2c4..4400d9d 100644
--- a/packages/SystemUI/res/drawable/recents_thumbnail_layers.xml
+++ b/packages/SystemUI/res/anim/recent_appear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2010 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.
@@ -13,7 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
- <item android:drawable="@drawable/recents_thumbnail_bg" android:id="@+id/base_layer"/>
- <item android:drawable="@drawable/recents_thumbnail_overlay" android:id="@+id/overlay_layer"/>
-</layer-list>
\ No newline at end of file
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@android:integer/config_shortAnimTime"
+ />
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index 8c29042..16008a3 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -32,8 +32,14 @@
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
android:clickable="true"
- android:background="@drawable/recents_thumbnail_layers"
- />
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_overlay">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ />
+ </FrameLayout>
<ImageView android:id="@+id/app_icon"
android:layout_width="wrap_content"
@@ -45,6 +51,7 @@
android:maxWidth="@dimen/status_bar_recents_thumbnail_max_width"
android:maxHeight="@dimen/status_bar_recents_thumbnail_max_height"
android:adjustViewBounds="true"
+ android:visibility="invisible"
/>
<TextView android:id="@+id/app_label"
@@ -60,6 +67,7 @@
android:layout_marginLeft="@dimen/recents_thumbnail_bg_padding_left"
android:singleLine="true"
android:ellipsize="marquee"
+ android:visibility="invisible"
/>
<TextView android:id="@+id/app_description"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index c705a69..c0fce71 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -32,8 +32,14 @@
android:clickable="true"
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
- android:background="@drawable/recents_thumbnail_layers"
- />
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_overlay">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ />
+ </FrameLayout>
<ImageView android:id="@+id/app_icon"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
index a204f17..125c87e 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
@@ -44,24 +44,23 @@
/>
<!-- navigation controls -->
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="80dip"
- android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_back"
- android:layout_alignParentLeft="true"
- systemui:keyCode="4"
- android:contentDescription="@string/accessibility_back"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
- />
<LinearLayout
android:id="@+id/navigationArea"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_toRightOf="@+id/back"
+ android:layout_alignParentLeft="true"
android:orientation="horizontal"
android:clipChildren="false"
android:clipToPadding="false"
>
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+ android:layout_width="80dip"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_back"
+ systemui:keyCode="4"
+ android:contentDescription="@string/accessibility_back"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ />
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="80dip"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index 386ce30..5306508 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -32,8 +32,14 @@
android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
android:scaleType="center"
android:clickable="true"
- android:background="@drawable/recents_thumbnail_layers"
- />
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_overlay">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ />
+ </FrameLayout>
<ImageView android:id="@+id/app_icon"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index d1919ca..6c4c9c1 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -37,6 +37,7 @@
android:orientation="horizontal"
android:clipChildren="false"
android:clipToPadding="false"
+ android:id="@+id/nav_buttons"
>
<!-- navigation controls -->
@@ -119,6 +120,7 @@
android:orientation="vertical"
android:clipChildren="false"
android:clipToPadding="false"
+ android:id="@+id/nav_buttons"
>
<!-- navigation controls -->
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 529a5bc..33eb223 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"No hi ha cap targeta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Connexió Bluetooth mitjançant dispositiu portàtil"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode d\'avió."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria: <xliff:g id="NUMBER">%d</xliff:g> %."</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Botó Configuració."</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Botó de notificacions."</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Elimina la notificació."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 8093de1..543bb9e 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Žádná karta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering přes Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim V letadle."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Stav baterie: <xliff:g id="NUMBER">%d</xliff:g> %."</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Tlačítko Nastavení."</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Tlačítko upozornění."</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Odebrat oznámení"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 8168f74..ea9b8d2 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -60,8 +60,7 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Kompatibilitätszoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Wenn eine App für einen kleineren Bildschirm ausgelegt ist, wird ein Zoom-Steuerelement neben der Uhr angezeigt."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Screenshot in Galerie gespeichert"</string>
- <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
- <skip />
+ <!-- outdated translation 655180965533683356 --> <string name="screenshot_failed_toast" msgid="1990979819772906912">"Screenshot konnte nicht gespeichert werden."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Als Medienplayer (MTP) bereitstellen"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Als Kamera (PTP) bereitstellen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 76dadd4..ee3e671 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Δεν υπάρχει SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Σύνδεση Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Λειτουργία πτήσης."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Μπαταρία <xliff:g id="NUMBER">%d</xliff:g> %."</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Κουμπί ρυθμίσεων."</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Κουμπί ειδοοποιήσεων"</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Κατάργηση ειδοποίησης."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 86470e4..a8bbd96 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -60,8 +60,7 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Zoom de compatibilidad"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Si la aplicación se ha diseñado para una pantalla más pequeña, aparecerá un control de zoom junto al reloj."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de pantalla guardada en la galería"</string>
- <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
- <skip />
+ <!-- outdated translation 655180965533683356 --> <string name="screenshot_failed_toast" msgid="1990979819772906912">"No se ha podido guardar la captura de pantalla."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Activar como reproductor de medios (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Activar como cámara (PTP)"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index c2098b1..aa0b487 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -60,8 +60,7 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Yhteensopivuustilan zoomaus"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Jos sovellus on suunniteltu pienemmälle näytölle, kellon viereen tulee näkyviin zoomaussäädin."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Kuvakaappaus on tallennettu galleriaan"</string>
- <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
- <skip />
+ <!-- outdated translation 655180965533683356 --> <string name="screenshot_failed_toast" msgid="1990979819772906912">"Kuvakaappausta ei voitu tallentaa"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-tiedostonsiirtoasetukset"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Käytä mediasoittimena (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Käytä kamerana (PTP)"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 858305f..b97ac2f 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Aucune carte SIM"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Partage de connexion Bluetooth"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterie : <xliff:g id="NUMBER">%d</xliff:g> %"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Bouton \"Paramètres\""</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Bouton \"Notifications\""</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Supprimer la notification"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index d4d5117..c7ef3f6 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Nessuna SIM presente."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modalità aereo."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteria: <xliff:g id="NUMBER">%d</xliff:g>%."</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Pulsante Impostazioni."</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Pulsante per le notifiche."</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Rimuovi la notifica."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 2f3509a..5ad4e2d 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIMがありません。"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetoothテザリング。"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"機内モード。"</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"電池残量: <xliff:g id="NUMBER">%d</xliff:g>%"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"設定ボタン。"</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"通知ボタン。"</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"通知を削除。"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f264ef4..10d5611 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -60,8 +60,7 @@
<string name="compat_mode_help_header" msgid="7020175705401506719">"Compatibilidade de zoom"</string>
<string name="compat_mode_help_body" msgid="4946726776359270040">"Sempre que uma aplicação tiver sido concebida para ecrãs mais pequenos, aparecerá um controlo de zoom junto ao relógio."</string>
<string name="screenshot_saving_toast" msgid="8592630119048713208">"Captura de ecrã guardada na Galeria"</string>
- <!-- no translation found for screenshot_failed_toast (1990979819772906912) -->
- <skip />
+ <!-- outdated translation 655180965533683356 --> <string name="screenshot_failed_toast" msgid="1990979819772906912">"Não foi possível guardar a captura de ecrã"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opções de transm. de fich. USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montar como leitor de multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como câmara (PTP)"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a6759fd..07fb12b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Sem SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Vínculo Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo de avião."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g>%."</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Botão Configurações."</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Botão de notificações."</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Remover notificação."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 2dd0bd4..70a7c88 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-карта отсутствует."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Общий Bluetooth-модем."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полета."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд батареи: <xliff:g id="NUMBER">%d</xliff:g>%"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Кнопка вызова настроек."</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Кнопка вызова панели уведомлений"</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Удалить уведомление."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index f6ab7e1..b6a774c 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Žiadna karta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Zdieľanie dátového pripojenia cez Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim V lietadle."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Batéria <xliff:g id="NUMBER">%d</xliff:g> %"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"Tlačidlo Nastavenia."</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"Tlačidlo upozornení."</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"Odstrániť upozornenie."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 8aa9c62..62e5a3e 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"无 SIM 卡。"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"蓝牙绑定。"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飞行模式。"</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"电池电量为 <xliff:g id="NUMBER">%d</xliff:g>%。"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"设置按钮。"</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"通知按钮。"</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"删除通知。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 17d0822..54fbefb 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -104,7 +104,9 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"沒有 SIM 卡。"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"藍牙數據連線"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飛行模式。"</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"電池電量為 <xliff:g id="NUMBER">%d</xliff:g>%。"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+ <skip />
<string name="accessibility_settings_button" msgid="7913780116850379698">"設定按鈕。"</string>
<string name="accessibility_notifications_button" msgid="2933903195211483438">"通知按鈕。"</string>
<string name="accessibility_remove_notification" msgid="4883990503785778699">"移除通知。"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 2818f87..e7ed052 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -30,7 +30,7 @@
public class SwipeHelper {
static final String TAG = "com.android.systemui.SwipeHelper";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final boolean DEBUG_INVALIDATE = false;
private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
@@ -142,7 +142,7 @@
// invalidate a rectangle relative to the view's coordinate system all the way up the view
// hierarchy
public static void invalidateGlobalRegion(View view, RectF childBounds) {
- childBounds.offset(view.getX(), view.getY());
+ //childBounds.offset(view.getTranslationX(), view.getTranslationY());
if (DEBUG_INVALIDATE)
Log.v(TAG, "-------------");
while (view.getParent() != null && view.getParent() instanceof View) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 28a5cc8..8c03ef8 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -41,6 +41,10 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Process;
+import android.os.SystemClock;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -51,12 +55,15 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
+import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.RelativeLayout;
+import android.widget.ScrollView;
import android.widget.TextView;
import com.android.systemui.R;
@@ -68,11 +75,12 @@
public class RecentsPanelView extends RelativeLayout
implements OnItemClickListener, RecentsCallback, StatusBarPanel, Animator.AnimatorListener {
static final String TAG = "RecentsListView";
- static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG;
+ static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
private static final int DISPLAY_TASKS = 20;
private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
private StatusBar mBar;
private ArrayList<ActivityDescription> mActivityDescriptions;
+ private AsyncTask<Void, Integer, Void> mThumbnailLoader;
private int mIconDpi;
private View mRecentsScrim;
private View mRecentsGlowView;
@@ -87,31 +95,47 @@
private Choreographer mChoreo;
private View mRecentsDismissButton;
private ActivityDescriptionAdapter mListAdapter;
+ private final Handler mHandler = new Handler();
- /* package */ final static class ActivityDescription {
+ /* package */ final class ActivityDescription {
+ final ActivityManager.RecentTaskInfo recentTaskInfo;
+ final ResolveInfo resolveInfo;
int taskId; // application task id for curating apps
- Bitmap thumbnail; // generated by Activity.onCreateThumbnail()
- Drawable icon; // application package icon
- String label; // application package label
- CharSequence description; // generated by Activity.onCreateDescription()
Intent intent; // launch intent for application
Matrix matrix; // arbitrary rotation matrix to correct orientation
String packageName; // used to override animations (see onClick())
int position; // position in list
- public ActivityDescription(Bitmap _thumbnail,
- Drawable _icon, String _label, CharSequence _desc, Intent _intent,
- int _id, int _pos, String _packageName)
- {
- thumbnail = _thumbnail;
- icon = _icon;
- label = _label;
- description = _desc;
+ private Bitmap mThumbnail; // generated by Activity.onCreateThumbnail()
+ private Drawable mIcon; // application package icon
+ private CharSequence mLabel; // application package label
+
+ public ActivityDescription(ActivityManager.RecentTaskInfo _recentInfo,
+ ResolveInfo _resolveInfo, Intent _intent,
+ int _id, int _pos, String _packageName) {
+ recentTaskInfo = _recentInfo;
+ resolveInfo = _resolveInfo;
intent = _intent;
taskId = _id;
position = _pos;
packageName = _packageName;
}
+
+ public CharSequence getLabel() {
+ return mLabel;
+ }
+
+ public Drawable getIcon() {
+ return mIcon;
+ }
+
+ public void setThumbnail(Bitmap thumbnail) {
+ mThumbnail = compositeBitmap(mGlowBitmap, thumbnail);
+ }
+
+ public Bitmap getThumbnail() {
+ return mThumbnail;
+ }
}
private final class OnLongClickDelegate implements View.OnLongClickListener {
@@ -126,6 +150,7 @@
/* package */ final static class ViewHolder {
View thumbnailView;
+ ImageView thumbnailViewImage;
ImageView iconView;
TextView labelView;
TextView descriptionView;
@@ -157,6 +182,8 @@
convertView = mInflater.inflate(R.layout.status_bar_recent_item, null);
holder = new ViewHolder();
holder.thumbnailView = convertView.findViewById(R.id.app_thumbnail);
+ holder.thumbnailViewImage = (ImageView) convertView.findViewById(
+ R.id.app_thumbnail_image);
holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
@@ -169,11 +196,10 @@
final int activityId = mActivityDescriptions.size() - position - 1;
final ActivityDescription activityDescription = mActivityDescriptions.get(activityId);
- final Bitmap thumb = activityDescription.thumbnail;
- updateDrawable(holder.thumbnailView, compositeBitmap(mGlowBitmap, thumb));
- holder.iconView.setImageDrawable(activityDescription.icon);
- holder.labelView.setText(activityDescription.label);
- holder.descriptionView.setText(activityDescription.description);
+ holder.thumbnailViewImage.setImageBitmap(activityDescription.getThumbnail());
+ holder.iconView.setImageDrawable(activityDescription.getIcon());
+ holder.labelView.setText(activityDescription.getLabel());
+ holder.descriptionView.setText(activityDescription.recentTaskInfo.description);
holder.thumbnailView.setTag(activityDescription);
holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView));
holder.activityDescription = activityDescription;
@@ -201,20 +227,6 @@
return x >= l && x < r && y >= t && y < b;
}
- private void updateDrawable(View thumbnailView, Bitmap bitmap) {
- Drawable d = thumbnailView.getBackground();
- if (d instanceof LayerDrawable) {
- LayerDrawable layerD = (LayerDrawable) d;
- Drawable thumb = layerD.findDrawableByLayerId(R.id.base_layer);
- if (thumb != null) {
- layerD.setDrawableByLayerId(R.id.base_layer,
- new BitmapDrawable(getResources(), bitmap));
- return;
- }
- }
- Log.w(TAG, "Failed to update drawable");
- }
-
public void show(boolean show, boolean animate) {
if (animate) {
if (mShowing != show) {
@@ -373,12 +385,12 @@
}
}
- private Drawable getFullResDefaultActivityIcon() {
+ Drawable getFullResDefaultActivityIcon() {
return getFullResIcon(Resources.getSystem(),
com.android.internal.R.mipmap.sym_def_app_icon);
}
- private Drawable getFullResIcon(Resources resources, int iconId) {
+ Drawable getFullResIcon(Resources resources, int iconId) {
try {
return resources.getDrawableForDensity(iconId, mIconDpi);
} catch (Resources.NotFoundException e) {
@@ -442,15 +454,13 @@
final String title = info.loadLabel(pm).toString();
// Drawable icon = info.loadIcon(pm);
Drawable icon = getFullResIcon(resolveInfo, pm);
- int id = recentTasks.get(i).id;
+ int id = recentInfo.id;
if (title != null && title.length() > 0 && icon != null) {
if (DEBUG) Log.v(TAG, "creating activity desc for id=" + id + ", label=" + title);
ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(
recentInfo.persistentId);
- ActivityDescription item = new ActivityDescription(
- thumbs != null ? thumbs.mainThumbnail : null,
- icon, title, recentInfo.description, intent, id,
- index, info.packageName);
+ ActivityDescription item = new ActivityDescription(recentInfo,
+ resolveInfo, intent, id, index, info.packageName);
activityDescriptions.add(item);
++index;
} else {
@@ -474,12 +484,137 @@
return desc;
}
+ void loadActivityDescription(ActivityDescription ad, int index) {
+ final ActivityManager am = (ActivityManager)
+ mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ final PackageManager pm = mContext.getPackageManager();
+ ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(
+ ad.recentTaskInfo.persistentId);
+ CharSequence label = ad.resolveInfo.activityInfo.loadLabel(pm);
+ Drawable icon = getFullResIcon(ad.resolveInfo, pm);
+ if (DEBUG) Log.v(TAG, "Loaded bitmap for #" + index + " in "
+ + ad + ": " + thumbs.mainThumbnail);
+ synchronized (ad) {
+ ad.mLabel = label;
+ ad.mIcon = icon;
+ ad.setThumbnail(thumbs.mainThumbnail);
+ }
+ }
+
+ void applyActivityDescription(ActivityDescription ad, int index, boolean anim) {
+ synchronized (ad) {
+ if (mRecentsContainer != null) {
+ ViewGroup container = mRecentsContainer;
+ if (container instanceof HorizontalScrollView
+ || container instanceof ScrollView) {
+ container = (ViewGroup)container.findViewById(
+ R.id.recents_linear_layout);
+ }
+ // Look for a view showing this thumbnail, to update.
+ for (int i=0; i<container.getChildCount(); i++) {
+ View v = container.getChildAt(i);
+ if (v.getTag() instanceof ViewHolder) {
+ ViewHolder h = (ViewHolder)v.getTag();
+ if (h.activityDescription == ad) {
+ if (DEBUG) Log.v(TAG, "Updatating thumbnail #" + index + " in "
+ + h.activityDescription
+ + ": " + ad.getThumbnail());
+ h.iconView.setImageDrawable(ad.getIcon());
+ if (anim) {
+ h.iconView.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
+ }
+ h.iconView.setVisibility(View.VISIBLE);
+ h.labelView.setText(ad.getLabel());
+ if (anim) {
+ h.labelView.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
+ }
+ h.labelView.setVisibility(View.VISIBLE);
+ Bitmap thumbnail = ad.getThumbnail();
+ if (thumbnail != null) {
+ // Should remove the default image in the frame
+ // that this now covers, to improve scrolling speed.
+ // That can't be done until the anim is complete though.
+ h.thumbnailViewImage.setImageBitmap(thumbnail);
+ if (anim) {
+ h.thumbnailViewImage.setAnimation(AnimationUtils.loadAnimation(
+ mContext, R.anim.recent_appear));
+ }
+ h.thumbnailViewImage.setVisibility(View.VISIBLE);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
private void refreshApplicationList() {
+ if (mThumbnailLoader != null) {
+ mThumbnailLoader.cancel(false);
+ mThumbnailLoader = null;
+ }
mActivityDescriptions = getRecentTasks();
mListAdapter.notifyDataSetInvalidated();
if (mActivityDescriptions.size() > 0) {
if (DEBUG) Log.v(TAG, "Showing " + mActivityDescriptions.size() + " apps");
updateUiElements(getResources().getConfiguration());
+ final ArrayList<ActivityDescription> descriptions = mActivityDescriptions;
+ loadActivityDescription(descriptions.get(0), 0);
+ applyActivityDescription(descriptions.get(0), 0, false);
+ if (descriptions.size() > 1) {
+ mThumbnailLoader = new AsyncTask<Void, Integer, Void>() {
+ @Override
+ protected void onProgressUpdate(Integer... values) {
+ final ActivityDescription ad = descriptions.get(values[0]);
+ if (!isCancelled()) {
+ applyActivityDescription(ad, values[0], true);
+ }
+ // This is to prevent the loader thread from getting ahead
+ // of our UI updates.
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ synchronized (ad) {
+ ad.notifyAll();
+ }
+ }
+ });
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ final int origPri = Process.getThreadPriority(Process.myTid());
+ Process.setThreadPriority(Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ long nextTime = SystemClock.uptimeMillis();
+ for (int i=1; i<descriptions.size(); i++) {
+ ActivityDescription ad = descriptions.get(i);
+ loadActivityDescription(ad, i);
+ long now = SystemClock.uptimeMillis();
+ nextTime += 200;
+ if (nextTime > now) {
+ try {
+ Thread.sleep(nextTime-now);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (isCancelled()) {
+ break;
+ }
+ synchronized (ad) {
+ publishProgress(i);
+ try {
+ ad.wait(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ Process.setThreadPriority(origPri);
+ return null;
+ }
+ };
+ mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
} else {
// Immediately hide this panel
if (DEBUG) Log.v(TAG, "Nothing to show");
@@ -548,7 +683,7 @@
public void handleSwipe(View view) {
ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription;
- if (DEBUG) Log.v(TAG, "Jettison " + ad.label);
+ if (DEBUG) Log.v(TAG, "Jettison " + ad.getLabel());
mActivityDescriptions.remove(ad);
// Handled by widget containers to enable LayoutTransitions properly
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 89900a1..959328f 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -66,20 +66,34 @@
private void update() {
mLinearLayout.removeAllViews();
+ // Once we can clear the data associated with individual item views,
+ // we can get rid of the removeAllViews() and the code below will
+ // recycle them.
for (int i = 0; i < mAdapter.getCount(); i++) {
- final View view = mAdapter.getView(i, null, mLinearLayout);
- view.setClickable(true);
- view.setOnLongClickListener(mOnLongClick);
+ View old = null;
+ if (i < mLinearLayout.getChildCount()) {
+ old = mLinearLayout.getChildAt(i);
+ old.setVisibility(View.VISIBLE);
+ }
+ final View view = mAdapter.getView(i, old, mLinearLayout);
- final View thumbnail = getChildContentView(view);
- // thumbnail is set to clickable in the layout file
- thumbnail.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- mCallback.handleOnClick(view);
- }
- });
+ if (old == null) {
+ view.setClickable(true);
+ view.setOnLongClickListener(mOnLongClick);
- mLinearLayout.addView(view);
+ final View thumbnail = getChildContentView(view);
+ // thumbnail is set to clickable in the layout file
+ thumbnail.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ mCallback.handleOnClick(view);
+ }
+ });
+
+ mLinearLayout.addView(view);
+ }
+ }
+ for (int i = mAdapter.getCount(); i < mLinearLayout.getChildCount(); i++) {
+ mLinearLayout.getChildAt(i).setVisibility(View.GONE);
}
// Scroll to end after layout.
post(new Runnable() {
@@ -128,8 +142,9 @@
final float y = ev.getY() + getScrollY();
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
View item = mLinearLayout.getChildAt(i);
- if (x >= item.getLeft() && x < item.getRight()
- && y >= item.getTop() && y < item.getBottom()) {
+ if (item.getVisibility() == View.VISIBLE
+ && x >= item.getLeft() && x < item.getRight()
+ && y >= item.getTop() && y < item.getBottom()) {
return item;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 86dc9a6..fe255cb 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -69,6 +69,7 @@
class SaveImageInBackgroundData {
Context context;
Bitmap image;
+ Runnable finisher;
int result;
}
@@ -141,6 +142,7 @@
Toast.makeText(params.context, R.string.screenshot_saving_toast,
Toast.LENGTH_SHORT).show();
}
+ params.finisher.run();
};
}
@@ -231,11 +233,9 @@
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM
- | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSLUCENT);
- mWindowLayoutParams.token = new Binder();
mWindowLayoutParams.setTitle("ScreenshotAnimation");
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
@@ -244,10 +244,11 @@
/**
* Creates a new worker thread and saves the screenshot to the media store.
*/
- private void saveScreenshotInWorkerThread() {
+ private void saveScreenshotInWorkerThread(Runnable finisher) {
SaveImageInBackgroundData data = new SaveImageInBackgroundData();
data.context = mContext;
data.image = mScreenBitmap;
+ data.finisher = finisher;
new SaveImageInBackgroundTask().execute(data);
}
@@ -269,7 +270,7 @@
/**
* Takes a screenshot of the current display and shows an animation.
*/
- void takeScreenshot() {
+ void takeScreenshot(Runnable finisher) {
// We need to orient the screenshot correctly (and the Surface api seems to take screenshots
// only in the natural orientation of the device :!)
mDisplay.getRealMetrics(mDisplayMetrics);
@@ -302,18 +303,19 @@
if (mScreenBitmap == null) {
Toast.makeText(mContext, R.string.screenshot_failed_toast,
Toast.LENGTH_SHORT).show();
+ finisher.run();
return;
}
// Start the post-screenshot animation
- startAnimation();
+ startAnimation(finisher);
}
/**
* Starts the animation after taking the screenshot
*/
- private void startAnimation() {
+ private void startAnimation(final Runnable finisher) {
// Add the view for the animation
mScreenshotView.setImageBitmap(mScreenBitmap);
mScreenshotLayout.requestFocus();
@@ -332,8 +334,7 @@
@Override
public void onAnimationEnd(Animator animation) {
// Save the screenshot once we have a bit of time now
- saveScreenshotInWorkerThread();
-
+ saveScreenshotInWorkerThread(finisher);
mWindowManager.removeView(mScreenshotLayout);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 35eaedf..05ff8be 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -26,7 +26,11 @@
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
import android.util.Log;
import com.android.internal.app.AlertActivity;
@@ -39,12 +43,30 @@
private static GlobalScreenshot mScreenshot;
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case 1:
+ final Messenger callback = msg.replyTo;
+ if (mScreenshot == null) {
+ mScreenshot = new GlobalScreenshot(TakeScreenshotService.this);
+ }
+ mScreenshot.takeScreenshot(new Runnable() {
+ @Override public void run() {
+ Message reply = Message.obtain(null, 1);
+ try {
+ callback.send(reply);
+ } catch (RemoteException e) {
+ }
+ }
+ });
+ }
+ }
+ };
+
@Override
public IBinder onBind(Intent intent) {
- if (mScreenshot == null) {
- mScreenshot = new GlobalScreenshot(this);
- }
- mScreenshot.takeScreenshot();
- return null;
+ return new Messenger(mHandler).getBinder();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 1e27233..a90eb3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -59,13 +59,17 @@
mNotification = notification;
setContentDescription(notification);
- final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
- final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
- final float scale = (float)imageBounds / (float)outerBounds;
- setScaleX(scale);
- setScaleY(scale);
- final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
- setAlpha(alpha);
+ // We do not resize and scale system icons (on the right), only notification icons (on the
+ // left).
+ if (notification != null) {
+ final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
+ final float scale = (float)imageBounds / (float)outerBounds;
+ setScaleX(scale);
+ setScaleY(scale);
+ final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
+ setAlpha(alpha);
+ }
}
private static boolean streq(String a, String b) {
@@ -247,4 +251,9 @@
}
}
}
+
+ public String toString() {
+ return "StatusBarIconView(slot=" + mSlot + " icon=" + mIcon
+ + " notification=" + mNotification + ")";
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index abf505c..5f1ae58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -29,6 +29,7 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.LinearLayout;
@@ -56,6 +57,7 @@
boolean mVertical;
boolean mHidden;
+ boolean mEnabled = true;
public View getRecentsButton() {
return mCurrentView.findViewById(R.id.recent_apps);
@@ -67,6 +69,7 @@
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
+
mHidden = false;
mDisplay = ((WindowManager)context.getSystemService(
@@ -79,6 +82,11 @@
mVertical = false;
}
+ public void setEnabled(final boolean enable) {
+ mEnabled = enable;
+ mCurrentView.setVisibility(enable ? View.VISIBLE : View.INVISIBLE);
+ }
+
public void setHidden(final boolean hide) {
if (hide == mHidden) return;
@@ -129,6 +137,11 @@
? findViewById(R.id.rot90)
: findViewById(R.id.rot270);
+ for (View v : mRotatedViews) {
+ // this helps avoid drawing artifacts with glowing navigation keys
+ ViewGroup group = (ViewGroup) v.findViewById(R.id.nav_buttons);
+ group.setMotionEventSplittingEnabled(false);
+ }
mCurrentView = mRotatedViews[Surface.ROTATION_0];
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 2e14bef..68f6dcf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.animation.ObjectAnimator;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Dialog;
import android.app.Notification;
@@ -90,6 +91,7 @@
static final String TAG = "PhoneStatusBar";
public static final boolean DEBUG = false;
public static final boolean SPEW = false;
+ public static final boolean DUMPTRUCK = true; // extra dumpsys info
// additional instrumentation for testing purposes; intended to be left on during development
public static final boolean CHATTY = DEBUG || true;
@@ -315,8 +317,8 @@
mPile = (ViewGroup)expanded.findViewById(R.id.latestItems);
mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
- mNoNotificationsTitle.setAlpha(0f);
- mNoNotificationsTitle.setVisibility(View.VISIBLE);
+ mNoNotificationsTitle.setVisibility(View.GONE); // disabling for now
+
mClearButton = expanded.findViewById(R.id.clear_all_button);
mClearButton.setOnClickListener(mClearButtonListener);
mClearButton.setAlpha(0f);
@@ -371,9 +373,11 @@
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
(translucent ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
+ if (ActivityManager.isHighEndGfx(mDisplay)) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ }
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
lp.setTitle("RecentsPanel");
lp.windowAnimations = R.style.Animation_RecentPanel;
@@ -1023,6 +1027,7 @@
mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
}
+ /*
if (mNoNotificationsTitle.isShown()) {
if (any != (mNoNotificationsTitle.getAlpha() == 0.0f)) {
ObjectAnimator a = ObjectAnimator.ofFloat(mNoNotificationsTitle, "alpha",
@@ -1034,6 +1039,7 @@
} else {
mNoNotificationsTitle.setAlpha(any ? 0.0f : 0.75f);
}
+ */
}
@@ -1045,12 +1051,30 @@
final int diff = state ^ old;
mDisabled = state;
+ if (DEBUG) {
+ Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
+ old, state, diff));
+ }
+
if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Slog.d(TAG, "DISABLE_EXPAND: yes");
animateCollapse();
}
}
+
+ if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
+ if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
+ Slog.d(TAG, "DISABLE_NAVIGATION: yes");
+
+ // close recents if it's visible
+ mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
+ mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
+ }
+
+ mNavigationBarView.setEnabled((state & StatusBarManager.DISABLE_NAVIGATION) == 0);
+ }
+
if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
@@ -1676,26 +1700,28 @@
pw.println(" mScrollView: " + viewInfo(mScrollView)
+ " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
}
- /*
- synchronized (mNotificationData) {
- int N = mNotificationData.ongoingCount();
- pw.println(" ongoingCount.size=" + N);
- for (int i=0; i<N; i++) {
- StatusBarNotification n = mNotificationData.getOngoing(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
- }
- N = mNotificationData.latestCount();
- pw.println(" ongoingCount.size=" + N);
- for (int i=0; i<N; i++) {
- StatusBarNotification n = mNotificationData.getLatest(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
- }
- }
- */
- if (false) {
+ if (DUMPTRUCK) {
+ synchronized (mNotificationData) {
+ int N = mNotificationData.size();
+ pw.println(" notification icons: " + N);
+ for (int i=0; i<N; i++) {
+ NotificationData.Entry e = mNotificationData.get(i);
+ pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
+ StatusBarNotification n = e.notification;
+ pw.println(" pkg=" + n.pkg + " id=" + n.id + " priority=" + n.priority);
+ pw.println(" notification=" + n.notification);
+ pw.println(" tickerText=\"" + n.notification.tickerText + "\"");
+ }
+ }
+
+ int N = mStatusIcons.getChildCount();
+ pw.println(" system icons: " + N);
+ for (int i=0; i<N; i++) {
+ StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
+ pw.println(" [" + i + "] icon=" + ic);
+ }
+
pw.println("see the logcat for a dump of the views we have created.");
// must happen on ui thread
mHandler.post(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index fc18eef..6368d1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -49,6 +49,8 @@
public class KeyButtonView extends ImageView {
private static final String TAG = "StatusBar.KeyButtonView";
+ final float GLOW_MAX_SCALE_FACTOR = 1.8f;
+
IWindowManager mWindowManager;
long mDownTime;
boolean mSending;
@@ -159,17 +161,22 @@
mGlowScale = x;
final float w = getWidth();
final float h = getHeight();
- if (x < 1.0f) {
+ if (GLOW_MAX_SCALE_FACTOR <= 1.0f) {
+ // this only works if we know the glow will never leave our bounds
invalidate();
} else {
- final float rx = (w * (x - 1.0f)) / 2.0f;
- final float ry = (h * (x - 1.0f)) / 2.0f;
+ final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
+ final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
com.android.systemui.SwipeHelper.invalidateGlobalRegion(
this,
new RectF(getLeft() - rx,
getTop() - ry,
getRight() + rx,
getBottom() + ry));
+
+ // also invalidate our immediate parent to help avoid situations where nearby glows
+ // interfere
+ ((View)getParent()).invalidate();
}
}
@@ -183,7 +190,7 @@
setDrawingAlpha(1f);
as.playTogether(
ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
- ObjectAnimator.ofFloat(this, "glowScale", 1.8f)
+ ObjectAnimator.ofFloat(this, "glowScale", GLOW_MAX_SCALE_FACTOR)
);
as.setDuration(50);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index e787113..76dec5e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -497,6 +497,8 @@
mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
mRecentButton.setOnClickListener(mOnClickListener);
mNavigationArea.setLayoutTransition(mBarContentsLayoutTransition);
+ // no multi-touch on the nav buttons
+ mNavigationArea.setMotionEventSplittingEnabled(false);
// The bar contents buttons
mFeedbackIconArea = (ViewGroup)sb.findViewById(R.id.feedbackIconArea);
@@ -966,11 +968,11 @@
if ((diff & StatusBarManager.DISABLE_BACK) != 0) {
if ((state & StatusBarManager.DISABLE_BACK) != 0) {
Slog.i(TAG, "DISABLE_BACK: yes");
- mBackButton.setVisibility(View.INVISIBLE);
+ mBackButton.setEnabled(false);
mInputMethodSwitchButton.setScreenLocked(true);
} else {
Slog.i(TAG, "DISABLE_BACK: no");
- mBackButton.setVisibility(View.VISIBLE);
+ mBackButton.setEnabled(true);
mInputMethodSwitchButton.setScreenLocked(false);
}
}
@@ -1218,9 +1220,7 @@
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
- if (v == mNotificationTrigger) {
- onClickNotificationTrigger();
- } else if (v == mRecentButton) {
+ if (v == mRecentButton) {
onClickRecentButton();
} else if (v == mInputMethodSwitchButton) {
onClickInputMethodSwitchButton();
@@ -1230,17 +1230,6 @@
}
};
- public void onClickNotificationTrigger() {
- if (DEBUG) Slog.d(TAG, "clicked notification icons; disabled=" + mDisabled);
- if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
- int msg = !mNotificationPanel.isShowing()
- ? MSG_OPEN_NOTIFICATION_PANEL
- : MSG_CLOSE_NOTIFICATION_PANEL;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
- }
-
public void onClickRecentButton() {
if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
@@ -1372,6 +1361,11 @@
// event.getY(),
// mInitialTouchX,
// mInitialTouchY));
+
+ if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
+ return true;
+ }
+
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 06b7fb9..86de558 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -1142,6 +1142,10 @@
// insecure and (is covered by another window OR this feature is enabled in general)
boolean enable = !mShowing
|| ((ENABLE_STATUS_BAR_IN_KEYGUARD || mHidden) && !isSecure());
+ if (DEBUG) {
+ Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mHidden=" + mHidden
+ + " isSecure=" + isSecure() + " --> enable=" + enable);
+ }
mStatusBarManager.disable(enable ?
StatusBarManager.DISABLE_NONE :
( StatusBarManager.DISABLE_EXPAND
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 0ee6488..c580f08 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -386,6 +386,11 @@
// Ditch the menu created above
st.menu = null;
+ if (mActionBar != null) {
+ // Don't show it in the action bar either
+ mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ }
+
return false;
}
@@ -406,6 +411,11 @@
}
if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) {
+ if (mActionBar != null) {
+ // The app didn't want to show the menu for now but it still exists.
+ // Clear it out of the action bar.
+ mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ }
st.menu.startDispatchingItemsChanged();
return false;
}
@@ -753,7 +763,7 @@
if (mPanelChordingKey != 0) {
mPanelChordingKey = 0;
- if (event.isCanceled()) {
+ if (event.isCanceled() || (mDecor != null && mDecor.mActionMode != null)) {
return;
}
@@ -3139,6 +3149,7 @@
public boolean hasPanelItems() {
if (shownPanelView == null) return false;
+ if (createdPanelView != null) return true;
if (isCompact || isInExpandedMode) {
return listMenuPresenter.getAdapter().getCount() > 0;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b60a038..7764e35 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -41,6 +41,8 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.LocalPowerManager;
+import android.os.Message;
+import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -2396,22 +2398,67 @@
}
}
+ ServiceConnection mScreenshotConnection = null;
+ Runnable mScreenshotTimeout = null;
+
+ void finishScreenshot(ServiceConnection conn) {
+ if (mScreenshotConnection == conn) {
+ mContext.unbindService(conn);
+ mScreenshotConnection = null;
+ if (mScreenshotTimeout != null) {
+ mHandler.removeCallbacks(mScreenshotTimeout);
+ mScreenshotTimeout = null;
+ }
+ }
+ }
+
private void takeScreenshot() {
mHandler.post(new Runnable() {
@Override
public void run() {
+ if (mScreenshotConnection != null) {
+ return;
+ }
ComponentName cn = new ComponentName("com.android.systemui",
"com.android.systemui.screenshot.TakeScreenshotService");
Intent intent = new Intent();
intent.setComponent(cn);
ServiceConnection conn = new ServiceConnection() {
@Override
- public void onServiceConnected(ComponentName name, IBinder service) {}
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (mScreenshotConnection != this) {
+ return;
+ }
+ Messenger messenger = new Messenger(service);
+ Message msg = Message.obtain(null, 1);
+ final ServiceConnection myConn = this;
+ Handler h = new Handler(mHandler.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ finishScreenshot(myConn);
+ }
+ };
+ msg.replyTo = new Messenger(h);
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ }
+ }
@Override
public void onServiceDisconnected(ComponentName name) {}
};
- mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
- mContext.unbindService(conn);
+ if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
+ mScreenshotConnection = conn;
+ mScreenshotTimeout = new Runnable() {
+ @Override public void run() {
+ if (mScreenshotConnection != null) {
+ finishScreenshot(mScreenshotConnection);
+ }
+ }
+
+ };
+ mHandler.postDelayed(mScreenshotTimeout, 10000);
+ }
}
});
}
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index fd03201..00aa14c 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -97,6 +97,9 @@
private static final boolean DEBUG_EVENTS = false;
private static final boolean DEBUG_OBB = false;
+ // Disable this since it messes up long-running cryptfs operations.
+ private static final boolean WATCHDOG_ENABLE = false;
+
private static final String TAG = "MountService";
private static final String VOLD_TAG = "VoldConnector";
@@ -1182,8 +1185,10 @@
Thread thread = new Thread(mConnector, VOLD_TAG);
thread.start();
- // Add ourself to the Watchdog monitors.
- Watchdog.getInstance().addMonitor(this);
+ // Add ourself to the Watchdog monitors if enabled.
+ if (WATCHDOG_ENABLE) {
+ Watchdog.getInstance().addMonitor(this);
+ }
}
/**
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e9c91e6..cba04df 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2699,7 +2699,6 @@
}
if (!haveBg) {
- Slog.i(TAG, "Low Memory: No more background processes.");
EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
long now = SystemClock.uptimeMillis();
for (int i=mLruProcesses.size()-1; i>=0; i--) {
diff --git a/tests/RenderScriptTests/ShadersTest/Android.mk b/tests/RenderScriptTests/ShadersTest/Android.mk
new file mode 100644
index 0000000..109b0a0
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/Android.mk
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := ShadersTest
+
+include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/ShadersTest/AndroidManifest.xml b/tests/RenderScriptTests/ShadersTest/AndroidManifest.xml
new file mode 100644
index 0000000..871200d
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.shaderstest">
+
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application android:label="_ShadersTest">
+ <activity android:name="ShadersTest"
+ android:label="_ShadersTest"
+ android:theme="@android:style/Theme.Black.NoTitleBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/RenderScriptTests/ShadersTest/res/drawable-nodpi/robot.png b/tests/RenderScriptTests/ShadersTest/res/drawable-nodpi/robot.png
new file mode 100644
index 0000000..f7353fd
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/res/drawable-nodpi/robot.png
Binary files differ
diff --git a/tests/RenderScriptTests/ShadersTest/res/raw/depth_fs.glsl b/tests/RenderScriptTests/ShadersTest/res/raw/depth_fs.glsl
new file mode 100644
index 0000000..096843b
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/res/raw/depth_fs.glsl
@@ -0,0 +1,13 @@
+void main() {
+ // Non-linear depth value
+ float z = gl_FragCoord.z;
+ // Near and far planes from the projection
+ // In practice, these values can be used to tweak
+ // the focus range
+ float n = UNI_near;
+ float f = UNI_far;
+ // Linear depth value
+ z = (2.0 * n) / (f + n - z * (f - n));
+
+ gl_FragColor = vec4(z, z, z, 1.0);
+}
diff --git a/tests/RenderScriptTests/ShadersTest/res/raw/robot.a3d b/tests/RenderScriptTests/ShadersTest/res/raw/robot.a3d
new file mode 100644
index 0000000..f48895c
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/res/raw/robot.a3d
Binary files differ
diff --git a/tests/RenderScriptTests/ShadersTest/res/raw/vignette_fs.glsl b/tests/RenderScriptTests/ShadersTest/res/raw/vignette_fs.glsl
new file mode 100644
index 0000000..2dc1ea3
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/res/raw/vignette_fs.glsl
@@ -0,0 +1,31 @@
+#define CRT_MASK
+
+varying vec2 varTex0;
+
+void main() {
+ lowp vec4 color = texture2D(UNI_Tex0, varTex0);
+
+ vec2 powers = pow(abs((gl_FragCoord.xy / vec2(UNI_width, UNI_height)) - 0.5), vec2(2.0));
+ float gradient = smoothstep(UNI_size - UNI_feather, UNI_size + UNI_feather,
+ powers.x + powers.y);
+
+ color = vec4(mix(color.rgb, vec3(0.0), gradient), 1.0);
+
+#ifdef CRT_MASK
+ float vShift = gl_FragCoord.y;
+ if (mod(gl_FragCoord.x, 6.0) >= 3.0) {
+ vShift += 2.0;
+ }
+
+ lowp vec3 r = vec3(0.95, 0.0, 0.2);
+ lowp vec3 g = vec3(0.2, 0.95, 0.0);
+ lowp vec3 b = vec3(0.0, 0.2, 0.95);
+ int channel = int(floor(mod(gl_FragCoord.x, 3.0)));
+ lowp vec4 crt = vec4(r[channel], g[channel], b[channel], 1.0);
+ crt *= clamp(floor(mod(vShift, 4.0)), 0.0, 1.0);
+
+ color = (crt * color * 1.25) + 0.05;
+#endif
+
+ gl_FragColor = color;
+}
diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTest.java b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTest.java
new file mode 100644
index 0000000..6803fbb
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.shaderstest;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ShadersTest extends Activity {
+
+ private ShadersTestView mView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mView = new ShadersTestView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mView.resume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mView.pause();
+ }
+}
diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestRS.java b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestRS.java
new file mode 100644
index 0000000..dad97e2
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestRS.java
@@ -0,0 +1,202 @@
+/*
+ * 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.shaderstest;
+
+import android.content.res.Resources;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Element.DataKind;
+import android.renderscript.Element.DataType;
+import android.renderscript.FileA3D;
+import android.renderscript.Mesh;
+import android.renderscript.Program;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramFragmentFixedFunction;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.renderscript.ProgramVertex;
+import android.renderscript.ProgramVertexFixedFunction;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.RenderScriptGL;
+import android.renderscript.Sampler;
+import android.renderscript.Type.Builder;
+
+@SuppressWarnings({"FieldCanBeLocal"})
+public class ShadersTestRS {
+ public ShadersTestRS() {
+ }
+
+ public void init(RenderScriptGL rs, Resources res) {
+ mRS = rs;
+ mRes = res;
+ initRS();
+ }
+
+ public void surfaceChanged() {
+ initBuffers(mRS.getWidth(), mRS.getHeight());
+ }
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ private Sampler mLinearClamp;
+ private Sampler mNearestClamp;
+ private ProgramStore mPSBackground;
+ private ProgramFragment mPFBackground;
+ private ProgramVertex mPVBackground;
+ private ProgramVertexFixedFunction.Constants mPVA;
+
+ private ProgramFragment mPFVignette;
+ private ScriptField_VignetteConstants_s mFSVignetteConst;
+
+ private Allocation mMeshTexture;
+ private Allocation mScreen;
+ private Allocation mScreenDepth;
+
+ private ScriptField_MeshInfo mMeshes;
+ private ScriptC_shaderstest mScript;
+
+
+ public void onActionDown(float x, float y) {
+ mScript.invoke_onActionDown(x, y);
+ }
+
+ public void onActionScale(float scale) {
+ mScript.invoke_onActionScale(scale);
+ }
+
+ public void onActionMove(float x, float y) {
+ mScript.invoke_onActionMove(x, y);
+ }
+
+ private void initPFS() {
+ ProgramStore.Builder b = new ProgramStore.Builder(mRS);
+
+ b.setDepthFunc(DepthFunc.LESS);
+ b.setDitherEnabled(false);
+ b.setDepthMaskEnabled(true);
+ mPSBackground = b.create();
+
+ mScript.set_gPFSBackground(mPSBackground);
+ }
+
+ private void initPF() {
+ mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
+ mScript.set_gLinear(mLinearClamp);
+
+ mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
+ mScript.set_gNearest(mNearestClamp);
+
+ ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
+ b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+ ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+ mPFBackground = b.create();
+ mPFBackground.bindSampler(mLinearClamp, 0);
+ mScript.set_gPFBackground(mPFBackground);
+
+ mFSVignetteConst = new ScriptField_VignetteConstants_s(mRS, 1);
+ mScript.bind_gFSVignetteConstants(mFSVignetteConst);
+
+ ProgramFragment.Builder fs;
+
+ fs = new ProgramFragment.Builder(mRS);
+ fs.setShader(mRes, R.raw.vignette_fs);
+ fs.addConstant(mFSVignetteConst.getAllocation().getType());
+ fs.addTexture(Program.TextureType.TEXTURE_2D);
+ mPFVignette = fs.create();
+ mPFVignette.bindConstants(mFSVignetteConst.getAllocation(), 0);
+ mScript.set_gPFVignette(mPFVignette);
+ }
+
+ private void initPV() {
+ ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
+ mPVBackground = pvb.create();
+
+ mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+ ((ProgramVertexFixedFunction) mPVBackground).bindConstants(mPVA);
+
+ mScript.set_gPVBackground(mPVBackground);
+ }
+
+ private void loadImage() {
+ mMeshTexture = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
+ Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ mScript.set_gTMesh(mMeshTexture);
+ }
+
+ private void initMeshes(FileA3D model) {
+ int numEntries = model.getIndexEntryCount();
+ int numMeshes = 0;
+ for (int i = 0; i < numEntries; i ++) {
+ FileA3D.IndexEntry entry = model.getIndexEntry(i);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ numMeshes ++;
+ }
+ }
+
+ if (numMeshes > 0) {
+ mMeshes = new ScriptField_MeshInfo(mRS, numMeshes);
+
+ for (int i = 0; i < numEntries; i ++) {
+ FileA3D.IndexEntry entry = model.getIndexEntry(i);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ Mesh mesh = entry.getMesh();
+ mMeshes.set_mMesh(i, mesh, false);
+ mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false);
+ }
+ }
+ mMeshes.copyAll();
+ } else {
+ throw new RSRuntimeException("No valid meshes in file");
+ }
+
+ mScript.bind_gMeshes(mMeshes);
+ mScript.invoke_updateMeshInfo();
+ }
+
+ private void initRS() {
+ mScript = new ScriptC_shaderstest(mRS, mRes, R.raw.shaderstest);
+
+ initPFS();
+ initPF();
+ initPV();
+
+ loadImage();
+
+ initBuffers(1, 1);
+
+ FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
+ initMeshes(model);
+
+ mRS.bindRootScript(mScript);
+ }
+
+ private void initBuffers(int width, int height) {
+ Builder b;
+ b = new Builder(mRS, Element.RGBA_8888(mRS));
+ b.setX(width).setY(height);
+ mScreen = Allocation.createTyped(mRS, b.create(),
+ Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+ mScript.set_gScreen(mScreen);
+
+ b = new Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16, DataKind.PIXEL_DEPTH));
+ b.setX(width).setY(height);
+ mScreenDepth = Allocation.createTyped(mRS, b.create(),
+ Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+ mScript.set_gScreenDepth(mScreenDepth);
+ }
+}
diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestView.java b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestView.java
new file mode 100644
index 0000000..e0a540f
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestView.java
@@ -0,0 +1,138 @@
+/*
+ * 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.shaderstest;
+
+import android.content.Context;
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScriptGL;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.SurfaceHolder;
+
+public class ShadersTestView extends RSSurfaceView {
+
+ private RenderScriptGL mRS;
+ private ShadersTestRS mRender;
+
+ private ScaleGestureDetector mScaleDetector;
+
+ private static final int INVALID_POINTER_ID = -1;
+ private int mActivePointerId = INVALID_POINTER_ID;
+
+ public ShadersTestView(Context context) {
+ super(context);
+ ensureRenderScript();
+ mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+ }
+
+ private void ensureRenderScript() {
+ if (mRS == null) {
+ RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+ sc.setDepth(16, 24);
+ mRS = createRenderScriptGL(sc);
+ mRender = new ShadersTestRS();
+ mRender.init(mRS, getResources());
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ ensureRenderScript();
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+ mRender.surfaceChanged();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ mRender = null;
+ if (mRS != null) {
+ mRS = null;
+ destroyRenderScriptGL();
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ mScaleDetector.onTouchEvent(ev);
+
+ boolean ret = false;
+ float x = ev.getX();
+ float y = ev.getY();
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(0);
+ ret = true;
+ break;
+ }
+ case MotionEvent.ACTION_MOVE: {
+ if (!mScaleDetector.isInProgress()) {
+ mRender.onActionMove(x, y);
+ }
+ mRender.onActionDown(x, y);
+ ret = true;
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ x = ev.getX(newPointerIndex);
+ y = ev.getY(newPointerIndex);
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ }
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+ private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ mRender.onActionScale(detector.getScaleFactor());
+ return true;
+ }
+ }
+}
+
+
diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
new file mode 100644
index 0000000..53f10f9
--- /dev/null
+++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
@@ -0,0 +1,193 @@
+// 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.shaderstest)
+
+#include "rs_graphics.rsh"
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+typedef struct VignetteConstants_s {
+ float size;
+ float feather;
+ float width;
+ float height;
+} VignetteConstants;
+VignetteConstants *gFSVignetteConstants;
+rs_program_fragment gPFVignette;
+
+rs_allocation gTMesh;
+
+rs_sampler gLinear;
+rs_sampler gNearest;
+
+rs_program_store gPFSBackground;
+
+rs_allocation gScreenDepth;
+rs_allocation gScreen;
+
+typedef struct MeshInfo {
+ rs_mesh mMesh;
+ int mNumIndexSets;
+ float3 bBoxMin;
+ float3 bBoxMax;
+} MeshInfo_t;
+MeshInfo_t *gMeshes;
+
+static float3 gLookAt;
+
+static float gRotateX;
+static float gRotateY;
+static float gZoom;
+
+static float gLastX;
+static float gLastY;
+
+void onActionDown(float x, float y) {
+ gLastX = x;
+ gLastY = y;
+}
+
+void onActionScale(float scale) {
+
+ gZoom *= 1.0f / scale;
+ gZoom = max(0.1f, min(gZoom, 500.0f));
+}
+
+void onActionMove(float x, float y) {
+ float dx = gLastX - x;
+ float dy = gLastY - y;
+
+ if (fabs(dy) <= 2.0f) {
+ dy = 0.0f;
+ }
+ if (fabs(dx) <= 2.0f) {
+ dx = 0.0f;
+ }
+
+ gRotateY -= dx;
+ if (gRotateY > 360) {
+ gRotateY -= 360;
+ }
+ if (gRotateY < 0) {
+ gRotateY += 360;
+ }
+
+ gRotateX -= dy;
+ gRotateX = min(gRotateX, 80.0f);
+ gRotateX = max(gRotateX, -80.0f);
+
+ gLastX = x;
+ gLastY = y;
+}
+
+void init() {
+ gRotateX = 0.0f;
+ gRotateY = 0.0f;
+ gZoom = 50.0f;
+ gLookAt = 0.0f;
+}
+
+void updateMeshInfo() {
+ rs_allocation allMeshes = rsGetAllocation(gMeshes);
+ int size = rsAllocationGetDimX(allMeshes);
+ gLookAt = 0.0f;
+ float minX, minY, minZ, maxX, maxY, maxZ;
+ for (int i = 0; i < size; i++) {
+ MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
+ rsgMeshComputeBoundingBox(info->mMesh,
+ &minX, &minY, &minZ,
+ &maxX, &maxY, &maxZ);
+ info->bBoxMin = (minX, minY, minZ);
+ info->bBoxMax = (maxX, maxY, maxZ);
+ gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
+ }
+ gLookAt = gLookAt / (float)size;
+}
+
+static void renderAllMeshes() {
+ rs_allocation allMeshes = rsGetAllocation(gMeshes);
+ int size = rsAllocationGetDimX(allMeshes);
+ gLookAt = 0.0f;
+ float minX, minY, minZ, maxX, maxY, maxZ;
+ for (int i = 0; i < size; i++) {
+ MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
+ rsgDrawMesh(info->mMesh);
+ }
+}
+
+static void renderOffscreen() {
+ rsgBindProgramVertex(gPVBackground);
+ rs_matrix4x4 proj;
+ float aspect = (float) rsAllocationGetDimX(gScreen) / (float) rsAllocationGetDimY(gScreen);
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 1000.0f);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
+
+ rsgBindProgramFragment(gPFBackground);
+ rsgBindTexture(gPFBackground, 0, gTMesh);
+
+ rs_matrix4x4 matrix;
+
+ rsMatrixLoadIdentity(&matrix);
+ rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
+ rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
+ rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
+ rsgProgramVertexLoadModelMatrix(&matrix);
+
+ renderAllMeshes();
+}
+
+static void drawOffscreenResult(int posX, int posY, float width, float height) {
+ // display the result d
+ rs_matrix4x4 proj, matrix;
+ rsMatrixLoadOrtho(&proj, 0, width, height, 0, -500, 500);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
+ rsMatrixLoadIdentity(&matrix);
+ rsgProgramVertexLoadModelMatrix(&matrix);
+ float startX = posX, startY = posY;
+ rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
+ startX, startY + height, 0, 0, 0,
+ startX + width, startY + height, 0, 1, 0,
+ startX + width, startY, 0, 1, 1);
+}
+
+int root(void) {
+ gFSVignetteConstants->size = 0.58f * 0.58f;
+ gFSVignetteConstants->feather = 0.2f;
+ gFSVignetteConstants->width = (float) rsAllocationGetDimX(gScreen);
+ gFSVignetteConstants->height = (float) rsAllocationGetDimY(gScreen);
+
+ rsgBindProgramStore(gPFSBackground);
+
+ // Render scene to fullscreenbuffer
+ rsgBindColorTarget(gScreen, 0);
+ rsgBindDepthTarget(gScreenDepth);
+ rsgClearDepth(1.0f);
+ rsgClearColor(1.0f, 1.0f, 1.0f, 0.0f);
+ renderOffscreen();
+
+ // Render on screen
+ rsgClearAllRenderTargets();
+ rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgClearDepth(1.0f);
+
+ rsgBindProgramFragment(gPFVignette);
+ rsgBindTexture(gPFVignette, 0, gScreen);
+ drawOffscreenResult(0, 0, rsgGetWidth(), rsgGetHeight());
+
+ return 0;
+}
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 3b043b3..bfc4d5e 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -203,70 +203,42 @@
private native static boolean doBooleanCommand(String command);
- //STOPSHIP: remove this after native interface works and replace all
- //calls to doBooleanTempCommand() with doBooleanCommand()
- private static boolean doBooleanTempCommand(String command) {
- try {
- String str = "/system/bin/wpa_cli " + command;
- Log.e("WifiNative", "===> " + str);
- Runtime.getRuntime()
- .exec(str).waitFor();
- } catch (Exception e) {
- Log.e("WifiNative", "exception with doBooleanTempCommand");
- return false;
- }
- return true;
- }
-
- private static String doStringTempCommand(String command) {
- String lines[] = null;
- try {
- String str = "/system/bin/wpa_cli " + command;
- Log.e("WifiNative", "===> " + str);
- Process p = Runtime.getRuntime()
- .exec(str);
- InputStream in = p.getInputStream();
- p.waitFor();
- byte[] bytes=new byte[in.available()];
- in.read(bytes);
- String s = new String(bytes);
- Log.e("WifiNative", "====> doString: " + s);
- lines = s.split("\\r?\\n");
- } catch (Exception e) {
- Log.e("WifiNative", "exception with doBooleanTempCommand");
- return null;
- }
- return lines[1];
- }
-
private native static int doIntCommand(String command);
private native static String doStringCommand(String command);
+ public static boolean wpsPbc() {
+ return doBooleanCommand("WPS_PBC");
+ }
+
+ public static boolean wpsPin(String pin) {
+ return doBooleanCommand("WPS_PIN any " + pin);
+ }
+
public static boolean p2pFind() {
- return doBooleanTempCommand("p2p_find");
+ return doBooleanCommand("P2P_FIND");
}
public static boolean p2pFind(int timeout) {
if (timeout <= 0) {
return p2pFind();
}
- return doBooleanTempCommand("p2p_find " + timeout);
+ return doBooleanCommand("P2P_FIND " + timeout);
}
public static boolean p2pListen() {
- return doBooleanTempCommand("p2p_listen");
+ return doBooleanCommand("P2P_LISTEN");
}
public static boolean p2pListen(int timeout) {
if (timeout <= 0) {
return p2pListen();
}
- return doBooleanTempCommand("p2p_listen " + timeout);
+ return doBooleanCommand("P2P_LISTEN " + timeout);
}
public static boolean p2pFlush() {
- return doBooleanTempCommand("p2p_flush");
+ return doBooleanCommand("P2P_FLUSH");
}
/* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
@@ -300,41 +272,36 @@
if (config.isPersistent) args.add("persistent");
if (config.joinExistingGroup) args.add("join");
- args.add("go_intent=" + config.groupOwnerIntent);
+ int groupOwnerIntent = config.groupOwnerIntent;
+ if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
+ groupOwnerIntent = 3; //default value
+ }
+ args.add("go_intent=" + groupOwnerIntent);
if (config.channel > 0) args.add("freq=" + config.channel);
- String command = "p2p_connect ";
+ String command = "P2P_CONNECT ";
for (String s : args) command += s + " ";
- return doStringTempCommand(command);
+ return doStringCommand(command);
}
public static boolean p2pGroupAdd() {
- return doBooleanTempCommand("p2p_group_add");
+ return doBooleanCommand("P2P_GROUP_ADD");
}
public static boolean p2pGroupRemove(String iface) {
if (iface == null) return false;
- return doBooleanTempCommand("p2p_group_remove " + iface);
+ return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
}
public static boolean p2pReject(String deviceAddress) {
- return doBooleanTempCommand("p2p_reject " + deviceAddress);
+ return doBooleanCommand("P2P_REJECT " + deviceAddress);
}
/* Invite a peer to a group */
public static boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
if (group == null || deviceAddress == null) return false;
- return doBooleanTempCommand("p2p_invite group=" + group.getInterface()
+ return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
+ " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
}
-
- public static boolean p2pWpsPbc() {
- return doBooleanTempCommand("wps_pbc");
- }
-
- public static boolean p2pWpsPin(String pin) {
- return doBooleanTempCommand("wps_pin any " + pin);
- }
-
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index fff5ee3..b77fd76 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -46,8 +46,10 @@
* This is an integer value between 0 and 15 where 0 indicates the least
* inclination to be a group owner and 15 indicates the highest inclination
* to be a group owner.
+ *
+ * A value of -1 indicates the system can choose an appropriate value.
*/
- public int groupOwnerIntent;
+ public int groupOwnerIntent = -1;
public boolean isPersistent;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 176191e..49ce124 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -767,10 +767,10 @@
notifyP2pProvDiscPinRequest((WifiP2pDevice) message.obj);
break;
case WifiP2pManager.WPS_PBC:
- WifiNative.p2pWpsPbc();
+ WifiNative.wpsPbc();
break;
case WifiP2pManager.WPS_PIN:
- WifiNative.p2pWpsPin((String) message.obj);
+ WifiNative.wpsPin((String) message.obj);
break;
default:
return NOT_HANDLED;