summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/16.txt2
-rw-r--r--api/current.txt31
-rw-r--r--cmds/stagefright/codec.cpp57
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java2
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java20
-rw-r--r--core/java/android/accounts/AbstractAccountAuthenticator.java2
-rw-r--r--core/java/android/animation/Animator.java4
-rwxr-xr-xcore/java/android/animation/ValueAnimator.java2
-rw-r--r--core/java/android/app/Activity.java4
-rw-r--r--core/java/android/app/Dialog.java2
-rw-r--r--core/java/android/app/PendingIntent.java2
-rw-r--r--core/java/android/app/Service.java2
-rw-r--r--core/java/android/app/admin/DeviceAdminReceiver.java2
-rw-r--r--core/java/android/bluetooth/AtCommandResult.java2
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java2
-rw-r--r--core/java/android/bluetooth/BluetoothPbap.java2
-rw-r--r--core/java/android/content/ContentResolver.java2
-rw-r--r--core/java/android/content/Context.java8
-rw-r--r--core/java/android/content/Intent.java24
-rw-r--r--core/java/android/content/pm/PackageManager.java4
-rw-r--r--core/java/android/content/pm/PackageParser.java45
-rw-r--r--core/java/android/emoji/EmojiFactory.java2
-rw-r--r--core/java/android/hardware/Camera.java4
-rw-r--r--core/java/android/hardware/Sensor.java4
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java2
-rw-r--r--core/java/android/net/NetworkPolicy.java37
-rw-r--r--core/java/android/net/NetworkPolicyManager.java6
-rw-r--r--core/java/android/net/http/SslError.java2
-rw-r--r--core/java/android/os/Parcel.java224
-rw-r--r--core/java/android/os/ParcelUuid.java2
-rw-r--r--core/java/android/os/Trace.java94
-rw-r--r--core/java/android/provider/Contacts.java2
-rw-r--r--core/java/android/provider/MediaStore.java6
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/server/BluetoothBondState.java2
-rw-r--r--core/java/android/text/method/BaseMovementMethod.java2
-rw-r--r--core/java/android/view/Choreographer.java187
-rw-r--r--core/java/android/view/DisplayList.java200
-rw-r--r--core/java/android/view/GLES20DisplayList.java245
-rw-r--r--core/java/android/view/Gravity.java61
-rw-r--r--core/java/android/view/HardwareLayer.java19
-rw-r--r--core/java/android/view/View.java392
-rw-r--r--core/java/android/view/ViewConfiguration.java3
-rw-r--r--core/java/android/view/ViewDebug.java6
-rw-r--r--core/java/android/view/ViewGroup.java16
-rw-r--r--core/java/android/view/ViewPropertyAnimator.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java39
-rw-r--r--core/java/android/view/WindowManager.java8
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java28
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java2
-rw-r--r--core/java/android/view/accessibility/AccessibilityRecord.java2
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java3
-rw-r--r--core/java/android/view/textservice/SpellCheckerInfo.java4
-rw-r--r--core/java/android/webkit/AutoCompletePopup.java252
-rw-r--r--core/java/android/webkit/CallbackProxy.java13
-rw-r--r--core/java/android/webkit/URLUtil.java2
-rw-r--r--core/java/android/webkit/WebViewClassic.java207
-rw-r--r--core/java/android/webkit/WebViewClient.java6
-rw-r--r--core/java/android/webkit/WebViewCore.java67
-rw-r--r--core/java/android/widget/CheckedTextView.java10
-rw-r--r--core/java/android/widget/ExpandableListView.java2
-rw-r--r--core/java/android/widget/GridView.java2
-rw-r--r--core/java/android/widget/HorizontalScrollView.java6
-rw-r--r--core/java/android/widget/ImageView.java3
-rw-r--r--core/java/android/widget/ListPopupWindow.java2
-rw-r--r--core/java/android/widget/ProgressBar.java3
-rw-r--r--core/java/android/widget/RadioButton.java10
-rw-r--r--core/java/android/widget/ScrollView.java4
-rw-r--r--core/java/android/widget/SimpleAdapter.java2
-rw-r--r--core/java/android/widget/SimpleCursorAdapter.java2
-rw-r--r--core/java/android/widget/SimpleCursorTreeAdapter.java2
-rw-r--r--core/java/android/widget/Spinner.java172
-rw-r--r--core/java/android/widget/Switch.java36
-rw-r--r--core/java/android/widget/TextView.java43
-rw-r--r--core/java/android/widget/ToggleButton.java10
-rw-r--r--core/java/com/android/internal/util/AsyncService.java2
-rw-r--r--core/java/com/android/internal/util/StateMachine.java2
-rw-r--r--core/java/com/android/internal/widget/SlidingTab.java2
-rw-r--r--core/jni/Android.mk2
-rw-r--r--core/jni/AndroidRuntime.cpp4
-rw-r--r--core/jni/android/graphics/Camera.cpp18
-rw-r--r--core/jni/android_media_AudioRecord.cpp2
-rw-r--r--core/jni/android_media_AudioTrack.cpp4
-rw-r--r--core/jni/android_os_Parcel.cpp289
-rw-r--r--core/jni/android_os_Trace.cpp72
-rw-r--r--core/jni/android_view_GLES20DisplayList.cpp227
-rw-r--r--core/jni/android_view_Surface.cpp2
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--core/res/res/anim/screen_rotate_180_enter.xml2
-rw-r--r--core/res/res/anim/screen_rotate_180_exit.xml2
-rw-r--r--core/res/res/anim/screen_rotate_180_frame.xml2
-rw-r--r--core/res/res/anim/screen_rotate_finish_enter.xml2
-rw-r--r--core/res/res/anim/screen_rotate_finish_exit.xml4
-rw-r--r--core/res/res/anim/screen_rotate_minus_90_enter.xml36
-rw-r--r--core/res/res/anim/screen_rotate_minus_90_exit.xml43
-rw-r--r--core/res/res/anim/screen_rotate_minus_90_frame.xml2
-rw-r--r--core/res/res/anim/screen_rotate_plus_90_enter.xml36
-rw-r--r--core/res/res/anim/screen_rotate_plus_90_exit.xml43
-rw-r--r--core/res/res/anim/screen_rotate_plus_90_frame.xml2
-rw-r--r--core/res/res/layout/action_bar_title_item.xml2
-rw-r--r--core/res/res/layout/dialog_custom_title.xml2
-rw-r--r--core/res/res/layout/dialog_custom_title_holo.xml2
-rw-r--r--core/res/res/layout/screen_custom_title.xml2
-rw-r--r--core/res/res/values-af/strings.xml2
-rw-r--r--core/res/res/values-am/strings.xml4
-rw-r--r--core/res/res/values-in/strings.xml52
-rwxr-xr-xcore/res/res/values/config.xml2
-rwxr-xr-xcore/res/res/values/strings.xml9
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java27
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java22
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java46
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java101
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java6
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java9
-rw-r--r--core/tests/coretests/src/android/util/ListScenario.java2
-rw-r--r--core/tests/coretests/src/android/view/GravityTest.java74
-rw-r--r--core/tests/coretests/src/android/view/ViewAttachTest.java6
-rw-r--r--data/etc/platform.xml4
-rw-r--r--drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h8
-rw-r--r--drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngineConst.h37
-rw-r--r--drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp63
-rw-r--r--drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c9
-rw-r--r--graphics/java/android/graphics/Camera.java21
-rw-r--r--graphics/java/android/graphics/RectF.java2
-rw-r--r--graphics/java/android/graphics/Typeface.java78
-rw-r--r--graphics/java/android/graphics/drawable/ClipDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java4
-rw-r--r--graphics/java/android/graphics/drawable/ScaleDrawable.java1
-rw-r--r--include/media/AudioRecord.h8
-rw-r--r--include/media/AudioTrack.h12
-rw-r--r--include/media/IAudioFlinger.h5
-rw-r--r--libs/androidfw/ResourceTypes.cpp89
-rw-r--r--libs/hwui/DisplayListRenderer.cpp346
-rw-r--r--libs/hwui/DisplayListRenderer.h272
-rw-r--r--libs/hwui/OpenGLRenderer.cpp22
-rw-r--r--libs/rs/Android.mk71
-rw-r--r--libs/rs/RenderScript.cpp1
-rw-r--r--libs/rs/RenderScript.h2
-rw-r--r--libs/rs/driver/rsdGL.cpp1
-rw-r--r--libs/rs/rs.h8
-rw-r--r--libs/rs/rsAdapter.cpp1
-rw-r--r--libs/rs/rsAllocation.cpp2
-rw-r--r--libs/rs/rsAnimation.h2
-rw-r--r--libs/rs/rsComponent.h1
-rw-r--r--libs/rs/rsContext.cpp2
-rw-r--r--libs/rs/rsContext.h12
-rw-r--r--libs/rs/rsElement.h1
-rw-r--r--libs/rs/rsFileA3D.cpp2
-rw-r--r--libs/rs/rsFileA3D.h1
-rw-r--r--libs/rs/rsFont.cpp3
-rw-r--r--libs/rs/rsFont.h1
-rw-r--r--libs/rs/rsMesh.cpp2
-rw-r--r--libs/rs/rsMesh.h2
-rw-r--r--libs/rs/rsObjectBase.h1
-rw-r--r--libs/rs/rsPath.cpp1
-rw-r--r--libs/rs/rsPath.h2
-rw-r--r--libs/rs/rsProgramVertex.cpp1
-rw-r--r--libs/rs/rsSampler.cpp2
-rw-r--r--libs/rs/rsSampler.h1
-rw-r--r--libs/rs/rsScriptC_Lib.cpp1
-rw-r--r--libs/rs/rsScriptC_LibGL.cpp2
-rw-r--r--libs/rs/rsThreadIO.cpp2
-rw-r--r--libs/rs/rsType.cpp82
-rw-r--r--libs/rs/rsType.h40
-rw-r--r--libs/rs/rsUtils.h2
-rw-r--r--libs/rs/rsg_generator.c3
-rw-r--r--media/java/android/media/MediaCodec.java33
-rw-r--r--media/java/android/media/MediaExtractor.java2
-rw-r--r--media/java/android/media/MediaPlayer.java7
-rw-r--r--media/java/android/media/MediaRecorder.java2
-rw-r--r--media/jni/android_media_MediaCodec.cpp2
-rw-r--r--media/jni/android_media_MediaExtractor.cpp35
-rw-r--r--media/jni/soundpool/SoundPool.cpp5
-rw-r--r--media/libmedia/AudioRecord.cpp4
-rw-r--r--media/libmedia/AudioTrack.cpp17
-rw-r--r--media/libmedia/IAudioFlinger.cpp6
-rw-r--r--media/libmedia/JetPlayer.cpp2
-rw-r--r--media/libmedia/ToneGenerator.cpp2
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp4
-rw-r--r--media/libstagefright/AudioPlayer.cpp11
-rw-r--r--media/libstagefright/AudioSource.cpp5
-rw-r--r--media/libstagefright/WAVExtractor.cpp82
-rw-r--r--media/libstagefright/codecs/aacenc/src/adj_thr.c4
-rw-r--r--media/libstagefright/codecs/amrwbenc/inc/basic_op.h4
-rw-r--r--media/libstagefright/foundation/AMessage.cpp6
-rw-r--r--media/libstagefright/include/WAVExtractor.h1
-rw-r--r--packages/SettingsProvider/res/values-in/strings.xml2
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar.xml8
-rw-r--r--packages/SystemUI/res/layout/navigation_bar.xml8
-rw-r--r--packages/SystemUI/res/values-in/strings.xml4
-rw-r--r--packages/SystemUI/res/values-sw600dp-port/dimens.xml6
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml6
-rw-r--r--packages/SystemUI/res/values-sw720dp/dimens.xml6
-rw-r--r--packages/SystemUI/res/values/dimens.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java22
-rw-r--r--services/audioflinger/AudioFlinger.cpp270
-rw-r--r--services/audioflinger/AudioFlinger.h98
-rw-r--r--services/audioflinger/AudioPolicyService.cpp8
-rw-r--r--services/audioflinger/AudioPolicyService.h8
-rw-r--r--services/input/InputDispatcher.cpp44
-rw-r--r--services/input/InputDispatcher.h4
-rw-r--r--services/java/com/android/server/NetworkManagementService.java1
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java23
-rw-r--r--services/java/com/android/server/wm/ScreenRotationAnimation.java14
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java10
-rw-r--r--services/java/com/android/server/wm/WindowState.java31
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java63
-rw-r--r--telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java56
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java78
-rw-r--r--tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.pngbin0 -> 23004 bytes
-rw-r--r--tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java24
-rw-r--r--tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs163
-rw-r--r--tools/aapt/Command.cpp12
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java9
-rw-r--r--wifi/java/android/net/wifi/WifiWatchdogStateMachine.java180
217 files changed, 4716 insertions, 1790 deletions
diff --git a/api/16.txt b/api/16.txt
index 6543ab0..8ff7675 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -10771,8 +10771,6 @@ package android.media {
method public void setAudioEncodingBitRate(int);
method public void setAudioSamplingRate(int);
method public void setAudioSource(int) throws java.lang.IllegalStateException;
- method public deprecated void setAuxiliaryOutputFile(java.io.FileDescriptor);
- method public deprecated void setAuxiliaryOutputFile(java.lang.String);
method public void setCamera(android.hardware.Camera);
method public void setCaptureRate(double);
method public void setLocation(float, float);
diff --git a/api/current.txt b/api/current.txt
index 77c9f6e..92c309c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -76,6 +76,7 @@ package android {
field public static final java.lang.String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
field public static final java.lang.String READ_CALENDAR = "android.permission.READ_CALENDAR";
field public static final java.lang.String READ_CONTACTS = "android.permission.READ_CONTACTS";
+ field public static final java.lang.String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
field public static final java.lang.String READ_HISTORY_BOOKMARKS = "com.android.browser.permission.READ_HISTORY_BOOKMARKS";
field public static final java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
@@ -8034,6 +8035,9 @@ package android.graphics {
ctor public Camera();
method public void applyToCanvas(android.graphics.Canvas);
method public float dotWithNormal(float, float, float);
+ method public float getLocationX();
+ method public float getLocationY();
+ method public float getLocationZ();
method public void getMatrix(android.graphics.Matrix);
method public void restore();
method public void rotate(float, float, float);
@@ -9065,6 +9069,7 @@ package android.graphics.drawable {
method public int getMinimumWidth();
method public abstract int getOpacity();
method public boolean getPadding(android.graphics.Rect);
+ method public int getResolvedLayoutDirectionSelf();
method public int[] getState();
method public android.graphics.Region getTransparentRegion();
method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
@@ -9099,6 +9104,10 @@ package android.graphics.drawable {
method public abstract void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
}
+ public static abstract interface Drawable.Callback2 implements android.graphics.drawable.Drawable.Callback {
+ method public abstract int getResolvedLayoutDirection(android.graphics.drawable.Drawable);
+ }
+
public static abstract class Drawable.ConstantState {
ctor public Drawable.ConstantState();
method public abstract int getChangingConfigurations();
@@ -10930,8 +10939,6 @@ package android.media {
method public void setAudioEncodingBitRate(int);
method public void setAudioSamplingRate(int);
method public void setAudioSource(int) throws java.lang.IllegalStateException;
- method public deprecated void setAuxiliaryOutputFile(java.io.FileDescriptor);
- method public deprecated void setAuxiliaryOutputFile(java.lang.String);
method public void setCamera(android.hardware.Camera);
method public void setCaptureRate(double);
method public void setLocation(float, float);
@@ -22100,8 +22107,11 @@ package android.view {
public class Gravity {
ctor public Gravity();
method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect);
+ method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect);
+ method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect);
+ method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
method public static int getAbsoluteGravity(int, int);
method public static boolean isHorizontal(int);
method public static boolean isVertical(int);
@@ -23109,7 +23119,7 @@ package android.view {
method public void recycle();
}
- public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+ public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.graphics.drawable.Drawable.Callback2 android.view.KeyEvent.Callback {
ctor public View(android.content.Context);
ctor public View(android.content.Context, android.util.AttributeSet);
ctor public View(android.content.Context, android.util.AttributeSet, int);
@@ -23119,6 +23129,7 @@ package android.view {
method public void addOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
+ method public void announceForAccessibility(java.lang.CharSequence);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -23188,6 +23199,7 @@ package android.view {
method public final int getBottom();
method protected float getBottomFadingEdgeStrength();
method protected int getBottomPaddingOffset();
+ method public float getCameraDistance();
method public java.lang.CharSequence getContentDescription();
method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
@@ -24343,6 +24355,7 @@ package android.view.accessibility {
field public static final int INVALID_POSITION = -1; // 0xffffffff
field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+ field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40
field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
@@ -27495,9 +27508,19 @@ package android.widget {
ctor public Spinner(android.content.Context, android.util.AttributeSet);
ctor public Spinner(android.content.Context, android.util.AttributeSet, int);
ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int);
+ method public int getDropDownHorizontalOffset();
+ method public int getDropDownVerticalOffset();
+ method public int getDropDownWidth();
+ method public int getGravity();
+ method public android.graphics.drawable.Drawable getPopupBackground();
method public java.lang.CharSequence getPrompt();
method public void onClick(android.content.DialogInterface, int);
+ method public void setDropDownHorizontalOffset(int);
+ method public void setDropDownVerticalOffset(int);
+ method public void setDropDownWidth(int);
method public void setGravity(int);
+ method public void setPopupBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public void setPopupBackgroundResource(int);
method public void setPrompt(java.lang.CharSequence);
method public void setPromptId(int);
field public static final int MODE_DIALOG = 0; // 0x0
@@ -27534,8 +27557,10 @@ package android.widget {
method public void setTextOff(java.lang.CharSequence);
method public void setTextOn(java.lang.CharSequence);
method public void setThumbDrawable(android.graphics.drawable.Drawable);
+ method public void setThumbResource(int);
method public void setThumbTextPadding(int);
method public void setTrackDrawable(android.graphics.drawable.Drawable);
+ method public void setTrackResource(int);
}
public class TabHost extends android.widget.FrameLayout implements android.view.ViewTreeObserver.OnTouchModeChangeListener {
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index 0414b98..fea62cc 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -49,6 +49,7 @@ struct CodecState {
size_t mCSDIndex;
Vector<sp<ABuffer> > mInBuffers;
Vector<sp<ABuffer> > mOutBuffers;
+ bool mSignalledInputEOS;
bool mSawOutputEOS;
int64_t mNumBuffersDecoded;
int64_t mNumBytesDecoded;
@@ -127,6 +128,7 @@ static int decode(
}
state->mCSDIndex = 0;
+ state->mSignalledInputEOS = false;
state->mSawOutputEOS = false;
ALOGV("got %d pieces of codec specific data.", state->mCSD.size());
@@ -180,33 +182,7 @@ static int decode(
status_t err = extractor->getSampleTrackIndex(&trackIndex);
if (err != OK) {
- ALOGV("signalling EOS.");
-
- for (size_t i = 0; i < stateByTrack.size(); ++i) {
- CodecState *state = &stateByTrack.editValueAt(i);
-
- for (;;) {
- size_t index;
- err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
-
- if (err == -EAGAIN) {
- continue;
- }
-
- CHECK_EQ(err, (status_t)OK);
-
- err = state->mCodec->queueInputBuffer(
- index,
- 0 /* offset */,
- 0 /* size */,
- 0ll /* timeUs */,
- MediaCodec::BUFFER_FLAG_EOS);
-
- CHECK_EQ(err, (status_t)OK);
- break;
- }
- }
-
+ ALOGV("saw input eos");
sawInputEOS = true;
} else {
CodecState *state = &stateByTrack.editValueFor(trackIndex);
@@ -240,6 +216,33 @@ static int decode(
CHECK_EQ(err, -EAGAIN);
}
}
+ } else {
+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
+ CodecState *state = &stateByTrack.editValueAt(i);
+
+ if (!state->mSignalledInputEOS) {
+ size_t index;
+ status_t err =
+ state->mCodec->dequeueInputBuffer(&index, kTimeout);
+
+ if (err == OK) {
+ ALOGV("signalling input EOS on track %d", i);
+
+ err = state->mCodec->queueInputBuffer(
+ index,
+ 0 /* offset */,
+ 0 /* size */,
+ 0ll /* timeUs */,
+ MediaCodec::BUFFER_FLAG_EOS);
+
+ CHECK_EQ(err, (status_t)OK);
+
+ state->mSignalledInputEOS = true;
+ } else {
+ CHECK_EQ(err, -EAGAIN);
+ }
+ }
+ }
}
bool sawOutputEOSOnAllTracks = true;
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index a463a62..9ebbe03 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -104,7 +104,7 @@ import com.android.internal.os.HandlerCaller;
* </ul>
* <h3>Retrieving window content</h3>
* <p>
- * An service can specify in its declaration that it can retrieve the active window
+ * A service can specify in its declaration that it can retrieve the active window
* content which is represented as a tree of {@link AccessibilityNodeInfo}. Note that
* declaring this capability requires that the service declares its configuration via
* an XML resource referenced by {@link #SERVICE_META_DATA}.
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index eae0a4c..b55fda4 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -503,26 +503,38 @@ public class AccessibilityServiceInfo implements Parcelable {
public static String feedbackTypeToString(int feedbackType) {
StringBuilder builder = new StringBuilder();
builder.append("[");
- while (feedbackType > 0) {
+ while (feedbackType != 0) {
final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType);
feedbackType &= ~feedbackTypeFlag;
- if (builder.length() > 1) {
- builder.append(", ");
- }
switch (feedbackTypeFlag) {
case FEEDBACK_AUDIBLE:
+ if (builder.length() > 1) {
+ builder.append(", ");
+ }
builder.append("FEEDBACK_AUDIBLE");
break;
case FEEDBACK_HAPTIC:
+ if (builder.length() > 1) {
+ builder.append(", ");
+ }
builder.append("FEEDBACK_HAPTIC");
break;
case FEEDBACK_GENERIC:
+ if (builder.length() > 1) {
+ builder.append(", ");
+ }
builder.append("FEEDBACK_GENERIC");
break;
case FEEDBACK_SPOKEN:
+ if (builder.length() > 1) {
+ builder.append(", ");
+ }
builder.append("FEEDBACK_SPOKEN");
break;
case FEEDBACK_VISUAL:
+ if (builder.length() > 1) {
+ builder.append(", ");
+ }
builder.append("FEEDBACK_VISUAL");
break;
}
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 7183267..e9535ab 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -59,7 +59,7 @@ import java.util.Arrays;
* "Account & Sync" settings page and one user of the android:smallIcon is the Contact Application's
* tab panels.
* <p>
- * The preferences attribute points to an PreferenceScreen xml hierarchy that contains
+ * The preferences attribute points to a PreferenceScreen xml hierarchy that contains
* a list of PreferenceScreens that can be invoked to manage the authenticator. An example is:
* <pre>
* &lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"&gt;
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index e01fa1a..788765d 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -208,7 +208,7 @@ public abstract class Animator implements Cloneable {
* this call to its child objects to tell them to set up the values. A
* ObjectAnimator object will use the information it has about its target object
* and PropertyValuesHolder objects to get the start values for its properties.
- * An ValueAnimator object will ignore the request since it does not have enough
+ * A ValueAnimator object will ignore the request since it does not have enough
* information (such as a target object) to gather these values.
*/
public void setupStartValues() {
@@ -220,7 +220,7 @@ public abstract class Animator implements Cloneable {
* this call to its child objects to tell them to set up the values. A
* ObjectAnimator object will use the information it has about its target object
* and PropertyValuesHolder objects to get the start values for its properties.
- * An ValueAnimator object will ignore the request since it does not have enough
+ * A ValueAnimator object will ignore the request since it does not have enough
* information (such as a target object) to gather these values.
*/
public void setupEndValues() {
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 954ae66..f69120a 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -400,7 +400,7 @@ public class ValueAnimator extends Animator {
/**
* Sets the values, per property, being animated between. This function is called internally
- * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can
+ * by the constructors of ValueAnimator that take a list of values. But a ValueAnimator can
* be constructed without values and this method can be called to set the values manually
* instead.
*
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index f895431..599487d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -203,8 +203,8 @@ import java.util.HashMap;
* with the user. Between these two methods you can maintain resources that
* are needed to show the activity to the user. For example, you can register
* a {@link android.content.BroadcastReceiver} in onStart() to monitor for changes
- * that impact your UI, and unregister it in onStop() when the user an no
- * longer see what you are displaying. The onStart() and onStop() methods
+ * that impact your UI, and unregister it in onStop() when the user no
+ * longer sees what you are displaying. The onStart() and onStop() methods
* can be called multiple times, as the activity becomes visible and hidden
* to the user.
*
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index f1ce2bb..f04ff6a 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -591,7 +591,7 @@ public class Dialog implements DialogInterface, Window.Callback,
}
/**
- * Called when an key shortcut event is not handled by any of the views in the Dialog.
+ * Called when a key shortcut event is not handled by any of the views in the Dialog.
* Override this method to implement global key shortcuts for the Dialog.
* Key shortcuts can also be implemented by setting the
* {@link MenuItem#setShortcut(char, char) shortcut} property of menu items.
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index b0637a7..c95066c 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -351,7 +351,7 @@ public final class PendingIntent implements Parcelable {
/**
* Cancel a currently active PendingIntent. Only the original application
- * owning an PendingIntent can cancel it.
+ * owning a PendingIntent can cancel it.
*/
public void cancel() {
try {
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index be4b8af..207ae76 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -453,7 +453,7 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
/**
* Called by the system to notify a Service that it is no longer used and is being removed. The
- * service should clean up an resources it holds (threads, registered
+ * service should clean up any resources it holds (threads, registered
* receivers, etc) at this point. Upon return, there will be no more calls
* in to this Service object and it is effectively dead. Do not call this method directly.
*/
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 43cd330..30b65de 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -165,7 +165,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
= "android.app.action.ACTION_PASSWORD_EXPIRING";
/**
- * Name under which an DevicePolicy component publishes information
+ * Name under which a DevicePolicy component publishes information
* about itself. This meta-data must reference an XML resource containing
* a device-admin tag. XXX TO DO: describe syntax.
*/
diff --git a/core/java/android/bluetooth/AtCommandResult.java b/core/java/android/bluetooth/AtCommandResult.java
index 375a6dd..9675234 100644
--- a/core/java/android/bluetooth/AtCommandResult.java
+++ b/core/java/android/bluetooth/AtCommandResult.java
@@ -17,7 +17,7 @@
package android.bluetooth;
/**
- * The result of execution of an single AT command.<p>
+ * The result of execution of a single AT command.<p>
*
*
* This class can represent the final response to an AT command line, and also
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 189e8fc..04af5f7 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -193,7 +193,7 @@ public final class BluetoothDevice implements Parcelable {
public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
/**
- * Used as an Parcelable {@link BluetoothClass} extra field in {@link
+ * Used as a Parcelable {@link BluetoothClass} extra field in {@link
* #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents.
*/
public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 2683bef..639ae1a 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -60,7 +60,7 @@ public class BluetoothPbap {
public static final String PBAP_PREVIOUS_STATE =
"android.bluetooth.pbap.intent.PBAP_PREVIOUS_STATE";
- /** Indicates the state of an pbap connection state has changed.
+ /** Indicates the state of a pbap connection state has changed.
* This intent will always contain PBAP_STATE, PBAP_PREVIOUS_STATE and
* BluetoothIntent.ADDRESS extras.
*/
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 7a612bc..2930998 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -917,7 +917,7 @@ public abstract class ContentResolver {
}
/**
- * Call an provider-defined method. This can be used to implement
+ * Call a provider-defined method. This can be used to implement
* read or write interfaces which are cheaper than using a Cursor and/or
* do not fit into the traditional table model.
*
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 111f45e..0e9e256 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1270,7 +1270,7 @@ public abstract class Context {
/**
* Connect to an application service, creating it if needed. This defines
* a dependency between your application and the service. The given
- * <var>conn</var> will receive the service object when its created and be
+ * <var>conn</var> will receive the service object when it is created and be
* told if it dies and restarts. The service will be considered required
* by the system only for as long as the calling context exists. For
* example, if this Context is an Activity that is stopped, the service will
@@ -1279,15 +1279,15 @@ public abstract class Context {
* <p>This function will throw {@link SecurityException} if you do not
* have permission to bind to the given service.
*
- * <p class="note">Note: this method <em>can not be called from an
+ * <p class="note">Note: this method <em>can not be called from a
* {@link BroadcastReceiver} component</em>. A pattern you can use to
- * communicate from an BroadcastReceiver to a Service is to call
+ * communicate from a BroadcastReceiver to a Service is to call
* {@link #startService} with the arguments containing the command to be
* sent, with the service calling its
* {@link android.app.Service#stopSelf(int)} method when done executing
* that command. See the API demo App/Service/Service Start Arguments
* Controller for an illustration of this. It is okay, however, to use
- * this method from an BroadcastReceiver that has been registered with
+ * this method from a BroadcastReceiver that has been registered with
* {@link #registerReceiver}, since the lifetime of this BroadcastReceiver
* is tied to another object (the one that registered it).</p>
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5739119..6cf5b43 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -843,10 +843,10 @@ public class Intent implements Parcelable, Cloneable {
* just say what kind of data is desired, not a URI of existing data from
* which the user can pick. A ACTION_GET_CONTENT could allow the user to
* create the data as it runs (for example taking a picture or recording a
- * sound), let them browser over the web and download the desired data,
+ * sound), let them browse over the web and download the desired data,
* etc.
* <p>
- * There are two main ways to use this action: if you want an specific kind
+ * There are two main ways to use this action: if you want a specific kind
* of data, such as a person contact, you set the MIME type to the kind of
* data you want and launch it with {@link Context#startActivity(Intent)}.
* The system will then launch the best application to select that kind
@@ -864,12 +864,12 @@ public class Intent implements Parcelable, Cloneable {
* broad MIME type (such as image/* or {@literal *}/*), resulting in a
* broad range of content types the user can select from.
* <p>
- * When using such a broad GET_CONTENT action, it is often desireable to
+ * When using such a broad GET_CONTENT action, it is often desirable to
* only pick from data that can be represented as a stream. This is
* accomplished by requiring the {@link #CATEGORY_OPENABLE} in the Intent.
* <p>
* Callers can optionally specify {@link #EXTRA_LOCAL_ONLY} to request that
- * the launched content chooser only return results representing data that
+ * the launched content chooser only returns results representing data that
* is locally available on the device. For example, if this extra is set
* to true then an image picker should not show any pictures that are available
* from a remote server but not already on the local device (thus requiring
@@ -1908,14 +1908,14 @@ public class Intent implements Parcelable, Cloneable {
// location; they are not general-purpose actions.
/**
- * Broadcast Action: An GTalk connection has been established.
+ * Broadcast Action: A GTalk connection has been established.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_GTALK_SERVICE_CONNECTED =
"android.intent.action.GTALK_CONNECTED";
/**
- * Broadcast Action: An GTalk connection has been disconnected.
+ * Broadcast Action: A GTalk connection has been disconnected.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_GTALK_SERVICE_DISCONNECTED =
@@ -2200,7 +2200,7 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_SELECTED_ALTERNATIVE = "android.intent.category.SELECTED_ALTERNATIVE";
/**
- * Intended to be used as a tab inside of an containing TabActivity.
+ * Intended to be used as a tab inside of a containing TabActivity.
*/
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_TAB = "android.intent.category.TAB";
@@ -2256,7 +2256,7 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
/**
- * To be used as an sample code example (not part of the normal user
+ * To be used as a sample code example (not part of the normal user
* experience).
*/
public static final String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE";
@@ -2506,7 +2506,7 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_KEY_CONFIRM = "android.intent.extra.KEY_CONFIRM";
/**
- * Used as an boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
+ * Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
* {@link android.content.Intent#ACTION_PACKAGE_CHANGED} intents to override the default action
* of restarting the application.
*/
@@ -3704,7 +3704,7 @@ public class Intent implements Parcelable, Cloneable {
}
/**
- * Check if an category exists in the intent.
+ * Check if a category exists in the intent.
*
* @param category The category to check.
*
@@ -4623,7 +4623,7 @@ public class Intent implements Parcelable, Cloneable {
/**
* Add a new category to the intent. Categories provide additional detail
- * about the action the intent is perform. When resolving an intent, only
+ * about the action the intent performs. When resolving an intent, only
* activities that provide <em>all</em> of the requested categories will be
* used.
*
@@ -4646,7 +4646,7 @@ public class Intent implements Parcelable, Cloneable {
}
/**
- * Remove an category from an intent.
+ * Remove a category from an intent.
*
* @param category The category to remove.
*
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f2133d8..544bd9c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -119,7 +119,7 @@ public abstract class PackageManager {
* {@link PackageInfo} flag: return the
* {@link PackageInfo#gids group ids} that are associated with an
* application.
- * This applies for any API returning an PackageInfo class, either
+ * This applies for any API returning a PackageInfo class, either
* directly or nested inside of another.
*/
public static final int GET_GIDS = 0x00000100;
@@ -142,7 +142,7 @@ public abstract class PackageManager {
* {@link ProviderInfo} flag: return the
* {@link ProviderInfo#uriPermissionPatterns URI permission patterns}
* that are associated with a content provider.
- * This applies for any API returning an ProviderInfo class, either
+ * This applies for any API returning a ProviderInfo class, either
* directly or nested inside of another.
*/
public static final int GET_URI_PERMISSION_PATTERNS = 0x00000800;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e88ee02..207f077 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -89,11 +89,25 @@ public class PackageParser {
this.fileVersion = fileVersion;
}
}
-
+
+ /** @hide */
+ public static class SplitPermissionInfo {
+ public final String rootPerm;
+ public final String[] newPerms;
+
+ public SplitPermissionInfo(String rootPerm, String[] newPerms) {
+ this.rootPerm = rootPerm;
+ this.newPerms = newPerms;
+ }
+ }
+
/**
* List of new permissions that have been added since 1.0.
* NOTE: These must be declared in SDK version order, with permissions
* added to older SDKs appearing before those added to newer SDKs.
+ * If sdkVersion is 0, then this is not a permission that we want to
+ * automatically add to older apps, but we do want to allow it to be
+ * granted during a platform update.
* @hide
*/
public static final PackageParser.NewPermissionInfo NEW_PERMISSIONS[] =
@@ -104,6 +118,17 @@ public class PackageParser {
android.os.Build.VERSION_CODES.DONUT, 0)
};
+ /**
+ * List of permissions that have been split into more granular or dependent
+ * permissions.
+ * @hide
+ */
+ public static final PackageParser.SplitPermissionInfo SPLIT_PERMISSIONS[] =
+ new PackageParser.SplitPermissionInfo[] {
+ new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE })
+ };
+
private String mArchiveSourcePath;
private String[] mSeparateProcesses;
private boolean mOnlyCoreApps;
@@ -1245,7 +1270,23 @@ public class PackageParser {
if (implicitPerms != null) {
Slog.i(TAG, implicitPerms.toString());
}
-
+
+ final int NS = PackageParser.SPLIT_PERMISSIONS.length;
+ for (int is=0; is<NS; is++) {
+ final PackageParser.SplitPermissionInfo spi
+ = PackageParser.SPLIT_PERMISSIONS[is];
+ if (!pkg.requestedPermissions.contains(spi.rootPerm)) {
+ break;
+ }
+ for (int in=0; in<spi.newPerms.length; in++) {
+ final String perm = spi.newPerms[in];
+ if (!pkg.requestedPermissions.contains(perm)) {
+ pkg.requestedPermissions.add(perm);
+ pkg.requestedPermissionsRequired.add(Boolean.TRUE);
+ }
+ }
+ }
+
if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.DONUT)) {
diff --git a/core/java/android/emoji/EmojiFactory.java b/core/java/android/emoji/EmojiFactory.java
index e0b12ae..8fd8695 100644
--- a/core/java/android/emoji/EmojiFactory.java
+++ b/core/java/android/emoji/EmojiFactory.java
@@ -33,7 +33,7 @@ public final class EmojiFactory {
private int sCacheSize = 100;
- // HashMap for caching Bitmap object. In order not to make an cache object
+ // HashMap for caching Bitmap object. In order not to make a cache object
// blow up, we use LinkedHashMap with size limit.
private class CustomLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
public CustomLinkedHashMap() {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 573e6ea..2775c7b 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1358,7 +1358,7 @@ public class Camera {
/**
* Returns an empty {@link Parameters} for testing purpose.
*
- * @return an Parameter object.
+ * @return a Parameter object.
*
* @hide
*/
@@ -3127,7 +3127,7 @@ public class Camera {
public void getFocusDistances(float[] output) {
if (output == null || output.length != 3) {
throw new IllegalArgumentException(
- "output must be an float array with three elements.");
+ "output must be a float array with three elements.");
}
splitFloat(get(KEY_FOCUS_DISTANCES), output);
}
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 68fc101..63fb32d 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -57,7 +57,7 @@ public class Sensor {
public static final int TYPE_GYROSCOPE = 4;
/**
- * A constant describing an light sensor type. See
+ * A constant describing a light sensor type. See
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
* details.
*/
@@ -77,7 +77,7 @@ public class Sensor {
public static final int TYPE_TEMPERATURE = 7;
/**
- * A constant describing an proximity sensor type. See
+ * A constant describing a proximity sensor type. See
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
* details.
*/
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 53cdf21..ba7dc4a 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2173,7 +2173,7 @@ public class InputMethodService extends AbstractInputMethodService {
* This is called when, while currently displayed in extract mode, the
* current input target changes. The default implementation will
* auto-hide the IME if the new target is not a full editor, since this
- * can be an confusing experience for the user.
+ * can be a confusing experience for the user.
*/
public void onExtractingInputChanged(EditorInfo ei) {
if (ei.inputType == InputType.TYPE_NULL) {
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index 04cf1a3..5b94784 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -36,6 +36,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
public final NetworkTemplate template;
public int cycleDay;
+ public String cycleTimezone;
public long warningBytes;
public long limitBytes;
public long lastWarningSnooze;
@@ -44,15 +45,18 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
private static final long DEFAULT_MTU = 1500;
- public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes,
- long limitBytes, boolean metered) {
- this(template, cycleDay, warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, metered);
+ public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
+ long warningBytes, long limitBytes, boolean metered) {
+ this(template, cycleDay, cycleTimezone, warningBytes, limitBytes, SNOOZE_NEVER,
+ SNOOZE_NEVER, metered);
}
- public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes,
- long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered) {
+ public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
+ long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze,
+ boolean metered) {
this.template = checkNotNull(template, "missing NetworkTemplate");
this.cycleDay = cycleDay;
+ this.cycleTimezone = checkNotNull(cycleTimezone, "missing cycleTimezone");
this.warningBytes = warningBytes;
this.limitBytes = limitBytes;
this.lastWarningSnooze = lastWarningSnooze;
@@ -63,6 +67,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
public NetworkPolicy(Parcel in) {
template = in.readParcelable(null);
cycleDay = in.readInt();
+ cycleTimezone = in.readString();
warningBytes = in.readLong();
limitBytes = in.readLong();
lastWarningSnooze = in.readLong();
@@ -70,10 +75,11 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
metered = in.readInt() != 0;
}
- /** {@inheritDoc} */
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(template, flags);
dest.writeInt(cycleDay);
+ dest.writeString(cycleTimezone);
dest.writeLong(warningBytes);
dest.writeLong(limitBytes);
dest.writeLong(lastWarningSnooze);
@@ -81,7 +87,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
dest.writeInt(metered ? 1 : 0);
}
- /** {@inheritDoc} */
+ @Override
public int describeContents() {
return 0;
}
@@ -112,7 +118,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
lastLimitSnooze = SNOOZE_NEVER;
}
- /** {@inheritDoc} */
+ @Override
public int compareTo(NetworkPolicy another) {
if (another == null || another.limitBytes == LIMIT_DISABLED) {
// other value is missing or disabled; we win
@@ -127,8 +133,8 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
@Override
public int hashCode() {
- return Objects.hashCode(template, cycleDay, warningBytes, limitBytes, lastWarningSnooze,
- lastLimitSnooze, metered);
+ return Objects.hashCode(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
+ lastWarningSnooze, lastLimitSnooze, metered);
}
@Override
@@ -139,6 +145,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
&& limitBytes == other.limitBytes
&& lastWarningSnooze == other.lastWarningSnooze
&& lastLimitSnooze == other.lastLimitSnooze && metered == other.metered
+ && Objects.equal(cycleTimezone, other.cycleTimezone)
&& Objects.equal(template, other.template);
}
return false;
@@ -146,17 +153,19 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
@Override
public String toString() {
- return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", warningBytes="
- + warningBytes + ", limitBytes=" + limitBytes + ", lastWarningSnooze="
- + lastWarningSnooze + ", lastLimitSnooze=" + lastLimitSnooze + ", metered="
- + metered;
+ return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", cycleTimezone="
+ + cycleTimezone + ", warningBytes=" + warningBytes + ", limitBytes=" + limitBytes
+ + ", lastWarningSnooze=" + lastWarningSnooze + ", lastLimitSnooze="
+ + lastLimitSnooze + ", metered=" + metered;
}
public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
+ @Override
public NetworkPolicy createFromParcel(Parcel in) {
return new NetworkPolicy(in);
}
+ @Override
public NetworkPolicy[] newArray(int size) {
return new NetworkPolicy[size];
}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 9d253c7..7173751 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -131,7 +131,7 @@ public class NetworkPolicyManager {
* @hide
*/
public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
- final Time now = new Time(Time.TIMEZONE_UTC);
+ final Time now = new Time(policy.cycleTimezone);
now.set(currentTime);
// first, find cycle boundary for current month
@@ -157,7 +157,7 @@ public class NetworkPolicyManager {
/** {@hide} */
public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
- final Time now = new Time(Time.TIMEZONE_UTC);
+ final Time now = new Time(policy.cycleTimezone);
now.set(currentTime);
// first, find cycle boundary for current month
@@ -183,7 +183,7 @@ public class NetworkPolicyManager {
/**
* Snap to the cycle day for the current month given; when cycle day doesn't
- * exist, it snaps to 1st of following month.
+ * exist, it snaps to last second of current month.
*
* @hide
*/
diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java
index 863304c..1cd73d2 100644
--- a/core/java/android/net/http/SslError.java
+++ b/core/java/android/net/http/SslError.java
@@ -64,7 +64,7 @@ public class SslError {
public static final int SSL_MAX_ERROR = 6;
/**
- * The SSL error set bitfield (each individual error is an bit index;
+ * The SSL error set bitfield (each individual error is a bit index;
* multiple individual errors can be OR-ed)
*/
int mErrors;
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 15e3af4..788ab74 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -180,9 +180,14 @@ public final class Parcel {
private static final String TAG = "Parcel";
@SuppressWarnings({"UnusedDeclaration"})
- private int mObject; // used by native code
- @SuppressWarnings({"UnusedDeclaration"})
- private int mOwnObject; // used by native code
+ private int mNativePtr; // used by native code
+
+ /**
+ * Flag indicating if {@link #mNativePtr} was allocated by this object,
+ * indicating that we're responsible for its lifecycle.
+ */
+ private boolean mOwnsNativeParcelObject;
+
private RuntimeException mStack;
private static final int POOL_SIZE = 6;
@@ -224,6 +229,48 @@ public final class Parcel {
private static final int EX_ILLEGAL_STATE = -5;
private static final int EX_HAS_REPLY_HEADER = -128; // special; see below
+ private static native int nativeDataSize(int nativePtr);
+ private static native int nativeDataAvail(int nativePtr);
+ private static native int nativeDataPosition(int nativePtr);
+ private static native int nativeDataCapacity(int nativePtr);
+ private static native void nativeSetDataSize(int nativePtr, int size);
+ private static native void nativeSetDataPosition(int nativePtr, int pos);
+ private static native void nativeSetDataCapacity(int nativePtr, int size);
+
+ private static native boolean nativePushAllowFds(int nativePtr, boolean allowFds);
+ private static native void nativeRestoreAllowFds(int nativePtr, boolean lastValue);
+
+ private static native void nativeWriteByteArray(int nativePtr, byte[] b, int offset, int len);
+ private static native void nativeWriteInt(int nativePtr, int val);
+ private static native void nativeWriteLong(int nativePtr, long val);
+ private static native void nativeWriteFloat(int nativePtr, float val);
+ private static native void nativeWriteDouble(int nativePtr, double val);
+ private static native void nativeWriteString(int nativePtr, String val);
+ private static native void nativeWriteStrongBinder(int nativePtr, IBinder val);
+ private static native void nativeWriteFileDescriptor(int nativePtr, FileDescriptor val);
+
+ private static native byte[] nativeCreateByteArray(int nativePtr);
+ private static native int nativeReadInt(int nativePtr);
+ private static native long nativeReadLong(int nativePtr);
+ private static native float nativeReadFloat(int nativePtr);
+ private static native double nativeReadDouble(int nativePtr);
+ private static native String nativeReadString(int nativePtr);
+ private static native IBinder nativeReadStrongBinder(int nativePtr);
+ private static native FileDescriptor nativeReadFileDescriptor(int nativePtr);
+
+ private static native int nativeCreate();
+ private static native void nativeFreeBuffer(int nativePtr);
+ private static native void nativeDestroy(int nativePtr);
+
+ private static native byte[] nativeMarshall(int nativePtr);
+ private static native void nativeUnmarshall(
+ int nativePtr, byte[] data, int offest, int length);
+ private static native void nativeAppendFrom(
+ int thisNativePtr, int otherNativePtr, int offset, int length);
+ private static native boolean nativeHasFileDescriptors(int nativePtr);
+ private static native void nativeWriteInterfaceToken(int nativePtr, String interfaceName);
+ private static native void nativeEnforceInterface(int nativePtr, String interfaceName);
+
public final static Parcelable.Creator<String> STRING_CREATOR
= new Parcelable.Creator<String>() {
public String createFromParcel(Parcel source) {
@@ -262,7 +309,15 @@ public final class Parcel {
public final void recycle() {
if (DEBUG_RECYCLE) mStack = null;
freeBuffer();
- final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool;
+
+ final Parcel[] pool;
+ if (mOwnsNativeParcelObject) {
+ pool = sOwnedPool;
+ } else {
+ mNativePtr = 0;
+ pool = sHolderPool;
+ }
+
synchronized (pool) {
for (int i=0; i<POOL_SIZE; i++) {
if (pool[i] == null) {
@@ -276,19 +331,25 @@ public final class Parcel {
/**
* Returns the total amount of data contained in the parcel.
*/
- public final native int dataSize();
+ public final int dataSize() {
+ return nativeDataSize(mNativePtr);
+ }
/**
* Returns the amount of data remaining to be read from the
* parcel. That is, {@link #dataSize}-{@link #dataPosition}.
*/
- public final native int dataAvail();
+ public final int dataAvail() {
+ return nativeDataAvail(mNativePtr);
+ }
/**
* Returns the current position in the parcel data. Never
* more than {@link #dataSize}.
*/
- public final native int dataPosition();
+ public final int dataPosition() {
+ return nativeDataPosition(mNativePtr);
+ }
/**
* Returns the total amount of space in the parcel. This is always
@@ -296,7 +357,9 @@ public final class Parcel {
* amount of room left until the parcel needs to re-allocate its
* data buffer.
*/
- public final native int dataCapacity();
+ public final int dataCapacity() {
+ return nativeDataCapacity(mNativePtr);
+ }
/**
* Change the amount of data in the parcel. Can be either smaller or
@@ -305,14 +368,18 @@ public final class Parcel {
*
* @param size The new number of bytes in the Parcel.
*/
- public final native void setDataSize(int size);
+ public final void setDataSize(int size) {
+ nativeSetDataSize(mNativePtr, size);
+ }
/**
* Move the current read/write position in the parcel.
* @param pos New offset in the parcel; must be between 0 and
* {@link #dataSize}.
*/
- public final native void setDataPosition(int pos);
+ public final void setDataPosition(int pos) {
+ nativeSetDataPosition(mNativePtr, pos);
+ }
/**
* Change the capacity (current available space) of the parcel.
@@ -321,13 +388,19 @@ public final class Parcel {
* less than {@link #dataSize} -- that is, you can not drop existing data
* with this method.
*/
- public final native void setDataCapacity(int size);
+ public final void setDataCapacity(int size) {
+ nativeSetDataCapacity(mNativePtr, size);
+ }
/** @hide */
- public final native boolean pushAllowFds(boolean allowFds);
+ public final boolean pushAllowFds(boolean allowFds) {
+ return nativePushAllowFds(mNativePtr, allowFds);
+ }
/** @hide */
- public final native void restoreAllowFds(boolean lastValue);
+ public final void restoreAllowFds(boolean lastValue) {
+ nativeRestoreAllowFds(mNativePtr, lastValue);
+ }
/**
* Returns the raw bytes of the parcel.
@@ -340,27 +413,40 @@ public final class Parcel {
* such does not attempt to maintain compatibility with data created
* in different versions of the platform.
*/
- public final native byte[] marshall();
+ public final byte[] marshall() {
+ return nativeMarshall(mNativePtr);
+ }
/**
* Set the bytes in data to be the raw bytes of this Parcel.
*/
- public final native void unmarshall(byte[] data, int offest, int length);
+ public final void unmarshall(byte[] data, int offest, int length) {
+ nativeUnmarshall(mNativePtr, data, offest, length);
+ }
- public final native void appendFrom(Parcel parcel, int offset, int length);
+ public final void appendFrom(Parcel parcel, int offset, int length) {
+ nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
+ }
/**
* Report whether the parcel contains any marshalled file descriptors.
*/
- public final native boolean hasFileDescriptors();
+ public final boolean hasFileDescriptors() {
+ return nativeHasFileDescriptors(mNativePtr);
+ }
/**
* Store or read an IBinder interface token in the parcel at the current
* {@link #dataPosition}. This is used to validate that the marshalled
* transaction is intended for the target interface.
*/
- public final native void writeInterfaceToken(String interfaceName);
- public final native void enforceInterface(String interfaceName);
+ public final void writeInterfaceToken(String interfaceName) {
+ nativeWriteInterfaceToken(mNativePtr, interfaceName);
+ }
+
+ public final void enforceInterface(String interfaceName) {
+ nativeEnforceInterface(mNativePtr, interfaceName);
+ }
/**
* Write a byte array into the parcel at the current {@link #dataPosition},
@@ -372,7 +458,7 @@ public final class Parcel {
}
/**
- * Write an byte array into the parcel at the current {@link #dataPosition},
+ * Write a byte array into the parcel at the current {@link #dataPosition},
* growing {@link #dataCapacity} if needed.
* @param b Bytes to place into the parcel.
* @param offset Index of first byte to be written.
@@ -384,40 +470,48 @@ public final class Parcel {
return;
}
Arrays.checkOffsetAndCount(b.length, offset, len);
- writeNative(b, offset, len);
+ nativeWriteByteArray(mNativePtr, b, offset, len);
}
- private native void writeNative(byte[] b, int offset, int len);
-
/**
* Write an integer value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeInt(int val);
+ public final void writeInt(int val) {
+ nativeWriteInt(mNativePtr, val);
+ }
/**
* Write a long integer value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeLong(long val);
+ public final void writeLong(long val) {
+ nativeWriteLong(mNativePtr, val);
+ }
/**
* Write a floating point value into the parcel at the current
* dataPosition(), growing dataCapacity() if needed.
*/
- public final native void writeFloat(float val);
+ public final void writeFloat(float val) {
+ nativeWriteFloat(mNativePtr, val);
+ }
/**
* Write a double precision floating point value into the parcel at the
* current dataPosition(), growing dataCapacity() if needed.
*/
- public final native void writeDouble(double val);
+ public final void writeDouble(double val) {
+ nativeWriteDouble(mNativePtr, val);
+ }
/**
* Write a string value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeString(String val);
+ public final void writeString(String val) {
+ nativeWriteString(mNativePtr, val);
+ }
/**
* Write a CharSequence value into the parcel at the current dataPosition(),
@@ -432,7 +526,9 @@ public final class Parcel {
* Write an object into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
- public final native void writeStrongBinder(IBinder val);
+ public final void writeStrongBinder(IBinder val) {
+ nativeWriteStrongBinder(mNativePtr, val);
+ }
/**
* Write an object into the parcel at the current dataPosition(),
@@ -452,10 +548,12 @@ public final class Parcel {
* accepts contextual flags and will close the original file descriptor
* if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
*/
- public final native void writeFileDescriptor(FileDescriptor val);
+ public final void writeFileDescriptor(FileDescriptor val) {
+ nativeWriteFileDescriptor(mNativePtr, val);
+ }
/**
- * Write an byte value into the parcel at the current dataPosition(),
+ * Write a byte value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
public final void writeByte(byte val) {
@@ -1341,29 +1439,39 @@ public final class Parcel {
/**
* Read an integer value from the parcel at the current dataPosition().
*/
- public final native int readInt();
+ public final int readInt() {
+ return nativeReadInt(mNativePtr);
+ }
/**
* Read a long integer value from the parcel at the current dataPosition().
*/
- public final native long readLong();
+ public final long readLong() {
+ return nativeReadLong(mNativePtr);
+ }
/**
* Read a floating point value from the parcel at the current
* dataPosition().
*/
- public final native float readFloat();
+ public final float readFloat() {
+ return nativeReadFloat(mNativePtr);
+ }
/**
* Read a double precision floating point value from the parcel at the
* current dataPosition().
*/
- public final native double readDouble();
+ public final double readDouble() {
+ return nativeReadDouble(mNativePtr);
+ }
/**
* Read a string value from the parcel at the current dataPosition().
*/
- public final native String readString();
+ public final String readString() {
+ return nativeReadString(mNativePtr);
+ }
/**
* Read a CharSequence value from the parcel at the current dataPosition().
@@ -1376,17 +1484,18 @@ public final class Parcel {
/**
* Read an object from the parcel at the current dataPosition().
*/
- public final native IBinder readStrongBinder();
+ public final IBinder readStrongBinder() {
+ return nativeReadStrongBinder(mNativePtr);
+ }
/**
* Read a FileDescriptor from the parcel at the current dataPosition().
*/
public final ParcelFileDescriptor readFileDescriptor() {
- FileDescriptor fd = internalReadFileDescriptor();
+ FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
return fd != null ? new ParcelFileDescriptor(fd) : null;
}
- private native FileDescriptor internalReadFileDescriptor();
/*package*/ static native FileDescriptor openFileDescriptor(String file,
int mode) throws FileNotFoundException;
/*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
@@ -1471,7 +1580,9 @@ public final class Parcel {
/**
* Read and return a byte[] object from the parcel.
*/
- public final native byte[] createByteArray();
+ public final byte[] createByteArray() {
+ return nativeCreateByteArray(mNativePtr);
+ }
/**
* Read a byte[] object from the parcel and copy it into the
@@ -2065,12 +2176,37 @@ public final class Parcel {
return new Parcel(obj);
}
- private Parcel(int obj) {
+ private Parcel(int nativePtr) {
if (DEBUG_RECYCLE) {
mStack = new RuntimeException();
}
//Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
- init(obj);
+ init(nativePtr);
+ }
+
+ private void init(int nativePtr) {
+ if (nativePtr != 0) {
+ mNativePtr = nativePtr;
+ mOwnsNativeParcelObject = false;
+ } else {
+ mNativePtr = nativeCreate();
+ mOwnsNativeParcelObject = true;
+ }
+ }
+
+ private void freeBuffer() {
+ if (mOwnsNativeParcelObject) {
+ nativeFreeBuffer(mNativePtr);
+ }
+ }
+
+ private void destroy() {
+ if (mNativePtr != 0) {
+ if (mOwnsNativeParcelObject) {
+ nativeDestroy(mNativePtr);
+ }
+ mNativePtr = 0;
+ }
}
@Override
@@ -2083,10 +2219,6 @@ public final class Parcel {
destroy();
}
- private native void freeBuffer();
- private native void init(int obj);
- private native void destroy();
-
/* package */ void readMapInternal(Map outVal, int N,
ClassLoader loader) {
while (N > 0) {
diff --git a/core/java/android/os/ParcelUuid.java b/core/java/android/os/ParcelUuid.java
index 88fcfc5..2c68ddd 100644
--- a/core/java/android/os/ParcelUuid.java
+++ b/core/java/android/os/ParcelUuid.java
@@ -42,7 +42,7 @@ public final class ParcelUuid implements Parcelable {
*
* @param uuid
* the UUID string to parse.
- * @return an ParcelUuid instance.
+ * @return a ParcelUuid instance.
* @throws NullPointerException
* if {@code uuid} is {@code null}.
* @throws IllegalArgumentException
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
new file mode 100644
index 0000000..af94a37
--- /dev/null
+++ b/core/java/android/os/Trace.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2012 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.os;
+
+/**
+ * Writes trace events to the kernel trace buffer. These trace events can be
+ * collected using the "atrace" program for offline analysis.
+ *
+ * This tracing mechanism is independent of the method tracing mechanism
+ * offered by {@link Debug#startMethodTracing}. In particular, it enables
+ * tracing of events that occur across processes.
+ *
+ * @hide
+ */
+public final class Trace {
+ // These tags must be kept in sync with frameworks/native/include/utils/Trace.h.
+ public static final long TRACE_TAG_NEVER = 0;
+ public static final long TRACE_TAG_ALWAYS = 1L << 0;
+ public static final long TRACE_TAG_GRAPHICS = 1L << 1;
+ public static final long TRACE_TAG_INPUT = 1L << 2;
+ public static final long TRACE_TAG_VIEW = 1L << 3;
+
+ private static final long sEnabledTags = nativeGetEnabledTags();
+
+ private static native long nativeGetEnabledTags();
+ private static native void nativeTraceCounter(long tag, String name, int value);
+ private static native void nativeTraceBegin(long tag, String name);
+ private static native void nativeTraceEnd(long tag);
+
+ private Trace() {
+ }
+
+ /**
+ * Returns true if a trace tag is enabled.
+ *
+ * @param traceTag The trace tag to check.
+ * @return True if the trace tag is valid.
+ */
+ public static boolean isTagEnabled(long traceTag) {
+ return (sEnabledTags & traceTag) != 0;
+ }
+
+ /**
+ * Writes trace message to indicate the value of a given counter.
+ *
+ * @param traceTag The trace tag.
+ * @param counterName The counter name to appear in the trace.
+ * @param counterValue The counter value.
+ */
+ public static void traceCounter(long traceTag, String counterName, int counterValue) {
+ if ((sEnabledTags & traceTag) != 0) {
+ nativeTraceCounter(traceTag, counterName, counterValue);
+ }
+ }
+
+ /**
+ * Writes a trace message to indicate that a given method has begun.
+ * Must be followed by a call to {@link #traceEnd} using the same tag.
+ *
+ * @param traceTag The trace tag.
+ * @param methodName The method name to appear in the trace.
+ */
+ public static void traceBegin(long traceTag, String methodName) {
+ if ((sEnabledTags & traceTag) != 0) {
+ nativeTraceBegin(traceTag, methodName);
+ }
+ }
+
+ /**
+ * Writes a trace message to indicate that the current method has ended.
+ * Must be called exactly once for each call to {@link #traceBegin} using the same tag.
+ *
+ * @param traceTag The trace tag.
+ */
+ public static void traceEnd(long traceTag) {
+ if ((sEnabledTags & traceTag) != 0) {
+ nativeTraceEnd(traceTag);
+ }
+ }
+}
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index a29ecb5..c7e3c08 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -84,7 +84,7 @@ public class Contacts {
@Deprecated
public static final int KIND_ORGANIZATION = 4;
/**
- * Signifies an Phone row that is stored in the Phones table
+ * Signifies a Phone row that is stored in the Phones table
* @deprecated see {@link android.provider.ContactsContract}
*/
@Deprecated
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 6c6b118..38945c2 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -192,7 +192,7 @@ public final class MediaStore {
/**
* Standard Intent action that can be sent to have the camera application
- * capture an video and return it.
+ * capture a video and return it.
* <p>
* The caller may pass in an extra EXTRA_VIDEO_QUALITY to control the video quality.
* <p>
@@ -441,12 +441,12 @@ public final class MediaStore {
public static final int MEDIA_TYPE_AUDIO = 2;
/**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file is an video file.
+ * Constant for the {@link #MEDIA_TYPE} column indicating that file is a video file.
*/
public static final int MEDIA_TYPE_VIDEO = 3;
/**
- * Constant for the {@link #MEDIA_TYPE} column indicating that file is an playlist file.
+ * Constant for the {@link #MEDIA_TYPE} column indicating that file is a playlist file.
*/
public static final int MEDIA_TYPE_PLAYLIST = 4;
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bc6594b..fbb3273 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3129,6 +3129,14 @@ public final class Settings {
"wifi_watchdog_arp_interval_ms";
/**
+ * ms delay interval between rssi polling when the signal is known to be weak
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS =
+ "wifi_watchdog_rssi_fetch_interval_ms";
+
+
+ /**
* ms delay before rechecking a connect SSID for walled garden with a http download.
* @hide
*/
diff --git a/core/java/android/server/BluetoothBondState.java b/core/java/android/server/BluetoothBondState.java
index fbc1c27..0446f02 100644
--- a/core/java/android/server/BluetoothBondState.java
+++ b/core/java/android/server/BluetoothBondState.java
@@ -140,7 +140,7 @@ class BluetoothBondState {
return;
}
- // Check if this was an pending outgoing bonding.
+ // Check if this was a pending outgoing bonding.
// If yes, reset the state.
if (oldState == BluetoothDevice.BOND_BONDING) {
if (address.equals(mPendingOutgoingBonding)) {
diff --git a/core/java/android/text/method/BaseMovementMethod.java b/core/java/android/text/method/BaseMovementMethod.java
index f554b90..113a4be 100644
--- a/core/java/android/text/method/BaseMovementMethod.java
+++ b/core/java/android/text/method/BaseMovementMethod.java
@@ -350,7 +350,7 @@ public class BaseMovementMethod implements MovementMethod {
}
/**
- * Performs an line-end movement action.
+ * Performs a line-end movement action.
* Moves the cursor or scrolls to the end of the line.
*
* @param widget The text view.
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 10edc06..d217cab 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -92,8 +92,8 @@ public final class Choreographer {
private Callback mCallbackPool;
- private Callback mAnimationCallbacks;
- private Callback mDrawCallbacks;
+ private final CallbackQueue mAnimationCallbackQueue = new CallbackQueue();
+ private final CallbackQueue mDrawCallbackQueue = new CallbackQueue();
private boolean mAnimationScheduled;
private boolean mDrawScheduled;
@@ -205,10 +205,15 @@ public final class Choreographer {
throw new IllegalArgumentException("action must not be null");
}
+ if (DEBUG) {
+ Log.d(TAG, "PostAnimationCallback: " + action + ", token=" + token
+ + ", delayMillis=" + delayMillis);
+ }
+
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
- mAnimationCallbacks = addCallbackLocked(mAnimationCallbacks, dueTime, action, token);
+ mAnimationCallbackQueue.addCallbackLocked(dueTime, action, token);
if (dueTime <= now) {
scheduleAnimationLocked(now);
@@ -231,8 +236,12 @@ public final class Choreographer {
* @see #postAnimationCallbackDelayed
*/
public void removeAnimationCallbacks(Runnable action, Object token) {
+ if (DEBUG) {
+ Log.d(TAG, "RemoveAnimationCallbacks: " + action + ", token=" + token);
+ }
+
synchronized (mLock) {
- mAnimationCallbacks = removeCallbacksLocked(mAnimationCallbacks, action, token);
+ mAnimationCallbackQueue.removeCallbacksLocked(action, token);
if (action != null && token == null) {
mHandler.removeMessages(MSG_DO_SCHEDULE_ANIMATION, action);
}
@@ -268,10 +277,15 @@ public final class Choreographer {
throw new IllegalArgumentException("action must not be null");
}
+ if (DEBUG) {
+ Log.d(TAG, "PostDrawCallback: " + action + ", token=" + token
+ + ", delayMillis=" + delayMillis);
+ }
+
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
- mDrawCallbacks = addCallbackLocked(mDrawCallbacks, dueTime, action, token);
+ mDrawCallbackQueue.addCallbackLocked(dueTime, action, token);
scheduleDrawLocked(now);
if (dueTime <= now) {
@@ -295,8 +309,12 @@ public final class Choreographer {
* @see #postDrawCallbackDelayed
*/
public void removeDrawCallbacks(Runnable action, Object token) {
+ if (DEBUG) {
+ Log.d(TAG, "RemoveDrawCallbacks: " + action + ", token=" + token);
+ }
+
synchronized (mLock) {
- mDrawCallbacks = removeCallbacksLocked(mDrawCallbacks, action, token);
+ mDrawCallbackQueue.removeCallbacksLocked(action, token);
if (action != null && token == null) {
mHandler.removeMessages(MSG_DO_SCHEDULE_DRAW, action);
}
@@ -373,24 +391,7 @@ public final class Choreographer {
}
mLastAnimationTime = start;
- callbacks = mAnimationCallbacks;
- if (callbacks != null) {
- if (callbacks.dueTime > start) {
- callbacks = null;
- } else {
- Callback predecessor = callbacks;
- Callback successor = predecessor.next;
- while (successor != null) {
- if (successor.dueTime > start) {
- predecessor.next = null;
- break;
- }
- predecessor = successor;
- successor = successor.next;
- }
- mAnimationCallbacks = successor;
- }
- }
+ callbacks = mAnimationCallbackQueue.extractDueCallbacksLocked(start);
}
if (callbacks != null) {
@@ -421,24 +422,7 @@ public final class Choreographer {
}
mLastDrawTime = start;
- callbacks = mDrawCallbacks;
- if (callbacks != null) {
- if (callbacks.dueTime > start) {
- callbacks = null;
- } else {
- Callback predecessor = callbacks;
- Callback successor = predecessor.next;
- while (successor != null) {
- if (successor.dueTime > start) {
- predecessor.next = null;
- break;
- }
- predecessor = successor;
- successor = successor.next;
- }
- mDrawCallbacks = successor;
- }
- }
+ callbacks = mDrawCallbackQueue.extractDueCallbacksLocked(start);
}
if (callbacks != null) {
@@ -464,7 +448,7 @@ public final class Choreographer {
void doScheduleAnimation() {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
- if (mAnimationCallbacks != null && mAnimationCallbacks.dueTime <= now) {
+ if (mAnimationCallbackQueue.hasDueCallbacksLocked(now)) {
scheduleAnimationLocked(now);
}
}
@@ -473,7 +457,7 @@ public final class Choreographer {
void doScheduleDraw() {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
- if (mDrawCallbacks != null && mDrawCallbacks.dueTime <= now) {
+ if (mDrawCallbackQueue.hasDueCallbacksLocked(now)) {
scheduleDrawLocked(now);
}
}
@@ -487,50 +471,12 @@ public final class Choreographer {
return Looper.myLooper() == mLooper;
}
- private Callback addCallbackLocked(Callback head,
- long dueTime, Runnable action, Object token) {
- Callback callback = obtainCallbackLocked(dueTime, action, token);
- if (head == null) {
- return callback;
- }
- Callback entry = head;
- if (dueTime < entry.dueTime) {
- callback.next = entry;
- return callback;
- }
- while (entry.next != null) {
- if (dueTime < entry.next.dueTime) {
- callback.next = entry.next;
- break;
- }
- entry = entry.next;
- }
- entry.next = callback;
- return head;
- }
-
- private Callback removeCallbacksLocked(Callback head, Runnable action, Object token) {
- Callback predecessor = null;
- for (Callback callback = head; callback != null;) {
- final Callback next = callback.next;
- if ((action == null || callback.action == action)
- && (token == null || callback.token == token)) {
- if (predecessor != null) {
- predecessor.next = next;
- } else {
- head = next;
- }
- recycleCallbackLocked(callback);
- } else {
- predecessor = callback;
- }
- callback = next;
- }
- return head;
- }
-
private void runCallbacks(Callback head) {
while (head != null) {
+ if (DEBUG) {
+ Log.d(TAG, "RunCallback: " + head.action + ", token=" + head.token
+ + ", waitMillis=" + (SystemClock.uptimeMillis() - head.dueTime));
+ }
head.action.run();
head = head.next;
}
@@ -609,4 +555,73 @@ public final class Choreographer {
public Runnable action;
public Object token;
}
+
+ private final class CallbackQueue {
+ private Callback mHead;
+
+ public boolean hasDueCallbacksLocked(long now) {
+ return mHead != null && mHead.dueTime <= now;
+ }
+
+ public Callback extractDueCallbacksLocked(long now) {
+ Callback callbacks = mHead;
+ if (callbacks == null || callbacks.dueTime > now) {
+ return null;
+ }
+
+ Callback last = callbacks;
+ Callback next = last.next;
+ while (next != null) {
+ if (next.dueTime > now) {
+ last.next = null;
+ break;
+ }
+ last = next;
+ next = next.next;
+ }
+ mHead = next;
+ return callbacks;
+ }
+
+ public void addCallbackLocked(long dueTime, Runnable action, Object token) {
+ Callback callback = obtainCallbackLocked(dueTime, action, token);
+ Callback entry = mHead;
+ if (entry == null) {
+ mHead = callback;
+ return;
+ }
+ if (dueTime < entry.dueTime) {
+ callback.next = entry;
+ mHead = callback;
+ return;
+ }
+ while (entry.next != null) {
+ if (dueTime < entry.next.dueTime) {
+ callback.next = entry.next;
+ break;
+ }
+ entry = entry.next;
+ }
+ entry.next = callback;
+ }
+
+ public void removeCallbacksLocked(Runnable action, Object token) {
+ Callback predecessor = null;
+ for (Callback callback = mHead; callback != null;) {
+ final Callback next = callback.next;
+ if ((action == null || callback.action == action)
+ && (token == null || callback.token == token)) {
+ if (predecessor != null) {
+ predecessor.next = next;
+ } else {
+ mHead = next;
+ }
+ recycleCallbackLocked(callback);
+ } else {
+ predecessor = callback;
+ }
+ callback = next;
+ }
+ }
+ }
}
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index f60c8f0..a50f09f 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -70,4 +70,204 @@ public abstract class DisplayList {
* @return The size of this display list in bytes
*/
public abstract int getSize();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // DisplayList Property Setters
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Set the caching property on the DisplayList, which indicates whether the DisplayList
+ * holds a layer. Layer DisplayLists should avoid creating an alpha layer, since alpha is
+ * handled in the drawLayer operation directly (and more efficiently).
+ *
+ * @param caching true if the DisplayList represents a hardware layer, false otherwise.
+ */
+ public abstract void setCaching(boolean caching);
+
+ /**
+ * Set whether the DisplayList should clip itself to its bounds. This property is controlled by
+ * the view's parent.
+ *
+ * @param clipChildren true if the DisplayList should clip to its bounds
+ */
+ public abstract void setClipChildren(boolean clipChildren);
+
+ /**
+ * Set the application scale on the DisplayList. This scale is incurred by applications that
+ * are auto-scaled for compatibility reasons. By default, the value is 1 (unscaled).
+ *
+ * @param scale The scaling factor
+ */
+ public abstract void setApplicationScale(float scale);
+
+ /**
+ * Sets the alpha value for the DisplayList
+ *
+ * @param alpha The translucency of the DisplayList
+ * @see View#setAlpha(float)
+ */
+ public abstract void setAlpha(float alpha);
+
+ /**
+ * Sets the translationX value for the DisplayList
+ *
+ * @param translationX The translationX value of the DisplayList
+ * @see View#setTranslationX(float)
+ */
+ public abstract void setTranslationX(float translationX);
+
+ /**
+ * Sets the translationY value for the DisplayList
+ *
+ * @param translationY The translationY value of the DisplayList
+ * @see View#setTranslationY(float)
+ */
+ public abstract void setTranslationY(float translationY);
+
+ /**
+ * Sets the rotation value for the DisplayList
+ *
+ * @param rotation The rotation value of the DisplayList
+ * @see View#setRotation(float)
+ */
+ public abstract void setRotation(float rotation);
+
+ /**
+ * Sets the rotationX value for the DisplayList
+ *
+ * @param rotationX The rotationX value of the DisplayList
+ * @see View#setRotationX(float)
+ */
+ public abstract void setRotationX(float rotationX);
+
+ /**
+ * Sets the rotationY value for the DisplayList
+ *
+ * @param rotationY The rotationY value of the DisplayList
+ * @see View#setRotationY(float)
+ */
+ public abstract void setRotationY(float rotationY);
+
+ /**
+ * Sets the scaleX value for the DisplayList
+ *
+ * @param scaleX The scaleX value of the DisplayList
+ * @see View#setScaleX(float)
+ */
+ public abstract void setScaleX(float scaleX);
+
+ /**
+ * Sets the scaleY value for the DisplayList
+ *
+ * @param scaleY The scaleY value of the DisplayList
+ * @see View#setScaleY(float)
+ */
+ public abstract void setScaleY(float scaleY);
+
+ /**
+ * Sets all of the transform-related values of the View onto the DisplayList
+ *
+ * @param alpha The alpha value of the DisplayList
+ * @param translationX The translationX value of the DisplayList
+ * @param translationY The translationY value of the DisplayList
+ * @param rotation The rotation value of the DisplayList
+ * @param rotationX The rotationX value of the DisplayList
+ * @param rotationY The rotationY value of the DisplayList
+ * @param scaleX The scaleX value of the DisplayList
+ * @param scaleY The scaleY value of the DisplayList
+ */
+ public abstract void setTransformationInfo(float alpha, float translationX, float translationY,
+ float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
+
+ /**
+ * Sets the pivotX value for the DisplayList
+ *
+ * @param pivotX The pivotX value of the DisplayList
+ * @see View#setPivotX(float)
+ */
+ public abstract void setPivotX(float pivotX);
+
+ /**
+ * Sets the pivotY value for the DisplayList
+ *
+ * @param pivotY The pivotY value of the DisplayList
+ * @see View#setPivotY(float)
+ */
+ public abstract void setPivotY(float pivotY);
+
+ /**
+ * Sets the camera distance for the DisplayList
+ *
+ * @param distance The distance in z of the camera of the DisplayList
+ * @see View#setCameraDistance(float)
+ */
+ public abstract void setCameraDistance(float distance);
+
+ /**
+ * Sets the left value for the DisplayList
+ *
+ * @param left The left value of the DisplayList
+ * @see View#setLeft(int)
+ */
+ public abstract void setLeft(int left);
+
+ /**
+ * Sets the top value for the DisplayList
+ *
+ * @param top The top value of the DisplayList
+ * @see View#setTop(int)
+ */
+ public abstract void setTop(int top);
+
+ /**
+ * Sets the right value for the DisplayList
+ *
+ * @param right The right value of the DisplayList
+ * @see View#setRight(int)
+ */
+ public abstract void setRight(int right);
+
+ /**
+ * Sets the bottom value for the DisplayList
+ *
+ * @param bottom The bottom value of the DisplayList
+ * @see View#setBottom(int)
+ */
+ public abstract void setBottom(int bottom);
+
+ /**
+ * Sets the left and top values for the DisplayList
+ *
+ * @param left The left value of the DisplayList
+ * @param top The top value of the DisplayList
+ * @see View#setLeft(int)
+ * @see View#setTop(int)
+ */
+ public abstract void setLeftTop(int left, int top);
+
+ /**
+ * Sets the left and top values for the DisplayList
+ *
+ * @param left The left value of the DisplayList
+ * @param top The top value of the DisplayList
+ * @see View#setLeft(int)
+ * @see View#setTop(int)
+ */
+ public abstract void setLeftTopRightBottom(int left, int top, int right, int bottom);
+
+ /**
+ * Offsets the left and right values for the DisplayList
+ *
+ * @param offset The amount that the left and right values of the DisplayList are offset
+ * @see View#offsetLeftAndRight(int)
+ */
+ public abstract void offsetLeftRight(int offset);
+
+ /**
+ * Offsets the top and bottom values for the DisplayList
+ *
+ * @param offset The amount that the top and bottom values of the DisplayList are offset
+ * @see View#offsetTopAndBottom(int)
+ */
+ public abstract void offsetTopBottom(int offset);
}
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 969c9ab..9b4cf21 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -96,6 +96,251 @@ class GLES20DisplayList extends DisplayList {
return GLES20Canvas.getDisplayListSize(mFinalizer.mNativeDisplayList);
}
+ ///////////////////////////////////////////////////////////////////////////
+ // Native View Properties
+ ///////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void setCaching(boolean caching) {
+ try {
+ nSetCaching(getNativeDisplayList(), caching);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setClipChildren(boolean clipChildren) {
+ try {
+ nSetClipChildren(getNativeDisplayList(), clipChildren);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setApplicationScale(float scale) {
+ try {
+ nSetApplicationScale(getNativeDisplayList(), scale);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ try {
+ nSetAlpha(getNativeDisplayList(), alpha);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setTranslationX(float translationX) {
+ try {
+ nSetTranslationX(getNativeDisplayList(), translationX);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setTranslationY(float translationY) {
+ try {
+ nSetTranslationY(getNativeDisplayList(), translationY);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setRotation(float rotation) {
+ try {
+ nSetRotation(getNativeDisplayList(), rotation);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setRotationX(float rotationX) {
+ try {
+ nSetRotationX(getNativeDisplayList(), rotationX);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setRotationY(float rotationY) {
+ try {
+ nSetRotationY(getNativeDisplayList(), rotationY);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setScaleX(float scaleX) {
+ try {
+ nSetScaleX(getNativeDisplayList(), scaleX);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setScaleY(float scaleY) {
+ try {
+ nSetScaleY(getNativeDisplayList(), scaleY);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setTransformationInfo(float alpha, float translationX, float translationY,
+ float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
+ try {
+ nSetTransformationInfo(getNativeDisplayList(), alpha, translationX, translationY,
+ rotation, rotationX, rotationY, scaleX, scaleY);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setPivotX(float pivotX) {
+ try {
+ nSetPivotX(getNativeDisplayList(), pivotX);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setPivotY(float pivotY) {
+ try {
+ nSetPivotY(getNativeDisplayList(), pivotY);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setCameraDistance(float distance) {
+ try {
+ nSetCameraDistance(getNativeDisplayList(), distance);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setLeft(int left) {
+ try {
+ nSetLeft(getNativeDisplayList(), left);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setTop(int top) {
+ try {
+ nSetTop(getNativeDisplayList(), top);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setRight(int right) {
+ try {
+ nSetRight(getNativeDisplayList(), right);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setBottom(int bottom) {
+ try {
+ nSetBottom(getNativeDisplayList(), bottom);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setLeftTop(int left, int top) {
+ try {
+ nSetLeftTop(getNativeDisplayList(), left, top);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+ try {
+ nSetLeftTopRightBottom(getNativeDisplayList(), left, top, right, bottom);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void offsetLeftRight(int offset) {
+ try {
+ nOffsetLeftRight(getNativeDisplayList(), offset);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ @Override
+ public void offsetTopBottom(int offset) {
+ try {
+ nOffsetTopBottom(getNativeDisplayList(), offset);
+ } catch (IllegalStateException e) {
+ // invalid DisplayList okay: we'll set current values the next time we render to it
+ }
+ }
+
+ private static native void nOffsetTopBottom(int displayList, int offset);
+ private static native void nOffsetLeftRight(int displayList, int offset);
+ private static native void nSetLeftTopRightBottom(int displayList, int left, int top,
+ int right, int bottom);
+ private static native void nSetLeftTop(int displayList, int left, int top);
+ private static native void nSetBottom(int displayList, int bottom);
+ private static native void nSetRight(int displayList, int right);
+ private static native void nSetTop(int displayList, int top);
+ private static native void nSetLeft(int displayList, int left);
+ private static native void nSetCameraDistance(int displayList, float distance);
+ private static native void nSetPivotY(int displayList, float pivotY);
+ private static native void nSetPivotX(int displayList, float pivotX);
+ private static native void nSetCaching(int displayList, boolean caching);
+ private static native void nSetClipChildren(int displayList, boolean clipChildren);
+ private static native void nSetApplicationScale(int displayList, float scale);
+ private static native void nSetAlpha(int displayList, float alpha);
+ private static native void nSetTranslationX(int displayList, float translationX);
+ private static native void nSetTranslationY(int displayList, float translationY);
+ private static native void nSetRotation(int displayList, float rotation);
+ private static native void nSetRotationX(int displayList, float rotationX);
+ private static native void nSetRotationY(int displayList, float rotationY);
+ private static native void nSetScaleX(int displayList, float scaleX);
+ private static native void nSetScaleY(int displayList, float scaleY);
+ private static native void nSetTransformationInfo(int displayList, float alpha,
+ float translationX, float translationY, float rotation, float rotationX,
+ float rotationY, float scaleX, float scaleY);
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Finalization
+ ///////////////////////////////////////////////////////////////////////////
+
private static class DisplayListFinalizer {
final int mNativeDisplayList;
diff --git a/core/java/android/view/Gravity.java b/core/java/android/view/Gravity.java
index 63f5ec1..f031fe7 100644
--- a/core/java/android/view/Gravity.java
+++ b/core/java/android/view/Gravity.java
@@ -153,7 +153,8 @@ public class Gravity
* container.
* @param layoutDirection The layout direction.
*
- * @hide
+ * @see {@link View#LAYOUT_DIRECTION_LTR}
+ * @see {@link View#LAYOUT_DIRECTION_RTL}
*/
public static void apply(int gravity, int w, int h, Rect container,
Rect outRect, int layoutDirection) {
@@ -268,6 +269,37 @@ public class Gravity
}
/**
+ * Apply a gravity constant to an object.
+ *
+ * @param gravity The desired placement of the object, as defined by the
+ * constants in this class.
+ * @param w The horizontal size of the object.
+ * @param h The vertical size of the object.
+ * @param container The frame of the containing space, in which the object
+ * will be placed. Should be large enough to contain the
+ * width and height of the object.
+ * @param xAdj Offset to apply to the X axis. If gravity is LEFT this
+ * pushes it to the right; if gravity is RIGHT it pushes it to
+ * the left; if gravity is CENTER_HORIZONTAL it pushes it to the
+ * right or left; otherwise it is ignored.
+ * @param yAdj Offset to apply to the Y axis. If gravity is TOP this pushes
+ * it down; if gravity is BOTTOM it pushes it up; if gravity is
+ * CENTER_VERTICAL it pushes it down or up; otherwise it is
+ * ignored.
+ * @param outRect Receives the computed frame of the object in its
+ * container.
+ * @param layoutDirection The layout direction.
+ *
+ * @see {@link View#LAYOUT_DIRECTION_LTR}
+ * @see {@link View#LAYOUT_DIRECTION_RTL}
+ */
+ public static void apply(int gravity, int w, int h, Rect container,
+ int xAdj, int yAdj, Rect outRect, int layoutDirection) {
+ int absGravity = getAbsoluteGravity(gravity, layoutDirection);
+ apply(absGravity, w, h, container, xAdj, yAdj, outRect);
+ }
+
+ /**
* Apply additional gravity behavior based on the overall "display" that an
* object exists in. This can be used after
* {@link #apply(int, int, int, Rect, int, int, Rect)} to place the object
@@ -320,7 +352,32 @@ public class Gravity
}
}
}
-
+
+ /**
+ * Apply additional gravity behavior based on the overall "display" that an
+ * object exists in. This can be used after
+ * {@link #apply(int, int, int, Rect, int, int, Rect)} to place the object
+ * within a visible display. By default this moves or clips the object
+ * to be visible in the display; the gravity flags
+ * {@link #DISPLAY_CLIP_HORIZONTAL} and {@link #DISPLAY_CLIP_VERTICAL}
+ * can be used to change this behavior.
+ *
+ * @param gravity Gravity constants to modify the placement within the
+ * display.
+ * @param display The rectangle of the display in which the object is
+ * being placed.
+ * @param inoutObj Supplies the current object position; returns with it
+ * modified if needed to fit in the display.
+ * @param layoutDirection The layout direction.
+ *
+ * @see {@link View#LAYOUT_DIRECTION_LTR}
+ * @see {@link View#LAYOUT_DIRECTION_RTL}
+ */
+ public static void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection) {
+ int absGravity = getAbsoluteGravity(gravity, layoutDirection);
+ applyDisplay(absGravity, display, inoutObj);
+ }
+
/**
* <p>Indicate whether the supplied gravity has a vertical pull.</p>
*
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index a97167b..e73f7bf 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -36,6 +36,7 @@ abstract class HardwareLayer {
int mWidth;
int mHeight;
+ DisplayList mDisplayList;
boolean mOpaque;
@@ -79,6 +80,24 @@ abstract class HardwareLayer {
}
/**
+ * Returns the DisplayList for the layer.
+ *
+ * @return The DisplayList of the hardware layer
+ */
+ DisplayList getDisplayList() {
+ return mDisplayList;
+ }
+
+ /**
+ * Sets the DisplayList for the layer.
+ *
+ * @param displayList The new DisplayList for this layer
+ */
+ void setDisplayList(DisplayList displayList) {
+ mDisplayList = displayList;
+ }
+
+ /**
* Returns whether or not this layer is opaque.
*
* @return True if the layer is opaque, false otherwise
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a651362..bf48ff2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -336,9 +336,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
* Padding can be used to offset the content of the view by a specific amount of
* pixels. For instance, a left padding of 2 will push the view's content by
* 2 pixels to the right of the left edge. Padding can be set using the
- * {@link #setPadding(int, int, int, int)} method and queried by calling
- * {@link #getPaddingLeft()}, {@link #getPaddingTop()},
- * {@link #getPaddingRight()}, {@link #getPaddingBottom()}.
+ * {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
+ * method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
+ * {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
+ * {@link #getPaddingEnd()}.
* </p>
*
* <p>
@@ -1497,6 +1498,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>();
/**
+ * Temporary flag, used to enable processing of View properties in the native DisplayList
+ * object instead of during draw(). Soon to be enabled by default for hardware-accelerated
+ * apps.
+ * @hide
+ */
+ protected static final boolean USE_DISPLAY_LIST_PROPERTIES = false;
+
+ /**
* Map used to store views' tags.
*/
private SparseArray<Object> mKeyedTags;
@@ -3952,6 +3961,24 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
+ * Convenience method for sending a {@link AccessibilityEvent#TYPE_ANNOUNCEMENT}
+ * {@link AccessibilityEvent} to make an announcement which is related to some
+ * sort of a context change for which none of the events representing UI transitions
+ * is a good fit. For example, announcing a new page in a book. If accessibility
+ * is not enabled this method does nothing.
+ *
+ * @param text The announcement text.
+ */
+ public void announceForAccessibility(CharSequence text) {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_ANNOUNCEMENT);
+ event.getText().add(text);
+ sendAccessibilityEventUnchecked(event);
+ }
+ }
+
+ /**
* @see #sendAccessibilityEvent(int)
*
* Note: Called from the default {@link AccessibilityDelegate}.
@@ -7265,6 +7292,24 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
+ * Gets the distance along the Z axis from the camera to this view.
+ *
+ * @see #setCameraDistance(float)
+ *
+ * @return The distance along the Z axis.
+ */
+ public float getCameraDistance() {
+ ensureTransformationInfo();
+ final float dpi = mResources.getDisplayMetrics().densityDpi;
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mCamera == null) {
+ info.mCamera = new Camera();
+ info.matrix3D = new Matrix();
+ }
+ return -(info.mCamera.getLocationZ() * dpi);
+ }
+
+ /**
* <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
* views are drawn) from the camera to this view. The camera's distance
* affects 3D transformations, for instance rotations around the X and Y
@@ -7319,6 +7364,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setCameraDistance(distance);
+ }
}
/**
@@ -7360,6 +7408,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setRotation(rotation);
+ }
}
}
@@ -7407,6 +7458,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setRotationY(rotationY);
+ }
}
}
@@ -7454,6 +7508,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setRotationX(rotationX);
+ }
}
}
@@ -7493,6 +7550,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setScaleX(scaleX);
+ }
}
}
@@ -7532,6 +7592,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setScaleY(scaleY);
+ }
}
}
@@ -7577,6 +7640,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setPivotX(pivotX);
+ }
}
}
@@ -7621,6 +7687,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setPivotY(pivotY);
+ }
}
}
@@ -7667,6 +7736,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
} else {
mPrivateFlags &= ~ALPHA_SET;
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setAlpha(alpha);
+ }
}
}
}
@@ -7691,6 +7763,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
return true;
} else {
mPrivateFlags &= ~ALPHA_SET;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setAlpha(alpha);
+ }
}
}
return false;
@@ -7740,6 +7815,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
int oldHeight = mBottom - mTop;
mTop = top;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setTop(mTop);
+ }
onSizeChanged(width, mBottom - mTop, width, oldHeight);
@@ -7806,6 +7884,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
int oldHeight = mBottom - mTop;
mBottom = bottom;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setBottom(mBottom);
+ }
onSizeChanged(width, mBottom - mTop, width, oldHeight);
@@ -7866,6 +7947,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
int height = mBottom - mTop;
mLeft = left;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setLeft(left);
+ }
onSizeChanged(mRight - mLeft, height, oldWidth, height);
@@ -7879,6 +7963,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+
+ }
}
}
@@ -7923,6 +8010,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
int height = mBottom - mTop;
mRight = right;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setRight(mRight);
+ }
onSizeChanged(mRight - mLeft, height, oldWidth, height);
@@ -8019,6 +8109,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setTranslationX(translationX);
+ }
}
}
@@ -8056,6 +8149,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setTranslationY(translationY);
+ }
}
}
@@ -8188,6 +8284,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
mTop += offset;
mBottom += offset;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.offsetTopBottom(offset);
+ }
if (!matrixIsIdentity) {
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
@@ -8229,6 +8328,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
mLeft += offset;
mRight += offset;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.offsetLeftRight(offset);
+ }
if (!matrixIsIdentity) {
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
@@ -8852,13 +8954,15 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* (for instance, if the Runnable was not in the queue already.)
*/
public boolean removeCallbacks(Runnable action) {
- final AttachInfo attachInfo = mAttachInfo;
- if (attachInfo != null) {
- attachInfo.mHandler.removeCallbacks(action);
- attachInfo.mViewRootImpl.mChoreographer.removeAnimationCallbacks(action, null);
- } else {
- // Assume that post will succeed later
- ViewRootImpl.getRunQueue().removeCallbacks(action);
+ if (action != null) {
+ final AttachInfo attachInfo = mAttachInfo;
+ if (attachInfo != null) {
+ attachInfo.mHandler.removeCallbacks(action);
+ attachInfo.mViewRootImpl.mChoreographer.removeAnimationCallbacks(action, null);
+ } else {
+ // Assume that post will succeed later
+ ViewRootImpl.getRunQueue().removeCallbacks(action);
+ }
}
return true;
}
@@ -9799,8 +9903,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*
* @param layoutDirection the direction of the layout
*
- * {@link #LAYOUT_DIRECTION_LTR}
- * {@link #LAYOUT_DIRECTION_RTL}
+ * @see {@link #LAYOUT_DIRECTION_LTR}
+ * @see {@link #LAYOUT_DIRECTION_RTL}
*/
public void onPaddingChanged(int layoutDirection) {
}
@@ -10363,7 +10467,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
return null;
}
- mHardwareLayer.redraw(getDisplayList(), mLocalDirtyRect);
+ mHardwareLayer.redraw(getHardwareLayerDisplayList(mHardwareLayer), mLocalDirtyRect);
mLocalDirtyRect.setEmpty();
}
@@ -10515,78 +10619,138 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * <p>Returns a display list that can be used to draw this view again
- * without executing its draw method.</p>
+ * Returns a DisplayList. If the incoming displayList is null, one will be created.
+ * Otherwise, the same display list will be returned (after having been rendered into
+ * along the way, depending on the invalidation state of the view).
*
- * @return A DisplayList ready to replay, or null if caching is not enabled.
- *
- * @hide
+ * @param displayList The previous version of this displayList, could be null.
+ * @param isLayer Whether the requester of the display list is a layer. If so,
+ * the view will avoid creating a layer inside the resulting display list.
+ * @return A new or reused DisplayList object.
*/
- public DisplayList getDisplayList() {
+ private DisplayList getDisplayList(DisplayList displayList, boolean isLayer) {
if (!canHaveDisplayList()) {
return null;
}
if (((mPrivateFlags & DRAWING_CACHE_VALID) == 0 ||
- mDisplayList == null || !mDisplayList.isValid() ||
- mRecreateDisplayList)) {
+ displayList == null || !displayList.isValid() ||
+ (!isLayer && mRecreateDisplayList))) {
// Don't need to recreate the display list, just need to tell our
// children to restore/recreate theirs
- if (mDisplayList != null && mDisplayList.isValid() &&
- !mRecreateDisplayList) {
+ if (displayList != null && displayList.isValid() &&
+ !isLayer && !mRecreateDisplayList) {
mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
mPrivateFlags &= ~DIRTY_MASK;
dispatchGetDisplayList();
- return mDisplayList;
+ return displayList;
}
- // If we got here, we're recreating it. Mark it as such to ensure that
- // we copy in child display lists into ours in drawChild()
- mRecreateDisplayList = true;
- if (mDisplayList == null) {
+ if (!isLayer) {
+ // If we got here, we're recreating it. Mark it as such to ensure that
+ // we copy in child display lists into ours in drawChild()
+ mRecreateDisplayList = true;
+ }
+ if (displayList == null) {
final String name = getClass().getSimpleName();
- mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList(name);
+ displayList = mAttachInfo.mHardwareRenderer.createDisplayList(name);
// If we're creating a new display list, make sure our parent gets invalidated
// since they will need to recreate their display list to account for this
// new child display list.
invalidateParentCaches();
}
- final HardwareCanvas canvas = mDisplayList.start();
+ boolean caching = false;
+ final HardwareCanvas canvas = displayList.start();
int restoreCount = 0;
- try {
- int width = mRight - mLeft;
- int height = mBottom - mTop;
+ int width = mRight - mLeft;
+ int height = mBottom - mTop;
+ try {
canvas.setViewport(width, height);
// The dirty rect should always be null for a display list
canvas.onPreDraw(null);
+ int layerType = (
+ !(mParent instanceof ViewGroup) || ((ViewGroup)mParent).mDrawLayers) ?
+ getLayerType() : LAYER_TYPE_NONE;
+ if (!isLayer && layerType == LAYER_TYPE_HARDWARE && USE_DISPLAY_LIST_PROPERTIES) {
+ final HardwareLayer layer = getHardwareLayer();
+ if (layer != null && layer.isValid()) {
+ canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint);
+ } else {
+ canvas.saveLayer(0, 0,
+ mRight - mLeft, mBottom - mTop, mLayerPaint,
+ Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
+ }
+ caching = true;
+ } else {
- computeScroll();
+ computeScroll();
- restoreCount = canvas.save();
- canvas.translate(-mScrollX, -mScrollY);
- mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
- mPrivateFlags &= ~DIRTY_MASK;
+ if (!USE_DISPLAY_LIST_PROPERTIES) {
+ restoreCount = canvas.save();
+ }
+ canvas.translate(-mScrollX, -mScrollY);
+ if (!isLayer) {
+ mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~DIRTY_MASK;
+ }
- // Fast path for layouts with no backgrounds
- if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
- dispatchDraw(canvas);
- } else {
- draw(canvas);
+ // Fast path for layouts with no backgrounds
+ if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
+ dispatchDraw(canvas);
+ } else {
+ draw(canvas);
+ }
}
} finally {
- canvas.restoreToCount(restoreCount);
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ canvas.restoreToCount(restoreCount);
+ }
canvas.onPostDraw();
- mDisplayList.end();
+ displayList.end();
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ displayList.setCaching(caching);
+ }
+ if (isLayer && USE_DISPLAY_LIST_PROPERTIES) {
+ displayList.setLeftTopRightBottom(0, 0, width, height);
+ } else {
+ setDisplayListProperties(displayList);
+ }
}
- } else {
+ } else if (!isLayer) {
mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
mPrivateFlags &= ~DIRTY_MASK;
}
+ return displayList;
+ }
+
+ /**
+ * Get the DisplayList for the HardwareLayer
+ *
+ * @param layer The HardwareLayer whose DisplayList we want
+ * @return A DisplayList fopr the specified HardwareLayer
+ */
+ private DisplayList getHardwareLayerDisplayList(HardwareLayer layer) {
+ DisplayList displayList = getDisplayList(layer.getDisplayList(), true);
+ layer.setDisplayList(displayList);
+ return displayList;
+ }
+
+
+ /**
+ * <p>Returns a display list that can be used to draw this view again
+ * without executing its draw method.</p>
+ *
+ * @return A DisplayList ready to replay, or null if caching is not enabled.
+ *
+ * @hide
+ */
+ public DisplayList getDisplayList() {
+ mDisplayList = getDisplayList(mDisplayList, false);
return mDisplayList;
}
@@ -11056,13 +11220,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * <p>Indicates whether this view is attached to an hardware accelerated
+ * <p>Indicates whether this view is attached to a hardware accelerated
* window or not.</p>
*
* <p>Even if this method returns true, it does not mean that every call
* to {@link #draw(android.graphics.Canvas)} will be made with an hardware
* accelerated {@link android.graphics.Canvas}. For instance, if this view
- * is drawn onto an offscren {@link android.graphics.Bitmap} and its
+ * is drawn onto an offscreen {@link android.graphics.Bitmap} and its
* window is hardware accelerated,
* {@link android.graphics.Canvas#isHardwareAccelerated()} will likely
* return false, and this method will return true.</p>
@@ -11131,19 +11295,57 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
return more;
}
+ void setDisplayListProperties() {
+ setDisplayListProperties(mDisplayList);
+ }
+
+ /**
+ * This method is called by getDisplayList() when a display list is created or re-rendered.
+ * It sets or resets the current value of all properties on that display list (resetting is
+ * necessary when a display list is being re-created, because we need to make sure that
+ * previously-set transform values
+ */
+ void setDisplayListProperties(DisplayList displayList) {
+ if (USE_DISPLAY_LIST_PROPERTIES && displayList != null) {
+ displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
+ if (mParent instanceof ViewGroup) {
+ displayList.setClipChildren(
+ (((ViewGroup)mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
+ }
+ if (mAttachInfo != null && mAttachInfo.mScalingRequired &&
+ mAttachInfo.mApplicationScale != 1.0f) {
+ displayList.setApplicationScale(1f / mAttachInfo.mApplicationScale);
+ }
+ if (mTransformationInfo != null) {
+ displayList.setTransformationInfo(mTransformationInfo.mAlpha,
+ mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY,
+ mTransformationInfo.mRotation, mTransformationInfo.mRotationX,
+ mTransformationInfo.mRotationY, mTransformationInfo.mScaleX,
+ mTransformationInfo.mScaleY);
+ displayList.setCameraDistance(getCameraDistance());
+ if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == PIVOT_EXPLICITLY_SET) {
+ displayList.setPivotX(getPivotX());
+ displayList.setPivotY(getPivotY());
+ }
+ }
+ }
+ }
+
/**
* This method is called by ViewGroup.drawChild() to have each child view draw itself.
* This draw() method is an implementation detail and is not intended to be overridden or
* to be called from anywhere else other than ViewGroup.drawChild().
*/
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
+ boolean useDisplayListProperties = USE_DISPLAY_LIST_PROPERTIES && mAttachInfo != null &&
+ mAttachInfo.mHardwareAccelerated;
boolean more = false;
final boolean childHasIdentityMatrix = hasIdentityMatrix();
final int flags = parent.mGroupFlags;
- if ((flags & parent.FLAG_CLEAR_TRANSFORMATION) == parent.FLAG_CLEAR_TRANSFORMATION) {
+ if ((flags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) == ViewGroup.FLAG_CLEAR_TRANSFORMATION) {
parent.mChildTransformation.clear();
- parent.mGroupFlags &= ~parent.FLAG_CLEAR_TRANSFORMATION;
+ parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
Transformation transformToApply = null;
@@ -11154,8 +11356,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
int layerType = parent.mDrawLayers ? getLayerType() : LAYER_TYPE_NONE;
final boolean hardwareAccelerated = canvas.isHardwareAccelerated();
- if ((flags & parent.FLAG_CHILDREN_DRAWN_WITH_CACHE) == parent.FLAG_CHILDREN_DRAWN_WITH_CACHE ||
- (flags & parent.FLAG_ALWAYS_DRAWN_WITH_CACHE) == parent.FLAG_ALWAYS_DRAWN_WITH_CACHE) {
+ if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 ||
+ (flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
caching = true;
if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
} else {
@@ -11167,8 +11369,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
more = drawAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
transformToApply = parent.mChildTransformation;
- } else if ((flags & parent.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) ==
- parent.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) {
+ } else if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
final boolean hasTransform =
parent.getChildStaticTransformation(this, parent.mChildTransformation);
if (hasTransform) {
@@ -11218,6 +11419,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
buildDrawingCache(true);
cache = getDrawingCache(true);
break;
+ case LAYER_TYPE_HARDWARE:
+ if (useDisplayListProperties) {
+ hasDisplayList = canHaveDisplayList();
+ }
+ break;
case LAYER_TYPE_NONE:
// Delay getting the display list until animation-driven alpha values are
// set up and possibly passed on to the view
@@ -11226,24 +11432,33 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
}
}
+ useDisplayListProperties &= hasDisplayList;
final boolean hasNoCache = cache == null || hasDisplayList;
final boolean offsetForScroll = cache == null && !hasDisplayList &&
layerType != LAYER_TYPE_HARDWARE;
- final int restoreTo = canvas.save();
+ int restoreTo = -1;
+ if (!useDisplayListProperties) {
+ restoreTo = canvas.save();
+ }
if (offsetForScroll) {
canvas.translate(mLeft - sx, mTop - sy);
} else {
- canvas.translate(mLeft, mTop);
+ if (!useDisplayListProperties) {
+ canvas.translate(mLeft, mTop);
+ }
if (scalingRequired) {
+ if (useDisplayListProperties) {
+ restoreTo = canvas.save();
+ }
// mAttachInfo cannot be null, otherwise scalingRequired == false
final float scale = 1.0f / mAttachInfo.mApplicationScale;
canvas.scale(scale, scale);
}
}
- float alpha = getAlpha();
+ float alpha = useDisplayListProperties ? 1 : getAlpha();
if (transformToApply != null || alpha < 1.0f || !hasIdentityMatrix()) {
if (transformToApply != null || !childHasIdentityMatrix) {
int transX = 0;
@@ -11258,20 +11473,22 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (concatMatrix) {
// Undo the scroll translation, apply the transformation matrix,
// then redo the scroll translate to get the correct result.
- canvas.translate(-transX, -transY);
- canvas.concat(transformToApply.getMatrix());
- canvas.translate(transX, transY);
- parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION;
+ if (!hasDisplayList) {
+ canvas.translate(-transX, -transY);
+ canvas.concat(transformToApply.getMatrix());
+ canvas.translate(transX, transY);
+ }
+ parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
float transformAlpha = transformToApply.getAlpha();
if (transformAlpha < 1.0f) {
alpha *= transformToApply.getAlpha();
- parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION;
+ parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
}
- if (!childHasIdentityMatrix) {
+ if (!childHasIdentityMatrix && !useDisplayListProperties) {
canvas.translate(-transX, -transY);
canvas.concat(getMatrix());
canvas.translate(transX, transY);
@@ -11279,20 +11496,22 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
if (alpha < 1.0f) {
- parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION;
+ parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
if (hasNoCache) {
final int multipliedAlpha = (int) (255 * alpha);
if (!onSetAlpha(multipliedAlpha)) {
int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
- if ((flags & parent.FLAG_CLIP_CHILDREN) == parent.FLAG_CLIP_CHILDREN ||
+ if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 ||
layerType != LAYER_TYPE_NONE) {
layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
}
if (layerType == LAYER_TYPE_NONE) {
- final int scrollX = hasDisplayList ? 0 : sx;
- final int scrollY = hasDisplayList ? 0 : sy;
- canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft,
- scrollY + mBottom - mTop, multipliedAlpha, layerFlags);
+ if (!useDisplayListProperties) {
+ final int scrollX = hasDisplayList ? 0 : sx;
+ final int scrollY = hasDisplayList ? 0 : sy;
+ canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft,
+ scrollY + mBottom - mTop, multipliedAlpha, layerFlags);
+ }
}
} else {
// Alpha is handled by the child directly, clobber the layer's alpha
@@ -11305,7 +11524,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
mPrivateFlags &= ~ALPHA_SET;
}
- if ((flags & parent.FLAG_CLIP_CHILDREN) == parent.FLAG_CLIP_CHILDREN) {
+ if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN &&
+ !useDisplayListProperties) {
if (offsetForScroll) {
canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop));
} else {
@@ -11330,7 +11550,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (hasNoCache) {
boolean layerRendered = false;
- if (layerType == LAYER_TYPE_HARDWARE) {
+ if (layerType == LAYER_TYPE_HARDWARE && !useDisplayListProperties) {
final HardwareLayer layer = getHardwareLayer();
if (layer != null && layer.isValid()) {
mLayerPaint.setAlpha((int) (alpha * 255));
@@ -11376,11 +11596,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
if (alpha < 1.0f) {
cachePaint.setAlpha((int) (alpha * 255));
- parent.mGroupFlags |= parent.FLAG_ALPHA_LOWER_THAN_ONE;
- } else if ((flags & parent.FLAG_ALPHA_LOWER_THAN_ONE) ==
- parent.FLAG_ALPHA_LOWER_THAN_ONE) {
+ parent.mGroupFlags |= ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE;
+ } else if ((flags & ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE) != 0) {
cachePaint.setAlpha(255);
- parent.mGroupFlags &= ~parent.FLAG_ALPHA_LOWER_THAN_ONE;
+ parent.mGroupFlags &= ~ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE;
}
} else {
cachePaint = mLayerPaint;
@@ -11389,7 +11608,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
}
- canvas.restoreToCount(restoreTo);
+ if (restoreTo >= 0) {
+ canvas.restoreToCount(restoreTo);
+ }
if (a != null && !more) {
if (!hardwareAccelerated && !a.getFillAfter()) {
@@ -11847,6 +12068,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
mTop = top;
mRight = right;
mBottom = bottom;
+ if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
+ mDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
+ }
mPrivateFlags |= HAS_BOUNDS;
@@ -11963,7 +12187,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* @see #drawableStateChanged
*/
public void unscheduleDrawable(Drawable who) {
- if (mAttachInfo != null) {
+ if (mAttachInfo != null && who != null) {
mAttachInfo.mViewRootImpl.mChoreographer.removeAnimationCallbacks(null, who);
}
}
@@ -12453,9 +12677,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * Returns the start padding of this view. If there are inset and enabled
- * scrollbars, this value may include the space required to display the
- * scrollbars as well.
+ * Returns the start padding of this view depending on its resolved layout direction.
+ * If there are inset and enabled scrollbars, this value may include the space
+ * required to display the scrollbars as well.
*
* @return the start padding in pixels
*/
@@ -12476,9 +12700,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * Returns the end padding of this view. If there are inset and enabled
- * scrollbars, this value may include the space required to display the
- * scrollbars as well.
+ * Returns the end padding of this view depending on its resolved layout direction.
+ * If there are inset and enabled scrollbars, this value may include the space
+ * required to display the scrollbars as well.
*
* @return the end padding in pixels
*/
@@ -13125,7 +13349,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * Creates an string of whitespaces used for indentation.
+ * Creates a string of whitespaces used for indentation.
*
* @param depth the indentation level
* @return a String containing (depth * 2 + 3) * 2 white spaces
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index b455ad5..20183ee 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -305,8 +305,9 @@ public class ViewConfiguration {
mScaledTouchExplorationTapSlop = (int) (density * TOUCH_EXPLORATION_TAP_SLOP + 0.5f);
mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
+ final Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
// Size of the screen in bytes, in ARGB_8888 format
- mMaximumDrawingCacheSize = 4 * metrics.widthPixels * metrics.heightPixels;
+ mMaximumDrawingCacheSize = 4 * display.getRawWidth() * display.getRawHeight();
mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 2a17845..8f6badf 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -264,7 +264,7 @@ public class ViewDebug {
/**
* Defines a mapping from an int value to a String. Such a mapping can be used
- * in a @ExportedProperty to provide more meaningful values to the end user.
+ * in an @ExportedProperty to provide more meaningful values to the end user.
*
* @see android.view.ViewDebug.ExportedProperty
*/
@@ -287,8 +287,8 @@ public class ViewDebug {
}
/**
- * Defines a mapping from an flag to a String. Such a mapping can be used
- * in a @ExportedProperty to provide more meaningful values to the end user.
+ * Defines a mapping from a flag to a String. Such a mapping can be used
+ * in an @ExportedProperty to provide more meaningful values to the end user.
*
* @see android.view.ViewDebug.ExportedProperty
*/
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c9e0242..1993ce6 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2736,7 +2736,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @attr ref android.R.styleable#ViewGroup_clipChildren
*/
public void setClipChildren(boolean clipChildren) {
- setBooleanFlag(FLAG_CLIP_CHILDREN, clipChildren);
+ boolean previousValue = (mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN;
+ if (clipChildren != previousValue) {
+ setBooleanFlag(FLAG_CLIP_CHILDREN, clipChildren);
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ for (int i = 0; i < mChildrenCount; ++i) {
+ View child = getChildAt(i);
+ if (child.mDisplayList != null) {
+ child.mDisplayList.setClipChildren(clipChildren);
+ }
+ }
+ }
+ }
}
/**
@@ -3973,6 +3984,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final View v = children[i];
v.mTop += offset;
v.mBottom += offset;
+ if (USE_DISPLAY_LIST_PROPERTIES && v.mDisplayList != null) {
+ v.mDisplayList.offsetTopBottom(offset);
+ }
}
}
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 0fdcd0f..fe0e659 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -866,6 +866,8 @@ public class ViewPropertyAnimator {
info.mAlpha = value;
break;
}
+ // TODO: optimize to set only the properties that have changed
+ mView.setDisplayListProperties();
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 72365c7..4472f8c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -51,6 +51,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.Trace;
import android.util.AndroidRuntimeException;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -960,7 +961,12 @@ public final class ViewRootImpl implements ViewParent,
}
}
- performTraversals();
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "performTraversals");
+ try {
+ performTraversals();
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
if (ViewDebug.DEBUG_LATENCY) {
long now = System.nanoTime();
@@ -1919,7 +1925,13 @@ public final class ViewRootImpl implements ViewParent,
final boolean fullRedrawNeeded = mFullRedrawNeeded;
mFullRedrawNeeded = false;
- draw(fullRedrawNeeded);
+
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
+ try {
+ draw(fullRedrawNeeded);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
if (ViewDebug.DEBUG_LATENCY) {
long now = System.nanoTime();
@@ -2897,17 +2909,22 @@ public final class ViewRootImpl implements ViewParent,
q.mDeliverTimeNanos = System.nanoTime();
}
- if (q.mEvent instanceof KeyEvent) {
- deliverKeyEvent(q);
- } else {
- final int source = q.mEvent.getSource();
- if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
- deliverPointerEvent(q);
- } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
- deliverTrackballEvent(q);
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "deliverInputEvent");
+ try {
+ if (q.mEvent instanceof KeyEvent) {
+ deliverKeyEvent(q);
} else {
- deliverGenericMotionEvent(q);
+ final int source = q.mEvent.getSource();
+ if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ deliverPointerEvent(q);
+ } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
+ deliverTrackballEvent(q);
+ } else {
+ deliverGenericMotionEvent(q);
+ }
}
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c0eb65b..f3ef329 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -787,10 +787,10 @@ public interface WindowManager extends ViewManager {
* hardware accelerated. This is used for the starting preview windows
* in the system process, which don't need to have the overhead of
* hardware acceleration (they are just a static rendering), but should
- * be rendered as much to match the actual window of the app even if it
+ * be rendered as such to match the actual window of the app even if it
* is hardware accelerated.
* Even if the window isn't hardware accelerated, still do its rendering
- * as if it is.
+ * as if it was.
* Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
* that need hardware acceleration (e.g. LockScreen), where hardware acceleration
* is generally disabled. This flag must be specified in addition to
@@ -803,7 +803,7 @@ public interface WindowManager extends ViewManager {
/**
* In the system process, we globally do not use hardware acceleration
- * because there are many threads doing UI there and they an conflict.
+ * because there are many threads doing UI there and they conflict.
* If certain parts of the UI that really do want to use hardware
* acceleration, this flag can be set to force it. This is basically
* for the lock screen. Anyone else using it, you are probably wrong.
@@ -814,7 +814,7 @@ public interface WindowManager extends ViewManager {
/**
* By default, wallpapers are sent new offsets when the wallpaper is scrolled. Wallpapers
- * may elect to skp these notifications if they are no doing anything productive with
+ * may elect to skip these notifications if they are not doing anything productive with
* them (they do not affect the wallpaper scrolling operation) by calling
* {@link
* android.service.wallpaper.WallpaperService.Engine#setOffsetNotificationsEnabled(boolean)}.
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 75b875a..58844fc 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -429,6 +429,26 @@ import java.util.List;
* view.</br>
* </p>
* <p>
+ * <b>MISCELLANEOUS TYPES</b></br>
+ * </p>
+ * <p>
+ * <b>Announcement</b> - represents the event of an application making an
+ * announcement. Usually this announcement is related to some sort of a context
+ * change for which none of the events representing UI transitions is a good fit.
+ * For example, announcing a new page in a book.</br>
+ * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li>
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the announcement.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * </ul>
+ * </p>
+ * <p>
* <b>Security note</b>
* <p>
* Since an event contains the text of its source privacy can be compromised by leaking
@@ -538,6 +558,11 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
/**
+ * Represents the event of an application making an announcement.
+ */
+ public static final int TYPE_ANNOUNCEMENT = 0x00004000;
+
+ /**
* Mask for {@link AccessibilityEvent} all types.
*
* @see #TYPE_VIEW_CLICKED
@@ -554,6 +579,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
* @see #TYPE_WINDOW_CONTENT_CHANGED
* @see #TYPE_VIEW_SCROLLED
* @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
+ * @see #TYPE_ANNOUNCEMENT
*/
public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
@@ -984,6 +1010,8 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
case TYPE_VIEW_SCROLLED:
return "TYPE_VIEW_SCROLLED";
+ case TYPE_ANNOUNCEMENT:
+ return "TYPE_ANNOUNCEMENT";
default:
return null;
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index c094fda..03c6211 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -994,7 +994,7 @@ public class AccessibilityNodeInfo implements Parcelable {
protected void enforceNotSealed() {
if (isSealed()) {
throw new IllegalStateException("Cannot perform this "
- + "action on an sealed instance.");
+ + "action on a sealed instance.");
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 23b235c..bc6074f 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -632,7 +632,7 @@ public class AccessibilityRecord {
void enforceNotSealed() {
if (isSealed()) {
throw new IllegalStateException("Cannot perform this "
- + "action on an sealed instance.");
+ + "action on a sealed instance.");
}
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 3b6ebbe..0e5ff20 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -62,6 +62,9 @@ import java.util.concurrent.TimeUnit;
* <p>Topics covered here:
* <ol>
* <li><a href="#ArchitectureOverview">Architecture Overview</a>
+ * <li><a href="#Applications">Applications</a>
+ * <li><a href="#InputMethods">Input Methods</a>
+ * <li><a href="#Security">Security</a>
* </ol>
*
* <a name="ArchitectureOverview"></a>
diff --git a/core/java/android/view/textservice/SpellCheckerInfo.java b/core/java/android/view/textservice/SpellCheckerInfo.java
index 9d8475d..137743a 100644
--- a/core/java/android/view/textservice/SpellCheckerInfo.java
+++ b/core/java/android/view/textservice/SpellCheckerInfo.java
@@ -38,7 +38,7 @@ import java.io.IOException;
import java.util.ArrayList;
/**
- * This class is used to specify meta information of an spell checker.
+ * This class is used to specify meta information of a spell checker.
*/
public final class SpellCheckerInfo implements Parcelable {
private static final String TAG = SpellCheckerInfo.class.getSimpleName();
@@ -53,7 +53,7 @@ public final class SpellCheckerInfo implements Parcelable {
private final String mSettingsActivityName;
/**
- * The array of the subtypes.
+ * The array of subtypes.
*/
private final ArrayList<SpellCheckerSubtype> mSubtypes = new ArrayList<SpellCheckerSubtype>();
diff --git a/core/java/android/webkit/AutoCompletePopup.java b/core/java/android/webkit/AutoCompletePopup.java
new file mode 100644
index 0000000..674428a
--- /dev/null
+++ b/core/java/android/webkit/AutoCompletePopup.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.webkit;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Message;
+import android.text.Editable;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.AbsoluteLayout;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ListAdapter;
+import android.widget.ListPopupWindow;
+
+class AutoCompletePopup implements OnItemClickListener, Filter.FilterListener {
+ private static class AnchorView extends View {
+ AnchorView(Context context) {
+ super(context);
+ setFocusable(false);
+ }
+ }
+ private static final int AUTOFILL_FORM = 100;
+ private boolean mIsAutoFillProfileSet;
+ private Handler mHandler;
+ private int mQueryId;
+ private Rect mNodeBounds = new Rect();
+ private int mNodeLayerId;
+ private ListPopupWindow mPopup;
+ private Filter mFilter;
+ private CharSequence mText;
+ private ListAdapter mAdapter;
+ private boolean mIsFocused;
+ private View mAnchor;
+ private WebViewClassic.WebViewInputConnection mInputConnection;
+ private WebViewClassic mWebView;
+
+ public AutoCompletePopup(Context context,
+ WebViewClassic webView,
+ WebViewClassic.WebViewInputConnection inputConnection) {
+ mInputConnection = inputConnection;
+ mWebView = webView;
+ mPopup = new ListPopupWindow(context);
+ mAnchor = new AnchorView(context);
+ mWebView.getWebView().addView(mAnchor);
+ mPopup.setOnItemClickListener(this);
+ mPopup.setAnchorView(mAnchor);
+ mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
+ mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AUTOFILL_FORM:
+ mWebView.autoFillForm(mQueryId);
+ break;
+ }
+ }
+ };
+ }
+
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK && mPopup.isShowing()) {
+ // special case for the back key, we do not even try to send it
+ // to the drop down list but instead, consume it immediately
+ if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+ KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState();
+ if (state != null) {
+ state.handleUpEvent(event);
+ }
+ if (event.isTracking() && !event.isCanceled()) {
+ mPopup.dismiss();
+ return true;
+ }
+ }
+ }
+ if (mPopup.isShowing()) {
+ return mPopup.onKeyPreIme(keyCode, event);
+ }
+ return false;
+ }
+
+ public void setFocused(boolean isFocused) {
+ mIsFocused = isFocused;
+ if (!mIsFocused) {
+ mPopup.dismiss();
+ }
+ }
+
+ public void setText(CharSequence text) {
+ mText = text;
+ if (mFilter != null) {
+ mFilter.filter(text, this);
+ }
+ }
+
+ public void setAutoFillQueryId(int queryId) {
+ mQueryId = queryId;
+ }
+
+ public void clearAdapter() {
+ mAdapter = null;
+ mFilter = null;
+ mPopup.dismiss();
+ mPopup.setAdapter(null);
+ }
+
+ public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
+ mPopup.setAdapter(adapter);
+ mAdapter = adapter;
+ if (adapter != null) {
+ mFilter = adapter.getFilter();
+ mFilter.filter(mText, this);
+ } else {
+ mFilter = null;
+ }
+ resetRect();
+ }
+
+ public void setNodeBounds(Rect nodeBounds, int layerId) {
+ mNodeBounds.set(nodeBounds);
+ mNodeLayerId = layerId;
+ resetRect();
+ }
+
+ public void resetRect() {
+ int left = mWebView.contentToViewX(mNodeBounds.left);
+ int right = mWebView.contentToViewX(mNodeBounds.right);
+ int width = right - left;
+ mPopup.setWidth(width);
+
+ int bottom = mWebView.contentToViewY(mNodeBounds.bottom);
+ int top = mWebView.contentToViewY(mNodeBounds.top);
+ int height = bottom - top;
+
+ AbsoluteLayout.LayoutParams lp =
+ (AbsoluteLayout.LayoutParams) mAnchor.getLayoutParams();
+ boolean needsUpdate = false;
+ if (null == lp) {
+ lp = new AbsoluteLayout.LayoutParams(width, height, left, top);
+ } else {
+ if ((lp.x != left) || (lp.y != top) || (lp.width != width)
+ || (lp.height != height)) {
+ needsUpdate = true;
+ lp.x = left;
+ lp.y = top;
+ lp.width = width;
+ lp.height = height;
+ }
+ }
+ if (needsUpdate) {
+ mAnchor.setLayoutParams(lp);
+ }
+ if (mPopup.isShowing()) {
+ mPopup.show(); // update its position
+ }
+ }
+
+ public void scrollDelta(int layerId, int dx, int dy) {
+ if (layerId == mNodeLayerId) {
+ mNodeBounds.offset(dx, dy);
+ resetRect();
+ }
+ }
+
+ // AdapterView.OnItemClickListener implementation
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ if (id == 0 && position == 0 && mInputConnection.getIsAutoFillable()) {
+ mText = "";
+ pushTextToInputConnection();
+ // Blank out the text box while we wait for WebCore to fill the form.
+ if (mIsAutoFillProfileSet) {
+ // Call a webview method to tell WebCore to autofill the form.
+ mWebView.autoFillForm(mQueryId);
+ } else {
+ // There is no autofill profile setup yet and the user has
+ // elected to try and set one up. Call through to the
+ // embedder to action that.
+ mWebView.getWebChromeClient().setupAutoFill(
+ mHandler.obtainMessage(AUTOFILL_FORM));
+ }
+ } else {
+ Object selectedItem;
+ if (position < 0) {
+ selectedItem = mPopup.getSelectedItem();
+ } else {
+ selectedItem = mAdapter.getItem(position);
+ }
+ if (selectedItem != null) {
+ setText(mFilter.convertResultToString(selectedItem));
+ pushTextToInputConnection();
+ }
+ }
+ mPopup.dismiss();
+ }
+
+ public void setIsAutoFillProfileSet(boolean isAutoFillProfileSet) {
+ mIsAutoFillProfileSet = isAutoFillProfileSet;
+ }
+
+ private void pushTextToInputConnection() {
+ Editable oldText = mInputConnection.getEditable();
+ mInputConnection.setSelection(0, oldText.length());
+ mInputConnection.replaceSelection(mText);
+ mInputConnection.setSelection(mText.length(), mText.length());
+ }
+
+ @Override
+ public void onFilterComplete(int count) {
+ if (!mIsFocused) {
+ mPopup.dismiss();
+ return;
+ }
+
+ boolean showDropDown = (count > 0) &&
+ (mInputConnection.getIsAutoFillable() || mText.length() > 0);
+ if (showDropDown) {
+ if (!mPopup.isShowing()) {
+ // Make sure the list does not obscure the IME when shown for the first time.
+ mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED);
+ }
+ mPopup.show();
+ mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
+ } else {
+ mPopup.dismiss();
+ }
+ }
+}
+
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 2afb841..800ebc8 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -76,6 +76,8 @@ class CallbackProxy extends Handler {
private volatile WebBackForwardListClient mWebBackForwardListClient;
// Used to call startActivity during url override.
private final Context mContext;
+ // block messages flag for destroy
+ private boolean mBlockMessages;
// Message IDs
private static final int PAGE_STARTED = 100;
@@ -155,10 +157,18 @@ class CallbackProxy extends Handler {
mBackForwardList = new WebBackForwardList(this);
}
+ protected synchronized void blockMessages() {
+ mBlockMessages = true;
+ }
+
+ protected synchronized boolean messagesBlocked() {
+ return mBlockMessages;
+ }
+
protected void shutdown() {
+ removeCallbacksAndMessages(null);
setWebViewClient(null);
setWebChromeClient(null);
- removeCallbacksAndMessages(null);
}
/**
@@ -265,6 +275,7 @@ class CallbackProxy extends Handler {
// in the UI thread. The WebViewClient and WebChromeClient functions
// that check for a non-null callback are ok because java ensures atomic
// 32-bit reads and writes.
+ if (messagesBlocked()) return;
switch (msg.what) {
case PAGE_STARTED:
String startedUrl = msg.getData().getString("url");
diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java
index 542dd21..9970c93 100644
--- a/core/java/android/webkit/URLUtil.java
+++ b/core/java/android/webkit/URLUtil.java
@@ -182,7 +182,7 @@ public final class URLUtil {
}
/**
- * @return True iff the url is an proxy url to allow cookieless network
+ * @return True iff the url is a proxy url to allow cookieless network
* requests from a file url.
* @deprecated Cookieless proxy is no longer supported.
*/
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 72aed4b..812d89a 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -375,7 +375,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
* InputConnection used for ContentEditable. This captures changes
* to the text and sends them either as key strokes or text changes.
*/
- private class WebViewInputConnection extends BaseInputConnection {
+ class WebViewInputConnection extends BaseInputConnection {
// Used for mapping characters to keys typed.
private KeyCharacterMap mKeyCharacterMap;
private boolean mIsKeySentByMe;
@@ -383,11 +383,31 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private int mImeOptions;
private String mHint;
private int mMaxLength;
+ private boolean mIsAutoFillable;
+ private boolean mIsAutoCompleteEnabled;
+ private String mName;
public WebViewInputConnection() {
super(mWebView, true);
}
+ public void setAutoFillable(int queryId) {
+ mIsAutoFillable = getSettings().getAutoFillEnabled()
+ && (queryId != WebTextView.FORM_NOT_AUTOFILLABLE);
+ int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION;
+ if (variation != EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD
+ && (mIsAutoFillable || mIsAutoCompleteEnabled)) {
+ if (mName != null && mName.length() > 0) {
+ requestFormData(mName, mFieldPointer, mIsAutoFillable,
+ mIsAutoCompleteEnabled);
+ }
+ }
+ }
+
+ public boolean getIsAutoFillable() {
+ return mIsAutoFillable;
+ }
+
@Override
public boolean sendKeyEvent(KeyEvent event) {
// Some IMEs send key events directly using sendKeyEvents.
@@ -582,6 +602,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mInputType = inputType;
mImeOptions = imeOptions;
mMaxLength = initData.mMaxLength;
+ mIsAutoCompleteEnabled = initData.mIsAutoCompleteEnabled;
+ mName = initData.mName;
+ mAutoCompletePopup.clearAdapter();
}
public void setupEditorInfo(EditorInfo outAttrs) {
@@ -629,6 +652,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
REPLACE_TEXT, start, end, text.toString());
mPrivateHandler.sendMessage(replaceMessage);
}
+ if (mAutoCompletePopup != null) {
+ StringBuilder newText = new StringBuilder();
+ newText.append(editable.subSequence(0, start));
+ newText.append(text);
+ newText.append(editable.subSequence(end, editable.length()));
+ mAutoCompletePopup.setText(newText.toString());
+ }
mIsKeySentByMe = false;
}
@@ -795,6 +825,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
WebViewInputConnection mInputConnection = null;
private int mFieldPointer;
private PastePopupWindow mPasteWindow;
+ AutoCompletePopup mAutoCompletePopup;
private static class OnTrimMemoryListener implements ComponentCallbacks2 {
private static OnTrimMemoryListener sInstance = null;
@@ -1104,6 +1135,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private static final int SWITCH_TO_SHORTPRESS = 3;
private static final int SWITCH_TO_LONGPRESS = 4;
private static final int RELEASE_SINGLE_TAP = 5;
+ private static final int REQUEST_FORM_DATA = 6;
private static final int DRAG_HELD_MOTIONLESS = 8;
private static final int AWAKEN_SCROLL_BARS = 9;
private static final int PREVENT_DEFAULT_TIMEOUT = 10;
@@ -1156,6 +1188,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
static final int REPLACE_TEXT = 143;
static final int CLEAR_CARET_HANDLE = 144;
static final int KEY_PRESS = 145;
+ static final int RELOCATE_AUTO_COMPLETE_POPUP = 146;
+ static final int FOCUS_NODE_CHANGED = 147;
+ static final int AUTOFILL_FORM = 148;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;
@@ -2070,6 +2105,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
private void destroyImpl() {
+ mCallbackProxy.blockMessages();
clearHelpers();
if (mListBoxDialog != null) {
mListBoxDialog.dismiss();
@@ -3559,7 +3595,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
@Override
public void clearFormData() {
checkThread();
- // TODO: Implement b/6083041
+ if (mAutoCompletePopup != null) {
+ mAutoCompletePopup.clearAdapter();
+ }
}
/**
@@ -3860,12 +3898,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
private void scrollLayerTo(int x, int y) {
- if (x == mScrollingLayerRect.left && y == mScrollingLayerRect.top) {
+ int dx = mScrollingLayerRect.left - x;
+ int dy = mScrollingLayerRect.top - y;
+ if (dx == 0 && y == 0) {
return;
}
if (mSelectingText) {
- int dx = mScrollingLayerRect.left - x;
- int dy = mScrollingLayerRect.top - y;
if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) {
mSelectCursorBase.offset(dx, dy);
}
@@ -3873,6 +3911,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mSelectCursorExtent.offset(dx, dy);
}
}
+ if (mAutoCompletePopup != null) {
+ mAutoCompletePopup.scrollDelta(mCurrentScrollingLayerId, dx, dy);
+ }
nativeScrollLayer(mCurrentScrollingLayerId, x, y);
mScrollingLayerRect.left = x;
mScrollingLayerRect.top = y;
@@ -3896,6 +3937,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// helper to pin the scrollTo parameters (already in view coordinates)
// returns true if the scroll was changed
private boolean pinScrollTo(int x, int y, boolean animate, int animationDuration) {
+ abortAnimation();
x = pinLocX(x);
y = pinLocY(y);
int dx = x - getScrollX();
@@ -3904,7 +3946,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if ((dx | dy) == 0) {
return false;
}
- abortAnimation();
if (animate) {
// Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
mScroller.startScroll(getScrollX(), getScrollY(), dx, dy,
@@ -4176,9 +4217,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// is used in the view system.
return;
}
- int vx = contentToViewX(cx);
- int vy = contentToViewY(cy);
- pinScrollTo(vx, vy, true, 0);
+ int vx = contentToViewDimension(cx - mScrollOffset.x);
+ int vy = contentToViewDimension(cy - mScrollOffset.y);
+ pinScrollBy(vx, vy, true, 0);
}
/**
@@ -4725,6 +4766,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
private void onZoomAnimationEnd() {
+ mPrivateHandler.sendEmptyMessage(RELOCATE_AUTO_COMPLETE_POPUP);
}
void onFixedLengthZoomAnimationStart() {
@@ -4879,11 +4921,20 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (mInputConnection == null) {
mInputConnection = new WebViewInputConnection();
+ mAutoCompletePopup = new AutoCompletePopup(mContext, this,
+ mInputConnection);
}
mInputConnection.setupEditorInfo(outAttrs);
return mInputConnection;
}
+ private void relocateAutoCompletePopup() {
+ if (mAutoCompletePopup != null) {
+ mAutoCompletePopup.resetRect();
+ mAutoCompletePopup.setText(mInputConnection.getEditable());
+ }
+ }
+
/**
* Called in response to a message from webkit telling us that the soft
* keyboard should be launched.
@@ -4915,6 +4966,91 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
/**
+ * Called by AutoCompletePopup to find saved form data associated with the
+ * textfield
+ * @param name Name of the textfield.
+ * @param nodePointer Pointer to the node of the textfield, so it can be
+ * compared to the currently focused textfield when the data is
+ * retrieved.
+ * @param autoFillable true if WebKit has determined this field is part of
+ * a form that can be auto filled.
+ * @param autoComplete true if the attribute "autocomplete" is set to true
+ * on the textfield.
+ */
+ /* package */ void requestFormData(String name, int nodePointer,
+ boolean autoFillable, boolean autoComplete) {
+ if (mWebViewCore.getSettings().getSaveFormData()) {
+ Message update = mPrivateHandler.obtainMessage(REQUEST_FORM_DATA);
+ update.arg1 = nodePointer;
+ RequestFormData updater = new RequestFormData(name, getUrl(),
+ update, autoFillable, autoComplete);
+ Thread t = new Thread(updater);
+ t.start();
+ }
+ }
+
+ /*
+ * This class requests an Adapter for the AutoCompletePopup which shows past
+ * entries stored in the database. It is a Runnable so that it can be done
+ * in its own thread, without slowing down the UI.
+ */
+ private class RequestFormData implements Runnable {
+ private String mName;
+ private String mUrl;
+ private Message mUpdateMessage;
+ private boolean mAutoFillable;
+ private boolean mAutoComplete;
+ private WebSettingsClassic mWebSettings;
+
+ public RequestFormData(String name, String url, Message msg,
+ boolean autoFillable, boolean autoComplete) {
+ mName = name;
+ mUrl = WebTextView.urlForAutoCompleteData(url);
+ mUpdateMessage = msg;
+ mAutoFillable = autoFillable;
+ mAutoComplete = autoComplete;
+ mWebSettings = getSettings();
+ }
+
+ @Override
+ public void run() {
+ ArrayList<String> pastEntries = new ArrayList<String>();
+
+ if (mAutoFillable) {
+ // Note that code inside the adapter click handler in AutoCompletePopup depends
+ // on the AutoFill item being at the top of the drop down list. If you change
+ // the order, make sure to do it there too!
+ if (mWebSettings != null && mWebSettings.getAutoFillProfile() != null) {
+ pastEntries.add(mWebView.getResources().getText(
+ com.android.internal.R.string.autofill_this_form).toString() +
+ " " +
+ mAutoFillData.getPreviewString());
+ mAutoCompletePopup.setIsAutoFillProfileSet(true);
+ } else {
+ // There is no autofill profile set up yet, so add an option that
+ // will invite the user to set their profile up.
+ pastEntries.add(mWebView.getResources().getText(
+ com.android.internal.R.string.setup_autofill).toString());
+ mAutoCompletePopup.setIsAutoFillProfileSet(false);
+ }
+ }
+
+ if (mAutoComplete) {
+ pastEntries.addAll(mDatabase.getFormData(mUrl, mName));
+ }
+
+ if (pastEntries.size() > 0) {
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(
+ mContext,
+ com.android.internal.R.layout.web_text_view_dropdown,
+ pastEntries);
+ mUpdateMessage.obj = adapter;
+ mUpdateMessage.sendToTarget();
+ }
+ }
+ }
+
+ /**
* Dump the display tree to "/sdcard/displayTree.txt"
*
* @hide debug only
@@ -4989,6 +5125,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
|| keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER;
}
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ if (mAutoCompletePopup != null) {
+ return mAutoCompletePopup.onKeyPreIme(keyCode, event);
+ }
+ return false;
+ }
+
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (DebugFlags.WEB_VIEW) {
@@ -5592,6 +5735,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// However, do not update the base layer as that hasn't changed
setNewPicture(mLoadedPicture, false);
}
+ relocateAutoCompletePopup();
}
@Override
@@ -7238,7 +7382,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
viewToContentX(getScrollX() + getWidth()
- mWebView.getVerticalScrollbarWidth()),
viewToContentY(getScrollY() + getViewHeightWithTitle()));
- content = nativeSubtractLayers(content);
int screenTop = contentToViewY(content.top);
int screenBottom = contentToViewY(content.bottom);
int height = screenBottom - screenTop;
@@ -8020,6 +8163,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
break;
}
+ case REQUEST_FORM_DATA:
+ if (mFieldPointer == msg.arg1) {
+ ArrayAdapter<String> adapter = (ArrayAdapter<String>)msg.obj;
+ mAutoCompletePopup.setAdapter(adapter);
+ }
+ break;
case LONG_PRESS_CENTER:
// as this is shared by keydown and trackballdown, reset all
@@ -8174,6 +8323,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
break;
+ case FOCUS_NODE_CHANGED:
+ if (mAutoCompletePopup != null) {
+ mAutoCompletePopup.setFocused(msg.arg1 == mFieldPointer);
+ }
+ // fall through to HIT_TEST_RESULT
case HIT_TEST_RESULT:
WebKitHitTest hit = (WebKitHitTest) msg.obj;
mFocusedNode = hit;
@@ -8190,11 +8344,20 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
case SET_AUTOFILLABLE:
mAutoFillData = (WebViewCore.AutoFillData) msg.obj;
- // TODO: Support (b/6083041)
+ if (mInputConnection != null) {
+ mInputConnection.setAutoFillable(mAutoFillData.getQueryId());
+ mAutoCompletePopup.setAutoFillQueryId(mAutoFillData.getQueryId());
+ }
break;
case AUTOFILL_COMPLETE:
- // TODO: Support (b/6083041)
+ if (mAutoCompletePopup != null) {
+ ArrayList<String> pastEntries = new ArrayList<String>();
+ mAutoCompletePopup.setAdapter(new ArrayAdapter<String>(
+ mContext,
+ com.android.internal.R.layout.web_text_view_dropdown,
+ pastEntries));
+ }
break;
case COPY_TO_CLIPBOARD:
@@ -8208,6 +8371,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mFieldPointer = initData.mFieldPointer;
mInputConnection.initEditorInfo(initData);
mInputConnection.setTextAndKeepSelection(initData.mText);
+ nativeMapLayerRect(mNativeClass, initData.mNodeLayerId,
+ initData.mNodeBounds);
+ mAutoCompletePopup.setNodeBounds(initData.mNodeBounds,
+ initData.mNodeLayerId);
+ mAutoCompletePopup.setText(mInputConnection.getEditable());
}
break;
@@ -8236,6 +8404,15 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mWebViewCore.sendMessage(EventHub.KEY_PRESS, msg.arg1);
break;
+ case RELOCATE_AUTO_COMPLETE_POPUP:
+ relocateAutoCompletePopup();
+ break;
+
+ case AUTOFILL_FORM:
+ mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM,
+ msg.arg1, /* unused */0);
+ break;
+
default:
super.handleMessage(msg);
break;
@@ -9019,7 +9196,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
/*package*/ void autoFillForm(int autoFillQueryId) {
- mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM, autoFillQueryId, /* unused */0);
+ mPrivateHandler.obtainMessage(AUTOFILL_FORM, autoFillQueryId, 0)
+ .sendToTarget();
}
/* package */ ViewManager getViewManager() {
@@ -9134,7 +9312,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private native void nativeCopyBaseContentToPicture(Picture pict);
private native boolean nativeHasContent();
private native void nativeStopGL();
- private native Rect nativeSubtractLayers(Rect content);
private native void nativeDiscardAllTextures();
private native void nativeTileProfilingStart();
private native float nativeTileProfilingStop();
@@ -9170,4 +9347,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private static native int nativeGetHandleLayerId(int instance, int handle,
Rect cursorLocation);
private static native boolean nativeIsBaseFirst(int instance);
+ private static native void nativeMapLayerRect(int instance, int layerId,
+ Rect rect);
}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 81de356..0c34037 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -204,7 +204,7 @@ public class WebViewClient {
/**
* Notify the host application that an SSL error occurred while loading a
- * resource, but the WebView but chose to proceed anyway based on a
+ * resource, but the WebView chose to proceed anyway based on a
* decision retained from a previous response to onReceivedSslError().
* @hide
*/
@@ -220,7 +220,7 @@ public class WebViewClient {
* default behavior is to cancel, returning no client certificate.
*
* @param view The WebView that is initiating the callback.
- * @param handler An ClientCertRequestHandler object that will
+ * @param handler A ClientCertRequestHandler object that will
* handle the user's response.
* @param host_and_port The host and port of the requesting server.
*
@@ -266,7 +266,7 @@ public class WebViewClient {
* Notify the host application that a key was not handled by the WebView.
* Except system keys, WebView always consumes the keys in the normal flow
* or if shouldOverrideKeyEvent returns true. This is called asynchronously
- * from where the key is dispatched. It gives the host application an chance
+ * from where the key is dispatched. It gives the host application a chance
* to handle the unhandled key events.
*
* @param view The WebView that is initiating the callback.
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 09aa286..8def74b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -339,10 +339,10 @@ public final class WebViewCore {
/**
* Called by JNI when the focus node changed.
*/
- private void focusNodeChanged(WebKitHitTest hitTest) {
+ private void focusNodeChanged(int nodePointer, WebKitHitTest hitTest) {
if (mWebView == null) return;
- mWebView.mPrivateHandler.obtainMessage(WebViewClassic.HIT_TEST_RESULT, hitTest)
- .sendToTarget();
+ mWebView.mPrivateHandler.obtainMessage(WebViewClassic.FOCUS_NODE_CHANGED,
+ nodePointer, 0, hitTest).sendToTarget();
}
/**
@@ -953,22 +953,32 @@ public final class WebViewCore {
static class TextFieldInitData {
public TextFieldInitData(int fieldPointer,
String text, int type, boolean isSpellCheckEnabled,
- boolean isTextFieldNext, String label, int maxLength) {
+ boolean autoComplete, boolean isTextFieldNext,
+ String name, String label, int maxLength,
+ Rect nodeBounds, int nodeLayerId) {
mFieldPointer = fieldPointer;
mText = text;
mType = type;
+ mIsAutoCompleteEnabled = autoComplete;
mIsSpellCheckEnabled = isSpellCheckEnabled;
mIsTextFieldNext = isTextFieldNext;
+ mName = name;
mLabel = label;
mMaxLength = maxLength;
+ mNodeBounds = nodeBounds;
+ mNodeLayerId = nodeLayerId;
}
int mFieldPointer;
String mText;
int mType;
boolean mIsSpellCheckEnabled;
boolean mIsTextFieldNext;
+ boolean mIsAutoCompleteEnabled;
+ String mName;
String mLabel;
int mMaxLength;
+ Rect mNodeBounds;
+ int mNodeLayerId;
}
// mAction of TouchEventData can be MotionEvent.getAction() which uses the
@@ -1244,6 +1254,23 @@ public final class WebViewCore {
+ " arg1=" + msg.arg1 + " arg2=" + msg.arg2
+ " obj=" + msg.obj);
}
+ switch (msg.what) {
+ case PAUSE_TIMERS:
+ mSavedPriority = Process.getThreadPriority(mTid);
+ Process.setThreadPriority(mTid,
+ Process.THREAD_PRIORITY_BACKGROUND);
+ pauseTimers();
+ if (mNativeClass != 0) {
+ nativeCloseIdleConnections(mNativeClass);
+ }
+ return;
+
+ case RESUME_TIMERS:
+ Process.setThreadPriority(mTid, mSavedPriority);
+ resumeTimers();
+ return;
+ }
+
if (mWebView == null || mNativeClass == 0) {
if (DebugFlags.WEB_VIEW_CORE) {
Log.w(LOGTAG, "Rejecting message " + msg.what
@@ -1252,8 +1279,6 @@ public final class WebViewCore {
return;
}
if (mDestroying == true
- && msg.what != EventHub.RESUME_TIMERS
- && msg.what != EventHub.PAUSE_TIMERS
&& msg.what != EventHub.DESTROY) {
if (DebugFlags.WEB_VIEW_CORE) {
Log.v(LOGTAG, "Rejecting message " + msg.what
@@ -1419,18 +1444,6 @@ public final class WebViewCore {
restoreState(msg.arg1);
break;
- case PAUSE_TIMERS:
- mSavedPriority = Process.getThreadPriority(mTid);
- Process.setThreadPriority(mTid,
- Process.THREAD_PRIORITY_BACKGROUND);
- pauseTimers();
- nativeCloseIdleConnections(mNativeClass);
- break;
-
- case RESUME_TIMERS:
- Process.setThreadPriority(mTid, mSavedPriority);
- resumeTimers();
- break;
case ON_PAUSE:
nativePause(mNativeClass);
@@ -1961,12 +1974,10 @@ public final class WebViewCore {
*/
void destroy() {
synchronized (mEventHub) {
- // Do not call removeMessages as then we risk removing PAUSE_TIMERS
- // or RESUME_TIMERS messages, which we must still handle as they
- // are per process. DESTROY will instead trigger a white list in
- // mEventHub, skipping any remaining messages in the queue
+ // send DESTROY to front of queue
+ // PAUSE/RESUME timers will still be processed even if they get handled later
mEventHub.mDestroying = true;
- mEventHub.sendMessage(
+ mEventHub.sendMessageAtFrontOfQueue(
Message.obtain(null, EventHub.DESTROY));
mEventHub.blockMessages();
}
@@ -2786,14 +2797,16 @@ public final class WebViewCore {
// called by JNI
private void initEditField(int pointer, String text, int inputType,
- boolean isSpellCheckEnabled, boolean nextFieldIsText,
- String label, int start, int end, int selectionPtr, int maxLength) {
+ boolean isSpellCheckEnabled, boolean isAutoCompleteEnabled,
+ boolean nextFieldIsText, String name,
+ String label, int start, int end, int selectionPtr, int maxLength,
+ Rect nodeRect, int nodeLayer) {
if (mWebView == null) {
return;
}
TextFieldInitData initData = new TextFieldInitData(pointer,
- text, inputType, isSpellCheckEnabled, nextFieldIsText, label,
- maxLength);
+ text, inputType, isSpellCheckEnabled, isAutoCompleteEnabled,
+ nextFieldIsText, name, label, maxLength, nodeRect, nodeLayer);
Message.obtain(mWebView.mPrivateHandler,
WebViewClassic.INIT_EDIT_FIELD, initData).sendToTarget();
Message.obtain(mWebView.mPrivateHandler,
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 19fb7b1..233d892 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -227,16 +227,6 @@ public class CheckedTextView extends TextView implements Checkable {
}
@Override
- public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- event.getText().add(mContext.getString(R.string.radiobutton_selected));
- } else {
- event.getText().add(mContext.getString(R.string.radiobutton_not_selected));
- }
- }
-
- @Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(CheckedTextView.class.getName());
diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java
index badfaa7..c2d8bda 100644
--- a/core/java/android/widget/ExpandableListView.java
+++ b/core/java/android/widget/ExpandableListView.java
@@ -740,7 +740,7 @@ public class ExpandableListView extends ListView {
/**
* Converts a flat list position (the raw position of an item (child or group)
- * in the list) to an group and/or child position (represented in a
+ * in the list) to a group and/or child position (represented in a
* packed position). This is useful in situations where the caller needs to
* use the underlying {@link ListView}'s methods. Use
* {@link ExpandableListView#getPackedPositionType} ,
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 0dedf8b..739bcce 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -99,7 +99,7 @@ public class GridView extends AbsListView {
private final Rect mTempRect = new Rect();
public GridView(Context context) {
- super(context);
+ this(context, null);
}
public GridView(Context context, AttributeSet attrs) {
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 0b4ebf4..0db6ef2 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -1389,7 +1389,7 @@ public class HorizontalScrollView extends FrameLayout {
}
mChildToScrollTo = null;
- // Calling this with the present values causes it to re-clam them
+ // Calling this with the present values causes it to re-claim them
scrollTo(mScrollX, mScrollY);
}
@@ -1412,7 +1412,7 @@ public class HorizontalScrollView extends FrameLayout {
}
/**
- * Return true if child is an descendant of parent, (or equal to the parent).
+ * Return true if child is a descendant of parent, (or equal to the parent).
*/
private boolean isViewDescendantOf(View child, View parent) {
if (child == parent) {
@@ -1427,7 +1427,7 @@ public class HorizontalScrollView extends FrameLayout {
* Fling the scroll view
*
* @param velocityX The initial velocity in the X direction. Positive
- * numbers mean that the finger/curor is moving down the screen,
+ * numbers mean that the finger/cursor is moving down the screen,
* which means we want to scroll towards the left.
*/
public void fling(int velocityX) {
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 07ae93b..3001ea1 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -193,9 +193,6 @@ public class ImageView extends View {
}
}
- /**
- * @hide
- */
@Override
public int getResolvedLayoutDirection(Drawable dr) {
return (dr == mDrawable) ?
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index f4d5d74..1d966b3 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -1017,7 +1017,7 @@ public class ListPopupWindow {
View hintView = mPromptView;
if (hintView != null) {
- // if an hint has been specified, we accomodate more space for it and
+ // if a hint has been specified, we accomodate more space for it and
// add a text view in the drop down menu, at the bottom of the list
LinearLayout hintContainer = new LinearLayout(context);
hintContainer.setOrientation(LinearLayout.VERTICAL);
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index e298acb..3bc4f7f 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -910,9 +910,6 @@ public class ProgressBar extends View {
}
}
- /**
- * @hide
- */
@Override
public int getResolvedLayoutDirection(Drawable who) {
return (who == mProgressDrawable || who == mIndeterminateDrawable) ?
diff --git a/core/java/android/widget/RadioButton.java b/core/java/android/widget/RadioButton.java
index b6dac3e..b1bb1c0 100644
--- a/core/java/android/widget/RadioButton.java
+++ b/core/java/android/widget/RadioButton.java
@@ -78,16 +78,6 @@ public class RadioButton extends CompoundButton {
}
@Override
- public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- event.getText().add(mContext.getString(R.string.radiobutton_selected));
- } else {
- event.getText().add(mContext.getString(R.string.radiobutton_not_selected));
- }
- }
-
- @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(RadioButton.class.getName());
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 3ffc0fe..25dd438 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1412,7 +1412,7 @@ public class ScrollView extends FrameLayout {
}
mChildToScrollTo = null;
- // Calling this with the present values causes it to re-clam them
+ // Calling this with the present values causes it to re-claim them
scrollTo(mScrollX, mScrollY);
}
@@ -1436,7 +1436,7 @@ public class ScrollView extends FrameLayout {
}
/**
- * Return true if child is an descendant of parent, (or equal to the parent).
+ * Return true if child is a descendant of parent, (or equal to the parent).
*/
private boolean isViewDescendantOf(View child, View parent) {
if (child == parent) {
diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java
index 4b17a92..98bcfff 100644
--- a/core/java/android/widget/SimpleAdapter.java
+++ b/core/java/android/widget/SimpleAdapter.java
@@ -268,7 +268,7 @@ public class SimpleAdapter extends BaseAdapter implements Filterable {
/**
* Called by bindView() to set the text for a TextView but only if
* there is no existing ViewBinder or if the existing ViewBinder cannot
- * handle binding to an TextView.
+ * handle binding to a TextView.
*
* @param v TextView to receive text
* @param text the text to be set for the TextView
diff --git a/core/java/android/widget/SimpleCursorAdapter.java b/core/java/android/widget/SimpleCursorAdapter.java
index c5c6c69..f74a314 100644
--- a/core/java/android/widget/SimpleCursorAdapter.java
+++ b/core/java/android/widget/SimpleCursorAdapter.java
@@ -216,7 +216,7 @@ public class SimpleCursorAdapter extends ResourceCursorAdapter {
/**
* Called by bindView() to set the text for a TextView but only if
* there is no existing ViewBinder or if the existing ViewBinder cannot
- * handle binding to an TextView.
+ * handle binding to a TextView.
*
* Intended to be overridden by Adapters that need to filter strings
* retrieved from the database.
diff --git a/core/java/android/widget/SimpleCursorTreeAdapter.java b/core/java/android/widget/SimpleCursorTreeAdapter.java
index a033542..6babf3e 100644
--- a/core/java/android/widget/SimpleCursorTreeAdapter.java
+++ b/core/java/android/widget/SimpleCursorTreeAdapter.java
@@ -283,7 +283,7 @@ public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter
/**
* Called by bindView() to set the text for a TextView but only if
* there is no existing ViewBinder or if the existing ViewBinder cannot
- * handle binding to an TextView.
+ * handle binding to a TextView.
*
* Intended to be overridden by Adapters that need to filter strings
* retrieved from the database.
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 6540613..aef8a34 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -26,6 +26,7 @@ import android.database.DataSetObserver;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -202,6 +203,130 @@ public class Spinner extends AbsSpinner implements OnClickListener {
}
}
+ /**
+ * Set the background drawable for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param background Background drawable
+ *
+ * @attr ref android.R.styleable#Spinner_popupBackground
+ */
+ public void setPopupBackgroundDrawable(Drawable background) {
+ if (!(mPopup instanceof DropdownPopup)) {
+ Log.e(TAG, "setPopupBackgroundDrawable: incompatible spinner mode; ignoring...");
+ return;
+ }
+ ((DropdownPopup) mPopup).setBackgroundDrawable(background);
+ }
+
+ /**
+ * Set the background drawable for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param resId Resource ID of a background drawable
+ *
+ * @attr ref android.R.styleable#Spinner_popupBackground
+ */
+ public void setPopupBackgroundResource(int resId) {
+ setPopupBackgroundDrawable(getContext().getResources().getDrawable(resId));
+ }
+
+ /**
+ * Get the background drawable for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; other modes will return null.
+ *
+ * @return background Background drawable
+ *
+ * @attr ref android.R.styleable#Spinner_popupBackground
+ */
+ public Drawable getPopupBackground() {
+ return mPopup.getBackground();
+ }
+
+ /**
+ * Set a vertical offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param pixels Vertical offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownVerticalOffset
+ */
+ public void setDropDownVerticalOffset(int pixels) {
+ mPopup.setVerticalOffset(pixels);
+ }
+
+ /**
+ * Get the configured vertical offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; other modes will return 0.
+ *
+ * @return Vertical offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownVerticalOffset
+ */
+ public int getDropDownVerticalOffset() {
+ return mPopup.getVerticalOffset();
+ }
+
+ /**
+ * Set a horizontal offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.
+ *
+ * @param pixels Horizontal offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownHorizontalOffset
+ */
+ public void setDropDownHorizontalOffset(int pixels) {
+ mPopup.setHorizontalOffset(pixels);
+ }
+
+ /**
+ * Get the configured horizontal offset in pixels for the spinner's popup window of choices.
+ * Only valid in {@link #MODE_DROPDOWN}; other modes will return 0.
+ *
+ * @return Horizontal offset in pixels
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownHorizontalOffset
+ */
+ public int getDropDownHorizontalOffset() {
+ return mPopup.getHorizontalOffset();
+ }
+
+ /**
+ * Set the width of the spinner's popup window of choices in pixels. This value
+ * may also be set to {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * to match the width of the Spinner itself, or
+ * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} to wrap to the measured size
+ * of contained dropdown list items.
+ *
+ * <p>Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes.</p>
+ *
+ * @param pixels Width in pixels, WRAP_CONTENT, or MATCH_PARENT
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownWidth
+ */
+ public void setDropDownWidth(int pixels) {
+ if (!(mPopup instanceof DropdownPopup)) {
+ Log.e(TAG, "Cannot set dropdown width for MODE_DIALOG, ignoring");
+ return;
+ }
+ mDropDownWidth = pixels;
+ }
+
+ /**
+ * Get the configured width of the spinner's popup window of choices in pixels.
+ * The returned value may also be {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
+ * meaning the popup window will match the width of the Spinner itself, or
+ * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} to wrap to the measured size
+ * of contained dropdown list items.
+ *
+ * @return Width in pixels, WRAP_CONTENT, or MATCH_PARENT
+ *
+ * @attr ref android.R.styleable#Spinner_dropDownWidth
+ */
+ public int getDropDownWidth() {
+ return mDropDownWidth;
+ }
+
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
@@ -231,6 +356,16 @@ public class Spinner extends AbsSpinner implements OnClickListener {
}
}
+ /**
+ * Describes how the selected item view is positioned. The default is determined by the
+ * current theme.
+ *
+ * @return A {@link android.view.Gravity Gravity} value
+ */
+ public int getGravity() {
+ return mGravity;
+ }
+
@Override
public void setAdapter(SpinnerAdapter adapter) {
super.setAdapter(adapter);
@@ -675,6 +810,13 @@ public class Spinner extends AbsSpinner implements OnClickListener {
*/
public void setPromptText(CharSequence hintText);
public CharSequence getHintText();
+
+ public void setBackgroundDrawable(Drawable bg);
+ public void setVerticalOffset(int px);
+ public void setHorizontalOffset(int px);
+ public Drawable getBackground();
+ public int getVerticalOffset();
+ public int getHorizontalOffset();
}
private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener {
@@ -719,6 +861,36 @@ public class Spinner extends AbsSpinner implements OnClickListener {
}
dismiss();
}
+
+ @Override
+ public void setBackgroundDrawable(Drawable bg) {
+ Log.e(TAG, "Cannot set popup background for MODE_DIALOG, ignoring");
+ }
+
+ @Override
+ public void setVerticalOffset(int px) {
+ Log.e(TAG, "Cannot set vertical offset for MODE_DIALOG, ignoring");
+ }
+
+ @Override
+ public void setHorizontalOffset(int px) {
+ Log.e(TAG, "Cannot set horizontal offset for MODE_DIALOG, ignoring");
+ }
+
+ @Override
+ public Drawable getBackground() {
+ return null;
+ }
+
+ @Override
+ public int getVerticalOffset() {
+ return 0;
+ }
+
+ @Override
+ public int getHorizontalOffset() {
+ return 0;
+ }
}
private class DropdownPopup extends ListPopupWindow implements SpinnerPopup {
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 23e55e2..a897cc3 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -359,6 +359,17 @@ public class Switch extends CompoundButton {
}
/**
+ * Set the drawable used for the track that the switch slides within.
+ *
+ * @param resId Resource ID of a track drawable
+ *
+ * @attr ref android.R.styleable#Switch_track
+ */
+ public void setTrackResource(int resId) {
+ setTrackDrawable(getContext().getResources().getDrawable(resId));
+ }
+
+ /**
* Get the drawable used for the track that the switch slides within.
*
* @return Track drawable
@@ -383,6 +394,18 @@ public class Switch extends CompoundButton {
}
/**
+ * Set the drawable used for the switch "thumb" - the piece that the user
+ * can physically touch and drag along the track.
+ *
+ * @param resId Resource ID of a thumb drawable
+ *
+ * @attr ref android.R.styleable#Switch_thumb
+ */
+ public void setThumbResource(int resId) {
+ setThumbDrawable(getContext().getResources().getDrawable(resId));
+ }
+
+ /**
* Get the drawable used for the switch "thumb" - the piece that the user
* can physically touch and drag along the track.
*
@@ -496,17 +519,8 @@ public class Switch extends CompoundButton {
@Override
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- CharSequence text = mOnLayout.getText();
- if (TextUtils.isEmpty(text)) {
- text = mContext.getString(R.string.switch_on);
- }
- event.getText().add(text);
- } else {
- CharSequence text = mOffLayout.getText();
- if (TextUtils.isEmpty(text)) {
- text = mContext.getString(R.string.switch_off);
- }
+ CharSequence text = isChecked() ? mOnLayout.getText() : mOffLayout.getText();
+ if (!TextUtils.isEmpty(text)) {
event.getText().add(text);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 4c89218..e535170 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1214,7 +1214,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (imm != null) imm.restartInput(this);
}
- if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().invalidateTextDisplayList();
prepareCursorControllers();
// start or stop the cursor blinking as appropriate
@@ -2328,7 +2328,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void setHighlightColor(int color) {
if (mHighlightColor != color) {
mHighlightColor = color;
- if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().invalidateTextDisplayList();
invalidate();
}
}
@@ -2349,7 +2349,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mShadowDx = dx;
mShadowDy = dy;
- if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().invalidateTextDisplayList();
invalidate();
}
@@ -2841,7 +2841,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
if (inval) {
- if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().invalidateTextDisplayList();
invalidate();
}
}
@@ -3334,7 +3334,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Invalidate display list if hint will be used
if (mEditor != null && mText.length() == 0 && mHint != null) {
- getEditor().mTextDisplayListIsValid = false;
+ getEditor().invalidateTextDisplayList();
}
}
@@ -4396,9 +4396,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- /**
- * @hide
- */
@Override
public int getResolvedLayoutDirection(Drawable who) {
if (who == null) return View.LAYOUT_DIRECTION_LTR;
@@ -4429,13 +4426,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (dr.mDrawableStart != null) dr.mDrawableStart.mutate().setAlpha(alpha);
if (dr.mDrawableEnd != null) dr.mDrawableEnd.mutate().setAlpha(alpha);
}
- if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().invalidateTextDisplayList();
}
return true;
}
if (mCurrentAlpha != 255) {
- if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().invalidateTextDisplayList();
}
mCurrentAlpha = 255;
return false;
@@ -6292,7 +6289,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- if (changed && mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (changed && mEditor != null) getEditor().invalidateTextDisplayList();
}
private boolean isShowingHint() {
@@ -7130,7 +7127,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} else {
ims.mContentChanged = true;
}
- if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().invalidateTextDisplayList();
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
@@ -8277,7 +8274,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (getEditor().mPositionListener != null) {
getEditor().mPositionListener.onScrollChanged();
}
- getEditor().mTextDisplayListIsValid = false;
+ getEditor().invalidateTextDisplayList();
}
}
@@ -11303,7 +11300,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
InputMethodState mInputMethodState;
DisplayList mTextDisplayList;
- boolean mTextDisplayListIsValid;
boolean mFrozenWithFocus;
boolean mSelectionMoved;
@@ -11392,9 +11388,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
removeCallbacks(mShowSuggestionRunnable);
}
- if (mTextDisplayList != null) {
- mTextDisplayList.invalidate();
- }
+ invalidateTextDisplayList();
if (mSpellChecker != null) {
mSpellChecker.closeSession();
@@ -11551,7 +11545,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
void sendOnTextChanged(int start, int after) {
updateSpellCheckSpans(start, start + after, false);
- mTextDisplayListIsValid = false;
+ invalidateTextDisplayList();
// Hide the controllers as soon as text is modified (typing, procedural...)
// We do not hide the span controllers, since they can be added when a new text is
@@ -11708,10 +11702,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
layout.drawBackground(canvas, highlight, mHighlightPaint, cursorOffsetVertical,
firstLine, lastLine);
- if (mTextDisplayList == null || !mTextDisplayList.isValid() ||
- !mTextDisplayListIsValid) {
+ if (mTextDisplayList == null || !mTextDisplayList.isValid()) {
+ boolean displayListCreated = false;
if (mTextDisplayList == null) {
mTextDisplayList = getHardwareRenderer().createDisplayList("Text");
+ displayListCreated = true;
}
final HardwareCanvas hardwareCanvas = mTextDisplayList.start();
@@ -11726,7 +11721,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} finally {
hardwareCanvas.onPostDraw();
mTextDisplayList.end();
- mTextDisplayListIsValid = true;
+ if (displayListCreated && USE_DISPLAY_LIST_PROPERTIES) {
+ mTextDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
+ }
}
}
canvas.translate(mScrollX, mScrollY);
@@ -11744,6 +11741,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (translate) canvas.translate(0, -cursorOffsetVertical);
}
+ private void invalidateTextDisplayList() {
+ if (mTextDisplayList != null) mTextDisplayList.invalidate();
+ }
+
private void updateCursorsPositions() {
if (mCursorDrawableRes == 0) {
mCursorCount = 0;
diff --git a/core/java/android/widget/ToggleButton.java b/core/java/android/widget/ToggleButton.java
index a0edafe..4beee96 100644
--- a/core/java/android/widget/ToggleButton.java
+++ b/core/java/android/widget/ToggleButton.java
@@ -154,16 +154,6 @@ public class ToggleButton extends CompoundButton {
}
@Override
- public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(event);
- if (isChecked()) {
- event.getText().add(mContext.getString(R.string.togglebutton_pressed));
- } else {
- event.getText().add(mContext.getString(R.string.togglebutton_not_pressed));
- }
- }
-
- @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(ToggleButton.class.getName());
diff --git a/core/java/com/android/internal/util/AsyncService.java b/core/java/com/android/internal/util/AsyncService.java
index 54d3c42..e39a2bf 100644
--- a/core/java/com/android/internal/util/AsyncService.java
+++ b/core/java/com/android/internal/util/AsyncService.java
@@ -106,7 +106,7 @@ abstract public class AsyncService extends Service {
/**
* Called when service is destroyed. After returning the
- * service is dead an no more processing should be expected
+ * service is dead and no more processing should be expected
* to occur.
*/
@Override
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 61c0c8e..da189f1 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1195,7 +1195,7 @@ public class StateMachine {
}
/**
- * Constructor creates an StateMachine using the looper.
+ * Constructor creates a StateMachine using the looper.
*
* @param name of the state machine
*/
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index 3865510..f535a08 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -416,7 +416,7 @@ public class SlidingTab extends ViewGroup {
}
/**
- * Start animating the slider. Note we need two animations since an ValueAnimator
+ * Start animating the slider. Note we need two animations since a ValueAnimator
* keeps internal state of the invalidation region which is just the view being animated.
*
* @param anim1
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 642988b..92b07b3 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -53,6 +53,7 @@ LOCAL_SRC_FILES:= \
android_view_KeyEvent.cpp \
android_view_KeyCharacterMap.cpp \
android_view_HardwareRenderer.cpp \
+ android_view_GLES20DisplayList.cpp \
android_view_GLES20Canvas.cpp \
android_view_MotionEvent.cpp \
android_view_PointerIcon.cpp \
@@ -69,6 +70,7 @@ LOCAL_SRC_FILES:= \
android_os_StatFs.cpp \
android_os_SystemClock.cpp \
android_os_SystemProperties.cpp \
+ android_os_Trace.cpp \
android_os_UEventObserver.cpp \
android_net_LocalSocketImpl.cpp \
android_net_NetUtils.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index de9fd33..92ff8da 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -117,6 +117,7 @@ extern int register_android_graphics_Xfermode(JNIEnv* env);
extern int register_android_graphics_PixelFormat(JNIEnv* env);
extern int register_android_view_Display(JNIEnv* env);
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
+extern int register_android_view_GLES20DisplayList(JNIEnv* env);
extern int register_android_view_GLES20Canvas(JNIEnv* env);
extern int register_android_view_HardwareRenderer(JNIEnv* env);
extern int register_android_view_Surface(JNIEnv* env);
@@ -136,6 +137,7 @@ extern int register_android_os_Power(JNIEnv *env);
extern int register_android_os_StatFs(JNIEnv *env);
extern int register_android_os_SystemProperties(JNIEnv *env);
extern int register_android_os_SystemClock(JNIEnv* env);
+extern int register_android_os_Trace(JNIEnv* env);
extern int register_android_os_FileObserver(JNIEnv *env);
extern int register_android_os_FileUtils(JNIEnv *env);
extern int register_android_os_UEventObserver(JNIEnv* env);
@@ -1101,6 +1103,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_nio_utils),
REG_JNI(register_android_graphics_PixelFormat),
REG_JNI(register_android_graphics_Graphics),
+ REG_JNI(register_android_view_GLES20DisplayList),
REG_JNI(register_android_view_GLES20Canvas),
REG_JNI(register_android_view_HardwareRenderer),
REG_JNI(register_android_view_Surface),
@@ -1151,6 +1154,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_os_ParcelFileDescriptor),
REG_JNI(register_android_os_Power),
REG_JNI(register_android_os_StatFs),
+ REG_JNI(register_android_os_Trace),
REG_JNI(register_android_os_UEventObserver),
REG_JNI(register_android_net_LocalSocketImpl),
REG_JNI(register_android_net_NetworkUtils),
diff --git a/core/jni/android/graphics/Camera.cpp b/core/jni/android/graphics/Camera.cpp
index 76d415a..5176d9a 100644
--- a/core/jni/android/graphics/Camera.cpp
+++ b/core/jni/android/graphics/Camera.cpp
@@ -57,6 +57,21 @@ static void Camera_setLocation(JNIEnv* env, jobject obj, jfloat x, jfloat y, jfl
v->setCameraLocation(SkFloatToScalar(x), SkFloatToScalar(y), SkFloatToScalar(z));
}
+static jfloat Camera_getLocationX(JNIEnv* env, jobject obj) {
+ Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID);
+ return SkScalarToFloat(v->getCameraLocationX());
+}
+
+static jfloat Camera_getLocationY(JNIEnv* env, jobject obj) {
+ Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID);
+ return SkScalarToFloat(v->getCameraLocationY());
+}
+
+static jfloat Camera_getLocationZ(JNIEnv* env, jobject obj) {
+ Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID);
+ return SkScalarToFloat(v->getCameraLocationZ());
+}
+
static void Camera_getMatrix(JNIEnv* env, jobject obj, int native_matrix) {
Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID);
v->getMatrix((SkMatrix*)native_matrix);
@@ -93,6 +108,9 @@ static JNINativeMethod gCameraMethods[] = {
{ "rotateZ", "(F)V", (void*)Camera_rotateZ },
{ "rotate", "(FFF)V", (void*)Camera_rotate },
{ "setLocation", "(FFF)V", (void*)Camera_setLocation },
+ { "getLocationX", "()F", (void*)Camera_getLocationX },
+ { "getLocationY", "()F", (void*)Camera_getLocationY },
+ { "getLocationZ", "()F", (void*)Camera_getLocationZ },
{ "nativeGetMatrix", "(I)V", (void*)Camera_getMatrix },
{ "nativeApplyToCanvas", "(I)V", (void*)Camera_applyToCanvas },
{ "dotWithNormal", "(FFF)F", (void*)Camera_dotWithNormal }
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 68a8de8..b34dbce 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -203,7 +203,7 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
format, // word length, PCM
channels,
frameCount,
- 0, // flags
+ (AudioRecord::record_flags) 0, // flags
recorderCallback,// callback_t
lpCallbackData,// void* user
0, // notificationFrames,
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 26c9435..57f5d3d 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -279,7 +279,7 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
format,// word length, PCM
nativeChannelMask,
frameCount,
- 0,// flags
+ AUDIO_POLICY_OUTPUT_FLAG_NONE,
audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
0,// shared mem
@@ -300,7 +300,7 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
format,// word length, PCM
nativeChannelMask,
frameCount,
- 0,// flags
+ AUDIO_POLICY_OUTPUT_FLAG_NONE,
audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user));
0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
lpJniStorage->mMemBase,// shared mem
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 8a99049..3dfaac3 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -61,14 +61,13 @@ namespace android {
static struct parcel_offsets_t
{
- jfieldID mObject;
- jfieldID mOwnObject;
+ jfieldID mNativePtr;
} gParcelOffsets;
Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
{
if (obj) {
- Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mObject);
+ Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mNativePtr);
if (p != NULL) {
return p;
}
@@ -77,33 +76,33 @@ Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
return NULL;
}
-static jint android_os_Parcel_dataSize(JNIEnv* env, jobject clazz)
+static jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
return parcel ? parcel->dataSize() : 0;
}
-static jint android_os_Parcel_dataAvail(JNIEnv* env, jobject clazz)
+static jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
return parcel ? parcel->dataAvail() : 0;
}
-static jint android_os_Parcel_dataPosition(JNIEnv* env, jobject clazz)
+static jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
return parcel ? parcel->dataPosition() : 0;
}
-static jint android_os_Parcel_dataCapacity(JNIEnv* env, jobject clazz)
+static jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
return parcel ? parcel->dataCapacity() : 0;
}
-static void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size)
+static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jint nativePtr, jint size)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->setDataSize(size);
if (err != NO_ERROR) {
@@ -112,17 +111,17 @@ static void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size)
}
}
-static void android_os_Parcel_setDataPosition(JNIEnv* env, jobject clazz, jint pos)
+static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jint nativePtr, jint pos)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
parcel->setDataPosition(pos);
}
}
-static void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint size)
+static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jint nativePtr, jint size)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->setDataCapacity(size);
if (err != NO_ERROR) {
@@ -131,9 +130,9 @@ static void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint s
}
}
-static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
+static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean allowFds)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
jboolean ret = JNI_TRUE;
if (parcel != NULL) {
ret = (jboolean)parcel->pushAllowFds(allowFds);
@@ -141,19 +140,18 @@ static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jbool
return ret;
}
-static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue)
+static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean lastValue)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
parcel->restoreAllowFds((bool)lastValue);
}
}
-static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
- jobject data, jint offset,
- jint length)
+static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jint nativePtr, jobject data,
+ jint offset, jint length)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel == NULL) {
return;
}
@@ -177,21 +175,17 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
}
}
-
-static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
-{
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeInt32(val);
- if (err != NO_ERROR) {
- signalExceptionForError(env, clazz, err);
- }
+static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jint nativePtr, jint val) {
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ const status_t err = parcel->writeInt32(val);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
}
}
-static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
+static void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jint nativePtr, jlong val)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeInt64(val);
if (err != NO_ERROR) {
@@ -200,9 +194,9 @@ static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
}
}
-static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
+static void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jint nativePtr, jfloat val)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeFloat(val);
if (err != NO_ERROR) {
@@ -211,9 +205,9 @@ static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
}
}
-static void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble val)
+static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jint nativePtr, jdouble val)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeDouble(val);
if (err != NO_ERROR) {
@@ -222,9 +216,9 @@ static void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble va
}
}
-static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val)
+static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jint nativePtr, jstring val)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
status_t err = NO_MEMORY;
if (val) {
@@ -242,9 +236,9 @@ static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring va
}
}
-static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
+static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
@@ -253,9 +247,9 @@ static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobj
}
}
-static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
+static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err =
parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
@@ -265,11 +259,11 @@ static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jo
}
}
-static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz)
+static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jint nativePtr)
{
jbyteArray ret = NULL;
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
int32_t len = parcel->readInt32();
@@ -291,45 +285,45 @@ static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jobject clazz)
return ret;
}
-static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
+static jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
return parcel->readInt32();
}
return 0;
}
-static jlong android_os_Parcel_readLong(JNIEnv* env, jobject clazz)
+static jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
return parcel->readInt64();
}
return 0;
}
-static jfloat android_os_Parcel_readFloat(JNIEnv* env, jobject clazz)
+static jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
return parcel->readFloat();
}
return 0;
}
-static jdouble android_os_Parcel_readDouble(JNIEnv* env, jobject clazz)
+static jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
return parcel->readDouble();
}
return 0;
}
-static jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz)
+static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
size_t len;
const char16_t* str = parcel->readString16Inplace(&len);
@@ -341,18 +335,18 @@ static jstring android_os_Parcel_readString(JNIEnv* env, jobject clazz)
return NULL;
}
-static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz)
+static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
-static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz)
+static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
int fd = parcel->readFileDescriptor();
if (fd < 0) return NULL;
@@ -363,7 +357,7 @@ static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jobject clazz)
return NULL;
}
-static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz,
+static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz,
jstring name, jint mode)
{
if (name == NULL) {
@@ -412,7 +406,7 @@ static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jobject clazz,
return object;
}
-static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, jobject orig)
+static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jclass clazz, jobject orig)
{
if (orig == NULL) {
jniThrowNullPointerException(env, NULL);
@@ -436,7 +430,7 @@ static jobject android_os_Parcel_dupFileDescriptor(JNIEnv* env, jobject clazz, j
return object;
}
-static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
+static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
{
if (object == NULL) {
jniThrowNullPointerException(env, NULL);
@@ -450,7 +444,7 @@ static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jo
}
}
-static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object)
+static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jclass clazz, jobject object)
{
if (object == NULL) {
jniThrowNullPointerException(env, NULL);
@@ -462,55 +456,29 @@ static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jo
}
}
-static void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz)
+static jint android_os_Parcel_create(JNIEnv* env, jclass clazz)
{
- int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
- if (own) {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- //ALOGI("Parcel.freeBuffer() called for C++ Parcel %p\n", parcel);
- parcel->freeData();
- }
- }
+ Parcel* parcel = new Parcel();
+ return reinterpret_cast<jint>(parcel);
}
-static void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt)
+static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = (Parcel*)parcelInt;
- int own = 0;
- if (!parcel) {
- //ALOGI("Initializing obj %p: creating new Parcel\n", clazz);
- own = 1;
- parcel = new Parcel;
- } else {
- //ALOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel);
- }
- if (parcel == NULL) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- return;
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ if (parcel != NULL) {
+ parcel->freeData();
}
- //ALOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own);
- env->SetIntField(clazz, gParcelOffsets.mOwnObject, own);
- env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel);
}
-static void android_os_Parcel_destroy(JNIEnv* env, jobject clazz)
+static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jint nativePtr)
{
- int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject);
- if (own) {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- env->SetIntField(clazz, gParcelOffsets.mObject, 0);
- //ALOGI("Destroying obj %p: deleting C++ Parcel %p\n", clazz, parcel);
- delete parcel;
- } else {
- env->SetIntField(clazz, gParcelOffsets.mObject, 0);
- //ALOGI("Destroying obj %p: leaving C++ Parcel %p\n", clazz);
- }
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+ delete parcel;
}
-static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz)
+static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jint nativePtr)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel == NULL) {
return NULL;
}
@@ -537,9 +505,10 @@ static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jobject clazz)
return ret;
}
-static void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray data, jint offset, jint length)
+static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jint nativePtr,
+ jbyteArray data, jint offset, jint length)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel == NULL || length < 0) {
return;
}
@@ -557,13 +526,14 @@ static void android_os_Parcel_unmarshall(JNIEnv* env, jobject clazz, jbyteArray
}
}
-static void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject parcel, jint offset, jint length)
+static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jint thisNativePtr,
+ jint otherNativePtr, jint offset, jint length)
{
- Parcel* thisParcel = parcelForJavaObject(env, clazz);
+ Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
if (thisParcel == NULL) {
return;
}
- Parcel* otherParcel = parcelForJavaObject(env, parcel);
+ Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
if (otherParcel == NULL) {
return;
}
@@ -574,10 +544,10 @@ static void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject par
}
}
-static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
+static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jint nativePtr)
{
jboolean ret = JNI_FALSE;
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
if (parcel->hasFileDescriptors()) {
ret = JNI_TRUE;
@@ -586,9 +556,10 @@ static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
return ret;
}
-static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name)
+static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jint nativePtr,
+ jstring name)
{
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
// In the current implementation, the token is just the serialized interface name that
// the caller expects to be invoking
@@ -600,11 +571,11 @@ static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, js
}
}
-static void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstring name)
+static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jint nativePtr, jstring name)
{
jboolean ret = JNI_FALSE;
- Parcel* parcel = parcelForJavaObject(env, clazz);
+ Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const jchar* str = env->GetStringCritical(name, 0);
if (str) {
@@ -639,44 +610,50 @@ static void android_os_Parcel_enforceInterface(JNIEnv* env, jobject clazz, jstri
// ----------------------------------------------------------------------------
static const JNINativeMethod gParcelMethods[] = {
- {"dataSize", "()I", (void*)android_os_Parcel_dataSize},
- {"dataAvail", "()I", (void*)android_os_Parcel_dataAvail},
- {"dataPosition", "()I", (void*)android_os_Parcel_dataPosition},
- {"dataCapacity", "()I", (void*)android_os_Parcel_dataCapacity},
- {"setDataSize", "(I)V", (void*)android_os_Parcel_setDataSize},
- {"setDataPosition", "(I)V", (void*)android_os_Parcel_setDataPosition},
- {"setDataCapacity", "(I)V", (void*)android_os_Parcel_setDataCapacity},
- {"pushAllowFds", "(Z)Z", (void*)android_os_Parcel_pushAllowFds},
- {"restoreAllowFds", "(Z)V", (void*)android_os_Parcel_restoreAllowFds},
- {"writeNative", "([BII)V", (void*)android_os_Parcel_writeNative},
- {"writeInt", "(I)V", (void*)android_os_Parcel_writeInt},
- {"writeLong", "(J)V", (void*)android_os_Parcel_writeLong},
- {"writeFloat", "(F)V", (void*)android_os_Parcel_writeFloat},
- {"writeDouble", "(D)V", (void*)android_os_Parcel_writeDouble},
- {"writeString", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeString},
- {"writeStrongBinder", "(Landroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
- {"writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
- {"createByteArray", "()[B", (void*)android_os_Parcel_createByteArray},
- {"readInt", "()I", (void*)android_os_Parcel_readInt},
- {"readLong", "()J", (void*)android_os_Parcel_readLong},
- {"readFloat", "()F", (void*)android_os_Parcel_readFloat},
- {"readDouble", "()D", (void*)android_os_Parcel_readDouble},
- {"readString", "()Ljava/lang/String;", (void*)android_os_Parcel_readString},
- {"readStrongBinder", "()Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
- {"internalReadFileDescriptor", "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
- {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
- {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
- {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
- {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
- {"freeBuffer", "()V", (void*)android_os_Parcel_freeBuffer},
- {"init", "(I)V", (void*)android_os_Parcel_init},
- {"destroy", "()V", (void*)android_os_Parcel_destroy},
- {"marshall", "()[B", (void*)android_os_Parcel_marshall},
- {"unmarshall", "([BII)V", (void*)android_os_Parcel_unmarshall},
- {"appendFrom", "(Landroid/os/Parcel;II)V", (void*)android_os_Parcel_appendFrom},
- {"hasFileDescriptors", "()Z", (void*)android_os_Parcel_hasFileDescriptors},
- {"writeInterfaceToken", "(Ljava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
- {"enforceInterface", "(Ljava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
+ {"nativeDataSize", "(I)I", (void*)android_os_Parcel_dataSize},
+ {"nativeDataAvail", "(I)I", (void*)android_os_Parcel_dataAvail},
+ {"nativeDataPosition", "(I)I", (void*)android_os_Parcel_dataPosition},
+ {"nativeDataCapacity", "(I)I", (void*)android_os_Parcel_dataCapacity},
+ {"nativeSetDataSize", "(II)V", (void*)android_os_Parcel_setDataSize},
+ {"nativeSetDataPosition", "(II)V", (void*)android_os_Parcel_setDataPosition},
+ {"nativeSetDataCapacity", "(II)V", (void*)android_os_Parcel_setDataCapacity},
+
+ {"nativePushAllowFds", "(IZ)Z", (void*)android_os_Parcel_pushAllowFds},
+ {"nativeRestoreAllowFds", "(IZ)V", (void*)android_os_Parcel_restoreAllowFds},
+
+ {"nativeWriteByteArray", "(I[BII)V", (void*)android_os_Parcel_writeNative},
+ {"nativeWriteInt", "(II)V", (void*)android_os_Parcel_writeInt},
+ {"nativeWriteLong", "(IJ)V", (void*)android_os_Parcel_writeLong},
+ {"nativeWriteFloat", "(IF)V", (void*)android_os_Parcel_writeFloat},
+ {"nativeWriteDouble", "(ID)V", (void*)android_os_Parcel_writeDouble},
+ {"nativeWriteString", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeString},
+ {"nativeWriteStrongBinder", "(ILandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
+ {"nativeWriteFileDescriptor", "(ILjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
+
+ {"nativeCreateByteArray", "(I)[B", (void*)android_os_Parcel_createByteArray},
+ {"nativeReadInt", "(I)I", (void*)android_os_Parcel_readInt},
+ {"nativeReadLong", "(I)J", (void*)android_os_Parcel_readLong},
+ {"nativeReadFloat", "(I)F", (void*)android_os_Parcel_readFloat},
+ {"nativeReadDouble", "(I)D", (void*)android_os_Parcel_readDouble},
+ {"nativeReadString", "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString},
+ {"nativeReadStrongBinder", "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
+ {"nativeReadFileDescriptor", "(I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
+
+ {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
+ {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
+ {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
+ {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
+
+ {"nativeCreate", "()I", (void*)android_os_Parcel_create},
+ {"nativeFreeBuffer", "(I)V", (void*)android_os_Parcel_freeBuffer},
+ {"nativeDestroy", "(I)V", (void*)android_os_Parcel_destroy},
+
+ {"nativeMarshall", "(I)[B", (void*)android_os_Parcel_marshall},
+ {"nativeUnmarshall", "(I[BII)V", (void*)android_os_Parcel_unmarshall},
+ {"nativeAppendFrom", "(IIII)V", (void*)android_os_Parcel_appendFrom},
+ {"nativeHasFileDescriptors", "(I)Z", (void*)android_os_Parcel_hasFileDescriptors},
+ {"nativeWriteInterfaceToken", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
+ {"nativeEnforceInterface", "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
};
const char* const kParcelPathName = "android/os/Parcel";
@@ -688,10 +665,8 @@ int register_android_os_Parcel(JNIEnv* env)
clazz = env->FindClass(kParcelPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel");
- gParcelOffsets.mObject
- = env->GetFieldID(clazz, "mObject", "I");
- gParcelOffsets.mOwnObject
- = env->GetFieldID(clazz, "mOwnObject", "I");
+ gParcelOffsets.mNativePtr
+ = env->GetFieldID(clazz, "mNativePtr", "I");
return AndroidRuntime::registerNativeMethods(
env, kParcelPathName,
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
new file mode 100644
index 0000000..af8edae
--- /dev/null
+++ b/core/jni/android_os_Trace.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#define LOG_TAG "Trace"
+
+#include <JNIHelp.h>
+#include <ScopedUtfChars.h>
+
+#include <utils/Trace.h>
+#include <cutils/log.h>
+
+namespace android {
+
+static jlong android_os_Trace_nativeGetEnabledTags(JNIEnv* env, jclass clazz) {
+ return Tracer::getEnabledTags();
+}
+
+static void android_os_Trace_nativeTraceCounter(JNIEnv* env, jclass clazz,
+ jlong tag, jstring nameStr, jint value) {
+ ScopedUtfChars name(env, nameStr);
+ Tracer::traceCounter(tag, name.c_str(), value);
+}
+
+static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass clazz,
+ jlong tag, jstring nameStr) {
+ ScopedUtfChars name(env, nameStr);
+ Tracer::traceBegin(tag, name.c_str());
+}
+
+static void android_os_Trace_nativeTraceEnd(JNIEnv* env, jclass clazz,
+ jlong tag) {
+ Tracer::traceEnd(tag);
+}
+
+static JNINativeMethod gTraceMethods[] = {
+ /* name, signature, funcPtr */
+ { "nativeGetEnabledTags",
+ "()J",
+ (void*)android_os_Trace_nativeGetEnabledTags },
+ { "nativeTraceCounter",
+ "(JLjava/lang/String;I)V",
+ (void*)android_os_Trace_nativeTraceCounter },
+ { "nativeTraceBegin",
+ "(JLjava/lang/String;)V",
+ (void*)android_os_Trace_nativeTraceBegin },
+ { "nativeTraceEnd",
+ "(J)V",
+ (void*)android_os_Trace_nativeTraceEnd },
+};
+
+int register_android_os_Trace(JNIEnv* env) {
+ int res = jniRegisterNativeMethods(env, "android/os/Trace",
+ gTraceMethods, NELEM(gTraceMethods));
+ LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+ return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_GLES20DisplayList.cpp b/core/jni/android_view_GLES20DisplayList.cpp
new file mode 100644
index 0000000..407c196
--- /dev/null
+++ b/core/jni/android_view_GLES20DisplayList.cpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <EGL/egl.h>
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <DisplayListRenderer.h>
+
+namespace android {
+
+using namespace uirenderer;
+
+/**
+ * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
+ * devices. This means all the logic must be compiled only when the
+ * preprocessor variable USE_OPENGL_RENDERER is defined.
+ */
+#ifdef USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// DisplayList view properties
+// ----------------------------------------------------------------------------
+
+static void android_view_GLES20DisplayList_setCaching(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, jboolean caching) {
+ displayList->setCaching(caching);
+}
+
+static void android_view_GLES20DisplayList_setApplicationScale(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float scale) {
+ displayList->setApplicationScale(scale);
+}
+
+static void android_view_GLES20DisplayList_setClipChildren(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, jboolean clipChildren) {
+ displayList->setClipChildren(clipChildren);
+}
+
+static void android_view_GLES20DisplayList_setAlpha(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float alpha) {
+ displayList->setAlpha(alpha);
+}
+
+static void android_view_GLES20DisplayList_setTranslationX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float tx) {
+ displayList->setTranslationX(tx);
+}
+
+static void android_view_GLES20DisplayList_setTranslationY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float ty) {
+ displayList->setTranslationY(ty);
+}
+
+static void android_view_GLES20DisplayList_setRotation(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float rotation) {
+ displayList->setRotation(rotation);
+}
+
+static void android_view_GLES20DisplayList_setRotationX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float rx) {
+ displayList->setRotationX(rx);
+}
+
+static void android_view_GLES20DisplayList_setRotationY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float ry) {
+ displayList->setRotationY(ry);
+}
+
+static void android_view_GLES20DisplayList_setScaleX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float sx) {
+ displayList->setScaleX(sx);
+}
+
+static void android_view_GLES20DisplayList_setScaleY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float sy) {
+ displayList->setScaleY(sy);
+}
+
+static void android_view_GLES20DisplayList_setTransformationInfo(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float alpha,
+ float translationX, float translationY, float rotation, float rotationX, float rotationY,
+ float scaleX, float scaleY) {
+ displayList->setAlpha(alpha);
+ displayList->setTranslationX(translationX);
+ displayList->setTranslationY(translationY);
+ displayList->setRotation(rotation);
+ displayList->setRotationX(rotationX);
+ displayList->setRotationY(rotationY);
+ displayList->setScaleX(scaleX);
+ displayList->setScaleY(scaleY);
+}
+
+static void android_view_GLES20DisplayList_setPivotX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float px) {
+ displayList->setPivotX(px);
+}
+
+static void android_view_GLES20DisplayList_setPivotY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float py) {
+ displayList->setPivotY(py);
+}
+
+static void android_view_GLES20DisplayList_setCameraDistance(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float distance) {
+ displayList->setCameraDistance(distance);
+}
+
+static void android_view_GLES20DisplayList_setLeft(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int left) {
+ displayList->setLeft(left);
+}
+
+static void android_view_GLES20DisplayList_setTop(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int top) {
+ displayList->setTop(top);
+}
+
+static void android_view_GLES20DisplayList_setRight(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int right) {
+ displayList->setRight(right);
+}
+
+static void android_view_GLES20DisplayList_setBottom(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int bottom) {
+ displayList->setBottom(bottom);
+}
+
+static void android_view_GLES20DisplayList_setLeftTop(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int left, int top) {
+ displayList->setLeftTop(left, top);
+}
+
+static void android_view_GLES20DisplayList_setLeftTopRightBottom(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int left, int top,
+ int right, int bottom) {
+ displayList->setLeftTopRightBottom(left, top, right, bottom);
+}
+
+static void android_view_GLES20DisplayList_offsetLeftRight(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int offset) {
+ displayList->offsetLeftRight(offset);
+}
+
+static void android_view_GLES20DisplayList_offsetTopBottom(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int offset) {
+ displayList->offsetTopBottom(offset);
+}
+
+#endif // USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/GLES20DisplayList";
+
+static JNINativeMethod gMethods[] = {
+#ifdef USE_OPENGL_RENDERER
+ { "nSetCaching", "(IZ)V", (void*) android_view_GLES20DisplayList_setCaching },
+ { "nSetApplicationScale", "(IF)V",
+ (void*) android_view_GLES20DisplayList_setApplicationScale },
+ { "nSetClipChildren", "(IZ)V", (void*) android_view_GLES20DisplayList_setClipChildren },
+ { "nSetAlpha", "(IF)V", (void*) android_view_GLES20DisplayList_setAlpha },
+ { "nSetTranslationX", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationX },
+ { "nSetTranslationY", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationY },
+ { "nSetRotation", "(IF)V", (void*) android_view_GLES20DisplayList_setRotation },
+ { "nSetRotationX", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationX },
+ { "nSetRotationY", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationY },
+ { "nSetScaleX", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleX },
+ { "nSetScaleY", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleY },
+ { "nSetTransformationInfo", "(IFFFFFFFF)V",
+ (void*) android_view_GLES20DisplayList_setTransformationInfo },
+ { "nSetPivotX", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotX },
+ { "nSetPivotY", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotY },
+ { "nSetCameraDistance", "(IF)V",
+ (void*) android_view_GLES20DisplayList_setCameraDistance },
+ { "nSetLeft", "(II)V", (void*) android_view_GLES20DisplayList_setLeft },
+ { "nSetTop", "(II)V", (void*) android_view_GLES20DisplayList_setTop },
+ { "nSetRight", "(II)V", (void*) android_view_GLES20DisplayList_setRight },
+ { "nSetBottom", "(II)V", (void*) android_view_GLES20DisplayList_setBottom },
+ { "nSetLeftTop", "(III)V", (void*) android_view_GLES20DisplayList_setLeftTop },
+ { "nSetLeftTopRightBottom", "(IIIII)V",
+ (void*) android_view_GLES20DisplayList_setLeftTopRightBottom },
+ { "nOffsetLeftRight", "(II)V", (void*) android_view_GLES20DisplayList_offsetLeftRight },
+ { "nOffsetTopBottom", "(II)V", (void*) android_view_GLES20DisplayList_offsetTopBottom },
+
+#endif
+};
+
+#ifdef USE_OPENGL_RENDERER
+ #define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className);
+
+ #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+ var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find method " methodName);
+#else
+ #define FIND_CLASS(var, className)
+ #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
+#endif
+
+int register_android_view_GLES20DisplayList(JNIEnv* env) {
+ return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
+
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index c387752..30d4e20 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -888,7 +888,7 @@ void nativeClassInit(JNIEnv* env, jclass clazz)
no.native_region = env->GetFieldID(region, "mNativeRegion", "I");
jclass parcel = env->FindClass("android/os/Parcel");
- no.native_parcel = env->GetFieldID(parcel, "mObject", "I");
+ no.native_parcel = env->GetFieldID(parcel, "mNativePtr", "I");
jclass rect = env->FindClass("android/graphics/Rect");
ro.l = env->GetFieldID(rect, "left", "I");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 17d2212..8f03fe0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -639,6 +639,13 @@
android:label="@string/permgrouplab_storage"
android:description="@string/permgroupdesc_storage" />
+ <!-- Allows an application to read from external storage -->
+ <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+ android:permissionGroup="android.permission-group.STORAGE"
+ android:label="@string/permlab_sdcardRead"
+ android:description="@string/permdesc_sdcardRead"
+ android:protectionLevel="dangerous" />
+
<!-- Allows an application to write to external storage -->
<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:permissionGroup="android.permission-group.STORAGE"
diff --git a/core/res/res/anim/screen_rotate_180_enter.xml b/core/res/res/anim/screen_rotate_180_enter.xml
index 688a8d5..e2f3ce2 100644
--- a/core/res/res/anim/screen_rotate_180_enter.xml
+++ b/core/res/res/anim/screen_rotate_180_enter.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml
index 58a1868..fe4a950 100644
--- a/core/res/res/anim/screen_rotate_180_exit.xml
+++ b/core/res/res/anim/screen_rotate_180_exit.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim/screen_rotate_180_frame.xml b/core/res/res/anim/screen_rotate_180_frame.xml
index 19dade1..1a3ee67 100644
--- a/core/res/res/anim/screen_rotate_180_frame.xml
+++ b/core/res/res/anim/screen_rotate_180_frame.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_finish_enter.xml b/core/res/res/anim/screen_rotate_finish_enter.xml
index 9d731e6..f12a1ae 100644
--- a/core/res/res/anim/screen_rotate_finish_enter.xml
+++ b/core/res/res/anim/screen_rotate_finish_enter.xml
@@ -26,7 +26,6 @@
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
android:duration="@android:integer/config_shortAnimTime"/>
- <!--
<scale android:fromXScale="100%p" android:toXScale="100%"
android:fromYScale="100%p" android:toYScale="100%"
android:pivotX="50%" android:pivotY="50%"
@@ -34,5 +33,4 @@
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
android:duration="@android:integer/config_mediumAnimTime" />
- -->
</set>
diff --git a/core/res/res/anim/screen_rotate_finish_exit.xml b/core/res/res/anim/screen_rotate_finish_exit.xml
index 60daa18..3d9c569 100644
--- a/core/res/res/anim/screen_rotate_finish_exit.xml
+++ b/core/res/res/anim/screen_rotate_finish_exit.xml
@@ -19,8 +19,8 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <scale android:fromXScale="1.0" android:toXScale="1.0"
- android:fromYScale="1.0" android:toYScale="1.0"
+ <scale android:fromXScale="1.0" android:toXScale="1.1111111111111"
+ android:fromYScale="1.0" android:toYScale="1.1111111111111"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/accelerate_decelerate"
android:fillEnabled="true"
diff --git a/core/res/res/anim/screen_rotate_minus_90_enter.xml b/core/res/res/anim/screen_rotate_minus_90_enter.xml
index d2aebc9..38a674d 100644
--- a/core/res/res/anim/screen_rotate_minus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_enter.xml
@@ -19,44 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="-90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_exit.xml b/core/res/res/anim/screen_rotate_minus_90_exit.xml
index c7c38cd..a75aca7 100644
--- a/core/res/res/anim/screen_rotate_minus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_exit.xml
@@ -19,51 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="@android:integer/config_longAnimTime"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="0" android:toDegrees="90"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_minus_90_frame.xml b/core/res/res/anim/screen_rotate_minus_90_frame.xml
index 874f2e9..2d198f3 100644
--- a/core/res/res/anim/screen_rotate_minus_90_frame.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_frame.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_enter.xml b/core/res/res/anim/screen_rotate_plus_90_enter.xml
index 63d7043..583d2ba 100644
--- a/core/res/res/anim/screen_rotate_plus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_enter.xml
@@ -19,44 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_exit.xml b/core/res/res/anim/screen_rotate_plus_90_exit.xml
index ea48c81..a2bef41 100644
--- a/core/res/res/anim/screen_rotate_plus_90_exit.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_exit.xml
@@ -19,51 +19,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <!--
- <scale android:fromXScale="1.0" android:toXScale="0.565"
- android:fromYScale="1.0" android:toYScale="0.565"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.777777777"
- android:fromYScale="1.0" android:toYScale="1.777777777"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime"/>
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:startOffset="75"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
- <!--
- <scale android:fromXScale="100%" android:toXScale="100%p"
- android:fromYScale="100%" android:toYScale="100%p"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="@android:integer/config_mediumAnimTime" />
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
- -->
<rotate android:fromDegrees="0" android:toDegrees="-90"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/anim/screen_rotate_plus_90_frame.xml b/core/res/res/anim/screen_rotate_plus_90_frame.xml
index 03c6aa6..cd20050 100644
--- a/core/res/res/anim/screen_rotate_plus_90_frame.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_frame.xml
@@ -24,5 +24,5 @@
android:interpolator="@interpolator/decelerate_quint"
android:fillEnabled="true"
android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_mediumAnimTime" />
+ android:duration="@android:integer/config_longAnimTime" />
</set>
diff --git a/core/res/res/layout/action_bar_title_item.xml b/core/res/res/layout/action_bar_title_item.xml
index 4c74f6a..2e21383 100644
--- a/core/res/res/layout/action_bar_title_item.xml
+++ b/core/res/res/layout/action_bar_title_item.xml
@@ -18,7 +18,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:paddingRight="16dip"
+ android:paddingRight="8dip"
android:background="?android:attr/actionBarItemBackground"
android:enabled="false">
diff --git a/core/res/res/layout/dialog_custom_title.xml b/core/res/res/layout/dialog_custom_title.xml
index e52fba6..3784c59 100644
--- a/core/res/res/layout/dialog_custom_title.xml
+++ b/core/res/res/layout/dialog_custom_title.xml
@@ -15,7 +15,7 @@
-->
<!--
-This is an custom layout for a dialog.
+This is a custom layout for a dialog.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/core/res/res/layout/dialog_custom_title_holo.xml b/core/res/res/layout/dialog_custom_title_holo.xml
index e2335a7..cf71197 100644
--- a/core/res/res/layout/dialog_custom_title_holo.xml
+++ b/core/res/res/layout/dialog_custom_title_holo.xml
@@ -15,7 +15,7 @@
-->
<!--
-This is an custom layout for a dialog.
+This is a custom layout for a dialog.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/core/res/res/layout/screen_custom_title.xml b/core/res/res/layout/screen_custom_title.xml
index c62a06a..e3364d1 100644
--- a/core/res/res/layout/screen_custom_title.xml
+++ b/core/res/res/layout/screen_custom_title.xml
@@ -15,7 +15,7 @@
-->
<!--
-This is an custom layout for a screen.
+This is a custom layout for a screen.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9ac20fa..48f4606 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -769,7 +769,7 @@
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"verkry toegang tot inhoud ekstern"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Stel die houer in staat om toegang te verkry tot inhoudverskaffers vanuit die dop. Behoort nooit nodig te wees vir gewone programme nie."</string>
<string name="permlab_updateLock" msgid="3527558366616680889">"ontmoedig outomatiese toestelopdaterings"</string>
- <string name="permdesc_updateLock" msgid="1655625832166778492">"Laat die houer toe om inligting aan die stelsel te bied oor wanneer \'n goeie tyd vir \'n nie-interaktiewe herlaai sal wees om die toestel op te gradeer."</string>
+ <string name="permdesc_updateLock" msgid="1655625832166778492">"Laat die houer toe om inligting aan die stelsel te bied oor wanneer \'n goeie tyd vir \'n nie-interaktiewe herselflaai sal wees om die toestel op te gradeer."</string>
<string name="save_password_message" msgid="767344687139195790">"Wil jy hê die blaaier moet hierdie wagwoord onthou?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nie nou nie"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Onthou"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index dc74d94..b055634 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1086,8 +1086,8 @@
<string name="ime_action_done" msgid="8971516117910934605">"ተከናውኗል"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"ያለፈው"</string>
<string name="ime_action_default" msgid="2840921885558045721">"አከናውን"</string>
- <string name="dial_number_using" msgid="5789176425167573586">"የደወሉት ቁጥር"\n"<xliff:g id="NUMBER">%s</xliff:g>በመጠቀም ላይ"</string>
- <string name="create_contact_using" msgid="4947405226788104538">\n"በመጠቀም<xliff:g id="NUMBER">%s</xliff:g>ዕውቂያ ፍጠር"</string>
+ <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g>ን በመጠቀም "\n" ደውል"</string>
+ <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>ን በመጠቀም "\n" ዕውቂያ ፍጠር"</string>
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"የሚከተለው ወይም ተጨማሪ መተግበሪያዎች ወደ መለያህ ለመድረስ አሁን እና ወደፊት ፈቃድ ትጠይቃለህ።"</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"ይህን ጥየቃ መፍቀድ ይፈልጋሉ?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"የመድረሻ ጥያቄ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 7d08048..d2d4ece 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -68,7 +68,7 @@
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Nomor penelepon bawaan tidak dibatasi. Panggilan selanjutnya: Dibatasi"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Nomor penelepon bawaan tidak dibatasi. Panggilan selanjutnya: Tidak dibatasi"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Layanan tidak diperlengkapi."</string>
- <string name="CLIRPermanent" msgid="3377371145926835671">"Anda tidak dapat mengubah pengaturan nomor penelepon."</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"Anda tidak dapat mengubah setelan nomor penelepon."</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"Akses terbatas berubah"</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"Layanan data dicekal."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Layanan darurat dicekal."</string>
@@ -219,7 +219,7 @@
<string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Memungkinkan apl mengontrol mode kompatibilitas layar aplikasi lain. Aplikasi berbahaya dapat merusak perilaku aplikasi lain."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"mengaktifkan debugging apl"</string>
<string name="permdesc_setDebugApp" msgid="4474512416299013256">"Mengizinkan apl mengaktifkan debugging untuk apl lain. Apl berbahaya dapat menggunakan cara ini untuk menutup apl lain."</string>
- <string name="permlab_changeConfiguration" msgid="8214475779521218295">"ubah pengaturan UI Anda"</string>
+ <string name="permlab_changeConfiguration" msgid="8214475779521218295">"ubah setelan UI Anda"</string>
<string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Mengizinkan apl mengubah konfigurasi saat ini, misalnya lokal atau ukuran fon keseluruhan."</string>
<string name="permlab_enableCarMode" msgid="5684504058192921098">"aktifkan mode mobil"</string>
<string name="permdesc_enableCarMode" msgid="4853187425751419467">"Mengizinkan apl mengaktifkan mode mobil."</string>
@@ -317,10 +317,10 @@
<string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Memungkinkan aplikasi memberikan atau mencabut izin khusus untuk aplikasi tersebut atau aplikasi lainnya. Aplikasi berbahaya dapat menggunakannya untuk mengakses fitur yang tidak Anda beri izin."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"menyetel apl yang disukai"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Mengizinkan apl memodifikasi apl pilihan Anda. Apl berbahaya dapat diam-diam mengubah apl yang berjalan, menipu apl yang ada untuk mengumpulkan data pribadi dari Anda."</string>
- <string name="permlab_writeSettings" msgid="1365523497395143704">"ubah pengaturan sistem global"</string>
- <string name="permdesc_writeSettings" msgid="7775723441558907181">"Mengizinkan apl memodifikasi data pengaturan sistem. Apl berbahaya dapat merusak konfigurasi sistem anda."</string>
- <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ubah pengaturan sistem aman"</string>
- <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Mengizinkan apl memodifikasi data pengaturan aman sistem. Tidak untuk digunakan oleh apl normal."</string>
+ <string name="permlab_writeSettings" msgid="1365523497395143704">"ubah setelan sistem global"</string>
+ <string name="permdesc_writeSettings" msgid="7775723441558907181">"Mengizinkan apl memodifikasi data setelan sistem. Apl berbahaya dapat merusak konfigurasi sistem anda."</string>
+ <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ubah setelan sistem aman"</string>
+ <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Mengizinkan apl memodifikasi data setelan aman sistem. Tidak untuk digunakan oleh apl normal."</string>
<string name="permlab_writeGservices" msgid="2149426664226152185">"ubah peta layanan Google"</string>
<string name="permdesc_writeGservices" msgid="1287309437638380229">"Mengizinkan apl memodifikasi peta layanan Google. Tidak untuk digunakan oleh apl normal."</string>
<string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"mulai secara otomatis pada saat boot"</string>
@@ -364,8 +364,8 @@
<string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Mengizinkan apl menggunakan fitur tingkat rendah SurfaceFlinger."</string>
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca buffer frame"</string>
<string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Mengizinkan apl membaca konten penyangga frame."</string>
- <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ubah pengaturan audio Anda"</string>
- <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Mengizinkan apl memodifikasi pengaturan audio global, misalnya volume dan perutean."</string>
+ <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ubah setelan audio Anda"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Mengizinkan apl memodifikasi setelan audio global, misalnya volume dan perutean."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"rekam audio"</string>
<string name="permdesc_recordAudio" msgid="2387462233976248635">"Mengizinkan apl mengakses jalur rekaman audio."</string>
<string name="permlab_camera" msgid="3616391919559751192">"ambil gambar dan video"</string>
@@ -434,8 +434,8 @@
<string name="permdesc_setWallpaper" msgid="7373447920977624745">"Mengizinkan apl menyetel wallpaper sistem."</string>
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"atur petunjuk ukuran wallpaper"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Mengizinkan apl menyetel petunjuk ukuran wallpaper sistem."</string>
- <string name="permlab_masterClear" msgid="2315750423139697397">"setel ulang sistem ke pengaturan bawaan pabrik"</string>
- <string name="permdesc_masterClear" msgid="3665380492633910226">"Mengizinkan apl menyetel ulang sistem ke pengaturan pabrik sepenuhnya, menghapus semua data, konfigurasi, dan apl yang terpasang."</string>
+ <string name="permlab_masterClear" msgid="2315750423139697397">"setel ulang sistem ke setelan bawaan pabrik"</string>
+ <string name="permdesc_masterClear" msgid="3665380492633910226">"Mengizinkan apl menyetel ulang sistem ke setelan pabrik sepenuhnya, menghapus semua data, konfigurasi, dan apl yang terpasang."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"atur waktu"</string>
<string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Mengizinkan apl mengubah waktu pada jam tablet."</string>
<string name="permdesc_setTime" product="default" msgid="1855702730738020">"Mengizinkan apl mengubah waktu pada jam ponsel."</string>
@@ -457,14 +457,14 @@
<string name="permdesc_accessNetworkState" msgid="479772796952547198">"Mengizinkan apl melihat keadaan semua jaringan."</string>
<string name="permlab_createNetworkSockets" msgid="9121633680349549585">"akses internet penuh"</string>
<string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Mengizinkan apl membuat soket jaringan."</string>
- <string name="permlab_writeApnSettings" msgid="505660159675751896">"mengubah/mencegat lalu lintas dan pengaturan jaringan"</string>
- <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Mengizinkan apl mengubah pengaturan jaringan dan mencegat serta memeriksa semua lalu lintas jaringan, misalnya mengubah proxy dan port APN apa saja. Apl berbahaya dapat memantau, mengalihkan, atau mengubah paket jaringan tanpa sepengetahuan Anda."</string>
+ <string name="permlab_writeApnSettings" msgid="505660159675751896">"mengubah/mencegat lalu lintas dan setelan jaringan"</string>
+ <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Mengizinkan apl mengubah setelan jaringan dan mencegat serta memeriksa semua lalu lintas jaringan, misalnya mengubah proxy dan port APN apa saja. Apl berbahaya dapat memantau, mengalihkan, atau mengubah paket jaringan tanpa sepengetahuan Anda."</string>
<string name="permlab_changeNetworkState" msgid="958884291454327309">"ubah konektivitas jaringan"</string>
<string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Mengizinkan apl mengubah keadaan konektivitas jaringan."</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"mengubah konektivitas yang tertambat"</string>
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"Mengizinkan apl mengubah status konektivitas jaringan yang tertambat."</string>
- <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"mengubah pengaturan penggunaan data latar belakang"</string>
- <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Mengizinkan apl mengubah pengaturan penggunaan data latar belakang."</string>
+ <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"mengubah setelan penggunaan data latar belakang"</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Mengizinkan apl mengubah setelan penggunaan data latar belakang."</string>
<string name="permlab_accessWifiState" msgid="8100926650211034400">"lihat kondisi Wi-Fi"</string>
<string name="permdesc_accessWifiState" msgid="7770452658226256831">"Mengizinkan apl melihat informasi tentang keadaan Wi-Fi."</string>
<string name="permlab_changeWifiState" msgid="7280632711057112137">"ubah status Wi-Fi"</string>
@@ -485,10 +485,10 @@
<string name="permdesc_nfc" msgid="7120611819401789907">"Mengizinkan apl berkomunikasi dengan tag, kartu, dan alat pembaca Komunikasi Nirkabel Jarak Dekat (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="4977406164311535092">"nonaktifkan kunci tombol"</string>
<string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Mengizinkan apl menonaktifkan kunci tombol dan segala keamanan sandi yang terkait. Contoh nyata dari hal ini adalah ponsel menonaktifkan kunci tombol saat menerima panggilan telepon masuk, kemudian mengaktifkan kembali kunci tombol ketika panggilan selesai."</string>
- <string name="permlab_readSyncSettings" msgid="6201810008230503052">"baca pengaturan sinkron"</string>
- <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Mengizinkan apl membaca pengaturan sinkronisasi, misalnya apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
- <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"tuliskan pengaturan sinkronisasi"</string>
- <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Mengizinkan apl memodifikasi pengaturan sinkronisasi, seperti apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
+ <string name="permlab_readSyncSettings" msgid="6201810008230503052">"baca setelan sinkron"</string>
+ <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Mengizinkan apl membaca setelan sinkronisasi, misalnya apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
+ <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"tuliskan setelan sinkronisasi"</string>
+ <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Mengizinkan apl memodifikasi setelan sinkronisasi, seperti apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"statistika baca sinkron"</string>
<string name="permdesc_readSyncStats" msgid="3801971839939951678">"Mengizinkan apl membaca statistik sinkronisasi; mis., riwayat sinkronisasi yang telah terjadi."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca umpan langganan"</string>
@@ -695,10 +695,10 @@
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan info masuk Google."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan info masuk Google."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke pengaturan bawaan pabrik dan semua data pengguna hilang."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke pengaturan bawaan pabrik dan semua data pengguna hilang."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke pengaturan bawaan pabrik."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan disetel ulang ke pengaturan bawaan pabrik."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke setelan bawaan pabrik dan semua data pengguna hilang."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke setelan bawaan pabrik dan semua data pengguna hilang."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke setelan bawaan pabrik."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan disetel ulang ke setelan bawaan pabrik."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Lupa pola?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Pembuka kunci akun"</string>
@@ -910,7 +910,7 @@
<string name="capital_off" msgid="6815870386972805832">"MATI"</string>
<string name="whichApplication" msgid="4533185947064773386">"Tindakan lengkap menggunakan"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Gunakan secara bawaan untuk tindakan ini."</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Menghapus bawaan di Pengaturan sistem &gt; Apl &gt; Terunduh."</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Menghapus bawaan di Setelan sistem &gt; Apl &gt; Terunduh."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Pilih tindakan"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"Pilih apl untuk perangkat USB"</string>
<string name="noApplications" msgid="2991814273936504689">"Tidak ada apl yang dapat melakukan tindakan ini."</string>
@@ -931,7 +931,7 @@
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah diluncurkan aslinya."</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"Skala"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"Selalu tampilkan"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Aktifkan kembali dialog ini di Pengaturan sistem &gt; Apl &gt; Terunduh."</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Aktifkan kembali dialog ini di Setelan sistem &gt; Apl &gt; Terunduh."</string>
<string name="smv_application" msgid="3307209192155442829">"Apl <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar kebijakan StrictMode yang diberlakukannya sendiri."</string>
<string name="smv_process" msgid="5120397012047462446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar kebijakan StrictMode yang diberlakukan secara otomatis."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android sedang meningkatkan versi..."</string>
@@ -983,7 +983,7 @@
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Memulai Wi-Fi Langsung. Opsi ini akan mematikan hotspot/klien Wi-Fi."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulai Wi-Fi Langsung."</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Langsung aktif"</string>
- <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk pengaturan"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk setelan"</string>
<string name="accept" msgid="1645267259272829559">"Terima"</string>
<string name="decline" msgid="2112225451706137894">"Tolak"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Undangan terkirim"</string>
@@ -1027,7 +1027,7 @@
<string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Sebelum mematikan penyimpanan USB, lepaskan (\"keluarkan\") penyimpanan USB Anda dari komputer."</string>
<string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Sebelum mematikan penyimpanan USB, lepaskan (\"keluarkan\") kartu SD Android dari komputer."</string>
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Matikan penyimpanan USB"</string>
- <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Terjadi masalah saat mematikan penyimpanan USB. Periksa apakah Anda telah melepaskan inang USB, lalu coba sekali lagi."</string>
+ <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Terjadi masalah saat mematikan penyimpanan USB. Periksa apakah Anda telah melepaskan host USB, lalu coba sekali lagi."</string>
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Hidupkan penyimpanan USB"</string>
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Jika Anda menyalakan penyimpanan USB, beberapa apl yang Anda gunakan akan berhenti dan mungkin tidak dapat dibuka hingga penyimpanan USB dimatikan."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operasi USB gagal"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 49f2823..4d9b043 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -77,7 +77,7 @@
</integer-array>
<!-- Flag indicating whether the AUDIO_BECOMING_NOISY notification should
- be sent during an change to the audio output device. -->
+ be sent during a change to the audio output device. -->
<bool name="config_sendAudioBecomingNoisy">true</bool>
<!-- The duration (in milliseconds) of a short animation. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c8df649..7137b7c 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1429,6 +1429,15 @@
user dictionary.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
+ <string name="permlab_sdcardRead" product="nosdcard">read USB storage contents</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_sdcardRead" product="default">read SD card contents</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
+ <string name="permdesc_sdcardRead" product="nosdcard">Allows the app to read contents of USB storage.</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_sdcardRead" product="default">Allows the app to read contents of SD card.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
<string name="permlab_sdcardWrite" product="nosdcard">modify/delete USB storage contents</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_sdcardWrite" product="default">modify/delete SD card contents</string>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index 7233e7f..3ec9031 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -42,17 +42,13 @@ public class ConnectivityManagerStressTestRunner extends InstrumentationTestRunn
public int mSleepTime = 2 * 60 * 1000;
public String mReconnectSsid = "securenetdhcp";
public String mReconnectPassword = "androidwifi";
+ public boolean mWifiOnlyFlag = false;
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
- if (!UtilHelper.isWifiOnly(getContext())) {
- suite.addTestSuite(WifiApStress.class);
- suite.addTestSuite(WifiStressTest.class);
- } else {
- // only the wifi stress tests
- suite.addTestSuite(WifiStressTest.class);
- }
+ suite.addTestSuite(WifiApStress.class);
+ suite.addTestSuite(WifiStressTest.class);
return suite;
}
@@ -64,13 +60,11 @@ public class ConnectivityManagerStressTestRunner extends InstrumentationTestRunn
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- if (!UtilHelper.isWifiOnly(getContext())) {
- String valueStr = (String) icicle.get("softap_iterations");
- if (valueStr != null) {
- int iteration = Integer.parseInt(valueStr);
- if (iteration > 0) {
- mSoftapIterations = iteration;
- }
+ String valueStr = (String) icicle.get("softap_iterations");
+ if (valueStr != null) {
+ int iteration = Integer.parseInt(valueStr);
+ if (iteration > 0) {
+ mSoftapIterations = iteration;
}
}
@@ -107,5 +101,10 @@ public class ConnectivityManagerStressTestRunner extends InstrumentationTestRunn
mSleepTime = 1000 * sleepTime;
}
}
+
+ String wifiOnlyFlag = (String) icicle.get("wifi-only");
+ if (wifiOnlyFlag != null) {
+ mWifiOnlyFlag = true;
+ }
}
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index 9c1922f..b94306a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -35,23 +35,13 @@ import junit.framework.TestSuite;
*/
public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
- public String TEST_SSID = null;
+ public boolean mWifiOnlyFlag = false;
+ public String mTestSsid = null;
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
- if (!UtilHelper.isWifiOnly(getContext())) {
- suite.addTestSuite(ConnectivityManagerMobileTest.class);
- } else {
- // create a new test suite
- suite.setName("ConnectivityManagerWifiOnlyFunctionalTests");
- String[] methodNames = {"testConnectToWifi", "testConnectToWifWithKnownAP",
- "testDisconnectWifi", "testWifiStateChange"};
- Class<ConnectivityManagerMobileTest> testClass = ConnectivityManagerMobileTest.class;
- for (String method: methodNames) {
- suite.addTest(TestSuite.createTest(testClass, method));
- }
- }
+ suite.addTestSuite(ConnectivityManagerMobileTest.class);
suite.addTestSuite(WifiConnectionTest.class);
return suite;
}
@@ -66,7 +56,11 @@ public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
super.onCreate(icicle);
String testSSID = (String) icicle.get("ssid");
if (testSSID != null) {
- TEST_SSID = testSSID;
+ mTestSsid = testSSID;
+ }
+ String wifiOnlyFlag = (String) icicle.get("wifi-only");
+ if (wifiOnlyFlag != null) {
+ mWifiOnlyFlag = true;
}
}
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
deleted file mode 100644
index b9fe6ed..0000000
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- * 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.connectivitymanagertest;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.util.Log;
-
-public class UtilHelper {
-
- private static Boolean mIsWifiOnly = null;
- private static final Object sLock = new Object();
-
- /**
- * Return true if device is a wifi only device.
- */
- public static boolean isWifiOnly(Context context) {
- synchronized (sLock) {
- // cache the result from pkgMgr statically. It will never change, since its a
- // device configuration setting
- if (mIsWifiOnly == null) {
- PackageManager pkgMgr = context.getPackageManager();
- mIsWifiOnly = Boolean.valueOf(!pkgMgr
- .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
- && pkgMgr.hasSystemFeature(PackageManager.FEATURE_WIFI));
- String deviceType = mIsWifiOnly ? "wifi-only" : "telephony";
- Log.d("ConnectivityManagerTest", String.format("detected a %s device", deviceType));
- }
- }
- return mIsWifiOnly;
- }
-}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index 52326d5..bf188d3 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -31,16 +31,15 @@ import android.util.Log;
import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
import com.android.connectivitymanagertest.NetworkState;
-import com.android.connectivitymanagertest.UtilHelper;
public class ConnectivityManagerMobileTest extends
ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
private static final String LOG_TAG = "ConnectivityManagerMobileTest";
- private String TEST_ACCESS_POINT;
+ private String mTestAccessPoint;
private ConnectivityManagerTestActivity cmActivity;
private WakeLock wl;
- private boolean mIsWifiOnlyDevice;
+ private boolean mWifiOnlyFlag;
public ConnectivityManagerMobileTest() {
super(ConnectivityManagerTestActivity.class);
@@ -52,7 +51,9 @@ public class ConnectivityManagerMobileTest extends
cmActivity = getActivity();
ConnectivityManagerTestRunner mRunner =
(ConnectivityManagerTestRunner)getInstrumentation();
- TEST_ACCESS_POINT = mRunner.TEST_SSID;
+ mTestAccessPoint = mRunner.mTestSsid;
+ mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
+
PowerManager pm = (PowerManager)getInstrumentation().
getContext().getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "CMWakeLock");
@@ -63,8 +64,8 @@ public class ConnectivityManagerMobileTest extends
log("airplane is not disabled, disable it.");
cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
}
- mIsWifiOnlyDevice = UtilHelper.isWifiOnly(mRunner.getTargetContext());
- if (!mIsWifiOnlyDevice) {
+
+ if (!mWifiOnlyFlag) {
if (!cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT)) {
// Note: When the test fails in setUp(), tearDown is not called. In that case,
@@ -113,6 +114,10 @@ public class ConnectivityManagerMobileTest extends
// event should be expected.
@LargeTest
public void test3GToWifiNotification() {
+ if (mWifiOnlyFlag) {
+ Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ return;
+ }
// Enable Wi-Fi to avoid initial UNKNOWN state
cmActivity.enableWifi();
sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
@@ -159,9 +164,9 @@ public class ConnectivityManagerMobileTest extends
// Test case 2: test connection to a given AP
@LargeTest
public void testConnectToWifi() {
- assertNotNull("SSID is null", TEST_ACCESS_POINT);
+ assertNotNull("SSID is null", mTestAccessPoint);
NetworkInfo networkInfo;
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
//Prepare for connectivity verification
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -172,15 +177,15 @@ public class ConnectivityManagerMobileTest extends
NetworkState.TO_CONNECTION, State.CONNECTED);
// Enable Wifi and connect to a test access point
- assertTrue("failed to connect to " + TEST_ACCESS_POINT,
- cmActivity.connectToWifi(TEST_ACCESS_POINT));
+ assertTrue("failed to connect to " + mTestAccessPoint,
+ cmActivity.connectToWifi(mTestAccessPoint));
assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
log("wifi state is enabled");
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
@@ -192,7 +197,7 @@ public class ConnectivityManagerMobileTest extends
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
@@ -205,10 +210,10 @@ public class ConnectivityManagerMobileTest extends
// Test case 3: connect to Wifi with known AP
@LargeTest
public void testConnectToWifWithKnownAP() {
- assertNotNull("SSID is null", TEST_ACCESS_POINT);
- // Connect to TEST_ACCESS_POINT
- assertTrue("failed to connect to " + TEST_ACCESS_POINT,
- cmActivity.connectToWifi(TEST_ACCESS_POINT));
+ assertNotNull("SSID is null", mTestAccessPoint);
+ // Connect to mTestAccessPoint
+ assertTrue("failed to connect to " + mTestAccessPoint,
+ cmActivity.connectToWifi(mTestAccessPoint));
assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
@@ -227,13 +232,13 @@ public class ConnectivityManagerMobileTest extends
ConnectivityManagerTestActivity.LONG_TIMEOUT));
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
NetworkInfo networkInfo;
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
//Prepare for connectivity state verification
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -253,7 +258,7 @@ public class ConnectivityManagerMobileTest extends
// Wait for Wifi to be connected and mobile to be disconnected
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
@@ -270,11 +275,11 @@ public class ConnectivityManagerMobileTest extends
// Test case 4: test disconnect Wifi
@LargeTest
public void testDisconnectWifi() {
- assertNotNull("SSID is null", TEST_ACCESS_POINT);
+ assertNotNull("SSID is null", mTestAccessPoint);
// connect to Wifi
- assertTrue("failed to connect to " + TEST_ACCESS_POINT,
- cmActivity.connectToWifi(TEST_ACCESS_POINT));
+ assertTrue("failed to connect to " + mTestAccessPoint,
+ cmActivity.connectToWifi(mTestAccessPoint));
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -283,7 +288,7 @@ public class ConnectivityManagerMobileTest extends
sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
NetworkInfo networkInfo;
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(),
@@ -299,7 +304,7 @@ public class ConnectivityManagerMobileTest extends
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
@@ -311,7 +316,7 @@ public class ConnectivityManagerMobileTest extends
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
@@ -324,6 +329,10 @@ public class ConnectivityManagerMobileTest extends
// Test case 5: test connectivity from 3G to airplane mode, then to 3G again
@LargeTest
public void testDataConnectionWith3GToAmTo3G() {
+ if (mWifiOnlyFlag) {
+ Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ return;
+ }
//Prepare for state verification
NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -340,7 +349,9 @@ public class ConnectivityManagerMobileTest extends
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
assertEquals(State.DISCONNECTED, networkInfo.getState());
-
+ // wait until mobile is turn off
+ assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
+ State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
@@ -382,13 +393,17 @@ public class ConnectivityManagerMobileTest extends
// Test case 6: test connectivity with airplane mode Wifi connected
@LargeTest
public void testDataConnectionOverAMWithWifi() {
- assertNotNull("SSID is null", TEST_ACCESS_POINT);
+ if (mWifiOnlyFlag) {
+ Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ return;
+ }
+ assertNotNull("SSID is null", mTestAccessPoint);
// Eanble airplane mode
log("Enable airplane mode");
cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
NetworkInfo networkInfo;
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
@@ -402,8 +417,8 @@ public class ConnectivityManagerMobileTest extends
NetworkState.TO_CONNECTION, State.CONNECTED);
// Connect to Wifi
- assertTrue("failed to connect to " + TEST_ACCESS_POINT,
- cmActivity.connectToWifi(TEST_ACCESS_POINT));
+ assertTrue("failed to connect to " + mTestAccessPoint,
+ cmActivity.connectToWifi(mTestAccessPoint));
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -414,7 +429,7 @@ public class ConnectivityManagerMobileTest extends
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue("State validation failed", false);
}
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("state validation for Mobile failed");
log("reason: " +
@@ -428,11 +443,15 @@ public class ConnectivityManagerMobileTest extends
// Test case 7: test connectivity while transit from Wifi->AM->Wifi
@LargeTest
public void testDataConnectionWithWifiToAMToWifi () {
- // Connect to TEST_ACCESS_POINT
- assertNotNull("SSID is null", TEST_ACCESS_POINT);
+ if (mWifiOnlyFlag) {
+ Log.v(LOG_TAG, this.getName() + " is excluded for wifi-only test");
+ return;
+ }
+ // Connect to mTestAccessPoint
+ assertNotNull("SSID is null", mTestAccessPoint);
// Connect to Wifi
- assertTrue("failed to connect to " + TEST_ACCESS_POINT,
- cmActivity.connectToWifi(TEST_ACCESS_POINT));
+ assertTrue("failed to connect to " + mTestAccessPoint,
+ cmActivity.connectToWifi(mTestAccessPoint));
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -466,7 +485,7 @@ public class ConnectivityManagerMobileTest extends
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
@@ -483,10 +502,10 @@ public class ConnectivityManagerMobileTest extends
// Test case 8: test wifi state change while connecting/disconnecting to/from an AP
@LargeTest
public void testWifiStateChange () {
- assertNotNull("SSID is null", TEST_ACCESS_POINT);
- //Connect to TEST_ACCESS_POINT
- assertTrue("failed to connect to " + TEST_ACCESS_POINT,
- cmActivity.connectToWifi(TEST_ACCESS_POINT));
+ assertNotNull("SSID is null", mTestAccessPoint);
+ //Connect to mTestAccessPoint
+ assertTrue("failed to connect to " + mTestAccessPoint,
+ cmActivity.connectToWifi(mTestAccessPoint));
assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
@@ -503,7 +522,7 @@ public class ConnectivityManagerMobileTest extends
// Disconnect from the current AP
log("disconnect from the AP");
if (!cmActivity.disconnectAP()) {
- log("failed to disconnect from " + TEST_ACCESS_POINT);
+ log("failed to disconnect from " + mTestAccessPoint);
}
// Verify the connectivity state for Wifi is DISCONNECTED
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 41104fe..7e136be 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -51,6 +51,7 @@ public class WifiApStress
private int iterations;
private BufferedWriter mOutputWriter = null;
private int mLastIteration = 0;
+ private boolean mWifiOnlyFlag;
public WifiApStress() {
super(ConnectivityManagerTestActivity.class);
@@ -63,6 +64,7 @@ public class WifiApStress
ConnectivityManagerStressTestRunner mRunner =
(ConnectivityManagerStressTestRunner)getInstrumentation();
iterations = mRunner.mSoftapIterations;
+ mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
mAct.turnScreenOn();
}
@@ -79,6 +81,10 @@ public class WifiApStress
@LargeTest
public void testWifiHotSpot() {
+ if (mWifiOnlyFlag) {
+ Log.v(TAG, this.getName() + " is excluded for wi-fi only test");
+ return;
+ }
WifiConfiguration config = new WifiConfiguration();
config.SSID = NETWORK_ID;
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index feb63cd..f46546f 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -34,7 +34,6 @@ import android.util.Log;
import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
-import com.android.connectivitymanagertest.UtilHelper;
import java.io.BufferedWriter;
import java.io.File;
@@ -75,7 +74,7 @@ public class WifiStressTest
private String mPassword;
private ConnectivityManagerStressTestRunner mRunner;
private BufferedWriter mOutputWriter = null;
- private boolean mIsWifiOnlyDevice;
+ private boolean mWifiOnlyFlag;
public WifiStressTest() {
super(ConnectivityManagerTestActivity.class);
@@ -91,13 +90,13 @@ public class WifiStressTest
mPassword = mRunner.mReconnectPassword;
mScanIterations = mRunner.mScanIterations;
mWifiSleepTime = mRunner.mSleepTime;
+ mWifiOnlyFlag = mRunner.mWifiOnlyFlag;
log(String.format("mReconnectIterations(%d), mSsid(%s), mPassword(%s),"
+ "mScanIterations(%d), mWifiSleepTime(%d)", mReconnectIterations, mSsid,
mPassword, mScanIterations, mWifiSleepTime));
mOutputWriter = new BufferedWriter(new FileWriter(new File(
Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
mAct.turnScreenOn();
- mIsWifiOnlyDevice = UtilHelper.isWifiOnly(mRunner.getTargetContext());
if (!mAct.mWifiManager.isWifiEnabled()) {
log("Enable wi-fi before stress tests.");
if (!mAct.enableWifi()) {
@@ -269,7 +268,7 @@ public class WifiStressTest
assertTrue("Wait for Wi-Fi to idle timeout",
mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
// use long timeout as the pppd startup may take several retries.
assertTrue("Wait for cellular connection timeout",
mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
@@ -280,7 +279,7 @@ public class WifiStressTest
assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
- if (!mIsWifiOnlyDevice) {
+ if (!mWifiOnlyFlag) {
assertEquals("Cellular connection is down", State.CONNECTED,
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
diff --git a/core/tests/coretests/src/android/util/ListScenario.java b/core/tests/coretests/src/android/util/ListScenario.java
index 22be4e7..fa088a3 100644
--- a/core/tests/coretests/src/android/util/ListScenario.java
+++ b/core/tests/coretests/src/android/util/ListScenario.java
@@ -590,7 +590,7 @@ public abstract class ListScenario extends Activity {
}
/**
- * Return an the number of types created by the adapter. Override if your
+ * Return the number of types created by the adapter. Override if your
* adapter creates more than one type.
*/
public int getViewTypeCount() {
diff --git a/core/tests/coretests/src/android/view/GravityTest.java b/core/tests/coretests/src/android/view/GravityTest.java
deleted file mode 100644
index d8ef650..0000000
--- a/core/tests/coretests/src/android/view/GravityTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.view;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class GravityTest extends AndroidTestCase {
-
- @SmallTest
- public void testGetAbsoluteGravity() throws Exception {
- assertOneGravity(Gravity.LEFT, Gravity.LEFT, false);
- assertOneGravity(Gravity.LEFT, Gravity.LEFT, true);
-
- assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, false);
- assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, true);
-
- assertOneGravity(Gravity.TOP, Gravity.TOP, false);
- assertOneGravity(Gravity.TOP, Gravity.TOP, true);
-
- assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, false);
- assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, true);
-
- assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, false);
- assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, true);
-
- assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, false);
- assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, true);
-
- assertOneGravity(Gravity.CENTER, Gravity.CENTER, false);
- assertOneGravity(Gravity.CENTER, Gravity.CENTER, true);
-
- assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, false);
- assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, true);
-
- assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, false);
- assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, true);
-
- assertOneGravity(Gravity.FILL, Gravity.FILL, false);
- assertOneGravity(Gravity.FILL, Gravity.FILL, true);
-
- assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, false);
- assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, true);
-
- assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, false);
- assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, true);
-
- assertOneGravity(Gravity.LEFT, Gravity.START, false);
- assertOneGravity(Gravity.RIGHT, Gravity.START, true);
-
- assertOneGravity(Gravity.RIGHT, Gravity.END, false);
- assertOneGravity(Gravity.LEFT, Gravity.END, true);
- }
-
- private void assertOneGravity(int expected, int initial, boolean isRtl) {
- final int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
-
- assertEquals(expected, Gravity.getAbsoluteGravity(initial, layoutDirection));
- }
-}
diff --git a/core/tests/coretests/src/android/view/ViewAttachTest.java b/core/tests/coretests/src/android/view/ViewAttachTest.java
index cff66e4..a73f5a6 100644
--- a/core/tests/coretests/src/android/view/ViewAttachTest.java
+++ b/core/tests/coretests/src/android/view/ViewAttachTest.java
@@ -29,12 +29,12 @@ public class ViewAttachTest extends
/**
* Make sure that onAttachedToWindow and onDetachedToWindow is called in the
- * correct order The ViewAttachTestActivity contains a view that will throw
- * an RuntimeException if onDetachedToWindow and onAttachedToWindow is
+ * correct order. The ViewAttachTestActivity contains a view that will throw
+ * a RuntimeException if onDetachedToWindow and onAttachedToWindow are
* called in the wrong order.
*
* 1. Initiate the activity 2. Perform a series of orientation changes to
- * the activity (this will force the View hierarchy to be rebuild,
+ * the activity (this will force the View hierarchy to be rebuilt,
* generating onAttachedToWindow and onDetachedToWindow)
*
* Expected result: No RuntimeException is thrown from the TestView in
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 8be1db2..4b93e74 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -54,6 +54,10 @@
<group gid="log" />
</permission>
+ <permission name="android.permission.READ_EXTERNAL_STORAGE" >
+ <group gid="sdcard_r" />
+ </permission>
+
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
<group gid="sdcard_rw" />
</permission>
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
index 34804cf..c0e408e 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngine.h
@@ -499,6 +499,14 @@ ssize_t onPread(int uniqueId,
private:
+ static const String8 Description;
+ static const String8 FileSuffixes[];
+ static const String8 MimeTypes[];
+ static bool IsFileSuffixSupported(const String8& suffix);
+ static bool IsMimeTypeSupported(const String8& mime);
+ static void AddSupportedMimeTypes(DrmSupportInfo *info);
+ static void AddSupportedFileSuffixes(DrmSupportInfo *info);
+
/**
* Session Class for Forward Lock Conversion. An object of this class is created
* for every conversion.
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngineConst.h b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngineConst.h
deleted file mode 100644
index da95d60..0000000
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/include/FwdLockEngineConst.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- * 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.
- */
-
-#ifndef __FWDLOCKENGINECONST_H__
-#define __FWDLOCKENGINECONST_H__
-
-namespace android {
-
-/**
- * Constants for forward Lock Engine used for exposing engine's capabilities.
- */
-#define FWDLOCK_EXTENSION_FL ("FL")
-#define FWDLOCK_DOTEXTENSION_FL (".fl")
-#define FWDLOCK_MIMETYPE_FL ("application/x-android-drm-fl")
-
-#define FWDLOCK_EXTENSION_DM ("DM")
-#define FWDLOCK_DOTEXTENSION_DM (".dm")
-#define FWDLOCK_MIMETYPE_DM ("application/vnd.oma.drm.message")
-
-#define FWDLOCK_DESCRIPTION ("OMA V1 Forward Lock")
-
-};
-
-#endif /* __FWDLOCKENGINECONST_H__ */
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index 0273a4b..5ee41e6 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -35,7 +35,6 @@
#include "FwdLockConv.h"
#include "FwdLockFile.h"
#include "FwdLockGlue.h"
-#include "FwdLockEngineConst.h"
#include "MimeTypeUtil.h"
#undef LOG_TAG
@@ -160,6 +159,48 @@ android::status_t FwdLockEngine::onTerminate(int uniqueId) {
return DRM_NO_ERROR;
}
+const String8 FwdLockEngine::FileSuffixes[] = {
+ String8(".fl"),
+ String8(".dm"),
+};
+
+const String8 FwdLockEngine::MimeTypes[] = {
+ String8("application/x-android-drm-fl"),
+ String8("application/vnd.oma.drm.message"),
+};
+
+const String8 FwdLockEngine::Description("OMA V1 Forward Lock");
+
+void FwdLockEngine::AddSupportedMimeTypes(DrmSupportInfo *info) {
+ for (size_t i = 0, n = sizeof(MimeTypes)/sizeof(MimeTypes[0]); i < n; ++i) {
+ info->addMimeType(MimeTypes[i]);
+ }
+}
+
+void FwdLockEngine::AddSupportedFileSuffixes(DrmSupportInfo *info) {
+ for (size_t i = 0, n = sizeof(FileSuffixes)/sizeof(FileSuffixes[0]); i < n; ++i) {
+ info->addFileSuffix(FileSuffixes[i]);
+ }
+}
+
+bool FwdLockEngine::IsMimeTypeSupported(const String8& mime) {
+ for (size_t i = 0, n = sizeof(MimeTypes)/sizeof(MimeTypes[0]); i < n; ++i) {
+ if (mime == MimeTypes[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool FwdLockEngine::IsFileSuffixSupported(const String8& suffix) {
+ for (size_t i = 0, n = sizeof(FileSuffixes)/sizeof(FileSuffixes[0]); i < n; ++i) {
+ if (suffix == FileSuffixes[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
DrmSupportInfo* pSupportInfo = new DrmSupportInfo();
@@ -167,12 +208,9 @@ DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
// fill all Forward Lock mimetypes and extensions
if (NULL != pSupportInfo) {
- pSupportInfo->addMimeType(String8(FWDLOCK_MIMETYPE_FL));
- pSupportInfo->addFileSuffix(String8(FWDLOCK_DOTEXTENSION_FL));
- pSupportInfo->addMimeType(String8(FWDLOCK_MIMETYPE_DM));
- pSupportInfo->addFileSuffix(String8(FWDLOCK_DOTEXTENSION_DM));
-
- pSupportInfo->setDescription(String8(FWDLOCK_DESCRIPTION));
+ AddSupportedMimeTypes(pSupportInfo);
+ AddSupportedFileSuffixes(pSupportInfo);
+ pSupportInfo->setDescription(Description);
}
return pSupportInfo;
@@ -182,14 +220,8 @@ bool FwdLockEngine::onCanHandle(int uniqueId, const String8& path) {
bool result = false;
String8 extString = path.getPathExtension();
-
extString.toLower();
-
- if ((extString == String8(FWDLOCK_DOTEXTENSION_FL)) ||
- (extString == String8(FWDLOCK_DOTEXTENSION_DM))) {
- result = true;
- }
- return result;
+ return IsFileSuffixSupported(extString);
}
DrmInfoStatus* FwdLockEngine::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
@@ -308,8 +340,7 @@ int FwdLockEngine::onGetDrmObjectType(int uniqueId,
* (regardless of the relation between them to make it compatible with other DRM Engines)
*/
if (((0 == path.length()) || onCanHandle(uniqueId, path)) &&
- ((0 == mimeType.length()) || ((mimeStr == String8(FWDLOCK_MIMETYPE_FL)) ||
- (mimeStr == String8(FWDLOCK_MIMETYPE_DM)))) && (mimeType != path) ) {
+ ((0 == mimeType.length()) || IsMimeTypeSupported(mimeType)) && (mimeType != path) ) {
return DrmObjectType::CONTENT;
}
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
index dacf00e..365bdec 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <utils/Log.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@@ -107,6 +108,7 @@ static int FwdLockFile_AcquireSession(int fileDesc) {
}
pthread_mutex_unlock(&sessionAcquisitionMutex);
if (i == MAX_NUM_SESSIONS) {
+ ALOGE("Too many sessions opened at the same time");
errno = ENFILE;
}
}
@@ -293,7 +295,12 @@ int FwdLockFile_attach(int fileDesc) {
int FwdLockFile_open(const char *pFilename) {
int fileDesc = open(pFilename, O_RDONLY);
- if (fileDesc >= 0 && FwdLockFile_attach(fileDesc) < 0) {
+ if (fileDesc < 0) {
+ ALOGE("failed to open file '%s': %s", pFilename, strerror(errno));
+ return fileDesc;
+ }
+
+ if (FwdLockFile_attach(fileDesc) < 0) {
(void)close(fileDesc);
fileDesc = -1;
}
diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java
index 7ef35a9..6f71a2b 100644
--- a/graphics/java/android/graphics/Camera.java
+++ b/graphics/java/android/graphics/Camera.java
@@ -100,6 +100,27 @@ public class Camera {
public native void rotate(float x, float y, float z);
/**
+ * Gets the x location of the camera.
+ *
+ * @see #setLocation(float, float, float)
+ */
+ public native float getLocationX();
+
+ /**
+ * Gets the y location of the camera.
+ *
+ * @see #setLocation(float, float, float)
+ */
+ public native float getLocationY();
+
+ /**
+ * Gets the z location of the camera.
+ *
+ * @see #setLocation(float, float, float)
+ */
+ public native float getLocationZ();
+
+ /**
* Sets the location of the camera. The default location is set at
* 0, 0, -8.
*
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index 293dfcc..c633d84 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -84,7 +84,7 @@ public class RectF implements Parcelable {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- Rect r = (Rect) o;
+ RectF r = (RectF) o;
return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index ed6fa08..4487a3c 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.content.res.AssetManager;
+import android.util.SparseArray;
import java.io.File;
@@ -43,9 +44,11 @@ public class Typeface {
/** The NORMAL style of the default monospace typeface. */
public static final Typeface MONOSPACE;
- /* package */ static Typeface[] sDefaults;
-
- /* package */ int native_instance;
+ static Typeface[] sDefaults;
+ private static final SparseArray<SparseArray<Typeface>> sTypefaceCache =
+ new SparseArray<SparseArray<Typeface>>(3);
+
+ int native_instance;
// Style
public static final int NORMAL = 0;
@@ -53,19 +56,21 @@ public class Typeface {
public static final int ITALIC = 2;
public static final int BOLD_ITALIC = 3;
+ private int mStyle = 0;
+
/** Returns the typeface's intrinsic style attributes */
public int getStyle() {
- return nativeGetStyle(native_instance);
+ return mStyle;
}
/** Returns true if getStyle() has the BOLD bit set. */
public final boolean isBold() {
- return (getStyle() & BOLD) != 0;
+ return (mStyle & BOLD) != 0;
}
/** Returns true if getStyle() has the ITALIC bit set. */
public final boolean isItalic() {
- return (getStyle() & ITALIC) != 0;
+ return (mStyle & ITALIC) != 0;
}
/**
@@ -97,9 +102,32 @@ public class Typeface {
public static Typeface create(Typeface family, int style) {
int ni = 0;
if (family != null) {
+ // Return early if we're asked for the same face/style
+ if (family.mStyle == style) {
+ return family;
+ }
+
ni = family.native_instance;
}
- return new Typeface(nativeCreateFromTypeface(ni, style));
+
+ Typeface typeface;
+ SparseArray<Typeface> styles = sTypefaceCache.get(ni);
+
+ if (styles != null) {
+ typeface = styles.get(style);
+ if (typeface != null) {
+ return typeface;
+ }
+ }
+
+ typeface = new Typeface(nativeCreateFromTypeface(ni, style));
+ if (styles == null) {
+ styles = new SparseArray<Typeface>(4);
+ sTypefaceCache.put(ni, styles);
+ }
+ styles.put(style, typeface);
+
+ return typeface;
}
/**
@@ -143,15 +171,17 @@ public class Typeface {
// don't allow clients to call this directly
private Typeface(int ni) {
- if (0 == ni) {
+ if (ni == 0) {
throw new RuntimeException("native typeface cannot be made");
}
+
native_instance = ni;
+ mStyle = nativeGetStyle(ni);
}
static {
- DEFAULT = create((String)null, 0);
- DEFAULT_BOLD = create((String)null, Typeface.BOLD);
+ DEFAULT = create((String) null, 0);
+ DEFAULT_BOLD = create((String) null, Typeface.BOLD);
SANS_SERIF = create("sans-serif", 0);
SERIF = create("serif", 0);
MONOSPACE = create("monospace", 0);
@@ -159,14 +189,34 @@ public class Typeface {
sDefaults = new Typeface[] {
DEFAULT,
DEFAULT_BOLD,
- create((String)null, Typeface.ITALIC),
- create((String)null, Typeface.BOLD_ITALIC),
+ create((String) null, Typeface.ITALIC),
+ create((String) null, Typeface.BOLD_ITALIC),
};
}
protected void finalize() throws Throwable {
- super.finalize();
- nativeUnref(native_instance);
+ try {
+ nativeUnref(native_instance);
+ } finally {
+ super.finalize();
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Typeface typeface = (Typeface) o;
+
+ return mStyle == typeface.mStyle && native_instance == typeface.native_instance;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = native_instance;
+ result = 31 * result + mStyle;
+ return result;
}
private static native int nativeCreate(String familyName, int style);
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index 29edc04..c41dd07 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -24,7 +24,6 @@ import android.content.res.TypedArray;
import android.graphics.*;
import android.view.Gravity;
import android.util.AttributeSet;
-import android.view.View;
import java.io.IOException;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 4b9c98f..043adae 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -296,8 +296,6 @@ public abstract class Drawable {
/**
* Implement this interface if you want to create an drawable that is RTL aware
- *
- * @hide
*/
public static interface Callback2 extends Callback {
/**
@@ -387,8 +385,6 @@ public abstract class Drawable {
/**
* Use the current {@link android.graphics.drawable.Drawable.Callback2} implementation to get
* the resolved layout direction of this Drawable.
- *
- * @hide
*/
public int getResolvedLayoutDirectionSelf() {
final Callback callback = getCallback();
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 5fd5a16..ccad250 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -24,7 +24,6 @@ import android.content.res.TypedArray;
import android.graphics.*;
import android.view.Gravity;
import android.util.AttributeSet;
-import android.view.View;
import java.io.IOException;
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 4fbeb38..7df6668 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -143,6 +143,8 @@ public:
* user Context for use by the callback receiver.
*/
+ // FIXME consider removing this alias and replacing it by audio_in_acoustics_t
+ // or removing the parameter entirely if it is unused
enum record_flags {
RECORD_AGC_ENABLE = AUDIO_IN_ACOUSTICS_AGC_ENABLE,
RECORD_NS_ENABLE = AUDIO_IN_ACOUSTICS_NS_ENABLE,
@@ -154,7 +156,7 @@ public:
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
int frameCount = 0,
- uint32_t flags = 0,
+ record_flags flags = (record_flags) 0,
callback_t cbf = NULL,
void* user = NULL,
int notificationFrames = 0,
@@ -180,7 +182,7 @@ public:
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
int frameCount = 0,
- uint32_t flags = 0,
+ record_flags flags = (record_flags) 0,
callback_t cbf = NULL,
void* user = NULL,
int notificationFrames = 0,
@@ -383,7 +385,7 @@ private:
bool mMarkerReached;
uint32_t mNewPosition;
uint32_t mUpdatePeriod;
- uint32_t mFlags;
+ record_flags mFlags;
uint32_t mChannelMask;
audio_io_handle_t mInput;
int mSessionId;
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 95b9d86..552e829 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -153,7 +153,7 @@ public:
audio_format_t format = AUDIO_FORMAT_DEFAULT,
int channelMask = 0,
int frameCount = 0,
- uint32_t flags = 0,
+ audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_NONE,
callback_t cbf = NULL,
void* user = NULL,
int notificationFrames = 0,
@@ -165,7 +165,7 @@ public:
int format = AUDIO_FORMAT_DEFAULT,
int channelMask = 0,
int frameCount = 0,
- uint32_t flags = 0,
+ uint32_t flags = (uint32_t) AUDIO_POLICY_OUTPUT_FLAG_NONE,
callback_t cbf = 0,
void* user = 0,
int notificationFrames = 0,
@@ -185,7 +185,7 @@ public:
audio_format_t format = AUDIO_FORMAT_DEFAULT,
int channelMask = 0,
const sp<IMemory>& sharedBuffer = 0,
- uint32_t flags = 0,
+ audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_NONE,
callback_t cbf = NULL,
void* user = NULL,
int notificationFrames = 0,
@@ -209,7 +209,7 @@ public:
audio_format_t format = AUDIO_FORMAT_DEFAULT,
int channelMask = 0,
int frameCount = 0,
- uint32_t flags = 0,
+ audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_NONE,
callback_t cbf = NULL,
void* user = NULL,
int notificationFrames = 0,
@@ -473,7 +473,7 @@ protected:
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ audio_policy_output_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
bool enforceFrameCount);
@@ -515,7 +515,7 @@ protected:
uint32_t mNewPosition;
uint32_t mUpdatePeriod;
bool mFlushed; // FIXME will be made obsolete by making flush() synchronous
- uint32_t mFlags;
+ audio_policy_output_flags_t mFlags;
int mSessionId;
int mAuxEffectId;
mutable Mutex mLock;
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 7a2ada0..0f39cf3 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -28,6 +28,7 @@
#include <media/IAudioRecord.h>
#include <media/IAudioFlingerClient.h>
#include <system/audio.h>
+#include <system/audio_policy.h>
#include <hardware/audio_effect.h>
#include <media/IEffect.h>
#include <media/IEffectClient.h>
@@ -77,6 +78,8 @@ public:
virtual int channelCount(audio_io_handle_t output) const = 0;
virtual audio_format_t format(audio_io_handle_t output) const = 0;
virtual size_t frameCount(audio_io_handle_t output) const = 0;
+
+ // return estimated latency in milliseconds
virtual uint32_t latency(audio_io_handle_t output) const = 0;
/* set/get the audio hardware state. This will probably be used by
@@ -121,7 +124,7 @@ public:
audio_format_t *pFormat,
uint32_t *pChannels,
uint32_t *pLatencyMs,
- uint32_t flags) = 0;
+ audio_policy_output_flags_t flags) = 0;
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2) = 0;
virtual status_t closeOutput(audio_io_handle_t output) = 0;
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 07f3b16..f3a1d9a 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1687,7 +1687,9 @@ bool ResTable_config::isBetterThan(const ResTable_config& o,
// The configuration closest to the actual size is best.
// We assume that larger configs have already been filtered
// out at this point. That means we just want the largest one.
- return smallestScreenWidthDp >= o.smallestScreenWidthDp;
+ if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+ return smallestScreenWidthDp > o.smallestScreenWidthDp;
+ }
}
if (screenSizeDp || o.screenSizeDp) {
@@ -1711,7 +1713,9 @@ bool ResTable_config::isBetterThan(const ResTable_config& o,
//ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
// screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
// requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
- return (myDelta <= otherDelta);
+ if (myDelta != otherDelta) {
+ return myDelta < otherDelta;
+ }
}
if (screenLayout || o.screenLayout) {
@@ -1738,7 +1742,9 @@ bool ResTable_config::isBetterThan(const ResTable_config& o,
if (mySL == 0) return false;
return true;
}
- return fixedMySL >= fixedOSL;
+ if (fixedMySL != fixedOSL) {
+ return fixedMySL > fixedOSL;
+ }
}
if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
&& (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1857,7 +1863,9 @@ bool ResTable_config::isBetterThan(const ResTable_config& o,
myDelta += requested->screenHeight - screenHeight;
otherDelta += requested->screenHeight - o.screenHeight;
}
- return (myDelta <= otherDelta);
+ if (myDelta != otherDelta) {
+ return myDelta < otherDelta;
+ }
}
if (version || o.version) {
@@ -2150,7 +2158,7 @@ String8 ResTable_config::toString() const {
res.append("nodpi");
break;
default:
- res.appendFormat("density=%d", dtohs(density));
+ res.appendFormat("%ddpi", dtohs(density));
break;
}
}
@@ -2440,7 +2448,7 @@ status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
uint32_t bagTypeSpecFlags = 0;
mTable.lock();
const ssize_t N = mTable.getBagLocked(resID, &bag, &bagTypeSpecFlags);
- TABLE_NOISY(LOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
+ TABLE_NOISY(ALOGV("Applying style 0x%08x to theme %p, count=%d", resID, this, N));
if (N < 0) {
mTable.unlock();
return N;
@@ -2506,7 +2514,7 @@ status_t ResTable::Theme::applyStyle(uint32_t resID, bool force)
continue;
}
theme_entry* curEntry = curEntries + e;
- TABLE_NOISY(LOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
+ TABLE_NOISY(ALOGV("Attr 0x%08x: type=0x%x, data=0x%08x; curType=0x%x",
attrRes, bag->map.value.dataType, bag->map.value.data,
curEntry->value.dataType));
if (force || curEntry->value.dataType == Res_value::TYPE_NULL) {
@@ -2577,22 +2585,22 @@ ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
const uint32_t t = Res_GETTYPE(resID);
const uint32_t e = Res_GETENTRY(resID);
- TABLE_THEME(LOGI("Looking up attr 0x%08x in theme %p", resID, this));
+ TABLE_THEME(ALOGI("Looking up attr 0x%08x in theme %p", resID, this));
if (p >= 0) {
const package_info* const pi = mPackages[p];
- TABLE_THEME(LOGI("Found package: %p", pi));
+ TABLE_THEME(ALOGI("Found package: %p", pi));
if (pi != NULL) {
- TABLE_THEME(LOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
+ TABLE_THEME(ALOGI("Desired type index is %ld in avail %d", t, pi->numTypes));
if (t < pi->numTypes) {
const type_info& ti = pi->types[t];
- TABLE_THEME(LOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
+ TABLE_THEME(ALOGI("Desired entry index is %ld in avail %d", e, ti.numEntries));
if (e < ti.numEntries) {
const theme_entry& te = ti.entries[e];
if (outTypeSpecFlags != NULL) {
*outTypeSpecFlags |= te.typeSpecFlags;
}
- TABLE_THEME(LOGI("Theme value: type=0x%x, data=0x%08x",
+ TABLE_THEME(ALOGI("Theme value: type=0x%x, data=0x%08x",
te.value.dataType, te.value.data));
const uint8_t type = te.value.dataType;
if (type == Res_value::TYPE_ATTRIBUTE) {
@@ -2627,7 +2635,7 @@ ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
uint32_t newTypeSpecFlags;
blockIndex = getAttribute(inOutValue->data, inOutValue, &newTypeSpecFlags);
- TABLE_THEME(LOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
+ TABLE_THEME(ALOGI("Resolving attr reference: blockIndex=%d, type=0x%x, data=%p\n",
(int)blockIndex, (int)inOutValue->dataType, (void*)inOutValue->data));
if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newTypeSpecFlags;
//printf("Retrieved attribute new type=0x%x\n", inOutValue->dataType);
@@ -2772,7 +2780,7 @@ status_t ResTable::add(const void* data, size_t size, void* cookie,
header->size = dtohl(header->header->header.size);
//ALOGI("Got size 0x%x, again size 0x%x, raw size 0x%x\n", header->size,
// dtohl(header->header->header.size), header->header->header.size);
- LOAD_TABLE_NOISY(LOGV("Loading ResTable @%p:\n", header->header));
+ LOAD_TABLE_NOISY(ALOGV("Loading ResTable @%p:\n", header->header));
LOAD_TABLE_NOISY(printHexData(2, header->header, header->size < 256 ? header->size : 256,
16, 16, 0, false, printToLogFunc));
if (dtohs(header->header->header.headerSize) > header->size
@@ -2802,7 +2810,7 @@ status_t ResTable::add(const void* data, size_t size, void* cookie,
if (err != NO_ERROR) {
return (mError=err);
}
- TABLE_NOISY(LOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+ TABLE_NOISY(ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
(void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
const size_t csize = dtohl(chunk->size);
@@ -2856,7 +2864,7 @@ status_t ResTable::add(const void* data, size_t size, void* cookie,
ALOGW("No string values found in resource table!");
}
- TABLE_NOISY(LOGV("Returning from add with mError=%d\n", mError));
+ TABLE_NOISY(ALOGV("Returning from add with mError=%d\n", mError));
return mError;
}
@@ -3127,7 +3135,7 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
if (newIndex == BAD_INDEX) {
return BAD_INDEX;
}
- TABLE_THEME(LOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
+ TABLE_THEME(ALOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
(void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
//printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
if (inoutTypeSpecFlags != NULL) *inoutTypeSpecFlags |= newFlags;
@@ -3268,7 +3276,7 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
// This is what we are building.
bag_set* set = NULL;
- TABLE_NOISY(LOGI("Building bag: %p\n", (void*)resID));
+ TABLE_NOISY(ALOGI("Building bag: %p\n", (void*)resID));
ResTable_config bestConfig;
memset(&bestConfig, 0, sizeof(bestConfig));
@@ -3338,7 +3346,7 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
size_t N = count;
- TABLE_NOISY(LOGI("Found map: size=%p parent=%p count=%d\n",
+ TABLE_NOISY(ALOGI("Found map: size=%p parent=%p count=%d\n",
entrySize, parent, count));
// If this map inherits from another, we need to start
@@ -3357,9 +3365,9 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
if (NP > 0) {
memcpy(set+1, parentBag, NP*sizeof(bag_entry));
set->numAttrs = NP;
- TABLE_NOISY(LOGI("Initialized new bag with %d inherited attributes.\n", NP));
+ TABLE_NOISY(ALOGI("Initialized new bag with %d inherited attributes.\n", NP));
} else {
- TABLE_NOISY(LOGI("Initialized new bag with no inherited attributes.\n"));
+ TABLE_NOISY(ALOGI("Initialized new bag with no inherited attributes.\n"));
set->numAttrs = 0;
}
set->availAttrs = NT;
@@ -3386,7 +3394,7 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
bag_entry* entries = (bag_entry*)(set+1);
size_t curEntry = 0;
uint32_t pos = 0;
- TABLE_NOISY(LOGI("Starting with set %p, entries=%p, avail=%d\n",
+ TABLE_NOISY(ALOGI("Starting with set %p, entries=%p, avail=%d\n",
set, entries, set->availAttrs));
while (pos < count) {
TABLE_NOISY(printf("Now at %p\n", (void*)curOff));
@@ -3465,7 +3473,7 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
*outTypeSpecFlags = set->typeSpecFlags;
}
*outBag = (bag_entry*)(set+1);
- TABLE_NOISY(LOGI("Returning %d attrs\n", set->numAttrs));
+ TABLE_NOISY(ALOGI("Returning %d attrs\n", set->numAttrs));
return set->numAttrs;
}
return BAD_INDEX;
@@ -3474,27 +3482,10 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
void ResTable::setParameters(const ResTable_config* params)
{
mLock.lock();
- TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d sw%ddp w%ddp h%ddp\n",
- params->mcc, params->mnc,
- params->language[0] ? params->language[0] : '-',
- params->language[1] ? params->language[1] : '-',
- params->country[0] ? params->country[0] : '-',
- params->country[1] ? params->country[1] : '-',
- params->orientation,
- params->touchscreen,
- params->density,
- params->keyboard,
- params->inputFlags,
- params->navigation,
- params->screenWidth,
- params->screenHeight,
- params->smallestScreenWidthDp,
- params->screenWidthDp,
- params->screenHeightDp));
+ TABLE_GETENTRY(ALOGI("Setting parameters: %s\n", params->toString().string()));
mParams = *params;
for (size_t i=0; i<mPackageGroups.size(); i++) {
- TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
+ TABLE_NOISY(ALOGI("CLEARING BAGS FOR GROUP %d!", i));
mPackageGroups[i]->clearBagCache();
}
mLock.unlock();
@@ -4840,13 +4831,13 @@ ssize_t ResTable::getEntry(
ResTable_config thisConfig;
thisConfig.copyFromDtoH(thisType->config);
- TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
+ TABLE_GETENTRY(ALOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
entryIndex, typeIndex+1, dtohl(thisType->config.size),
thisConfig.toString().string()));
// Check to make sure this one is valid for the current parameters.
if (config && !thisConfig.match(*config)) {
- TABLE_GETENTRY(LOGI("Does not match config!\n"));
+ TABLE_GETENTRY(ALOGI("Does not match config!\n"));
continue;
}
@@ -4859,7 +4850,7 @@ ssize_t ResTable::getEntry(
uint32_t thisOffset = dtohl(eindex[entryIndex]);
if (thisOffset == ResTable_type::NO_ENTRY) {
- TABLE_GETENTRY(LOGI("Skipping because it is not defined!\n"));
+ TABLE_GETENTRY(ALOGI("Skipping because it is not defined!\n"));
continue;
}
@@ -4868,7 +4859,7 @@ ssize_t ResTable::getEntry(
// we will skip it. We check starting with things we most care
// about to those we least care about.
if (!thisConfig.isBetterThan(bestConfig, config)) {
- TABLE_GETENTRY(LOGI("This config is worse than last!\n"));
+ TABLE_GETENTRY(ALOGI("This config is worse than last!\n"));
continue;
}
}
@@ -4876,12 +4867,12 @@ ssize_t ResTable::getEntry(
type = thisType;
offset = thisOffset;
bestConfig = thisConfig;
- TABLE_GETENTRY(LOGI("Best entry so far -- using it!\n"));
+ TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n"));
if (!config) break;
}
if (type == NULL) {
- TABLE_GETENTRY(LOGI("No value found for requested entry!\n"));
+ TABLE_GETENTRY(ALOGI("No value found for requested entry!\n"));
return BAD_INDEX;
}
@@ -5024,7 +5015,7 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
- TABLE_NOISY(LOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
+ TABLE_NOISY(ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%p\n",
dtohs(chunk->type), dtohs(chunk->headerSize), dtohl(chunk->size),
(void*)(((const uint8_t*)chunk) - ((const uint8_t*)header->header))));
const size_t csize = dtohl(chunk->size);
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index d9b0e5a..24f4f1c 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -20,13 +20,11 @@
#include "DisplayListLogBuffer.h"
#include "DisplayListRenderer.h"
#include "Caches.h"
-
-#include <utils/String8.h>
+#include "SkCamera.h"
namespace android {
namespace uirenderer {
-
///////////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////////
@@ -101,6 +99,37 @@ DisplayList::~DisplayList() {
clearResources();
}
+void DisplayList::initProperties() {
+ mLeft = 0;
+ mTop = 0;
+ mTop = 0;
+ mBottom = 0;
+ mApplicationScale = -1;
+ mClipChildren = true;
+ mAlpha = 1;
+ mMultipliedAlpha = 255;
+ mTranslationX = 0;
+ mTranslationY = 0;
+ mRotation = 0;
+ mRotationX = 0;
+ mRotationY= 0;
+ mScaleX = 1;
+ mScaleY = 1;
+ mPivotX = 0;
+ mPivotY = 0;
+ mMatrixDirty = false;
+ mMatrixFlags = 0;
+ mPrevWidth = -1;
+ mPrevHeight = -1;
+ mWidth = 0;
+ mHeight = 0;
+ mPivotExplicitlySet = false;
+ mTransformMatrix = NULL;
+ mTransformCamera = NULL;
+ mTransformMatrix3D = NULL;
+ mCaching = false;
+}
+
void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
if (displayList) {
DISPLAY_LIST_LOGD("Deferring display list destruction");
@@ -111,6 +140,19 @@ void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
void DisplayList::clearResources() {
sk_free((void*) mReader.base());
+ if (mTransformMatrix) {
+ delete mTransformMatrix;
+ mTransformMatrix = NULL;
+ }
+ if (mTransformCamera) {
+ delete mTransformCamera;
+ mTransformCamera = NULL;
+ }
+ if (mTransformMatrix3D) {
+ delete mTransformMatrix3D;
+ mTransformMatrix3D = NULL;
+ }
+
Caches& caches = Caches::getInstance();
for (size_t i = 0; i < mBitmapResources.size(); i++) {
@@ -159,6 +201,7 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
// re-using display list - clear out previous allocations
clearResources();
}
+ initProperties();
mSize = writer.size();
void* buffer = sk_malloc_throw(mSize);
@@ -230,6 +273,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
int saveCount = renderer.getSaveCount() - 1;
+ outputViewProperties(renderer, (char*) indent);
mReader.rewind();
while (!mReader.eof()) {
@@ -238,7 +282,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
int skip = mReader.readInt();
ALOGD("%sSkip %d", (char*) indent, skip);
op &= ~OP_MAY_BE_SKIPPED_MASK;
- }
+ }
switch (op) {
case DrawGLFunction: {
@@ -268,7 +312,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
SkPaint* paint = getPaint(renderer);
int flags = getInt();
ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
- OP_NAMES[op], f1, f2, f3, f4, paint, flags);
+ OP_NAMES[op], f1, f2, f3, f4, paint, flags);
}
break;
case SaveLayerAlpha: {
@@ -279,7 +323,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
int alpha = getInt();
int flags = getInt();
ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
- OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
+ OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
}
break;
case Translate: {
@@ -312,7 +356,10 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
break;
case ConcatMatrix: {
SkMatrix* matrix = getMatrix();
- ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
+ ALOGD("%s%s new concat %p: [%f, %f, %f] [%f, %f, %f] [%f, %f, %f]",
+ (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1),
+ matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5),
+ matrix->get(6), matrix->get(7), matrix->get(8));
}
break;
case ClipRect: {
@@ -322,7 +369,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float f4 = getFloat();
int regionOp = getInt();
ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
- f1, f2, f3, f4, regionOp);
+ f1, f2, f3, f4, regionOp);
}
break;
case DrawDisplayList: {
@@ -331,7 +378,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
uint32_t height = getUInt();
int32_t flags = getInt();
ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
- displayList, width, height, flags, level + 1);
+ displayList, width, height, flags, level + 1);
renderer.outputDisplayList(displayList, level + 1);
}
break;
@@ -341,7 +388,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float y = getFloat();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
- layer, x, y, paint);
+ layer, x, y, paint);
}
break;
case DrawBitmap: {
@@ -350,7 +397,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float y = getFloat();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
- bitmap, x, y, paint);
+ bitmap, x, y, paint);
}
break;
case DrawBitmapMatrix: {
@@ -358,7 +405,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
SkMatrix* matrix = getMatrix();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
- bitmap, matrix, paint);
+ bitmap, matrix, paint);
}
break;
case DrawBitmapRect: {
@@ -373,7 +420,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float f8 = getFloat();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
+ (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
}
break;
case DrawBitmapMesh: {
@@ -422,7 +469,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float f4 = getFloat();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
- f1, f2, f3, f4, paint);
+ f1, f2, f3, f4, paint);
}
break;
case DrawRoundRect: {
@@ -434,7 +481,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float f6 = getFloat();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
}
break;
case DrawCircle: {
@@ -443,7 +490,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float f3 = getFloat();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
}
break;
case DrawOval: {
@@ -453,7 +500,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float f4 = getFloat();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
}
break;
case DrawArc: {
@@ -466,7 +513,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
int i1 = getInt();
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
}
break;
case DrawPath: {
@@ -497,7 +544,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
SkPaint* paint = getPaint(renderer);
float length = getFloat();
ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
- text.text(), text.length(), count, x, y, paint, length);
+ text.text(), text.length(), count, x, y, paint, length);
}
break;
case DrawTextOnPath: {
@@ -518,7 +565,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float* positions = getFloats(positionsCount);
SkPaint* paint = getPaint(renderer);
ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
- text.text(), text.length(), count, paint);
+ text.text(), text.length(), count, paint);
}
case ResetShader: {
ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
@@ -548,7 +595,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
float dy = getFloat();
int color = getInt();
ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
- radius, dx, dy, color);
+ radius, dx, dy, color);
}
break;
case ResetPaintFilter: {
@@ -563,20 +610,193 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
break;
default:
ALOGD("Display List error: op not handled: %s%s",
- (char*) indent, OP_NAMES[op]);
+ (char*) indent, OP_NAMES[op]);
break;
}
}
+ ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string());
+}
+
+void DisplayList::updateMatrix() {
+ if (mMatrixDirty) {
+ if (!mTransformMatrix) {
+ mTransformMatrix = new SkMatrix();
+ }
+ if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
+ mTransformMatrix->reset();
+ } else {
+ if (!mPivotExplicitlySet) {
+ if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
+ mPrevWidth = mWidth;
+ mPrevHeight = mHeight;
+ mPivotX = mPrevWidth / 2;
+ mPivotY = mPrevHeight / 2;
+ }
+ }
+ if ((mMatrixFlags & ROTATION_3D) == 0) {
+ mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
+ mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
+ mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+ } else {
+ if (!mTransformCamera) {
+ mTransformCamera = new Sk3DView();
+ mTransformMatrix3D = new SkMatrix();
+ }
+ mTransformMatrix->reset();
+ mTransformCamera->save();
+ mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+ mTransformCamera->rotateX(mRotationX);
+ mTransformCamera->rotateY(mRotationY);
+ mTransformCamera->rotateZ(-mRotation);
+ mTransformCamera->getMatrix(mTransformMatrix3D);
+ mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
+ mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
+ mPivotY + mTranslationY);
+ mTransformMatrix->postConcat(*mTransformMatrix3D);
+ mTransformCamera->restore();
+ }
+ }
+ mMatrixDirty = false;
+ }
+}
+
+void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ updateMatrix();
+ if (mApplicationScale >= 0) {
+ ALOGD("%s%s %.2f, %.2f", (char*) indent, "Scale",
+ mApplicationScale, mApplicationScale);
+ }
+ if (mLeft != 0 || mTop != 0) {
+ ALOGD("%s%s %d, %d", indent, "Translate", mLeft, mTop);
+ }
+ if (mAlpha < 1) {
+ // TODO: should be able to store the size of a DL at record time and not
+ // have to pass it into this call. In fact, this information might be in the
+ // location/size info that we store with the new native transform data.
+ int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+ if (mClipChildren) {
+ flags |= SkCanvas::kClipToLayer_SaveFlag;
+ }
+ ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
+ (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
+ mMultipliedAlpha, flags);
+ }
+ if (mMatrixFlags != 0) {
+ if (mMatrixFlags == TRANSLATION) {
+ ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
+ } else {
+ ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix", mTransformMatrix,
+ mTransformMatrix->get(0), mTransformMatrix->get(1),
+ mTransformMatrix->get(2), mTransformMatrix->get(3),
+ mTransformMatrix->get(4), mTransformMatrix->get(5),
+ mTransformMatrix->get(6), mTransformMatrix->get(7),
+ mTransformMatrix->get(8));
+ }
+ }
+ if (mClipChildren) {
+ ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
+ (float) mRight - mLeft, (float) mBottom - mTop);
+ }
+ }
+}
- ALOGD("%sDone", (char*) indent + 2);
+void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
+ uint32_t level) {
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+#if DEBUG_DISPLAY_LIST
+ uint32_t count = (level + 1) * 2;
+ char indent[count + 1];
+ for (uint32_t i = 0; i < count; i++) {
+ indent[i] = ' ';
+ }
+ indent[count] = '\0';
+#endif
+ updateMatrix();
+ if (mLeft != 0 || mTop != 0) {
+ DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate", mLeft, mTop);
+ renderer.translate(mLeft, mTop);
+ }
+ if (mApplicationScale >= 0) {
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, "Scale",
+ mApplicationScale, mApplicationScale);
+ renderer.scale(mApplicationScale, mApplicationScale);
+ }
+ if (mAlpha < 1 && !mCaching) {
+ // TODO: should be able to store the size of a DL at record time and not
+ // have to pass it into this call. In fact, this information might be in the
+ // location/size info that we store with the new native transform data.
+ int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+ if (mClipChildren) {
+ flags |= SkCanvas::kClipToLayer_SaveFlag;
+ }
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
+ (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
+ mMultipliedAlpha, flags);
+ renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
+ mMultipliedAlpha, flags);
+ }
+ if (mMatrixFlags != 0) {
+ if (mMatrixFlags == TRANSLATION) {
+ DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
+ renderer.translate(mTranslationX, mTranslationY);
+ } else {
+ DISPLAY_LIST_LOGD(
+ "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ indent, "ConcatMatrix", mTransformMatrix,
+ mTransformMatrix->get(0), mTransformMatrix->get(1),
+ mTransformMatrix->get(2), mTransformMatrix->get(3),
+ mTransformMatrix->get(4), mTransformMatrix->get(5),
+ mTransformMatrix->get(6), mTransformMatrix->get(7),
+ mTransformMatrix->get(8));
+ renderer.concatMatrix(mTransformMatrix);
+ }
+ }
+ if (mClipChildren) {
+ DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
+ (float) mRight - mLeft, (float) mBottom - mTop);
+ renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
+ SkRegion::kIntersect_Op);
+ }
+ }
+}
+
+void DisplayList::transformRect(float left, float top, float right, float bottom, Rect& result) {
+ result.left = left + mLeft;
+ result.top = top + mTop;
+ result.right = right + mLeft;
+ result.bottom = bottom + mTop;
+ if (mMatrixFlags != 0) {
+ if (mMatrixFlags == TRANSLATION) {
+ result.left += mTranslationX;
+ result.top += mTranslationY;
+ result.right += mTranslationX;
+ result.bottom += mTranslationY;
+ } else {
+ updateMatrix();
+ SkRect r;
+ r.fLeft = result.left;
+ r.fTop = result.top;
+ r.fRight = result.right;
+ r.fBottom = result.bottom;
+ mTransformMatrix->mapRect(&r);
+ result.left = r.fLeft;
+ result.top = r.fTop;
+ result.right = r.fRight;
+ result.bottom = r.fBottom;
+ }
+ }
}
+
/**
* Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
* in the output() function, since that function processes the same list of opcodes for the
* purposes of logging display list info for a given view.
*/
-bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
+bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
+ uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
bool needsInvalidate = false;
TextContainer text;
mReader.rewind();
@@ -592,6 +812,13 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
#endif
renderer.startMark(mName.string());
+ int restoreTo = 0;
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ DISPLAY_LIST_LOGD("%s%s %d", indent, "Save",
+ SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+ restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+ }
+ setViewProperties(renderer, width, height, level);
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
int saveCount = renderer.getSaveCount() - 1;
@@ -644,7 +871,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
SkPaint* paint = getPaint(renderer);
int32_t flags = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
- OP_NAMES[op], f1, f2, f3, f4, paint, flags);
+ OP_NAMES[op], f1, f2, f3, f4, paint, flags);
renderer.saveLayer(f1, f2, f3, f4, paint, flags);
}
break;
@@ -656,7 +883,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
int32_t alpha = getInt();
int32_t flags = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
- OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
+ OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
}
break;
@@ -695,7 +922,12 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
break;
case ConcatMatrix: {
SkMatrix* matrix = getMatrix();
- DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
+ DISPLAY_LIST_LOGD(
+ "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
+ (char*) indent, OP_NAMES[op], matrix,
+ matrix->get(0), matrix->get(1), matrix->get(2),
+ matrix->get(3), matrix->get(4), matrix->get(5),
+ matrix->get(6), matrix->get(7), matrix->get(8));
renderer.concatMatrix(matrix);
}
break;
@@ -706,7 +938,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float f4 = getFloat();
int32_t regionOp = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
- f1, f2, f3, f4, regionOp);
+ f1, f2, f3, f4, regionOp);
renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
}
break;
@@ -716,9 +948,9 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
uint32_t height = getUInt();
int32_t flags = getInt();
DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
- displayList, width, height, flags, level + 1);
- needsInvalidate |= renderer.drawDisplayList(displayList, width, height,
- dirty, flags, level + 1);
+ displayList, width, height, flags, level + 1);
+ needsInvalidate |= renderer.drawDisplayList(displayList, width,
+ height, dirty, flags, level + 1);
}
break;
case DrawLayer: {
@@ -726,8 +958,11 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float x = getFloat();
float y = getFloat();
SkPaint* paint = getPaint(renderer);
+ if (mCaching && mMultipliedAlpha < 255) {
+ paint->setAlpha(mMultipliedAlpha);
+ }
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
- layer, x, y, paint);
+ layer, x, y, paint);
renderer.drawLayer(layer, x, y, paint);
}
break;
@@ -737,7 +972,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float y = getFloat();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
- bitmap, x, y, paint);
+ bitmap, x, y, paint);
renderer.drawBitmap(bitmap, x, y, paint);
}
break;
@@ -746,7 +981,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
SkMatrix* matrix = getMatrix();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
- bitmap, matrix, paint);
+ bitmap, matrix, paint);
renderer.drawBitmap(bitmap, matrix, paint);
}
break;
@@ -762,7 +997,8 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float f8 = getFloat();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
+ (char*) indent, OP_NAMES[op], bitmap,
+ f1, f2, f3, f4, f5, f6, f7, f8,paint);
renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
}
break;
@@ -821,7 +1057,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float f4 = getFloat();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
- f1, f2, f3, f4, paint);
+ f1, f2, f3, f4, paint);
renderer.drawRect(f1, f2, f3, f4, paint);
}
break;
@@ -834,7 +1070,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float f6 = getFloat();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
}
break;
@@ -844,7 +1080,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float f3 = getFloat();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
renderer.drawCircle(f1, f2, f3, paint);
}
break;
@@ -855,7 +1091,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float f4 = getFloat();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
renderer.drawOval(f1, f2, f3, f4, paint);
}
break;
@@ -869,7 +1105,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
int32_t i1 = getInt();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
- (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
+ (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
}
break;
@@ -965,7 +1201,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
float dy = getFloat();
int32_t color = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
- radius, dx, dy, color);
+ radius, dx, dy, color);
renderer.setupShadow(radius, dx, dy, color);
}
break;
@@ -984,14 +1220,19 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
break;
default:
DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
- (char*) indent, OP_NAMES[op]);
+ (char*) indent, OP_NAMES[op]);
break;
}
}
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+ renderer.restoreToCount(restoreTo);
+ }
renderer.endMark();
- DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
+ DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
+ needsInvalidate);
return needsInvalidate;
}
@@ -999,7 +1240,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
// Base structure
///////////////////////////////////////////////////////////////////////////////
-DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE),
+DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE),
mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
}
@@ -1071,7 +1312,6 @@ void DisplayListRenderer::prepareDirty(float left, float top,
void DisplayListRenderer::finish() {
insertRestoreToCount();
insertTranlate();
- OpenGLRenderer::finish();
}
void DisplayListRenderer::interrupt() {
@@ -1178,7 +1418,19 @@ bool DisplayListRenderer::drawDisplayList(DisplayList* displayList,
uint32_t width, uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
- const bool reject = quickReject(0.0f, 0.0f, width, height);
+ float top = 0;
+ float left = 0;
+ float right = width;
+ float bottom = height;
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ Rect transformedRect;
+ displayList->transformRect(left, top, right, bottom, transformedRect);
+ left = transformedRect.left;
+ top = transformedRect.top;
+ right = transformedRect.right;
+ bottom = transformedRect.bottom;
+ }
+ const bool reject = quickReject(left, top, right, bottom);
uint32_t* location = addOp(DisplayList::DrawDisplayList, reject);
addDisplayList(displayList);
addSize(width, height);
@@ -1275,7 +1527,7 @@ void DisplayListRenderer::drawRect(float left, float top, float right, float bot
}
void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, SkPaint* paint) {
+ float rx, float ry, SkPaint* paint) {
const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
quickReject(left, top, right, bottom);
uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 02f8438..abe8b82 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -20,6 +20,7 @@
#include <SkChunkAlloc.h>
#include <SkFlattenable.h>
#include <SkMatrix.h>
+#include <SkCamera.h>
#include <SkPaint.h>
#include <SkPath.h>
#include <SkRefCnt.h>
@@ -28,11 +29,8 @@
#include <cutils/compiler.h>
-#include <utils/String8.h>
-
#include "DisplayListLogBuffer.h"
#include "OpenGLRenderer.h"
-#include "utils/Functor.h"
namespace android {
namespace uirenderer {
@@ -51,6 +49,16 @@ namespace uirenderer {
#define DISPLAY_LIST_LOGD(...)
#endif
+// Set to 1 to enable native processing of View properties. 0 by default. Eventually this
+// will go away and we will always use this approach for accelerated apps.
+#define USE_DISPLAY_LIST_PROPERTIES 0
+
+#define TRANSLATION 0x0001
+#define ROTATION 0x0002
+#define ROTATION_3D 0x0004
+#define SCALE 0x0008
+#define PIVOT 0x0010
+
///////////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////////
@@ -119,13 +127,18 @@ public:
static const char* OP_NAMES[];
+ void setViewProperties(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
+ uint32_t level);
+ void outputViewProperties(OpenGLRenderer& renderer, char* indent);
+
ANDROID_API size_t getSize();
ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
ANDROID_API static void outputLogBuffer(int fd);
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
- bool replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
+ bool replay(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
+ Rect& dirty, int32_t flags, uint32_t level = 0);
void output(OpenGLRenderer& renderer, uint32_t level = 0);
@@ -143,11 +156,240 @@ public:
}
}
+ void setApplicationScale(float scale) {
+ mApplicationScale = scale;
+ }
+
+ void setClipChildren(bool clipChildren) {
+ mClipChildren = clipChildren;
+ }
+
+ void setAlpha(float alpha) {
+ if (alpha != mAlpha) {
+ mAlpha = alpha;
+ mMultipliedAlpha = (int)(255 * alpha);
+ }
+ }
+
+ void setTranslationX(float translationX) {
+ if (translationX != mTranslationX) {
+ mTranslationX = translationX;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mTranslationX, 0) && ALMOST_EQUAL(mTranslationY, 0)) {
+ mMatrixFlags &= ~TRANSLATION;
+ } else {
+ mMatrixFlags |= TRANSLATION;
+ }
+ }
+ }
+
+ void setTranslationY(float translationY) {
+ if (translationY != mTranslationY) {
+ mTranslationY = translationY;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mTranslationX, 0) && ALMOST_EQUAL(mTranslationY, 0)) {
+ mMatrixFlags &= ~TRANSLATION;
+ } else {
+ mMatrixFlags |= TRANSLATION;
+ }
+ }
+ }
+
+ void setRotation(float rotation) {
+ if (rotation != mRotation) {
+ mRotation = rotation;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mRotation, 0)) {
+ mMatrixFlags &= ~ROTATION;
+ } else {
+ mMatrixFlags |= ROTATION;
+ }
+ }
+ }
+
+ void setRotationX(float rotationX) {
+ if (rotationX != mRotationX) {
+ mRotationX = rotationX;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mRotationX, 0) && ALMOST_EQUAL(mRotationY, 0)) {
+ mMatrixFlags &= ~ROTATION_3D;
+ } else {
+ mMatrixFlags |= ROTATION_3D;
+ }
+ }
+ }
+
+ void setRotationY(float rotationY) {
+ if (rotationY != mRotationY) {
+ mRotationY = rotationY;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mRotationX, 0) && ALMOST_EQUAL(mRotationY, 0)) {
+ mMatrixFlags &= ~ROTATION_3D;
+ } else {
+ mMatrixFlags |= ROTATION_3D;
+ }
+ }
+ }
+
+ void setScaleX(float scaleX) {
+ if (scaleX != mScaleX) {
+ mScaleX = scaleX;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mScaleX, 1) && ALMOST_EQUAL(mScaleY, 1)) {
+ mMatrixFlags &= ~SCALE;
+ } else {
+ mMatrixFlags |= SCALE;
+ }
+ }
+ }
+
+ void setScaleY(float scaleY) {
+ if (scaleY != mScaleY) {
+ mScaleY = scaleY;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mScaleX, 1) && ALMOST_EQUAL(mScaleY, 1)) {
+ mMatrixFlags &= ~SCALE;
+ } else {
+ mMatrixFlags |= SCALE;
+ }
+ }
+ }
+
+ void setPivotX(float pivotX) {
+ mPivotX = pivotX;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mPivotX, 0) && ALMOST_EQUAL(mPivotY, 0)) {
+ mMatrixFlags &= ~PIVOT;
+ } else {
+ mMatrixFlags |= PIVOT;
+ }
+ mPivotExplicitlySet = true;
+ }
+
+ void setPivotY(float pivotY) {
+ mPivotY = pivotY;
+ mMatrixDirty = true;
+ if (ALMOST_EQUAL(mPivotX, 0) && ALMOST_EQUAL(mPivotY, 0)) {
+ mMatrixFlags &= ~PIVOT;
+ } else {
+ mMatrixFlags |= PIVOT;
+ }
+ mPivotExplicitlySet = true;
+ }
+
+ void setCameraDistance(float distance) {
+ if (distance != mCameraDistance) {
+ mCameraDistance = distance;
+ mMatrixDirty = true;
+ if (!mTransformCamera) {
+ mTransformCamera = new Sk3DView();
+ mTransformMatrix3D = new SkMatrix();
+ }
+ mTransformCamera->setCameraLocation(0, 0, distance);
+ }
+ }
+
+ void setLeft(int left) {
+ if (left != mLeft) {
+ mLeft = left;
+ mWidth = mRight - mLeft;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setTop(int top) {
+ if (top != mTop) {
+ mTop = top;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setRight(int right) {
+ if (right != mRight) {
+ mRight = right;
+ mWidth = mRight - mLeft;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setBottom(int bottom) {
+ if (bottom != mBottom) {
+ mBottom = bottom;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setLeftTop(int left, int top) {
+ if (left != mLeft || top != mTop) {
+ mLeft = left;
+ mTop = top;
+ mWidth = mRight - mLeft;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+ if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
+ mLeft = left;
+ mTop = top;
+ mRight = right;
+ mBottom = bottom;
+ mWidth = mRight - mLeft;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void offsetLeftRight(int offset) {
+ if (offset != 0) {
+ mLeft += offset;
+ mRight += offset;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void offsetTopBottom(int offset) {
+ if (offset != 0) {
+ mTop += offset;
+ mBottom += offset;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setCaching(bool caching) {
+ mCaching = caching;
+ }
+
+ void transformRect(float left, float top, float right, float bottom, Rect& result);
+
private:
void init();
+ void initProperties();
+
void clearResources();
+ void updateMatrix();
+
class TextContainer {
public:
size_t length() const {
@@ -241,6 +483,28 @@ private:
bool mIsRenderable;
String8 mName;
+
+ // View properties
+ float mApplicationScale;
+ bool mClipChildren;
+ float mAlpha;
+ int mMultipliedAlpha;
+ float mTranslationX, mTranslationY;
+ float mRotation, mRotationX, mRotationY;
+ float mScaleX, mScaleY;
+ float mPivotX, mPivotY;
+ float mCameraDistance;
+ int mLeft, mTop, mRight, mBottom;
+ int mWidth, mHeight;
+ int mPrevWidth, mPrevHeight;
+ bool mPivotExplicitlySet;
+ bool mMatrixDirty;
+ bool mMatrixIsIdentity;
+ uint32_t mMatrixFlags;
+ SkMatrix* mTransformMatrix;
+ Sk3DView* mTransformCamera;
+ SkMatrix* mTransformMatrix3D;
+ bool mCaching;
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 339ae0a..685fddc 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1189,7 +1189,7 @@ void OpenGLRenderer::setupDrawPointUniforms() {
}
void OpenGLRenderer::setupDrawColorUniforms() {
- if (mColorSet || (mShader && mSetShaderColor)) {
+ if ((mColorSet && !mShader) || (mShader && mSetShaderColor)) {
mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA);
}
}
@@ -1323,14 +1323,26 @@ void OpenGLRenderer::finishDrawTexture() {
bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
Rect& dirty, int32_t flags, uint32_t level) {
- if (quickReject(0.0f, 0.0f, width, height)) {
+ float top = 0;
+ float left = 0;
+ float right = width;
+ float bottom = height;
+ if (USE_DISPLAY_LIST_PROPERTIES) {
+ Rect transformedRect;
+ displayList->transformRect(left, top, right, bottom, transformedRect);
+ left = transformedRect.left;
+ top = transformedRect.top;
+ right = transformedRect.right;
+ bottom = transformedRect.bottom;
+ }
+ if (quickReject(left, top, right, bottom)) {
return false;
}
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
- return displayList->replay(*this, dirty, flags, level);
+ return displayList->replay(*this, width, height, dirty, flags, level);
}
return false;
@@ -2174,13 +2186,12 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
return;
}
+ if (length < 0.0f) length = paint->measureText(text, bytesCount);
switch (paint->getTextAlign()) {
case SkPaint::kCenter_Align:
- if (length < 0.0f) length = paint->measureText(text, bytesCount);
x -= length / 2.0f;
break;
case SkPaint::kRight_Align:
- if (length < 0.0f) length = paint->measureText(text, bytesCount);
x -= length;
break;
default:
@@ -2189,7 +2200,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
SkPaint::FontMetrics metrics;
paint->getFontMetrics(&metrics, 0.0f);
- // If no length was specified, just perform the hit test on the Y axis
if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) {
return;
}
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 45ed453..f92741c 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -1,6 +1,41 @@
LOCAL_PATH:=$(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE := libRSDriver
+
+LOCAL_SRC_FILES:= \
+ driver/rsdAllocation.cpp \
+ driver/rsdBcc.cpp \
+ driver/rsdCore.cpp \
+ driver/rsdFrameBuffer.cpp \
+ driver/rsdFrameBufferObj.cpp \
+ driver/rsdGL.cpp \
+ driver/rsdMesh.cpp \
+ driver/rsdMeshObj.cpp \
+ driver/rsdPath.cpp \
+ driver/rsdProgram.cpp \
+ driver/rsdProgramRaster.cpp \
+ driver/rsdProgramStore.cpp \
+ driver/rsdRuntimeMath.cpp \
+ driver/rsdRuntimeStubs.cpp \
+ driver/rsdSampler.cpp \
+ driver/rsdShader.cpp \
+ driver/rsdShaderCache.cpp \
+ driver/rsdVertexArray.cpp
+
+LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2
+LOCAL_SHARED_LIBRARIES += libbcc libbcinfo libgui
+
+LOCAL_C_INCLUDES += external/zlib dalvik
+LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
+
+LOCAL_CFLAGS += -Werror -Wall -Wno-unused-parameter -Wno-unused-variable
+
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
# Build rsg-generator ====================
include $(CLEAR_VARS)
@@ -23,19 +58,6 @@ include $(BUILD_HOST_EXECUTABLE)
# TODO: This should go into build/core/config.mk
RSG_GENERATOR:=$(LOCAL_BUILT_MODULE)
-# include $(CLEAR_VARS)
-# input_data_file := $(LOCAL_PATH)/rslib.bc
-# slangdata_output_var_name := rs_runtime_lib_bc
-# LOCAL_MODULE := librslib_rt
-
-# LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-
-# LOCAL_MODULE_TAGS := optional
-# include frameworks/compile/slang/SlangData.mk
-# include $(BUILD_STATIC_LIBRARY)
-
-# Build render script lib ====================
-
include $(CLEAR_VARS)
LOCAL_MODULE := libRS
@@ -110,24 +132,6 @@ LOCAL_SRC_FILES:= \
rsStream.cpp \
rsThreadIO.cpp \
rsType.cpp \
- driver/rsdAllocation.cpp \
- driver/rsdBcc.cpp \
- driver/rsdCore.cpp \
- driver/rsdFrameBuffer.cpp \
- driver/rsdFrameBufferObj.cpp \
- driver/rsdGL.cpp \
- driver/rsdMesh.cpp \
- driver/rsdMeshObj.cpp \
- driver/rsdPath.cpp \
- driver/rsdProgram.cpp \
- driver/rsdProgramRaster.cpp \
- driver/rsdProgramStore.cpp \
- driver/rsdRuntimeMath.cpp \
- driver/rsdRuntimeStubs.cpp \
- driver/rsdSampler.cpp \
- driver/rsdShader.cpp \
- driver/rsdShaderCache.cpp \
- driver/rsdVertexArray.cpp \
RenderScript.cpp \
BaseObj.cpp \
Element.cpp \
@@ -136,9 +140,10 @@ LOCAL_SRC_FILES:= \
Script.cpp \
ScriptC.cpp
-LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo libgui
+LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libbcc
+LOCAL_SHARED_LIBRARIES += libui libbcinfo libgui
-LOCAL_STATIC_LIBRARIES := libdex libft2
+LOCAL_STATIC_LIBRARIES := libdex libft2 libRSDriver
LOCAL_C_INCLUDES += external/freetype/include external/zlib dalvik
LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
diff --git a/libs/rs/RenderScript.cpp b/libs/rs/RenderScript.cpp
index 0b42055..217b921 100644
--- a/libs/rs/RenderScript.cpp
+++ b/libs/rs/RenderScript.cpp
@@ -21,6 +21,7 @@
#include <string.h>
#include "RenderScript.h"
+#include "rs.h"
bool RenderScript::gInitialized = false;
pthread_mutex_t RenderScript::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 0eb6a6d..5ad76e2 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -22,7 +22,7 @@
#include <utils/String8.h>
#include <utils/Vector.h>
-#include "rs.h"
+#include "rsDefines.h"
class Element;
class Type;
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index 63bf7cc..fae602c 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -37,6 +37,7 @@
#include <malloc.h>
#include "rsContext.h"
+#include "rsDevice.h"
#include "rsdShaderCache.h"
#include "rsdVertexArray.h"
#include "rsdFrameBufferObj.h"
diff --git a/libs/rs/rs.h b/libs/rs/rs.h
index fbcaf4a..825b9b8 100644
--- a/libs/rs/rs.h
+++ b/libs/rs/rs.h
@@ -20,10 +20,6 @@
#include <stdint.h>
#include <sys/types.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "rsDefines.h"
//
@@ -61,10 +57,6 @@ RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion,
#include "rsgApiFuncDecl.h"
-#ifdef __cplusplus
-};
-#endif
-
#endif // RENDER_SCRIPT_H
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
index 177fb60..41811ae 100644
--- a/libs/rs/rsAdapter.cpp
+++ b/libs/rs/rsAdapter.cpp
@@ -16,6 +16,7 @@
*/
#include "rsContext.h"
+#include "rsAdapter.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 83c88fd..a404c49 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -15,6 +15,8 @@
*/
#include "rsContext.h"
+#include "rsAllocation.h"
+#include "rsAdapter.h"
#include "rs_hal.h"
#include "system/window.h"
diff --git a/libs/rs/rsAnimation.h b/libs/rs/rsAnimation.h
index bff8d6f..526a081 100644
--- a/libs/rs/rsAnimation.h
+++ b/libs/rs/rsAnimation.h
@@ -19,7 +19,7 @@
#include "rsUtils.h"
#include "rsObjectBase.h"
-
+#include "rsDefines.h"
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index 8629d0d..a2e8c0f 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -18,6 +18,7 @@
#define ANDROID_COMPONENT_H
#include "rsUtils.h"
+#include "rsDefines.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 0f3cea7..1b51872 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -14,9 +14,11 @@
* limitations under the License.
*/
+#include "rs.h"
#include "rsDevice.h"
#include "rsContext.h"
#include "rsThreadIO.h"
+#include "rsMesh.h"
#include <ui/FramebufferNativeWindow.h>
#include <gui/DisplayEventReceiver.h>
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 05c799e..0f44267 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -18,18 +18,10 @@
#define ANDROID_RS_CONTEXT_H
#include "rsUtils.h"
-#include "rsType.h"
-#include "rsAllocation.h"
-#include "rsMesh.h"
-
#include "rs_hal.h"
-#include "rsMutex.h"
#include "rsThreadIO.h"
-#include "rsMatrix4x4.h"
-#include "rsDevice.h"
#include "rsScriptC.h"
-#include "rsAdapter.h"
#include "rsSampler.h"
#include "rsFont.h"
#include "rsPath.h"
@@ -39,13 +31,13 @@
#include "rsProgramVertex.h"
#include "rsFBOCache.h"
-#include "rsgApiStructs.h"
-
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
+class Device;
+
#if 0
#define CHECK_OBJ(o) { \
GET_TLS(); \
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 4b6b460..b86d3bc 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -19,6 +19,7 @@
#include "rsComponent.h"
#include "rsUtils.h"
+#include "rsDefines.h"
#include "rsObjectBase.h"
// ---------------------------------------------------------------------------
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index ac658c8..173b9a5 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -20,7 +20,7 @@
#include "rsMesh.h"
#include "rsAnimation.h"
-
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h
index baf81de..08062c6 100644
--- a/libs/rs/rsFileA3D.h
+++ b/libs/rs/rsFileA3D.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_RS_FILE_A3D_H
#define ANDROID_RS_FILE_A3D_H
-#include "rs.h"
#include "rsMesh.h"
#include <androidfw/Asset.h>
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index c4276cf..1f53c79 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -16,9 +16,10 @@
*/
#include "rsContext.h"
-
+#include "rs.h"
#include "rsFont.h"
#include "rsProgramFragment.h"
+#include "rsMesh.h"
#include <cutils/properties.h>
#ifndef ANDROID_RS_SERIALIZE
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 88c4795..2bd30b7 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -17,7 +17,6 @@
#ifndef ANDROID_RS_FONT_H
#define ANDROID_RS_FONT_H
-#include "rs.h"
#include "rsStream.h"
#include <utils/String8.h>
#include <utils/Vector.h>
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 67c7299..399a52b 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -15,6 +15,8 @@
*/
#include "rsContext.h"
+#include "rsMesh.h"
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 8eea427..7ca63cf 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -18,7 +18,7 @@
#define ANDROID_RS_MESH_H
-#include "rs.h"
+#include "rsObjectBase.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index d9f5f3b..586da19 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -18,6 +18,7 @@
#define ANDROID_RS_OBJECT_BASE_H
#include "rsUtils.h"
+#include "rsDefines.h"
#define RS_OBJECT_DEBUG 0
diff --git a/libs/rs/rsPath.cpp b/libs/rs/rsPath.cpp
index c4f4978..055bb86 100644
--- a/libs/rs/rsPath.cpp
+++ b/libs/rs/rsPath.cpp
@@ -15,6 +15,7 @@
*/
#include "rsContext.h"
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsPath.h b/libs/rs/rsPath.h
index 7c05503..1abfc9a 100644
--- a/libs/rs/rsPath.h
+++ b/libs/rs/rsPath.h
@@ -18,7 +18,7 @@
#define ANDROID_RS_PATH_H
-#include "rs.h"
+#include "rsObjectBase.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index c8a53ea..23fcbe7 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -16,6 +16,7 @@
#include "rsContext.h"
#include "rsProgramVertex.h"
+#include "rsMatrix4x4.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 5fc64a4..c7180bd 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -16,7 +16,7 @@
#include "rsContext.h"
#include "rsSampler.h"
-
+#include "rs.h"
using namespace android;
using namespace android::renderscript;
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index 013e4ca..dea4cb6 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -18,7 +18,6 @@
#define ANDROID_RS_SAMPLER_H
#include "rsAllocation.h"
-#include "rs.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index a5a0fae..749495d 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -19,6 +19,7 @@
#include "rsMatrix4x4.h"
#include "rsMatrix3x3.h"
#include "rsMatrix2x2.h"
+#include "rsgApiStructs.h"
#include "utils/Timers.h"
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index bda18fd..21b1c42 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -19,6 +19,8 @@
#include "rsMatrix4x4.h"
#include "rsMatrix3x3.h"
#include "rsMatrix2x2.h"
+#include "rsMesh.h"
+#include "rsgApiStructs.h"
#include "utils/Timers.h"
#include "driver/rsdVertexArray.h"
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 7182f53..8a0a5dc 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -15,8 +15,8 @@
*/
#include "rsContext.h"
-
#include "rsThreadIO.h"
+#include "rsgApiStructs.h"
#include <unistd.h>
#include <sys/types.h>
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 70ab7b7..b668a78 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -20,9 +20,8 @@ using namespace android;
using namespace android::renderscript;
Type::Type(Context *rsc) : ObjectBase(rsc) {
- mLODs = 0;
- mLODCount = 0;
- clear();
+ memset(&mHal, 0, sizeof(mHal));
+ mDimLOD = false;
}
void Type::preDestroy() const {
@@ -35,16 +34,15 @@ void Type::preDestroy() const {
}
Type::~Type() {
- if (mLODs) {
- delete [] mLODs;
- mLODs = NULL;
- }
+ clear();
}
void Type::clear() {
- if (mLODs) {
- delete [] mLODs;
- mLODs = NULL;
+ if (mHal.state.lodCount) {
+ delete [] mHal.state.lodDimX;
+ delete [] mHal.state.lodDimY;
+ delete [] mHal.state.lodDimZ;
+ delete [] mHal.state.lodOffset;
}
mElement.clear();
memset(&mHal, 0, sizeof(mHal));
@@ -63,33 +61,39 @@ size_t Type::getOffsetForFace(uint32_t face) const {
}
void Type::compute() {
- uint32_t oldLODCount = mLODCount;
- if (mHal.state.dimLOD) {
+ uint32_t oldLODCount = mHal.state.lodCount;
+ if (mDimLOD) {
uint32_t l2x = rsFindHighBit(mHal.state.dimX) + 1;
uint32_t l2y = rsFindHighBit(mHal.state.dimY) + 1;
uint32_t l2z = rsFindHighBit(mHal.state.dimZ) + 1;
- mLODCount = rsMax(l2x, l2y);
- mLODCount = rsMax(mLODCount, l2z);
+ mHal.state.lodCount = rsMax(l2x, l2y);
+ mHal.state.lodCount = rsMax(mHal.state.lodCount, l2z);
} else {
- mLODCount = 1;
+ mHal.state.lodCount = 1;
}
- if (mLODCount != oldLODCount) {
- if (mLODs){
- delete [] mLODs;
+ if (mHal.state.lodCount != oldLODCount) {
+ if (oldLODCount) {
+ delete [] mHal.state.lodDimX;
+ delete [] mHal.state.lodDimY;
+ delete [] mHal.state.lodDimZ;
+ delete [] mHal.state.lodOffset;
}
- mLODs = new LOD[mLODCount];
+ mHal.state.lodDimX = new uint32_t[mHal.state.lodCount];
+ mHal.state.lodDimY = new uint32_t[mHal.state.lodCount];
+ mHal.state.lodDimZ = new uint32_t[mHal.state.lodCount];
+ mHal.state.lodOffset = new uint32_t[mHal.state.lodCount];
}
uint32_t tx = mHal.state.dimX;
uint32_t ty = mHal.state.dimY;
uint32_t tz = mHal.state.dimZ;
size_t offset = 0;
- for (uint32_t lod=0; lod < mLODCount; lod++) {
- mLODs[lod].mX = tx;
- mLODs[lod].mY = ty;
- mLODs[lod].mZ = tz;
- mLODs[lod].mOffset = offset;
+ for (uint32_t lod=0; lod < mHal.state.lodCount; lod++) {
+ mHal.state.lodDimX[lod] = tx;
+ mHal.state.lodDimY[lod] = ty;
+ mHal.state.lodDimZ[lod] = tz;
+ mHal.state.lodOffset[lod] = offset;
offset += tx * rsMax(ty, 1u) * rsMax(tz, 1u) * mElement->getSizeBytes();
if (tx > 1) tx >>= 1;
if (ty > 1) ty >>= 1;
@@ -107,27 +111,29 @@ void Type::compute() {
}
uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const {
- uint32_t offset = mLODs[lod].mOffset;
+ uint32_t offset = mHal.state.lodOffset[lod];
offset += x * mElement->getSizeBytes();
return offset;
}
uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const {
- uint32_t offset = mLODs[lod].mOffset;
- offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
+ uint32_t offset = mHal.state.lodOffset[lod];
+ offset += (x + y * mHal.state.lodDimX[lod]) * mElement->getSizeBytes();
return offset;
}
uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const {
- uint32_t offset = mLODs[lod].mOffset;
- offset += (x + y*mLODs[lod].mX + z*mLODs[lod].mX*mLODs[lod].mY) * mElement->getSizeBytes();
+ uint32_t offset = mHal.state.lodOffset[lod];
+ offset += (x +
+ y * mHal.state.lodDimX[lod] +
+ z * mHal.state.lodDimX[lod] * mHal.state.lodDimY[lod]) * mElement->getSizeBytes();
return offset;
}
uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face,
uint32_t x, uint32_t y) const {
- uint32_t offset = mLODs[lod].mOffset;
- offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
+ uint32_t offset = mHal.state.lodOffset[lod];
+ offset += (x + y * mHal.state.lodDimX[lod]) * mElement->getSizeBytes();
if (face != 0) {
uint32_t faceOffset = getSizeBytes() / 6;
@@ -143,7 +149,7 @@ void Type::dumpLOGV(const char *prefix) const {
mHal.state.dimX,
mHal.state.dimY,
mHal.state.dimZ,
- mHal.state.dimLOD,
+ mHal.state.lodCount,
mHal.state.faces);
snprintf(buf, sizeof(buf), "%s element: ", prefix);
mElement->dumpLOGV(buf);
@@ -162,7 +168,7 @@ void Type::serialize(OStream *stream) const {
stream->addU32(mHal.state.dimY);
stream->addU32(mHal.state.dimZ);
- stream->addU8((uint8_t)(mHal.state.dimLOD ? 1 : 0));
+ stream->addU8((uint8_t)(mHal.state.lodCount ? 1 : 0));
stream->addU8((uint8_t)(mHal.state.faces ? 1 : 0));
}
@@ -233,12 +239,12 @@ ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e,
Type *nt = new Type(rsc);
+ nt->mDimLOD = dimLOD;
returnRef.set(nt);
nt->mElement.set(e);
nt->mHal.state.dimX = dimX;
nt->mHal.state.dimY = dimY;
nt->mHal.state.dimZ = dimZ;
- nt->mHal.state.dimLOD = dimLOD;
nt->mHal.state.faces = dimFaces;
nt->compute();
@@ -251,14 +257,14 @@ ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e,
ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
return getTypeRef(rsc, mElement.get(), dimX,
- mHal.state.dimY, mHal.state.dimZ, mHal.state.dimLOD, mHal.state.faces);
+ getDimY(), getDimZ(), getDimLOD(), getDimFaces());
}
ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
uint32_t dimX,
uint32_t dimY) const {
return getTypeRef(rsc, mElement.get(), dimX, dimY,
- mHal.state.dimZ, mHal.state.dimLOD, mHal.state.faces);
+ getDimZ(), getDimLOD(), getDimFaces());
}
@@ -280,13 +286,13 @@ RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX,
void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
rsAssert(typeDataSize == 6);
// Pack the data in the follofing way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
- // mHal.state.dimLOD; mHal.state.faces; mElement; into typeData
+ // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
Type *t = static_cast<Type *>(type);
(*typeData++) = t->getDimX();
(*typeData++) = t->getDimY();
(*typeData++) = t->getDimZ();
- (*typeData++) = t->getDimLOD();
+ (*typeData++) = t->getDimLOD() ? 1 : 0;
(*typeData++) = t->getDimFaces() ? 1 : 0;
(*typeData++) = (uint32_t)t->getElement();
t->getElement()->incUserRef();
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 3878156..f1aeb0a 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -44,7 +44,11 @@ public:
uint32_t dimX;
uint32_t dimY;
uint32_t dimZ;
- bool dimLOD;
+ uint32_t *lodDimX;
+ uint32_t *lodDimY;
+ uint32_t *lodDimZ;
+ uint32_t *lodOffset;
+ uint32_t lodCount;
bool faces;
};
State state;
@@ -62,15 +66,24 @@ public:
uint32_t getDimX() const {return mHal.state.dimX;}
uint32_t getDimY() const {return mHal.state.dimY;}
uint32_t getDimZ() const {return mHal.state.dimZ;}
- uint32_t getDimLOD() const {return mHal.state.dimLOD;}
+ bool getDimLOD() const {return mDimLOD;}
bool getDimFaces() const {return mHal.state.faces;}
- uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;}
- uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;}
- uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;}
-
+ uint32_t getLODDimX(uint32_t lod) const {
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodDimX[lod];
+ }
+ uint32_t getLODDimY(uint32_t lod) const {
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodDimY[lod];
+ }
+ uint32_t getLODDimZ(uint32_t lod) const {
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodDimZ[lod];
+ }
uint32_t getLODOffset(uint32_t lod) const {
- rsAssert(lod < mLODCount); return mLODs[lod].mOffset;
+ rsAssert(lod < mHal.state.lodCount);
+ return mHal.state.lodOffset[lod];
}
uint32_t getLODOffset(uint32_t lod, uint32_t x) const;
uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const;
@@ -79,7 +92,7 @@ public:
uint32_t getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face,
uint32_t x, uint32_t y) const;
- uint32_t getLODCount() const {return mLODCount;}
+ uint32_t getLODCount() const {return mHal.state.lodCount;}
bool getIsNp2() const;
void clear();
@@ -106,14 +119,8 @@ public:
}
protected:
- struct LOD {
- size_t mX;
- size_t mY;
- size_t mZ;
- size_t mOffset;
- };
-
void makeLODTable();
+ bool mDimLOD;
// Internal structure from most to least significant.
// * Array dimensions
@@ -127,9 +134,6 @@ protected:
size_t mMipChainSizeBytes;
size_t mTotalSizeBytes;
- LOD *mLODs;
- uint32_t mLODCount;
-
protected:
virtual void preDestroy() const;
virtual ~Type();
diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h
index a9a992a..cbbae6c 100644
--- a/libs/rs/rsUtils.h
+++ b/libs/rs/rsUtils.h
@@ -34,8 +34,6 @@
#include <math.h>
-#include "rs.h"
-
namespace android {
namespace renderscript {
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 99c305e..c0f82dc 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -187,7 +187,7 @@ void printApiCpp(FILE *f) {
fprintf(f, "#include \"rsDevice.h\"\n");
fprintf(f, "#include \"rsContext.h\"\n");
fprintf(f, "#include \"rsThreadIO.h\"\n");
- //fprintf(f, "#include \"rsgApiStructs.h\"\n");
+ fprintf(f, "#include \"rsgApiStructs.h\"\n");
fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
fprintf(f, "#include \"rsFifo.h\"\n");
fprintf(f, "\n");
@@ -408,6 +408,7 @@ void printPlaybackCpp(FILE *f) {
fprintf(f, "#include \"rsDevice.h\"\n");
fprintf(f, "#include \"rsContext.h\"\n");
fprintf(f, "#include \"rsThreadIO.h\"\n");
+ fprintf(f, "#include \"rsgApiStructs.h\"\n");
fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
fprintf(f, "\n");
fprintf(f, "namespace android {\n");
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 7f496ca..bccf1f9 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -92,14 +92,12 @@ public class MediaCodec
* "width" - Integer
* "height" - Integer
* optional "max-input-size" - Integer
- * optional "csd-0", "csd-1" ... - ByteBuffer
*
* Audio formats have the following fields:
* "mime" - String
* "channel-count" - Integer
* "sample-rate" - Integer
* optional "max-input-size" - Integer
- * optional "csd-0", "csd-1" ... - ByteBuffer
*
* If the format is used to configure an encoder, additional
* fields must be included:
@@ -114,7 +112,7 @@ public class MediaCodec
*
* @param surface Specify a surface on which to render the output of this
* decoder.
- * @param flags Specify {@see #CONFIGURE_FLAG_ENCODE} to configure the
+ * @param flags Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
* component as an encoder.
*/
public void configure(
@@ -155,6 +153,19 @@ public class MediaCodec
/** After filling a range of the input buffer at the specified index
* submit it to the component.
+ *
+ * Many decoders require the actual compressed data stream to be
+ * preceded by "codec specific data", i.e. setup data used to initialize
+ * the codec such as PPS/SPS in the case of AVC video or code tables
+ * in the case of vorbis audio.
+ * The class MediaExtractor provides codec specific data as part of
+ * the returned track format in entries named "csd-0", "csd-1" ...
+ *
+ * These buffers should be submitted using the flag {@link #FLAG_CODECCONFIG}.
+ *
+ * To indicate that this is the final piece of input data (or rather that
+ * no more input data follows unless the decoder is subsequently flushed)
+ * specify the flag {@link FLAG_EOS}.
*/
public native final void queueInputBuffer(
int index,
@@ -184,15 +195,25 @@ public class MediaCodec
public native final void releaseOutputBuffer(int index, boolean render);
/** Call this after dequeueOutputBuffer signals a format change by returning
- * {@see #INFO_OUTPUT_FORMAT_CHANGED}
+ * {@link #INFO_OUTPUT_FORMAT_CHANGED}
*/
public native final Map<String, Object> getOutputFormat();
+ /** Call this after start() returns.
+ */
+ public ByteBuffer[] getInputBuffers() {
+ return getBuffers(true /* input */);
+ }
+
/** Call this after start() returns and whenever dequeueOutputBuffer
* signals an output buffer change by returning
- * {@see #INFO_OUTPUT_BUFFERS_CHANGED}
+ * {@link #INFO_OUTPUT_BUFFERS_CHANGED}
*/
- public native final ByteBuffer[] getBuffers(boolean input);
+ public ByteBuffer[] getOutputBuffers() {
+ return getBuffers(false /* input */);
+ }
+
+ private native final ByteBuffer[] getBuffers(boolean input);
private static native final void native_init();
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 6a7f2f5..5732c72 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -56,7 +56,7 @@ public class MediaExtractor
public native boolean advance();
// Retrieve the current encoded sample and store it in the byte buffer
- // starting at the given offset.
+ // starting at the given offset. Returns the sample size.
public native int readSampleData(ByteBuffer byteBuf, int offset);
// Returns the track index the current sample originates from.
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index e663e91..139ff01 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -813,6 +813,13 @@ public class MediaPlayer
*
* @param path the path of the file, or the http/rtsp URL of the stream you want to play
* @throws IllegalStateException if it is called in an invalid state
+ *
+ * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
+ * process other than the calling application. This implies that the pathname
+ * should be an absolute path (as any other process runs with unspecified current working
+ * directory), and that the pathname should reference a world-readable file.
+ * As an alternative, the application could first open the file for reading,
+ * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
*/
public native void setDataSource(String path)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 6319630..2fe45ec 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -582,6 +582,7 @@ public class MediaRecorder
* Currently not implemented. It does nothing.
* @deprecated Time lapse mode video recording using camera still image capture
* is not desirable, and will not be supported.
+ * @hide
*/
public void setAuxiliaryOutputFile(FileDescriptor fd)
{
@@ -592,6 +593,7 @@ public class MediaRecorder
* Currently not implemented. It does nothing.
* @deprecated Time lapse mode video recording using camera still image capture
* is not desirable, and will not be supported.
+ * @hide
*/
public void setAuxiliaryOutputFile(String path)
{
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 71e698f..04d7c22 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -134,7 +134,7 @@ status_t JMediaCodec::dequeueOutputBuffer(
uint32_t flags;
status_t err;
if ((err = mCodec->dequeueOutputBuffer(
- index, &size, &offset, &timeUs, &flags, timeoutUs)) != OK) {
+ index, &offset, &size, &timeUs, &flags, timeoutUs)) != OK) {
return err;
}
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 4757adf..0c86fc2 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -101,14 +101,37 @@ status_t JMediaExtractor::readSampleData(
void *dst = env->GetDirectBufferAddress(byteBuf);
+ jlong dstSize;
+ jbyteArray byteArray = NULL;
+
if (dst == NULL) {
- // XXX if dst is NULL also fall back to "array()"
- return INVALID_OPERATION;
- }
+ jclass byteBufClass = env->FindClass("java/nio/ByteBuffer");
+ CHECK(byteBufClass != NULL);
+
+ jmethodID arrayID =
+ env->GetMethodID(byteBufClass, "array", "()[B");
+ CHECK(arrayID != NULL);
+
+ byteArray =
+ (jbyteArray)env->CallObjectMethod(byteBuf, arrayID);
+
+ if (byteArray == NULL) {
+ return INVALID_OPERATION;
+ }
- jlong dstSize = env->GetDirectBufferCapacity(byteBuf);
+ jboolean isCopy;
+ dst = env->GetByteArrayElements(byteArray, &isCopy);
+
+ dstSize = env->GetArrayLength(byteArray);
+ } else {
+ dstSize = env->GetDirectBufferCapacity(byteBuf);
+ }
if (dstSize < offset) {
+ if (byteArray != NULL) {
+ env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
+ }
+
return -ERANGE;
}
@@ -116,6 +139,10 @@ status_t JMediaExtractor::readSampleData(
status_t err = mImpl->readSampleData(buffer);
+ if (byteArray != NULL) {
+ env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0);
+ }
+
if (err != OK) {
return err;
}
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index ceb87db..5aed8a1 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -608,10 +608,11 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
// do not create a new audio track if current track is compatible with sample parameters
#ifdef USE_SHARED_MEM_BUFFER
newTrack = new AudioTrack(streamType, sampleRate, sample->format(),
- channels, sample->getIMemory(), 0, callback, userData);
+ channels, sample->getIMemory(), AUDIO_POLICY_OUTPUT_FLAG_NONE, callback, userData);
#else
newTrack = new AudioTrack(streamType, sampleRate, sample->format(),
- channels, frameCount, 0, callback, userData, bufferFrames);
+ channels, frameCount, AUDIO_POLICY_OUTPUT_FLAG_NONE, callback, userData,
+ bufferFrames);
#endif
oldTrack = mAudioTrack;
status = newTrack->initCheck();
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 943f3af..22c3a18 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -89,7 +89,7 @@ AudioRecord::AudioRecord(
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ record_flags flags,
callback_t cbf,
void* user,
int notificationFrames,
@@ -124,7 +124,7 @@ status_t AudioRecord::set(
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ record_flags flags,
callback_t cbf,
void* user,
int notificationFrames,
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index a1c99e5..34563ca 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -92,7 +92,7 @@ AudioTrack::AudioTrack(
audio_format_t format,
int channelMask,
int frameCount,
- uint32_t flags,
+ audio_policy_output_flags_t flags,
callback_t cbf,
void* user,
int notificationFrames,
@@ -119,10 +119,11 @@ AudioTrack::AudioTrack(
int notificationFrames,
int sessionId)
: mStatus(NO_INIT),
+ mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
{
mStatus = set((audio_stream_type_t)streamType, sampleRate, (audio_format_t)format, channelMask,
- frameCount, flags, cbf, user, notificationFrames,
+ frameCount, (audio_policy_output_flags_t)flags, cbf, user, notificationFrames,
0, false, sessionId);
}
@@ -132,7 +133,7 @@ AudioTrack::AudioTrack(
audio_format_t format,
int channelMask,
const sp<IMemory>& sharedBuffer,
- uint32_t flags,
+ audio_policy_output_flags_t flags,
callback_t cbf,
void* user,
int notificationFrames,
@@ -172,7 +173,7 @@ status_t AudioTrack::set(
audio_format_t format,
int channelMask,
int frameCount,
- uint32_t flags,
+ audio_policy_output_flags_t flags,
callback_t cbf,
void* user,
int notificationFrames,
@@ -221,7 +222,7 @@ status_t AudioTrack::set(
// force direct flag if format is not linear PCM
if (!audio_is_linear_pcm(format)) {
- flags |= AUDIO_POLICY_OUTPUT_FLAG_DIRECT;
+ flags = (audio_policy_output_flags_t) (flags | AUDIO_POLICY_OUTPUT_FLAG_DIRECT);
}
if (!audio_is_output_channel(channelMask)) {
@@ -233,7 +234,7 @@ status_t AudioTrack::set(
audio_io_handle_t output = AudioSystem::getOutput(
streamType,
sampleRate, format, channelMask,
- (audio_policy_output_flags_t)flags);
+ flags);
if (output == 0) {
ALOGE("Could not get audio output for stream type %d", streamType);
@@ -707,7 +708,7 @@ audio_io_handle_t AudioTrack::getOutput()
audio_io_handle_t AudioTrack::getOutput_l()
{
return AudioSystem::getOutput(mStreamType,
- mCblk->sampleRate, mFormat, mChannelMask, (audio_policy_output_flags_t)mFlags);
+ mCblk->sampleRate, mFormat, mChannelMask, mFlags);
}
int AudioTrack::getSessionId() const
@@ -734,7 +735,7 @@ status_t AudioTrack::createTrack_l(
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ audio_policy_output_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
bool enforceFrameCount)
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index ebadbfa..47c261da 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -362,7 +362,7 @@ public:
audio_format_t *pFormat,
uint32_t *pChannels,
uint32_t *pLatencyMs,
- uint32_t flags)
+ audio_policy_output_flags_t flags)
{
Parcel data, reply;
uint32_t devices = pDevices ? *pDevices : 0;
@@ -377,7 +377,7 @@ public:
data.writeInt32(format);
data.writeInt32(channels);
data.writeInt32(latency);
- data.writeInt32(flags);
+ data.writeInt32((int32_t) flags);
remote()->transact(OPEN_OUTPUT, data, &reply);
audio_io_handle_t output = (audio_io_handle_t) reply.readInt32();
ALOGV("openOutput() returned output, %d", output);
@@ -845,7 +845,7 @@ status_t BnAudioFlinger::onTransact(
audio_format_t format = (audio_format_t) data.readInt32();
uint32_t channels = data.readInt32();
uint32_t latency = data.readInt32();
- uint32_t flags = data.readInt32();
+ audio_policy_output_flags_t flags = (audio_policy_output_flags_t) data.readInt32();
audio_io_handle_t output = openOutput(&devices,
&samplingRate,
&format,
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
index 6cb5b82..a85956c 100644
--- a/media/libmedia/JetPlayer.cpp
+++ b/media/libmedia/JetPlayer.cpp
@@ -94,7 +94,7 @@ int JetPlayer::init()
AUDIO_FORMAT_PCM_16_BIT,
(pLibConfig->numChannels == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
mTrackBufferSize,
- 0);
+ AUDIO_POLICY_OUTPUT_FLAG_NONE);
// create render and playback thread
{
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 54eb98a..9c3170c 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -1024,7 +1024,7 @@ bool ToneGenerator::initAudioTrack() {
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_CHANNEL_OUT_MONO,
0,
- 0,
+ AUDIO_POLICY_OUTPUT_FLAG_NONE,
audioCallback,
this,
0,
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 1a85c9c..bbc53f3 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1503,7 +1503,7 @@ status_t MediaPlayerService::AudioOutput::open(
format,
channelMask,
frameCount,
- 0 /* flags */,
+ AUDIO_POLICY_OUTPUT_FLAG_NONE,
CallbackWrapper,
this,
0,
@@ -1515,7 +1515,7 @@ status_t MediaPlayerService::AudioOutput::open(
format,
channelMask,
frameCount,
- 0,
+ AUDIO_POLICY_OUTPUT_FLAG_NONE,
NULL,
NULL,
0,
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 650b6c4..23c3c74 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -151,7 +151,7 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
mAudioTrack = new AudioTrack(
AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
- 0, 0, &AudioCallback, this, 0);
+ 0, AUDIO_POLICY_OUTPUT_FLAG_NONE, &AudioCallback, this, 0);
if ((err = mAudioTrack->initCheck()) != OK) {
delete mAudioTrack;
@@ -437,8 +437,11 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
kKeyTime, &mPositionTimeMediaUs));
mPositionTimeRealUs =
- ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
+ -mLatencyUs + ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
/ mSampleRate;
+ if (mPositionTimeRealUs < 0) {
+ mPositionTimeRealUs = 0;
+ }
ALOGV("buffer->size() = %d, "
"mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
@@ -493,7 +496,9 @@ int64_t AudioPlayer::getRealTimeUs() {
int64_t AudioPlayer::getRealTimeUsLocked() const {
CHECK(mStarted);
CHECK_NE(mSampleRate, 0);
- return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
+ int64_t t = -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
+ if (t < 0) return 0;
+ return t;
}
int64_t AudioPlayer::getMediaTimeUs() {
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 5b2ea1f..cbe709b 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -56,9 +56,10 @@ AudioSource::AudioSource(
ALOGV("sampleRate: %d, channels: %d", sampleRate, channels);
CHECK(channels == 1 || channels == 2);
- uint32_t flags = AudioRecord::RECORD_AGC_ENABLE |
+ AudioRecord::record_flags flags = (AudioRecord::record_flags)
+ (AudioRecord::RECORD_AGC_ENABLE |
AudioRecord::RECORD_NS_ENABLE |
- AudioRecord::RECORD_IIR_ENABLE;
+ AudioRecord::RECORD_IIR_ENABLE);
mRecord = new AudioRecord(
inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
channels > 1? AUDIO_CHANNEL_IN_STEREO: AUDIO_CHANNEL_IN_MONO,
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 501f4806..c35a77a 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -28,15 +28,22 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <utils/String8.h>
+#include <cutils/bitops.h>
+
+#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
namespace android {
enum {
- WAVE_FORMAT_PCM = 1,
- WAVE_FORMAT_ALAW = 6,
- WAVE_FORMAT_MULAW = 7,
+ WAVE_FORMAT_PCM = 0x0001,
+ WAVE_FORMAT_ALAW = 0x0006,
+ WAVE_FORMAT_MULAW = 0x0007,
+ WAVE_FORMAT_EXTENSIBLE = 0xFFFE
};
+static const char* WAVEEXT_SUBFORMAT = "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71";
+
+
static uint32_t U32_LE_AT(const uint8_t *ptr) {
return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
}
@@ -84,7 +91,8 @@ private:
WAVExtractor::WAVExtractor(const sp<DataSource> &source)
: mDataSource(source),
- mValidFormat(false) {
+ mValidFormat(false),
+ mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) {
mInitCheck = init();
}
@@ -161,21 +169,37 @@ status_t WAVExtractor::init() {
return NO_INIT;
}
- uint8_t formatSpec[16];
- if (mDataSource->readAt(offset, formatSpec, 16) < 16) {
+ uint8_t formatSpec[40];
+ if (mDataSource->readAt(offset, formatSpec, 2) < 2) {
return NO_INIT;
}
mWaveFormat = U16_LE_AT(formatSpec);
if (mWaveFormat != WAVE_FORMAT_PCM
&& mWaveFormat != WAVE_FORMAT_ALAW
- && mWaveFormat != WAVE_FORMAT_MULAW) {
+ && mWaveFormat != WAVE_FORMAT_MULAW
+ && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
return ERROR_UNSUPPORTED;
}
+ uint8_t fmtSize = 16;
+ if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
+ fmtSize = 40;
+ }
+ if (mDataSource->readAt(offset, formatSpec, fmtSize) < fmtSize) {
+ return NO_INIT;
+ }
+
mNumChannels = U16_LE_AT(&formatSpec[2]);
- if (mNumChannels != 1 && mNumChannels != 2) {
- return ERROR_UNSUPPORTED;
+ if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
+ if (mNumChannels != 1 && mNumChannels != 2) {
+ ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask",
+ mNumChannels);
+ }
+ } else {
+ if (mNumChannels < 1 && mNumChannels > 8) {
+ return ERROR_UNSUPPORTED;
+ }
}
mSampleRate = U32_LE_AT(&formatSpec[4]);
@@ -186,7 +210,8 @@ status_t WAVExtractor::init() {
mBitsPerSample = U16_LE_AT(&formatSpec[14]);
- if (mWaveFormat == WAVE_FORMAT_PCM) {
+ if (mWaveFormat == WAVE_FORMAT_PCM
+ || mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
if (mBitsPerSample != 8 && mBitsPerSample != 16
&& mBitsPerSample != 24) {
return ERROR_UNSUPPORTED;
@@ -199,6 +224,42 @@ status_t WAVExtractor::init() {
}
}
+ if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
+ uint16_t validBitsPerSample = U16_LE_AT(&formatSpec[18]);
+ if (validBitsPerSample != mBitsPerSample) {
+ ALOGE("validBits(%d) != bitsPerSample(%d) are not supported",
+ validBitsPerSample, mBitsPerSample);
+ return ERROR_UNSUPPORTED;
+ }
+
+ mChannelMask = U32_LE_AT(&formatSpec[20]);
+ ALOGV("numChannels=%d channelMask=0x%x", mNumChannels, mChannelMask);
+ if ((mChannelMask >> 18) != 0) {
+ ALOGE("invalid channel mask 0x%x", mChannelMask);
+ return ERROR_MALFORMED;
+ }
+
+ if ((mChannelMask != CHANNEL_MASK_USE_CHANNEL_ORDER)
+ && (popcount(mChannelMask) != mNumChannels)) {
+ ALOGE("invalid number of channels (%d) in channel mask (0x%x)",
+ popcount(mChannelMask), mChannelMask);
+ return ERROR_MALFORMED;
+ }
+
+ // In a WAVE_EXT header, the first two bytes of the GUID stored at byte 24 contain
+ // the sample format, using the same definitions as a regular WAV header
+ mWaveFormat = U16_LE_AT(&formatSpec[24]);
+ if (mWaveFormat != WAVE_FORMAT_PCM
+ && mWaveFormat != WAVE_FORMAT_ALAW
+ && mWaveFormat != WAVE_FORMAT_MULAW) {
+ return ERROR_UNSUPPORTED;
+ }
+ if (memcmp(&formatSpec[26], WAVEEXT_SUBFORMAT, 14)) {
+ ALOGE("unsupported GUID");
+ return ERROR_UNSUPPORTED;
+ }
+ }
+
mValidFormat = true;
} else if (!memcmp(chunkHeader, "data", 4)) {
if (mValidFormat) {
@@ -224,6 +285,7 @@ status_t WAVExtractor::init() {
}
mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
+ mTrackMeta->setInt32(kKeyChannelMask, mChannelMask);
mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
size_t bytesPerSample = mBitsPerSample >> 3;
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index 373b063..07b33b7 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -438,7 +438,7 @@ static void correctThresh(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
Word32 redThrExp = thrExp[ch][sfbGrp+sfb] + redVal;
- if (((*pahFlag < AH_ACTIVE) || (deltaPe > 0)) && (redThrExp > 0) ) {
+ if (((*pahFlag < AH_ACTIVE) || (deltaPe > 0)) && (redThrExp > 0) && (redThrExp >= *psfbNActiveLines)) {
*psfbPeFactors = (*psfbNActiveLines) * (0x7fffffff / redThrExp);
normFactor = L_add(normFactor, *psfbPeFactors);
@@ -466,7 +466,7 @@ static void correctThresh(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
deltaSfbPe = *psfbPeFactors * deltaPe;
/* thr3(n) = thr2(n)*2^deltaSfbPe/b(n) */
- if (*psfbNActiveLines > 0) {
+ if (*psfbNActiveLines > 0 && (normFactor* (*psfbNActiveLines)) != 0) {
/* new threshold */
Word32 thrFactor;
sfbEn = psyOutChan->sfbEnergy[sfbGrp+sfb];
diff --git a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
index c23dce6..f42a27c 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
@@ -29,11 +29,7 @@
#define MIN_16 (Word16)-32768 /* 0x8000 */
-#ifdef LINUX
-#define static_vo static __inline__
-#else
#define static_vo static __inline
-#endif
#define saturate(L_var1) (((L_var1) > 0X00007fffL) ? (MAX_16): (((L_var1) < (Word32) 0xffff8000L) ? (MIN_16): ((L_var1) & 0xffff)))
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 9a00186..8b01ac6 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -74,6 +74,7 @@ void AMessage::freeItem(Item *item) {
case kTypeObject:
case kTypeMessage:
+ case kTypeBuffer:
{
if (item->u.refValue != NULL) {
item->u.refValue->decStrong(this);
@@ -292,6 +293,7 @@ sp<AMessage> AMessage::dup() const {
}
case kTypeObject:
+ case kTypeBuffer:
{
to->u.refValue = from->u.refValue;
to->u.refValue->incStrong(msg.get());
@@ -396,6 +398,10 @@ AString AMessage::debugString(int32_t indent) const {
tmp = StringPrintf(
"RefBase *%s = %p", item.mName, item.u.refValue);
break;
+ case kTypeBuffer:
+ tmp = StringPrintf(
+ "ABuffer *%s = %p", item.mName, item.u.refValue);
+ break;
case kTypeMessage:
tmp = StringPrintf(
"AMessage %s = %s",
diff --git a/media/libstagefright/include/WAVExtractor.h b/media/libstagefright/include/WAVExtractor.h
index ce1f33a..c567ccd 100644
--- a/media/libstagefright/include/WAVExtractor.h
+++ b/media/libstagefright/include/WAVExtractor.h
@@ -47,6 +47,7 @@ private:
bool mValidFormat;
uint16_t mWaveFormat;
uint16_t mNumChannels;
+ uint32_t mChannelMask;
uint32_t mSampleRate;
uint16_t mBitsPerSample;
off64_t mDataOffset;
diff --git a/packages/SettingsProvider/res/values-in/strings.xml b/packages/SettingsProvider/res/values-in/strings.xml
index d5aea43..bed20eb 100644
--- a/packages/SettingsProvider/res/values-in/strings.xml
+++ b/packages/SettingsProvider/res/values-in/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4567566098528588863">"Pengaturan Penyimpanan"</string>
+ <string name="app_label" msgid="4567566098528588863">"Setelan Penyimpanan"</string>
</resources>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
index b96c357..2308bf0 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
@@ -54,7 +54,7 @@
android:clipToPadding="false"
>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
@@ -62,7 +62,7 @@
systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
@@ -70,14 +70,14 @@
systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:contentDescription="@string/accessibility_recent"
systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_width="80dip"
+ android:layout_width="@dimen/navigation_menu_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 82fcc88..bb80098 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -49,7 +49,7 @@
android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
- android:layout_width="80dp"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
@@ -64,7 +64,7 @@
android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
- android:layout_width="80dp"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
@@ -80,7 +80,7 @@
android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
- android:layout_width="80dp"
+ android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:layout_weight="0"
@@ -88,7 +88,7 @@
android:contentDescription="@string/accessibility_recent"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
- android:layout_width="40dp"
+ android:layout_width="@dimen/navigation_menu_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 1e82646..93d8675 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -39,7 +39,7 @@
<string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tersisa"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Pengisian daya USB tidak didukung."\n"Gunakan hanya pengisi daya yang disediakan."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Penggunaan baterai"</string>
- <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Pengaturan"</string>
+ <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setelan"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode pesawat"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Putar layar secara otomatis"</string>
@@ -118,7 +118,7 @@
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Penambatan bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode pesawat."</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Baterai <xliff:g id="NUMBER">%d</xliff:g> persen."</string>
- <string name="accessibility_settings_button" msgid="799583911231893380">"Pengaturan sistem."</string>
+ <string name="accessibility_settings_button" msgid="799583911231893380">"Setelan sistem."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Menghapus pemberitahuan."</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS diaktifkan."</string>
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
index b8a6cfe..39eade6 100644
--- a/packages/SystemUI/res/values-sw600dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -18,5 +18,11 @@
<resources>
<!-- gap on either side of status bar notification icons -->
<dimen name="status_bar_icon_padding">0dp</dimen>
+
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">70dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">40dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index f522285..ba1cdfa 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -67,4 +67,10 @@
<!-- opacity at which Notification icons will be drawn in the status bar -->
<item type="dimen" name="status_bar_icon_drawing_alpha">100%</item>
+
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">80dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">40dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 6736c1a..b16b1e8 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -21,5 +21,11 @@
<!-- opacity at which Notification icons will be drawn in the status bar -->
<item type="dimen" name="status_bar_icon_drawing_alpha">100%</item>
+
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">80dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">80dip</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8fba86a..2c22e3c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -91,4 +91,9 @@
<!-- The padding on the global screenshot background image -->
<dimen name="global_screenshot_bg_padding">20dp</dimen>
+ <!-- The width of the view containing non-menu status bar icons -->
+ <dimen name="navigation_key_width">80dip</dimen>
+
+ <!-- The width of the view containing the menu status bar icon -->
+ <dimen name="navigation_menu_key_width">40dip</dimen>
</resources>
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 d33ed3f..6574c7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -304,6 +304,8 @@ public class NavigationBarView extends LinearLayout {
if (DEBUG) {
Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
}
+
+ setNavigationIconHints(mNavigationIconHints, true);
}
@Override
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 eda52fc..87eb9cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -123,6 +123,8 @@ public class TabletStatusBar extends BaseStatusBar implements
int mNaturalBarHeight = -1;
int mIconSize = -1;
int mIconHPadding = -1;
+ int mNavIconWidth = -1;
+ int mMenuNavIconWidth = -1;
private int mMaxNotificationIcons = 5;
H mHandler = new H();
@@ -462,6 +464,26 @@ public class TabletStatusBar extends BaseStatusBar implements
com.android.internal.R.dimen.system_bar_icon_size);
int newIconHPadding = res.getDimensionPixelSize(
R.dimen.status_bar_icon_padding);
+ int newNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_key_width);
+ int newMenuNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_menu_key_width);
+
+ if (mNavigationArea != null && newNavIconWidth != mNavIconWidth) {
+ mNavIconWidth = newNavIconWidth;
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ mNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
+ mBackButton.setLayoutParams(lp);
+ mHomeButton.setLayoutParams(lp);
+ mRecentButton.setLayoutParams(lp);
+ }
+
+ if (mNavigationArea != null && newMenuNavIconWidth != mMenuNavIconWidth) {
+ mMenuNavIconWidth = newMenuNavIconWidth;
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ mMenuNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
+ mMenuButton.setLayoutParams(lp);
+ }
if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index fd7418c..d537a20 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1464,7 +1464,8 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
mMasterVolume(audioFlinger->masterVolumeSW_l()),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
// mMixerStatus
- mPrevMixerStatus(MIXER_IDLE)
+ mPrevMixerStatus(MIXER_IDLE),
+ standbyDelay(AudioFlinger::mStandbyTimeInNsecs)
{
snprintf(mName, kNameLength, "AudioOut_%X", id);
@@ -1621,7 +1622,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra
uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
- if (t != 0) {
+ if (t != 0 && !t->isOutputTrack()) {
uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
@@ -1997,14 +1998,8 @@ bool AudioFlinger::PlaybackThread::threadLoop()
Vector< sp<Track> > tracksToRemove;
standbyTime = systemTime();
- mixBufferSize = mFrameCount * mFrameSize;
// MIXER
- // FIXME: Relaxed timing because of a certain device that can't meet latency
- // Should be reduced to 2x after the vendor fixes the driver issue
- // increase threshold again due to low power audio mode. The way this warning threshold is
- // calculated and its usefulness should be reconsidered anyway.
- nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
nsecs_t lastWarning = 0;
if (mType == MIXER) {
longStandbyExit = false;
@@ -2014,8 +2009,7 @@ if (mType == MIXER) {
// FIXME could this be made local to while loop?
writeFrames = 0;
- activeSleepTime = activeSleepTimeUs();
- idleSleepTime = idleSleepTimeUs();
+ cacheParameters_l();
sleepTime = idleSleepTime;
if (mType == MIXER) {
@@ -2025,13 +2019,6 @@ if (mType == MIXER) {
// MIXER
CpuStats cpuStats;
- // DIRECT
-if (mType == DIRECT) {
- // use shorter standby delay as on normal output to release
- // hardware resources as soon as possible
- standbyDelay = microseconds(activeSleepTime*2);
-}
-
acquireWakeLock();
while (!exitPending())
@@ -2050,25 +2037,7 @@ if (mType == MIXER) {
Mutex::Autolock _l(mLock);
if (checkForNewParameters_l()) {
- mixBufferSize = mFrameCount * mFrameSize;
-
-if (mType == MIXER) {
- // FIXME: Relaxed timing because of a certain device that can't meet latency
- // Should be reduced to 2x after the vendor fixes the driver issue
- // increase threshold again due to low power audio mode. The way this warning
- // threshold is calculated and its usefulness should be reconsidered anyway.
- maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
-}
-
- updateWaitTime_l();
-
- activeSleepTime = activeSleepTimeUs();
- idleSleepTime = idleSleepTimeUs();
-
-if (mType == DIRECT) {
- standbyDelay = microseconds(activeSleepTime*2);
-}
-
+ cacheParameters_l();
}
saveOutputTracks();
@@ -2103,19 +2072,11 @@ if (mType == DIRECT) {
checkSilentMode_l();
-if (mType == MIXER || mType == DUPLICATING) {
- standbyTime = systemTime() + mStandbyTimeInNsecs;
-}
-
-if (mType == DIRECT) {
standbyTime = systemTime() + standbyDelay;
-}
-
sleepTime = idleSleepTime;
-
-if (mType == MIXER) {
- sleepTimeShift = 0;
-}
+ if (mType == MIXER) {
+ sleepTimeShift = 0;
+ }
continue;
}
@@ -2261,7 +2222,7 @@ void AudioFlinger::MixerThread::threadLoop_mix()
sleepTimeShift--;
}
sleepTime = 0;
- standbyTime = systemTime() + mStandbyTimeInNsecs;
+ standbyTime = systemTime() + standbyDelay;
//TODO: delay standby when effects have a tail
}
@@ -2548,6 +2509,32 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
return mixerStatus;
}
+/*
+The derived values that are cached:
+ - mixBufferSize from frame count * frame size
+ - activeSleepTime from activeSleepTimeUs()
+ - idleSleepTime from idleSleepTimeUs()
+ - standbyDelay from mActiveSleepTimeUs (DIRECT only)
+ - maxPeriod from frame count and sample rate (MIXER only)
+
+The parameters that affect these derived values are:
+ - frame count
+ - frame size
+ - sample rate
+ - device type: A2DP or not
+ - device latency
+ - format: PCM or not
+ - active sleep time
+ - idle sleep time
+*/
+
+void AudioFlinger::PlaybackThread::cacheParameters_l()
+{
+ mixBufferSize = mFrameCount * mFrameSize;
+ activeSleepTime = activeSleepTimeUs();
+ idleSleepTime = idleSleepTimeUs();
+}
+
void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
{
ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
@@ -2718,6 +2705,17 @@ uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs()
return (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
}
+void AudioFlinger::MixerThread::cacheParameters_l()
+{
+ PlaybackThread::cacheParameters_l();
+
+ // FIXME: Relaxed timing because of a certain device that can't meet latency
+ // Should be reduced to 2x after the vendor fixes the driver issue
+ // increase threshold again due to low power audio mode. The way this warning
+ // threshold is calculated and its usefulness should be reconsidered anyway.
+ maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
@@ -2731,80 +2729,6 @@ AudioFlinger::DirectOutputThread::~DirectOutputThread()
{
}
-void AudioFlinger::DirectOutputThread::applyVolume()
-{
- // Do not apply volume on compressed audio
- if (!audio_is_linear_pcm(mFormat)) {
- return;
- }
-
- // convert to signed 16 bit before volume calculation
- if (mFormat == AUDIO_FORMAT_PCM_8_BIT) {
- size_t count = mFrameCount * mChannelCount;
- uint8_t *src = (uint8_t *)mMixBuffer + count-1;
- int16_t *dst = mMixBuffer + count-1;
- while(count--) {
- *dst-- = (int16_t)(*src--^0x80) << 8;
- }
- }
-
- size_t frameCount = mFrameCount;
- int16_t *out = mMixBuffer;
- if (rampVolume) {
- if (mChannelCount == 1) {
- int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
- int32_t vlInc = d / (int32_t)frameCount;
- int32_t vl = ((int32_t)mLeftVolShort << 16);
- do {
- out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
- out++;
- vl += vlInc;
- } while (--frameCount);
-
- } else {
- int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
- int32_t vlInc = d / (int32_t)frameCount;
- d = ((int32_t)rightVol - (int32_t)mRightVolShort) << 16;
- int32_t vrInc = d / (int32_t)frameCount;
- int32_t vl = ((int32_t)mLeftVolShort << 16);
- int32_t vr = ((int32_t)mRightVolShort << 16);
- do {
- out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
- out[1] = clamp16(mul(out[1], vr >> 16) >> 12);
- out += 2;
- vl += vlInc;
- vr += vrInc;
- } while (--frameCount);
- }
- } else {
- if (mChannelCount == 1) {
- do {
- out[0] = clamp16(mul(out[0], leftVol) >> 12);
- out++;
- } while (--frameCount);
- } else {
- do {
- out[0] = clamp16(mul(out[0], leftVol) >> 12);
- out[1] = clamp16(mul(out[1], rightVol) >> 12);
- out += 2;
- } while (--frameCount);
- }
- }
-
- // convert back to unsigned 8 bit after volume calculation
- if (mFormat == AUDIO_FORMAT_PCM_8_BIT) {
- size_t count = mFrameCount * mChannelCount;
- int16_t *src = mMixBuffer;
- uint8_t *dst = (uint8_t *)mMixBuffer;
- while(count--) {
- *dst++ = (uint8_t)(((int32_t)*src++ + (1<<7)) >> 8)^0x80;
- }
- }
-
- mLeftVolShort = leftVol;
- mRightVolShort = rightVol;
-}
-
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(
Vector< sp<Track> > *tracksToRemove
)
@@ -2965,7 +2889,79 @@ void AudioFlinger::DirectOutputThread::threadLoop_mix()
sleepTime = 0;
standbyTime = systemTime() + standbyDelay;
mActiveTrack.clear();
- applyVolume();
+
+ // apply volume
+
+ // Do not apply volume on compressed audio
+ if (!audio_is_linear_pcm(mFormat)) {
+ return;
+ }
+
+ // convert to signed 16 bit before volume calculation
+ if (mFormat == AUDIO_FORMAT_PCM_8_BIT) {
+ size_t count = mFrameCount * mChannelCount;
+ uint8_t *src = (uint8_t *)mMixBuffer + count-1;
+ int16_t *dst = mMixBuffer + count-1;
+ while(count--) {
+ *dst-- = (int16_t)(*src--^0x80) << 8;
+ }
+ }
+
+ frameCount = mFrameCount;
+ int16_t *out = mMixBuffer;
+ if (rampVolume) {
+ if (mChannelCount == 1) {
+ int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
+ int32_t vlInc = d / (int32_t)frameCount;
+ int32_t vl = ((int32_t)mLeftVolShort << 16);
+ do {
+ out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
+ out++;
+ vl += vlInc;
+ } while (--frameCount);
+
+ } else {
+ int32_t d = ((int32_t)leftVol - (int32_t)mLeftVolShort) << 16;
+ int32_t vlInc = d / (int32_t)frameCount;
+ d = ((int32_t)rightVol - (int32_t)mRightVolShort) << 16;
+ int32_t vrInc = d / (int32_t)frameCount;
+ int32_t vl = ((int32_t)mLeftVolShort << 16);
+ int32_t vr = ((int32_t)mRightVolShort << 16);
+ do {
+ out[0] = clamp16(mul(out[0], vl >> 16) >> 12);
+ out[1] = clamp16(mul(out[1], vr >> 16) >> 12);
+ out += 2;
+ vl += vlInc;
+ vr += vrInc;
+ } while (--frameCount);
+ }
+ } else {
+ if (mChannelCount == 1) {
+ do {
+ out[0] = clamp16(mul(out[0], leftVol) >> 12);
+ out++;
+ } while (--frameCount);
+ } else {
+ do {
+ out[0] = clamp16(mul(out[0], leftVol) >> 12);
+ out[1] = clamp16(mul(out[1], rightVol) >> 12);
+ out += 2;
+ } while (--frameCount);
+ }
+ }
+
+ // convert back to unsigned 8 bit after volume calculation
+ if (mFormat == AUDIO_FORMAT_PCM_8_BIT) {
+ size_t count = mFrameCount * mChannelCount;
+ int16_t *src = mMixBuffer;
+ uint8_t *dst = (uint8_t *)mMixBuffer;
+ while(count--) {
+ *dst++ = (uint8_t)(((int32_t)*src++ + (1<<7)) >> 8)^0x80;
+ }
+ }
+
+ mLeftVolShort = leftVol;
+ mRightVolShort = rightVol;
}
void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
@@ -3074,6 +3070,14 @@ uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs()
return time;
}
+void AudioFlinger::DirectOutputThread::cacheParameters_l()
+{
+ PlaybackThread::cacheParameters_l();
+
+ // use shorter standby delay as on normal output to release
+ // hardware resources as soon as possible
+ standbyDelay = microseconds(activeSleepTime*2);
+}
// ----------------------------------------------------------------------------
@@ -3127,7 +3131,7 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
void AudioFlinger::DuplicatingThread::threadLoop_write()
{
- standbyTime = systemTime() + mStandbyTimeInNsecs;
+ standbyTime = systemTime() + standbyDelay;
for (size_t i = 0; i < outputTracks.size(); i++) {
outputTracks[i]->write(mMixBuffer, writeFrames);
}
@@ -3223,6 +3227,14 @@ uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs()
return (mWaitTimeMs * 1000) / 2;
}
+void AudioFlinger::DuplicatingThread::cacheParameters_l()
+{
+ // updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first
+ updateWaitTime_l();
+
+ MixerThread::cacheParameters_l();
+}
+
// ----------------------------------------------------------------------------
// TrackBase constructor must be called with AudioFlinger::mLock held
@@ -5192,8 +5204,8 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l()
reqFormat == mInput->stream->common.get_format(&mInput->stream->common) &&
reqFormat == AUDIO_FORMAT_PCM_16_BIT &&
((int)mInput->stream->common.get_sample_rate(&mInput->stream->common) <= (2 * reqSamplingRate)) &&
- (popcount(mInput->stream->common.get_channels(&mInput->stream->common)) < 3) &&
- (reqChannelCount < 3)) {
+ popcount(mInput->stream->common.get_channels(&mInput->stream->common)) <= FCC_2 &&
+ (reqChannelCount <= FCC_2)) {
status = NO_ERROR;
}
if (status == NO_ERROR) {
@@ -5270,7 +5282,7 @@ void AudioFlinger::RecordThread::readInputParameters()
mFrameCount = mInputBytes / mFrameSize;
mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
- if (mSampleRate != mReqSampleRate && mChannelCount < 3 && mReqChannelCount < 3)
+ if (mSampleRate != mReqSampleRate && mChannelCount <= FCC_2 && mReqChannelCount <= FCC_2)
{
int channelCount;
// optmization: if mono to mono, use the resampler in stereo to stereo mode to avoid
@@ -5356,7 +5368,7 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
audio_format_t *pFormat,
uint32_t *pChannels,
uint32_t *pLatencyMs,
- uint32_t flags)
+ audio_policy_output_flags_t flags)
{
status_t status;
PlaybackThread *thread = NULL;
@@ -5559,7 +5571,7 @@ audio_io_handle_t AudioFlinger::openInput(uint32_t *pDevices,
if (inStream == NULL && status == BAD_VALUE &&
reqFormat == format && format == AUDIO_FORMAT_PCM_16_BIT &&
(samplingRate <= 2 * reqSamplingRate) &&
- (popcount(channels) < 3) && (popcount(reqChannels) < 3)) {
+ (popcount(channels) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
ALOGV("openInput() reopening with proposed sampling rate and channels");
status = inHwDev->open_input_stream(inHwDev, *pDevices, &format,
&channels, &samplingRate,
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2e259c0..f3c8dd2 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -58,13 +58,22 @@ class AudioResampler;
// ----------------------------------------------------------------------------
+// AudioFlinger has a hard-coded upper limit of 2 channels for capture and playback.
+// There is support for > 2 channel tracks down-mixed to 2 channel output via a down-mix effect.
+// Adding full support for > 2 channel capture or playback would require more than simply changing
+// this #define. There is an independent hard-coded upper limit in AudioMixer;
+// removing that AudioMixer limit would be necessary but insufficient to support > 2 channels.
+// The macro FCC_2 highlights some (but not all) places where there is are 2-channel assumptions.
+// Search also for "2", "left", "right", "[0]", "[1]", ">> 16", "<< 16", etc.
+#define FCC_2 2 // FCC_2 = Fixed Channel Count 2
+
static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
class AudioFlinger :
public BinderService<AudioFlinger>,
public BnAudioFlinger
{
- friend class BinderService<AudioFlinger>;
+ friend class BinderService<AudioFlinger>; // for AudioFlinger()
public:
static const char* getServiceName() { return "media.audio_flinger"; }
@@ -134,7 +143,7 @@ public:
audio_format_t *pFormat,
uint32_t *pChannels,
uint32_t *pLatencyMs,
- uint32_t flags);
+ audio_policy_output_flags_t flags);
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2);
@@ -213,6 +222,8 @@ private:
audio_hw_device_t* findSuitableHwDev_l(uint32_t devices);
void purgeStaleEffects_l();
+ // standby delay for MIXER and DUPLICATING playback threads is read from property
+ // ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs
static nsecs_t mStandbyTimeInNsecs;
// Internal dump utilites.
@@ -331,13 +342,6 @@ private:
int sessionId() const { return mSessionId; }
protected:
- friend class ThreadBase;
- friend class RecordHandle;
- friend class PlaybackThread;
- friend class RecordThread;
- friend class MixerThread;
- friend class DirectOutputThread;
-
TrackBase(const TrackBase&);
TrackBase& operator = (const TrackBase&);
@@ -523,15 +527,7 @@ private:
// check if some effects must be suspended when an effect chain is added
void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain);
- friend class AudioFlinger;
- friend class Track;
- friend class TrackBase;
- friend class PlaybackThread;
- friend class MixerThread;
- friend class DirectOutputThread;
- friend class DuplicatingThread;
- friend class RecordThread;
- friend class RecordTrack;
+ friend class AudioFlinger; // for mEffectChains
const type_t mType;
@@ -646,8 +642,7 @@ private:
int auxEffectId() const { return mAuxEffectId; }
protected:
- friend class ThreadBase;
- friend class TrackHandle;
+ // for numerous
friend class PlaybackThread;
friend class MixerThread;
friend class DirectOutputThread;
@@ -676,7 +671,9 @@ private:
return (mStreamType == AUDIO_STREAM_CNT);
}
+ public:
virtual bool isTimedTrack() const { return false; }
+ protected:
// we don't really need a lock for these
volatile bool mMute;
@@ -815,7 +812,7 @@ private:
audio_io_handle_t id, uint32_t device, type_t type);
virtual ~PlaybackThread();
- virtual status_t dump(int fd, const Vector<String16>& args);
+ status_t dump(int fd, const Vector<String16>& args);
// Thread virtuals
virtual status_t readyToRun();
@@ -831,12 +828,6 @@ protected:
virtual void threadLoop_write();
virtual void threadLoop_standby();
- // Non-trivial for DUPLICATING only
- virtual void updateWaitTime_l() { }
-
- // Non-trivial for DIRECT only
- virtual void applyVolume() { }
-
// prepareTracks_l reads and writes mActiveTracks, and also returns the
// pending set of tracks to remove via Vector 'tracksToRemove'. The caller is
// responsible for clearing or destroying this Vector later on, when it
@@ -847,7 +838,8 @@ public:
virtual status_t initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; }
- virtual uint32_t latency() const;
+ // return estimated latency in milliseconds, as reported by HAL
+ uint32_t latency() const;
void setMasterVolume(float value);
void setMasterMute(bool muted);
@@ -878,7 +870,7 @@ public:
bool isSuspended() const { return (mSuspended > 0); }
virtual String8 getParameters(const String8& keys);
virtual void audioConfigChanged_l(int event, int param = 0);
- virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
+ status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
int16_t *mixBuffer() const { return mMixBuffer; };
virtual void detachAuxEffect_l(int effectId);
@@ -920,15 +912,12 @@ public:
virtual void saveOutputTracks() { }
virtual void clearOutputTracks() { }
+ // Cache various calculated values, at threadLoop() entry and after a parameter change
+ virtual void cacheParameters_l();
+
private:
- friend class AudioFlinger;
- friend class OutputTrack;
- friend class Track;
- friend class TrackBase;
- friend class MixerThread;
- friend class DirectOutputThread;
- friend class DuplicatingThread;
+ friend class AudioFlinger; // for numerous
PlaybackThread(const Client&);
PlaybackThread& operator = (const PlaybackThread&);
@@ -955,8 +944,11 @@ public:
// FIXME rename these former local variables of threadLoop to standard "m" names
nsecs_t standbyTime;
size_t mixBufferSize;
+
+ // cached copies of activeSleepTimeUs() and idleSleepTimeUs() made by cacheParameters_l()
uint32_t activeSleepTime;
uint32_t idleSleepTime;
+
uint32_t sleepTime;
// mixer status returned by prepareTracks_l()
@@ -967,8 +959,13 @@ public:
// MIXER only
bool longStandbyExit;
uint32_t sleepTimeShift;
- // DIRECT only
+
+ // same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
nsecs_t standbyDelay;
+
+ // MIXER only
+ nsecs_t maxPeriod;
+
// DUPLICATING only
uint32_t writeFrames;
};
@@ -994,6 +991,7 @@ public:
virtual void deleteTrackName_l(int name);
virtual uint32_t idleSleepTimeUs();
virtual uint32_t suspendSleepTimeUs();
+ virtual void cacheParameters_l();
// threadLoop snippets
virtual void threadLoop_mix();
@@ -1019,6 +1017,7 @@ public:
virtual uint32_t activeSleepTimeUs();
virtual uint32_t idleSleepTimeUs();
virtual uint32_t suspendSleepTimeUs();
+ virtual void cacheParameters_l();
// threadLoop snippets
virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
@@ -1039,8 +1038,6 @@ public:
uint16_t rightVol;
private:
- void applyVolume(); // FIXME inline into threadLoop_mix()
-
// prepareTracks_l() tells threadLoop_mix() the name of the single active track
sp<Track> mActiveTrack;
};
@@ -1066,9 +1063,12 @@ private:
virtual void threadLoop_sleepTime();
virtual void threadLoop_write();
virtual void threadLoop_standby();
+ virtual void cacheParameters_l();
+ private:
// called from threadLoop, addOutputTrack, removeOutputTrack
virtual void updateWaitTime_l();
+ protected:
virtual void saveOutputTracks();
virtual void clearOutputTracks();
private:
@@ -1100,8 +1100,6 @@ private:
PlaybackThread *primaryPlaybackThread_l() const;
uint32_t primaryOutputDevice_l() const;
- friend class AudioBuffer;
-
// server side of the client's IAudioTrack
class TrackHandle : public android::BnAudioTrack {
public:
@@ -1126,10 +1124,6 @@ private:
const sp<PlaybackThread::Track> mTrack;
};
- friend class Client;
- friend class PlaybackThread::Track;
-
-
void removeClient_l(pid_t pid);
void removeNotificationClient(pid_t pid);
@@ -1160,8 +1154,7 @@ private:
void dump(char* buffer, size_t size);
private:
- friend class AudioFlinger;
- friend class RecordThread;
+ friend class AudioFlinger; // for mState
RecordTrack(const RecordTrack&);
RecordTrack& operator = (const RecordTrack&);
@@ -1343,8 +1336,7 @@ private:
status_t dump(int fd, const Vector<String16>& args);
protected:
- friend class EffectHandle;
- friend class AudioFlinger;
+ friend class AudioFlinger; // for mHandles
bool mPinned;
// Maximum time allocated to effect engines to complete the turn off sequence
@@ -1428,8 +1420,7 @@ mutable Mutex mLock; // mutex for process, commands and handl
void dump(char* buffer, size_t size);
protected:
- friend class AudioFlinger;
- friend class EffectModule;
+ friend class AudioFlinger; // for mEffect, mHasControl, mEnabled
EffectHandle(const EffectHandle&);
EffectHandle& operator =(const EffectHandle&);
@@ -1527,7 +1518,7 @@ mutable Mutex mLock; // mutex for process, commands and handl
status_t dump(int fd, const Vector<String16>& args);
protected:
- friend class AudioFlinger;
+ friend class AudioFlinger; // for mThread, mEffects
EffectChain(const EffectChain&);
EffectChain& operator =(const EffectChain&);
@@ -1603,9 +1594,6 @@ mutable Mutex mLock; // mutex for process, commands and handl
int mCnt;
};
- friend class RecordThread;
- friend class PlaybackThread;
-
enum master_volume_support {
// MVS_NONE:
// Audio HAL has no support for master volume, either setting or
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 62768bf..d57326b 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -298,8 +298,7 @@ audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
ssize_t idx = mInputs.indexOfKey(input);
InputDesc *inputDesc;
if (idx < 0) {
- inputDesc = new InputDesc();
- inputDesc->mSessionId = audioSession;
+ inputDesc = new InputDesc(audioSession);
mInputs.add(input, inputDesc);
} else {
inputDesc = mInputs.valueAt(idx);
@@ -358,7 +357,6 @@ void AudioPolicyService::releaseInput(audio_io_handle_t input)
}
InputDesc *inputDesc = mInputs.valueAt(index);
setPreProcessorEnabled(inputDesc, false);
- inputDesc->mEffects.clear();
delete inputDesc;
mInputs.removeItemsAt(index);
}
@@ -602,9 +600,9 @@ status_t AudioPolicyService::dumpPermissionDenial(int fd)
return NO_ERROR;
}
-void AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled)
+void AudioPolicyService::setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled)
{
- Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
+ const Vector<sp<AudioEffect> > &fxVector = inputDesc->mEffects;
for (size_t i = 0; i < fxVector.size(); i++) {
fxVector.itemAt(i)->setEnabled(enabled);
}
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index e41d51e..7119b90 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -279,15 +279,15 @@ private:
class InputDesc {
public:
- InputDesc() {}
- virtual ~InputDesc() {}
- int mSessionId;
+ InputDesc(int session) : mSessionId(session) {}
+ /*virtual*/ ~InputDesc() {}
+ const int mSessionId;
Vector< sp<AudioEffect> >mEffects;
};
static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
- void setPreProcessorEnabled(InputDesc *inputDesc, bool enabled);
+ void setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled);
status_t loadPreProcessorConfig(const char *path);
status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
EffectDesc *loadEffect(cnode *root);
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 149c0d3..da3548f 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "InputDispatcher"
+#define ATRACE_TAG ATRACE_TAG_INPUT
//#define LOG_NDEBUG 0
@@ -44,6 +45,7 @@
#include "InputDispatcher.h"
+#include <utils/Trace.h>
#include <cutils/log.h>
#include <androidfw/PowerManager.h>
@@ -280,6 +282,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
} else {
// Inbound queue has at least one entry.
mPendingEvent = mInboundQueue.dequeueAtHead();
+ traceInboundQueueLengthLocked();
}
// Poke user activity for this event.
@@ -379,6 +382,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
bool needWake = mInboundQueue.isEmpty();
mInboundQueue.enqueueAtTail(entry);
+ traceInboundQueueLengthLocked();
switch (entry->type) {
case EventEntry::TYPE_KEY: {
@@ -572,6 +576,7 @@ void InputDispatcher::drainInboundQueueLocked() {
EventEntry* entry = mInboundQueue.dequeueAtHead();
releaseInboundEventLocked(entry);
}
+ traceInboundQueueLengthLocked();
}
void InputDispatcher::releasePendingEventLocked() {
@@ -1867,6 +1872,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(
// Enqueue the dispatch entry.
connection->outboundQueue.enqueueAtTail(dispatchEntry);
+ traceOutboundQueueLengthLocked(connection);
}
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
@@ -1978,7 +1984,9 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
// Re-enqueue the event on the wait queue.
connection->outboundQueue.dequeue(dispatchEntry);
+ traceOutboundQueueLengthLocked(connection);
connection->waitQueue.enqueueAtTail(dispatchEntry);
+ traceWaitQueueLengthLocked(connection);
}
}
@@ -2009,7 +2017,9 @@ void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
// Clear the dispatch queues.
drainDispatchQueueLocked(&connection->outboundQueue);
+ traceOutboundQueueLengthLocked(connection);
drainDispatchQueueLocked(&connection->waitQueue);
+ traceWaitQueueLengthLocked(connection);
// The connection appears to be unrecoverably broken.
// Ignore already broken or zombie connections.
@@ -3311,8 +3321,10 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
// a few things.
if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
connection->waitQueue.dequeue(dispatchEntry);
+ traceWaitQueueLengthLocked(connection);
if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
connection->outboundQueue.enqueueAtHead(dispatchEntry);
+ traceOutboundQueueLengthLocked(connection);
} else {
releaseDispatchEntryLocked(dispatchEntry);
}
@@ -3498,6 +3510,28 @@ void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const
// TODO Write some statistics about how long we spend waiting.
}
+void InputDispatcher::traceInboundQueueLengthLocked() {
+ if (ATRACE_ENABLED()) {
+ ATRACE_INT("iq", mInboundQueue.count());
+ }
+}
+
+void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
+ if (ATRACE_ENABLED()) {
+ char counterName[40];
+ snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName());
+ ATRACE_INT(counterName, connection->outboundQueue.count());
+ }
+}
+
+void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
+ if (ATRACE_ENABLED()) {
+ char counterName[40];
+ snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName());
+ ATRACE_INT(counterName, connection->waitQueue.count());
+ }
+}
+
void InputDispatcher::dump(String8& dump) {
AutoMutex _l(mLock);
@@ -4014,6 +4048,16 @@ InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
InputDispatcher::Connection::~Connection() {
}
+const char* InputDispatcher::Connection::getWindowName() const {
+ if (inputWindowHandle != NULL) {
+ return inputWindowHandle->getName().string();
+ }
+ if (monitor) {
+ return "monitor";
+ }
+ return "?";
+}
+
const char* InputDispatcher::Connection::getStatusLabel() const {
switch (status) {
case STATUS_NORMAL:
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 4b36480..91f7554 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -805,6 +805,7 @@ private:
inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
+ const char* getWindowName() const;
const char* getStatusLabel() const;
DispatchEntry* findWaitQueueEntry(uint32_t seq);
@@ -1069,6 +1070,9 @@ private:
// Statistics gathering.
void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
+ void traceInboundQueueLengthLocked();
+ void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
+ void traceWaitQueueLengthLocked(const sp<Connection>& connection);
};
/* Enqueues and dispatches input events, endlessly. */
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 720b5fe..09d0698 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -880,7 +880,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
wifiFirmwareReload(wlanIface, "AP");
- mConnector.execute("softap", "start", wlanIface);
if (wifiConfig == null) {
mConnector.execute("softap", "set", wlanIface, softapIface);
} else {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2538455..fd968e0 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4934,7 +4934,7 @@ public final class ActivityManagerService extends ActivityManagerNative
void grantUriPermissionFromIntentLocked(int callingUid,
String targetPkg, Intent intent, UriPermissionOwner owner) {
NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
- intent, intent.getFlags(), null);
+ intent, intent != null ? intent.getFlags() : 0, null);
if (needed == null) {
return;
}
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index a890068..2ad24e2 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -156,6 +156,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
private static final int VERSION_ADDED_METERED = 4;
private static final int VERSION_SPLIT_SNOOZE = 5;
+ private static final int VERSION_ADDED_TIMEZONE = 6;
// @VisibleForTesting
public static final int TYPE_WARNING = 0x1;
@@ -171,6 +172,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
private static final String ATTR_CYCLE_DAY = "cycleDay";
+ private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
private static final String ATTR_WARNING_BYTES = "warningBytes";
private static final String ATTR_LIMIT_BYTES = "limitBytes";
private static final String ATTR_LAST_SNOOZE = "lastSnooze";
@@ -922,13 +924,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
com.android.internal.R.integer.config_networkPolicyDefaultWarning)
* MB_IN_BYTES;
- final Time time = new Time(Time.TIMEZONE_UTC);
+ final Time time = new Time();
time.setToNow();
+
final int cycleDay = time.monthDay;
+ final String cycleTimezone = time.timezone;
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
- mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, warningBytes,
- LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true));
+ mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, cycleTimezone,
+ warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true));
writePolicyLocked();
}
}
@@ -964,6 +968,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
+ final String cycleTimezone;
+ if (version >= VERSION_ADDED_TIMEZONE) {
+ cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
+ } else {
+ cycleTimezone = Time.TIMEZONE_UTC;
+ }
final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
final long lastLimitSnooze;
@@ -998,8 +1008,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final NetworkTemplate template = new NetworkTemplate(
networkTemplate, subscriberId);
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
- warningBytes, limitBytes, lastWarningSnooze, lastLimitSnooze,
- metered));
+ cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
+ lastLimitSnooze, metered));
} else if (TAG_UID_POLICY.equals(tag)) {
final int uid = readIntAttribute(in, ATTR_UID);
@@ -1054,7 +1064,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
out.startDocument(null, true);
out.startTag(null, TAG_POLICY_LIST);
- writeIntAttribute(out, ATTR_VERSION, VERSION_SPLIT_SNOOZE);
+ writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_TIMEZONE);
writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
// write all known network policies
@@ -1068,6 +1078,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
}
writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
+ out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 7ac67b6..7b5bf08 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -372,6 +372,12 @@ class ScreenRotationAnimation implements WindowManagerService.StepAnimator {
break;
}
+ // Compute partial steps between original and final sizes. These
+ // are used for the dimensions of the exiting and entering elements,
+ // so they are never stretched too significantly.
+ final int halfWidth = (finalWidth + mOriginalWidth) / 2;
+ final int halfHeight = (finalHeight + mOriginalHeight) / 2;
+
// Initialize the animations. This is a hack, redefining what "parent"
// means to allow supplying the last and next size. In this definition
// "%p" is the original (let's call it "previous") size, and "%" is the
@@ -379,14 +385,14 @@ class ScreenRotationAnimation implements WindowManagerService.StepAnimator {
if (firstStart) {
if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
mStartEnterAnimation.initialize(finalWidth, finalHeight,
- mOriginalWidth, mOriginalHeight);
- mStartExitAnimation.initialize(finalWidth, finalHeight,
+ halfWidth, halfHeight);
+ mStartExitAnimation.initialize(halfWidth, halfHeight,
mOriginalWidth, mOriginalHeight);
mStartFrameAnimation.initialize(finalWidth, finalHeight,
mOriginalWidth, mOriginalHeight);
mFinishEnterAnimation.initialize(finalWidth, finalHeight,
- mOriginalWidth, mOriginalHeight);
- mFinishExitAnimation.initialize(finalWidth, finalHeight,
+ halfWidth, halfHeight);
+ mFinishExitAnimation.initialize(halfWidth, halfHeight,
mOriginalWidth, mOriginalHeight);
mFinishFrameAnimation.initialize(finalWidth, finalHeight,
mOriginalWidth, mOriginalHeight);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 18b51a7..22949f3 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1535,7 +1535,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
final boolean isWallpaperVisible(WindowState wallpaperTarget) {
- if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target obscured="
+ if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
+ (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
+ " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
? wallpaperTarget.mAppToken.animation : null)
@@ -8239,6 +8239,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (!w.mAnimating) {
// We set the animation above so it
// is not yet running.
+ // TODO(cmautner): We lose the enter animation when this occurs.
w.clearAnimation();
}
}
@@ -8342,9 +8343,6 @@ public class WindowManagerService extends IWindowManager.Stub
// cases while they are hidden such as when first showing a
// window.
- if (mScreenRotationAnimation != null) {
- mScreenRotationAnimation.updateSurfaces();
- }
boolean displayed = false;
w.computeShownFrameLocked();
@@ -8852,6 +8850,10 @@ public class WindowManagerService extends IWindowManager.Stub
mInnerFields.mDimming = false;
mInnerFields.mSyswin = false;
+ if (mScreenRotationAnimation != null) {
+ mScreenRotationAnimation.updateSurfaces();
+ }
+
final int N = mWindows.size();
for (i=N-1; i>=0; i--) {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index b9ee660..167746f 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -304,6 +304,11 @@ final class WindowState implements WindowManagerPolicy.WindowState,
int mAnimDw;
int mAnimDh;
+ static final int ANIM_STATE_IDLE = 0;
+ static final int ANIM_STATE_RUNNING = 1;
+ static final int ANIM_STATE_STOPPING = 2;
+ int mAnimState = ANIM_STATE_IDLE;
+
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
int viewVisibility) {
@@ -640,6 +645,7 @@ final class WindowState implements WindowManagerPolicy.WindowState,
mLocalAnimating = false;
mAnimation.cancel();
mAnimation = null;
+ mAnimState = ANIM_STATE_IDLE;
}
}
@@ -651,6 +657,7 @@ final class WindowState implements WindowManagerPolicy.WindowState,
mAnimation.cancel();
mAnimation = null;
destroySurfaceLocked();
+ mAnimState = ANIM_STATE_IDLE;
}
mExiting = false;
}
@@ -968,6 +975,7 @@ final class WindowState implements WindowManagerPolicy.WindowState,
mAnimation = null;
// Make sure we clean up the animation.
mAnimating = true;
+ mAnimState = ANIM_STATE_IDLE;
}
mService.mFinishedStarting.add(mAppToken);
mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
@@ -980,7 +988,7 @@ final class WindowState implements WindowManagerPolicy.WindowState,
@Override
public boolean stepAnimation(long currentTime) {
- if ((mAnimation == null) || !mLocalAnimating) {
+ if ((mAnimation == null) || !mLocalAnimating || (mAnimState != ANIM_STATE_RUNNING)) {
return false;
}
mTransformation.clear();
@@ -989,8 +997,7 @@ final class WindowState implements WindowManagerPolicy.WindowState,
WindowManagerService.TAG, "Stepped animation in " + this +
": more=" + more + ", xform=" + mTransformation);
if (!more) {
- mAnimation.cancel();
- mAnimation = null;
+ mAnimState = ANIM_STATE_STOPPING;
}
return more;
}
@@ -1018,8 +1025,10 @@ final class WindowState implements WindowManagerPolicy.WindowState,
mAnimation.setStartTime(currentTime);
mLocalAnimating = true;
mAnimating = true;
+ mAnimState = ANIM_STATE_RUNNING;
}
- if ((mAnimation != null) && mLocalAnimating) {
+ if ((mAnimation != null) && mLocalAnimating &&
+ (mAnimState != ANIM_STATE_STOPPING)) {
return true;
}
if (WindowManagerService.DEBUG_ANIM) Slog.v(
@@ -1120,6 +1129,7 @@ final class WindowState implements WindowManagerPolicy.WindowState,
mAppToken.updateReportedVisibilityLocked();
}
+ mAnimState = ANIM_STATE_IDLE;
return false;
}
@@ -1305,12 +1315,15 @@ final class WindowState implements WindowManagerPolicy.WindowState,
}
if (WindowManagerService.localLOGV) Slog.v(
- WindowManagerService.TAG, "Continuing animation in " + this +
+ WindowManagerService.TAG, "computeShownFrameLocked: Animating " + this +
": " + mShownFrame +
- ", alpha=" + mTransformation.getAlpha());
+ ", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
return;
}
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "computeShownFrameLocked: " + this +
+ " not attached, mAlpha=" + mAlpha);
mShownFrame.set(mFrame);
if (mXOffset != 0 || mYOffset != 0) {
mShownFrame.offset(mXOffset, mYOffset);
@@ -1428,13 +1441,11 @@ final class WindowState implements WindowManagerPolicy.WindowState,
mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
return false;
}
- final AppWindowToken atoken = mAppToken;
- final boolean animating = atoken != null
- ? (atoken.animation != null) : false;
return mSurface != null && mPolicyVisibility && !mDestroying
&& ((!mAttachedHidden && mViewVisibility == View.VISIBLE
&& !mRootToken.hidden)
- || mAnimation != null || animating);
+ || mAnimation != null
+ || ((mAppToken != null) && (mAppToken.animation != null)));
}
/** Is the window or its container currently animating? */
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index e863f8b..b4fd55e 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -32,6 +32,7 @@ import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.text.format.Time.TIMEZONE_UTC;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
@@ -439,7 +440,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
final NetworkPolicy policy = new NetworkPolicy(
- sTemplateWifi, 5, 1024L, 1024L, false);
+ sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
assertTimeEquals(expectedCycle, actualCycle);
}
@@ -450,7 +451,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
final NetworkPolicy policy = new NetworkPolicy(
- sTemplateWifi, 20, 1024L, 1024L, false);
+ sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
assertTimeEquals(expectedCycle, actualCycle);
}
@@ -461,7 +462,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
final NetworkPolicy policy = new NetworkPolicy(
- sTemplateWifi, 30, 1024L, 1024L, false);
+ sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
assertTimeEquals(expectedCycle, actualCycle);
}
@@ -472,14 +473,53 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");
final NetworkPolicy policy = new NetworkPolicy(
- sTemplateWifi, 30, 1024L, 1024L, false);
+ sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
assertTimeEquals(expectedCycle, actualCycle);
}
+ public void testCycleBoundaryLeapYear() throws Exception {
+ final NetworkPolicy policy = new NetworkPolicy(
+ sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
+
+ assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
+ computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
+ assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
+ computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
+ assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
+ computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
+ assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
+ computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
+
+ assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
+ computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
+ assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
+ computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
+ assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
+ computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
+ assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
+ computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
+ }
+
+ public void testNextCycleTimezoneAfterUtc() throws Exception {
+ // US/Central is UTC-6
+ final NetworkPolicy policy = new NetworkPolicy(
+ sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
+ assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
+ computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
+ }
+
+ public void testNextCycleTimezoneBeforeUtc() throws Exception {
+ // Israel is UTC+2
+ final NetworkPolicy policy = new NetworkPolicy(
+ sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
+ assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
+ computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
+ }
+
public void testNextCycleSane() throws Exception {
final NetworkPolicy policy = new NetworkPolicy(
- sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, false);
+ sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
// walk forwards, ensuring that cycle boundaries don't get stuck
@@ -494,7 +534,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
public void testLastCycleSane() throws Exception {
final NetworkPolicy policy = new NetworkPolicy(
- sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, false);
+ sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
// walk backwards, ensuring that cycle boundaries look sane
@@ -552,7 +592,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
replay();
setNetworkPolicies(new NetworkPolicy(
- sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
+ sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
future.get();
verifyAndReset();
}
@@ -609,8 +649,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
future = expectMeteredIfacesChanged();
replay();
- setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES,
- 2 * MB_IN_BYTES, false));
+ setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1
+ * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
future.get();
verifyAndReset();
}
@@ -740,8 +780,9 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
future = expectMeteredIfacesChanged(TEST_IFACE);
replay();
- setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, WARNING_DISABLED,
- LIMIT_DISABLED, true));
+ setNetworkPolicies(new NetworkPolicy(
+ sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
+ true));
future.get();
verifyAndReset();
}
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 6f85c7d..983c349 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -39,30 +39,6 @@ import java.util.Locale;
* The formatting will be restarted once the text is cleared.
*/
public class PhoneNumberFormattingTextWatcher implements TextWatcher {
- /**
- * One or more characters were removed from the end.
- */
- private final static int STATE_REMOVE_LAST = 0;
-
- /**
- * One or more characters were appended.
- */
- private final static int STATE_APPEND = 1;
-
- /**
- * One or more digits were changed in the beginning or the middle of text.
- */
- private final static int STATE_MODIFY_DIGITS = 2;
-
- /**
- * The changes other than the above.
- */
- private final static int STATE_OTHER = 3;
-
- /**
- * The state of this change could be one value of the above
- */
- private int mState;
/**
* Indicates the change was caused by ourselves.
@@ -97,46 +73,30 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
mFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(countryCode);
}
+ @Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if (mSelfChange || mStopFormatting) {
return;
}
- if (count == 0 && s.length() == start) {
- // Append one or more new chars
- mState = STATE_APPEND;
- } else if (after == 0 && start + count == s.length() && count > 0) {
- // Remove one or more chars from the end of string.
- mState = STATE_REMOVE_LAST;
- } else if (count > 0 && !hasSeparator(s, start, count)) {
- // Remove the dialable chars in the begin or middle of text.
- mState = STATE_MODIFY_DIGITS;
- } else {
- mState = STATE_OTHER;
+ // If the user manually deleted any non-dialable characters, stop formatting
+ if (count > 0 && hasSeparator(s, start, count)) {
+ stopFormatting();
}
}
+ @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mSelfChange || mStopFormatting) {
return;
}
- if (mState == STATE_OTHER) {
- if (count > 0 && !hasSeparator(s, start, count)) {
- // User inserted the dialable characters in the middle of text.
- mState = STATE_MODIFY_DIGITS;
- }
- }
- // Check whether we should stop formatting.
- if (mState == STATE_APPEND && count > 0 && hasSeparator(s, start, count)) {
- // User appended the non-dialable character, stop formatting.
- stopFormatting();
- } else if (mState == STATE_OTHER) {
- // User must insert or remove the non-dialable characters in the begin or middle of
- // number, stop formatting.
+ // If the user inserted any non-dialable characters, stop formatting
+ if (count > 0 && hasSeparator(s, start, count)) {
stopFormatting();
}
}
+ @Override
public synchronized void afterTextChanged(Editable s) {
if (mStopFormatting) {
// Restart the formatting when all texts were clear.
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
index 6f0175e..a6a0fce 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
@@ -182,14 +182,17 @@ public class PhoneNumberWatcherTest extends AndroidTestCase {
public void testTextChangedByOtherTextWatcher() {
final TextWatcher cleanupTextWatcher = new TextWatcher() {
+ @Override
public void afterTextChanged(Editable s) {
s.clear();
}
+ @Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
+ @Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@@ -208,6 +211,81 @@ public class PhoneNumberWatcherTest extends AndroidTestCase {
assertEquals(expected1, number.toString());
}
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithFormattedNumber() {
+ String init = "650-1";
+ String expected = "+1-650-123-4567"; // Different formatting than ours
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithFormattedNameAndNumber() {
+ String init = "650-1";
+ String expected = "Test User <650-123-4567>";
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithNumericNameAndNumber() {
+ String init = "650";
+ String expected = "2nd Test User <650-123-4567>";
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing
+ */
+ public void testAutoCompleteWithUnformattedNumber() {
+ String init = "650-1";
+ String expected = "6501234567";
+ testReplacement(init, expected, expected);
+ }
+
+ /**
+ * Test the case where some other component is auto-completing what the user is typing, where
+ * the deleted text doesn't have any formatting and neither does the replacement text: in this
+ * case the replacement text should be formatted by the PhoneNumberFormattingTextWatcher.
+ */
+ public void testAutoCompleteUnformattedWithUnformattedNumber() {
+ String init = "650";
+ String replacement = "6501234567";
+ String expected = "(650) 123-4567";
+ testReplacement(init, replacement, expected);
+
+ String init2 = "650";
+ String replacement2 = "16501234567";
+ String expected2 = "1 650-123-4567";
+ testReplacement(init2, replacement2, expected2);
+ }
+
+ /**
+ * Helper method for testing replacing the entire string with another string
+ * @param init The initial string
+ * @param expected
+ */
+ private void testReplacement(String init, String replacement, String expected) {
+ TextWatcher textWatcher = getTextWatcher();
+
+ SpannableStringBuilder number = new SpannableStringBuilder(init);
+
+ // Replace entire text with the given values
+ textWatcher.beforeTextChanged(number, 0, init.length(), replacement.length());
+ number.replace(0, init.length(), replacement, 0, replacement.length());
+ Selection.setSelection(number, replacement.length()); // move the cursor to the end
+ textWatcher.onTextChanged(number, 0, init.length(), replacement.length());
+ textWatcher.afterTextChanged(number);
+
+ assertEquals(expected, number.toString());
+ // the cursor should be still at the end
+ assertEquals(expected.length(), Selection.getSelectionEnd(number));
+ }
+
private TextWatcher getTextWatcher() {
return new PhoneNumberFormattingTextWatcher("US");
}
diff --git a/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png
new file mode 100644
index 0000000..27c4618
--- /dev/null
+++ b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png
Binary files differ
diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
index cd5d53f..77cbf84 100644
--- a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
+++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
@@ -18,6 +18,7 @@ package com.android.rs.sample;
import android.app.Activity;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.SurfaceTexture;
@@ -66,13 +67,14 @@ public class SampleRSActivity extends Activity {
}
private final String TAG = "Img";
- private Bitmap mBitmapIn;
- private TextureView mDisplayView;
+ private Bitmap mBitmapTwoByTwo;
+ private Bitmap mBitmapCity;
private TextView mBenchmarkResult;
private RenderScript mRS;
- private Allocation mInPixelsAllocation;
+ private Allocation mTwoByTwoAlloc;
+ private Allocation mCityAlloc;
private ScriptC_sample mScript;
public void onStartTrackingTouch(SeekBar seekBar) {
@@ -86,14 +88,18 @@ public class SampleRSActivity extends Activity {
super.onCreate(savedInstanceState);
setContentView(R.layout.rs);
- mBitmapIn = loadBitmap(R.drawable.twobytwo);
- mDisplayView = (TextureView) findViewById(R.id.display);
+ mBitmapTwoByTwo = loadBitmap(R.drawable.twobytwo);
+ mBitmapCity = loadBitmap(R.drawable.city);
mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
mBenchmarkResult.setText("Result: not run");
mRS = RenderScript.create(this);
- mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
+ mTwoByTwoAlloc = Allocation.createFromBitmap(mRS, mBitmapTwoByTwo,
+ Allocation.MipmapControl.MIPMAP_NONE,
+ Allocation.USAGE_SCRIPT);
+
+ mCityAlloc = Allocation.createFromBitmap(mRS, mBitmapCity,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
@@ -101,8 +107,8 @@ public class SampleRSActivity extends Activity {
int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT;
- int outX = 32;
- int outY = 32;
+ int outX = 256;
+ int outY = 256;
// Wrap Linear
Allocation outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
@@ -144,7 +150,7 @@ public class SampleRSActivity extends Activity {
private synchronized void filterAlloc(Allocation alloc, Sampler sampler) {
long t = java.lang.System.currentTimeMillis();
- mScript.invoke_setSampleData(alloc, mInPixelsAllocation, sampler);
+ mScript.invoke_setSampleData(alloc, mTwoByTwoAlloc, sampler);
mScript.forEach_root(alloc);
alloc.ioSendOutput();
mRS.finish();
diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
index 8a027b2..0f3c0a7 100644
--- a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
+++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
@@ -38,39 +38,113 @@ static int32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
return max(0, min(coord, size - 1));
}
-static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord) {
- float2 wrappedCoord;
- float temp;
- if (wrapS == RS_SAMPLER_WRAP) {
- wrappedCoord.x = fract(coord.x, &temp);
- // Make sure that non zero integer uv's map to one
- if (wrappedCoord.x == 0.0f && coord.x != 0.0f) {
- wrappedCoord.x = 1.0f;
+#define convert_float(v) (float)v
+#define SAMPLE_1D_FUNC(vecsize) \
+ static float##vecsize get1DSample##vecsize(rs_allocation a, float2 weights, \
+ int iPixel, int next) { \
+ uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel); \
+ uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, next); \
+ float##vecsize p0 = convert_float##vecsize(*p0c); \
+ float##vecsize p1 = convert_float##vecsize(*p1c); \
+ return p0 * weights.x + p1 * weights.y; \
}
- if (wrappedCoord.x < 0.0f) {
- wrappedCoord.x += 1.0f;
+#define SAMPLE_2D_FUNC(vecsize) \
+ static float##vecsize get2DSample##vecsize(rs_allocation a, float4 weights, \
+ int2 iPixel, int nextX, int nextY) { \
+ uchar##vecsize *p0c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, iPixel.y); \
+ uchar##vecsize *p1c = (uchar##vecsize*)rsGetElementAt(a, nextX, iPixel.y); \
+ uchar##vecsize *p2c = (uchar##vecsize*)rsGetElementAt(a, iPixel.x, nextY); \
+ uchar##vecsize *p3c = (uchar##vecsize*)rsGetElementAt(a, nextX, nextY); \
+ float##vecsize p0 = convert_float##vecsize(*p0c); \
+ float##vecsize p1 = convert_float##vecsize(*p1c); \
+ float##vecsize p2 = convert_float##vecsize(*p2c); \
+ float##vecsize p3 = convert_float##vecsize(*p3c); \
+ return p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w; \
}
- } else {
- wrappedCoord.x = max(0.0f, min(coord.x, 1.0f));
+
+SAMPLE_1D_FUNC()
+SAMPLE_1D_FUNC(2)
+SAMPLE_1D_FUNC(3)
+SAMPLE_1D_FUNC(4)
+
+SAMPLE_2D_FUNC()
+SAMPLE_2D_FUNC(2)
+SAMPLE_2D_FUNC(3)
+SAMPLE_2D_FUNC(4)
+
+static float4 getBilinearSample565(rs_allocation a, float4 weights,
+ int2 iPixel, int nextX, int nextY) {
+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
+ return zero;
+}
+
+static float4 getBilinearSample(rs_allocation a, float4 weights,
+ int2 iPixel, int nextX, int nextY,
+ uint32_t vecSize, rs_data_type dt) {
+ if (dt == RS_TYPE_UNSIGNED_5_6_5) {
+ return getBilinearSample565(a, weights, iPixel, nextX, nextY);
}
- if (wrapT == RS_SAMPLER_WRAP) {
- wrappedCoord.y = fract(coord.y, &temp);
- // Make sure that non zero integer uv's map to one
- if (wrappedCoord.y == 0.0f && coord.y != 0.0f) {
- wrappedCoord.y = 1.0f;
- }
- if (wrappedCoord.y < 0.0f) {
- wrappedCoord.y += 1.0f;
- }
- } else {
- wrappedCoord.y = max(0.0f, min(coord.y, 1.0f));
+ float4 result;
+ switch(vecSize) {
+ case 1:
+ result.x = get2DSample(a, weights, iPixel, nextX, nextY);
+ result.yzw = 0.0f;
+ break;
+ case 2:
+ result.xy = get2DSample2(a, weights, iPixel, nextX, nextY);
+ result.zw = 0.0f;
+ break;
+ case 3:
+ result.xyz = get2DSample3(a, weights, iPixel, nextX, nextY);
+ result.w = 0.0f;
+ break;
+ case 4:
+ result = get2DSample4(a, weights, iPixel, nextX, nextY);
+ break;
}
- return wrappedCoord;
+
+ return result;
}
+static float4 getNearestSample(rs_allocation a, int2 iPixel, uint32_t vecSize, rs_data_type dt) {
+ if (dt == RS_TYPE_UNSIGNED_5_6_5) {
+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
+ return zero;
+ }
+
+ float4 result;
+ switch(vecSize) {
+ case 1:
+ result.x = convert_float(*((uchar*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ result.yzw = 0.0f;
+ case 2:
+ result.xy = convert_float2(*((uchar2*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ result.zw = 0.0f;
+ case 3:
+ result.xyz = convert_float3(*((uchar3*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ result.w = 0.0f;
+ case 4:
+ result = convert_float4(*((uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y)));
+ }
+
+ return result;
+}
+
+
// Naive implementation of texture filtering for prototyping purposes
static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
+
+ // Find out what kind of input data we are sampling
+ rs_element elem = rsAllocationGetElement(a);
+ uint32_t vecSize = rsElementGetVectorSize(elem);
+ rs_data_kind dk = rsElementGetDataKind(elem);
+ rs_data_type dt = rsElementGetDataType(elem);
+
+ if (dk == RS_KIND_USER || (dt != RS_TYPE_UNSIGNED_8 && dt != RS_TYPE_UNSIGNED_5_6_5)) {
+ float4 zero = {0.0f, 0.0f, 0.0f, 0.0f};
+ return zero;
+ }
//rsDebug("*****************************************", 0);
rs_sampler_value wrapS = rsgSamplerGetWrapS(s);
rs_sampler_value wrapT = rsgSamplerGetWrapT(s);
@@ -78,29 +152,20 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
rs_sampler_value sampleMin = rsgSamplerGetMinification(s);
rs_sampler_value sampleMag = rsgSamplerGetMagnification(s);
- uv = wrap(wrapS, wrapT, uv);
-
int32_t sourceW = rsAllocationGetDimX(a);
int32_t sourceH = rsAllocationGetDimY(a);
- /*rsDebug("uv", uv);
- rsDebug("sourceW", sourceW);
- rsDebug("sourceH", sourceH);*/
-
float2 dimF;
dimF.x = (float)(sourceW);
dimF.y = (float)(sourceH);
float2 pixelUV = uv * dimF;
int2 iPixel = convert_int2(pixelUV);
- /*rsDebug("iPixelX initial", iPixel.x);
- rsDebug("iPixelY initial", iPixel.y);*/
if (sampleMin == RS_SAMPLER_NEAREST ||
sampleMag == RS_SAMPLER_NEAREST) {
iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
- uchar4 *nearestSample = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
- return convert_float4(*nearestSample);
+ return getNearestSample(a, iPixel, vecSize, dt);
}
float2 frac = pixelUV - convert_float2(iPixel);
@@ -125,36 +190,12 @@ static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
weights.z = oneMinusFrac.x * frac.y;
weights.w = frac.x * frac.y;
- uint32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
- uint32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
+ int32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
+ int32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
- /*rsDebug("iPixelX wrapped", iPixel.x);
- rsDebug("iPixelY wrapped", iPixel.y);*/
-
- uchar4 *p0c = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
- uchar4 *p1c = (uchar4*)rsGetElementAt(a, nextX, iPixel.y);
- uchar4 *p2c = (uchar4*)rsGetElementAt(a, iPixel.x, nextY);
- uchar4 *p3c = (uchar4*)rsGetElementAt(a, nextX, nextY);
-
- float4 p0 = convert_float4(*p0c);
- float4 p1 = convert_float4(*p1c);
- float4 p2 = convert_float4(*p2c);
- float4 p3 = convert_float4(*p3c);
-
- float4 result = p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;
-
- /*rsDebug("pixelUV", pixelUV);
- rsDebug("frac", frac);
- rsDebug("oneMinusFrac", oneMinusFrac);
- rsDebug("p0", p0);
- rsDebug("p1", p1);
- rsDebug("p2", p2);
- rsDebug("p3", p3);
- rsDebug("w", weights);
- rsDebug("result", result);*/
- return result;
+ return getBilinearSample(a, weights, iPixel, nextX, nextY, vecSize, dt);
}
void root(uchar4 *out, uint32_t x, uint32_t y) {
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index c79e243..198fce4 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -636,6 +636,9 @@ int doDump(Bundle* bundle)
bool hasWriteExternalStoragePermission = false;
bool hasReadPhoneStatePermission = false;
+ // If an app requests write storage, they will also get read storage.
+ bool hasReadExternalStoragePermission = false;
+
// This next group of variables is used to implement a group of
// backward-compatibility heuristics necessitated by the addition of
// some new uses-feature constants in 2.1 and 2.2. In most cases, the
@@ -999,6 +1002,8 @@ int doDump(Bundle* bundle)
hasTelephonyPermission = true;
} else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
hasWriteExternalStoragePermission = true;
+ } else if (name == "android.permission.READ_EXTERNAL_STORAGE") {
+ hasReadExternalStoragePermission = true;
} else if (name == "android.permission.READ_PHONE_STATE") {
hasReadPhoneStatePermission = true;
}
@@ -1163,12 +1168,19 @@ int doDump(Bundle* bundle)
if (targetSdk < 4) {
if (!hasWriteExternalStoragePermission) {
printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n");
+ hasWriteExternalStoragePermission = true;
}
if (!hasReadPhoneStatePermission) {
printf("uses-permission:'android.permission.READ_PHONE_STATE'\n");
}
}
+ // If the application has requested WRITE_EXTERNAL_STORAGE, we will
+ // force them to always take READ_EXTERNAL_STORAGE as well.
+ if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) {
+ printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
+ }
+
/* The following blocks handle printing "inferred" uses-features, based
* on whether related features or permissions are used by the app.
* Note that the various spec*Feature variables denote whether the
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 843620c..05a8ca7 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1852,6 +1852,9 @@ public class WifiStateMachine extends StateMachine {
replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
WifiManager.BUSY);
break;
+ case WifiWatchdogStateMachine.RSSI_FETCH:
+ replyToMessage(message, WifiWatchdogStateMachine.RSSI_FETCH_FAILED);
+ break;
default:
loge("Error! unhandled message" + message);
break;
@@ -2998,6 +3001,12 @@ public class WifiStateMachine extends StateMachine {
mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
}
break;
+ case WifiWatchdogStateMachine.RSSI_FETCH:
+ eventLoggingEnabled = false;
+ fetchRssiAndLinkSpeedNative();
+ replyToMessage(message, WifiWatchdogStateMachine.RSSI_FETCH_SUCCEEDED,
+ mWifiInfo.getRssi());
+ break;
default:
return NOT_HANDLED;
}
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index a2f6343..5c9bef9 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -93,17 +93,36 @@ public class WifiWatchdogStateMachine extends StateMachine {
private static final String TAG = "WifiWatchdogStateMachine";
private static final String WALLED_GARDEN_NOTIFICATION_ID = "WifiWatchdog.walledgarden";
+ /* RSSI Levels as used by notification icon
+ Level 4 -55 <= RSSI
+ Level 3 -66 <= RSSI < -55
+ Level 2 -77 <= RSSI < -67
+ Level 1 -88 <= RSSI < -78
+ Level 0 RSSI < -88 */
+
/* Wi-fi connection is considered poor below this
RSSI level threshold and the watchdog report it
to the WifiStateMachine */
- private static final int RSSI_LEVEL_CUTOFF = 1;
+ private static final int RSSI_LEVEL_CUTOFF = 0;
/* Wi-fi connection is monitored actively below this
threshold */
- private static final int RSSI_LEVEL_MONITOR = 2;
+ private static final int RSSI_LEVEL_MONITOR = 1;
+ /* RSSI threshold during monitoring below which network is avoided */
+ private static final int RSSI_MONITOR_THRESHOLD = -84;
+ /* Number of times RSSI is measured to be low before being avoided */
+ private static final int RSSI_MONITOR_COUNT = 5;
+ private int mRssiMonitorCount = 0;
+
+ /* Avoid flapping */
+ private static final int MIN_INTERVAL_AVOID_BSSID_MS = 60 * 1000;
+ private String mLastAvoidedBssid;
+ /* a -ve interval to allow avoidance at boot */
+ private long mLastBssidAvoidedTime = -MIN_INTERVAL_AVOID_BSSID_MS;
private int mCurrentSignalLevel;
private static final long DEFAULT_ARP_CHECK_INTERVAL_MS = 2 * 60 * 1000;
+ private static final long DEFAULT_RSSI_FETCH_INTERVAL_MS = 1000;
private static final long DEFAULT_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000;
private static final int DEFAULT_NUM_ARP_PINGS = 5;
@@ -143,10 +162,14 @@ public class WifiWatchdogStateMachine extends StateMachine {
/* Internal messages */
private static final int CMD_ARP_CHECK = BASE + 11;
private static final int CMD_DELAYED_WALLED_GARDEN_CHECK = BASE + 12;
+ private static final int CMD_RSSI_FETCH = BASE + 13;
/* Notifications to WifiStateMachine */
static final int POOR_LINK_DETECTED = BASE + 21;
static final int GOOD_LINK_DETECTED = BASE + 22;
+ static final int RSSI_FETCH = BASE + 23;
+ static final int RSSI_FETCH_SUCCEEDED = BASE + 24;
+ static final int RSSI_FETCH_FAILED = BASE + 25;
private static final int SINGLE_ARP_CHECK = 0;
private static final int FULL_ARP_CHECK = 1;
@@ -167,11 +190,15 @@ public class WifiWatchdogStateMachine extends StateMachine {
private WalledGardenCheckState mWalledGardenCheckState = new WalledGardenCheckState();
/* Online and watching link connectivity */
private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
+ /* RSSI level is at RSSI_LEVEL_MONITOR and needs close monitoring */
+ private RssiMonitoringState mRssiMonitoringState = new RssiMonitoringState();
/* Online and doing nothing */
private OnlineState mOnlineState = new OnlineState();
private int mArpToken = 0;
private long mArpCheckIntervalMs;
+ private int mRssiFetchToken = 0;
+ private long mRssiFetchIntervalMs;
private long mWalledGardenIntervalMs;
private int mNumArpPings;
private int mMinArpResponses;
@@ -219,6 +246,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
addState(mConnectedState, mWatchdogEnabledState);
addState(mWalledGardenCheckState, mConnectedState);
addState(mOnlineWatchState, mConnectedState);
+ addState(mRssiMonitoringState, mOnlineWatchState);
addState(mOnlineState, mConnectedState);
if (isWatchdogEnabled()) {
@@ -239,6 +267,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
// Disable for wifi only devices.
if (Settings.Secure.getString(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON) == null
&& sWifiOnly) {
+ log("Disabling watchog for wi-fi only device");
putSettingsBoolean(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON, false);
}
WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context);
@@ -361,6 +390,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
pw.println("mLinkProperties: [" + mLinkProperties + "]");
pw.println("mCurrentSignalLevel: [" + mCurrentSignalLevel + "]");
pw.println("mArpCheckIntervalMs: [" + mArpCheckIntervalMs+ "]");
+ pw.println("mRssiFetchIntervalMs: [" + mRssiFetchIntervalMs + "]");
pw.println("mWalledGardenIntervalMs: [" + mWalledGardenIntervalMs + "]");
pw.println("mNumArpPings: [" + mNumArpPings + "]");
pw.println("mMinArpResponses: [" + mMinArpResponses + "]");
@@ -371,7 +401,9 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
private boolean isWatchdogEnabled() {
- return getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
+ boolean ret = getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
+ if (DBG) log("watchdog enabled " + ret);
+ return ret;
}
private void updateSettings() {
@@ -380,6 +412,9 @@ public class WifiWatchdogStateMachine extends StateMachine {
mArpCheckIntervalMs = Secure.getLong(mContentResolver,
Secure.WIFI_WATCHDOG_ARP_CHECK_INTERVAL_MS,
DEFAULT_ARP_CHECK_INTERVAL_MS);
+ mRssiFetchIntervalMs = Secure.getLong(mContentResolver,
+ Secure.WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS,
+ DEFAULT_RSSI_FETCH_INTERVAL_MS);
mNumArpPings = Secure.getInt(mContentResolver,
Secure.WIFI_WATCHDOG_NUM_ARP_PINGS,
DEFAULT_NUM_ARP_PINGS);
@@ -436,6 +471,11 @@ public class WifiWatchdogStateMachine extends StateMachine {
class DefaultState extends State {
@Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
+
+ @Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_WATCHDOG_SETTINGS_CHANGE:
@@ -445,13 +485,15 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
break;
case EVENT_RSSI_CHANGE:
- mCurrentSignalLevel = WifiManager.calculateSignalLevel(msg.arg1,
- WifiManager.RSSI_LEVELS);
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
break;
case EVENT_WIFI_RADIO_STATE_CHANGE:
case EVENT_NETWORK_STATE_CHANGE:
case CMD_ARP_CHECK:
case CMD_DELAYED_WALLED_GARDEN_CHECK:
+ case CMD_RSSI_FETCH:
+ case RSSI_FETCH_SUCCEEDED:
+ case RSSI_FETCH_FAILED:
//ignore
break;
default:
@@ -464,6 +506,11 @@ public class WifiWatchdogStateMachine extends StateMachine {
class WatchdogDisabledState extends State {
@Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
+
+ @Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_WATCHDOG_TOGGLED:
@@ -493,7 +540,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
@Override
public void enter() {
if (DBG) log("WifiWatchdogService enabled");
- }
+ }
@Override
public boolean processMessage(Message msg) {
@@ -507,6 +554,8 @@ public class WifiWatchdogStateMachine extends StateMachine {
NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ if (DBG) log("network state change " + networkInfo.getDetailedState());
+
switch (networkInfo.getDetailedState()) {
case VERIFYING_POOR_LINK:
mLinkProperties = (LinkProperties) intent.getParcelableExtra(
@@ -557,6 +606,10 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
class NotConnectedState extends State {
+ @Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
}
class VerifyingLinkState extends State {
@@ -568,7 +621,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
private void handleRssiChange() {
- if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
+ if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
//stay here
if (DBG) log("enter VerifyingLinkState, stay level: " + mCurrentSignalLevel);
} else {
@@ -587,11 +640,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
break;
case EVENT_RSSI_CHANGE:
- int signalLevel = WifiManager.calculateSignalLevel(msg.arg1,
- WifiManager.RSSI_LEVELS);
- if (DBG) log("RSSI change old: " + mCurrentSignalLevel + "new: " + signalLevel);
- mCurrentSignalLevel = signalLevel;
-
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
handleRssiChange();
break;
case CMD_ARP_CHECK:
@@ -680,11 +729,11 @@ public class WifiWatchdogStateMachine extends StateMachine {
private void handleRssiChange() {
if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
- if (DBG) log("Transition out, below cut off level: " + mCurrentSignalLevel);
- mWsmChannel.sendMessage(POOR_LINK_DETECTED);
+ sendPoorLinkDetected();
} else if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
- if (DBG) log("Start monitoring, level: " + mCurrentSignalLevel);
- sendMessage(obtainMessage(CMD_ARP_CHECK, ++mArpToken, 0));
+ transitionTo(mRssiMonitoringState);
+ } else {
+ //stay here
}
}
@@ -692,43 +741,82 @@ public class WifiWatchdogStateMachine extends StateMachine {
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_RSSI_CHANGE:
- int signalLevel = WifiManager.calculateSignalLevel(msg.arg1,
- WifiManager.RSSI_LEVELS);
- if (DBG) log("RSSI change old: " + mCurrentSignalLevel + "new: " + signalLevel);
- mCurrentSignalLevel = signalLevel;
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
+ //Ready to avoid bssid again ?
+ long time = android.os.SystemClock.elapsedRealtime();
+ if (time - mLastBssidAvoidedTime > MIN_INTERVAL_AVOID_BSSID_MS) {
+ handleRssiChange();
+ } else {
+ if (DBG) log("Early to avoid " + mWifiInfo + " time: " + time +
+ " last avoided: " + mLastBssidAvoidedTime);
+ }
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+ }
- handleRssiChange();
+ class RssiMonitoringState extends State {
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ sendMessage(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0));
+ }
+ public boolean processMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_RSSI_CHANGE:
+ mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
+ if (mCurrentSignalLevel <= RSSI_LEVEL_CUTOFF) {
+ sendPoorLinkDetected();
+ } else if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
+ //stay here;
+ } else {
+ //We dont need frequent RSSI monitoring any more
+ transitionTo(mOnlineWatchState);
+ }
break;
- case CMD_ARP_CHECK:
- if (msg.arg1 == mArpToken) {
- if (doArpTest(SINGLE_ARP_CHECK) != true) {
- if (DBG) log("single ARP fail, full ARP check");
- //do a full test
- if (doArpTest(FULL_ARP_CHECK) != true) {
- if (DBG) log("notify full ARP fail, level: " + mCurrentSignalLevel);
- mWsmChannel.sendMessage(POOR_LINK_DETECTED);
- }
- }
+ case CMD_RSSI_FETCH:
+ if (msg.arg1 == mRssiFetchToken) {
+ mWsmChannel.sendMessage(RSSI_FETCH);
+ sendMessageDelayed(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0),
+ mRssiFetchIntervalMs);
+ }
+ break;
+ case RSSI_FETCH_SUCCEEDED:
+ int rssi = msg.arg1;
+ if (DBG) log("RSSI_FETCH_SUCCEEDED: " + rssi);
+ if (msg.arg1 < RSSI_MONITOR_THRESHOLD) {
+ mRssiMonitorCount++;
+ } else {
+ mRssiMonitorCount = 0;
+ }
- if (mCurrentSignalLevel <= RSSI_LEVEL_MONITOR) {
- if (DBG) log("Continue ARP check, rssi level: " + mCurrentSignalLevel);
- sendMessageDelayed(obtainMessage(CMD_ARP_CHECK, ++mArpToken, 0),
- mArpCheckIntervalMs);
- }
+ if (mRssiMonitorCount > RSSI_MONITOR_COUNT) {
+ sendPoorLinkDetected();
+ ++mRssiFetchToken;
}
break;
+ case RSSI_FETCH_FAILED:
+ //can happen if we are waiting to get a disconnect notification
+ if (DBG) log("RSSI_FETCH_FAILED");
+ break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
- }
+ }
/* Child state of ConnectedState indicating that we are online
* and there is nothing to do
*/
class OnlineState extends State {
+ @Override
+ public void enter() {
+ if (DBG) log(getName() + "\n");
+ }
}
private boolean shouldCheckWalledGarden() {
@@ -794,6 +882,20 @@ public class WifiWatchdogStateMachine extends StateMachine {
return success;
}
+ private int calculateSignalLevel(int rssi) {
+ int signalLevel = WifiManager.calculateSignalLevel(rssi,
+ WifiManager.RSSI_LEVELS);
+ if (DBG) log("RSSI current: " + mCurrentSignalLevel + "new: " + rssi + ", " + signalLevel);
+ return signalLevel;
+ }
+
+ private void sendPoorLinkDetected() {
+ if (DBG) log("send POOR_LINK_DETECTED " + mWifiInfo);
+ mWsmChannel.sendMessage(POOR_LINK_DETECTED);
+ mLastAvoidedBssid = mWifiInfo.getBSSID();
+ mLastBssidAvoidedTime = android.os.SystemClock.elapsedRealtime();
+ }
+
/**
* Convenience function for retrieving a single secure settings value
* as a string with a default value.
@@ -844,11 +946,11 @@ public class WifiWatchdogStateMachine extends StateMachine {
return Settings.Secure.putInt(cr, name, value ? 1 : 0);
}
- private void log(String s) {
+ private static void log(String s) {
Log.d(TAG, s);
}
- private void loge(String s) {
+ private static void loge(String s) {
Log.e(TAG, s);
}
}