Loading core/jni/android_view_RenderNode.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -507,15 +507,15 @@ jmethodID gPositionListener_PositionChangedMethod; jmethodID gPositionListener_PositionLostMethod; static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, jlong renderNodePtr, jobject surfaceview) { class SurfaceViewPositionUpdater : public RenderNode::PositionListener { jlong renderNodePtr, jobject listener) { class PositionListenerTrampoline : public RenderNode::PositionListener { public: SurfaceViewPositionUpdater(JNIEnv* env, jobject surfaceview) { PositionListenerTrampoline(JNIEnv* env, jobject listener) { env->GetJavaVM(&mVm); mWeakRef = env->NewWeakGlobalRef(surfaceview); mWeakRef = env->NewWeakGlobalRef(listener); } virtual ~SurfaceViewPositionUpdater() { virtual ~PositionListenerTrampoline() { jnienv()->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; } Loading @@ -539,9 +539,14 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, bounds.roundOut(); } if (mPreviousPosition == bounds) { return; } mPreviousPosition = bounds; incStrong(0); auto functor = std::bind( std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePositionAsync), this, std::mem_fn(&PositionListenerTrampoline::doUpdatePositionAsync), this, (jlong) info.canvasContext.getFrameNumber(), (jint) bounds.left, (jint) bounds.top, (jint) bounds.right, (jint) bounds.bottom); Loading @@ -552,6 +557,11 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override { if (CC_UNLIKELY(!mWeakRef || (info && !info->updateWindowPositions))) return; if (mPreviousPosition.isEmpty()) { return; } mPreviousPosition.setEmpty(); ATRACE_NAME("SurfaceView position lost"); JNIEnv* env = jnienv(); jobject localref = env->NewLocalRef(mWeakRef); Loading @@ -561,6 +571,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, return; } // TODO: Remember why this is synchronous and then make a comment env->CallVoidMethod(localref, gPositionListener_PositionLostMethod, info ? info->canvasContext.getFrameNumber() : 0); env->DeleteLocalRef(localref); Loading Loading @@ -596,10 +607,11 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, JavaVM* mVm; jobject mWeakRef; uirenderer::Rect mPreviousPosition; }; RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); renderNode->setPositionListener(new SurfaceViewPositionUpdater(env, surfaceview)); renderNode->setPositionListener(new PositionListenerTrampoline(env, listener)); } // ---------------------------------------------------------------------------- Loading tests/HwAccelerationTest/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -1027,5 +1027,15 @@ </intent-filter> </activity> <activity android:name="PositionListenerActivity" android:label="RenderNode/PositionListener" android:screenOrientation="fullSensor"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.hwui.TEST" /> </intent-filter> </activity> </application> </manifest> tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * 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.test.hwui; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.RenderNode; import android.os.Bundle; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.ScrollView; import android.widget.TextView; @SuppressWarnings({"UnusedDeclaration"}) public class PositionListenerActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); ProgressBar spinner = new ProgressBar(this, null, android.R.attr.progressBarStyleLarge); layout.addView(spinner); ScrollView scrollingThing = new ScrollView(this); scrollingThing.addView(new MyPositionReporter(this)); layout.addView(scrollingThing); setContentView(layout); } static class MyPositionReporter extends TextView implements RenderNode.PositionUpdateListener { RenderNode mNode; int mCurrentCount = 0; int mTranslateY = 0; MyPositionReporter(Context c) { super(c); mNode = new RenderNode("positionListener"); mNode.requestPositionUpdates(this); setTextAlignment(TEXT_ALIGNMENT_VIEW_START); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(getMeasuredWidth(), 10000); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { mNode.setLeftTopRightBottom(left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { ScrollView parent = (ScrollView) getParent(); canvas.translate(0, parent.getScrollY()); super.onDraw(canvas); canvas.translate(0, -parent.getScrollY()); // Inject our listener proxy canvas.drawRenderNode(mNode); } @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { post(() -> { mCurrentCount++; setText(String.format("%d: Position [%d, %d, %d, %d]", mCurrentCount, left, top, right, bottom)); }); } @Override public void positionLost(long frameNumber) { post(() -> { mCurrentCount++; setText(mCurrentCount + " No position"); }); } } } Loading
core/jni/android_view_RenderNode.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -507,15 +507,15 @@ jmethodID gPositionListener_PositionChangedMethod; jmethodID gPositionListener_PositionLostMethod; static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, jlong renderNodePtr, jobject surfaceview) { class SurfaceViewPositionUpdater : public RenderNode::PositionListener { jlong renderNodePtr, jobject listener) { class PositionListenerTrampoline : public RenderNode::PositionListener { public: SurfaceViewPositionUpdater(JNIEnv* env, jobject surfaceview) { PositionListenerTrampoline(JNIEnv* env, jobject listener) { env->GetJavaVM(&mVm); mWeakRef = env->NewWeakGlobalRef(surfaceview); mWeakRef = env->NewWeakGlobalRef(listener); } virtual ~SurfaceViewPositionUpdater() { virtual ~PositionListenerTrampoline() { jnienv()->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; } Loading @@ -539,9 +539,14 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, bounds.roundOut(); } if (mPreviousPosition == bounds) { return; } mPreviousPosition = bounds; incStrong(0); auto functor = std::bind( std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePositionAsync), this, std::mem_fn(&PositionListenerTrampoline::doUpdatePositionAsync), this, (jlong) info.canvasContext.getFrameNumber(), (jint) bounds.left, (jint) bounds.top, (jint) bounds.right, (jint) bounds.bottom); Loading @@ -552,6 +557,11 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override { if (CC_UNLIKELY(!mWeakRef || (info && !info->updateWindowPositions))) return; if (mPreviousPosition.isEmpty()) { return; } mPreviousPosition.setEmpty(); ATRACE_NAME("SurfaceView position lost"); JNIEnv* env = jnienv(); jobject localref = env->NewLocalRef(mWeakRef); Loading @@ -561,6 +571,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, return; } // TODO: Remember why this is synchronous and then make a comment env->CallVoidMethod(localref, gPositionListener_PositionLostMethod, info ? info->canvasContext.getFrameNumber() : 0); env->DeleteLocalRef(localref); Loading Loading @@ -596,10 +607,11 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, JavaVM* mVm; jobject mWeakRef; uirenderer::Rect mPreviousPosition; }; RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); renderNode->setPositionListener(new SurfaceViewPositionUpdater(env, surfaceview)); renderNode->setPositionListener(new PositionListenerTrampoline(env, listener)); } // ---------------------------------------------------------------------------- Loading
tests/HwAccelerationTest/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -1027,5 +1027,15 @@ </intent-filter> </activity> <activity android:name="PositionListenerActivity" android:label="RenderNode/PositionListener" android:screenOrientation="fullSensor"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="com.android.test.hwui.TEST" /> </intent-filter> </activity> </application> </manifest>
tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * 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.test.hwui; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.RenderNode; import android.os.Bundle; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.ScrollView; import android.widget.TextView; @SuppressWarnings({"UnusedDeclaration"}) public class PositionListenerActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); ProgressBar spinner = new ProgressBar(this, null, android.R.attr.progressBarStyleLarge); layout.addView(spinner); ScrollView scrollingThing = new ScrollView(this); scrollingThing.addView(new MyPositionReporter(this)); layout.addView(scrollingThing); setContentView(layout); } static class MyPositionReporter extends TextView implements RenderNode.PositionUpdateListener { RenderNode mNode; int mCurrentCount = 0; int mTranslateY = 0; MyPositionReporter(Context c) { super(c); mNode = new RenderNode("positionListener"); mNode.requestPositionUpdates(this); setTextAlignment(TEXT_ALIGNMENT_VIEW_START); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(getMeasuredWidth(), 10000); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { mNode.setLeftTopRightBottom(left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { ScrollView parent = (ScrollView) getParent(); canvas.translate(0, parent.getScrollY()); super.onDraw(canvas); canvas.translate(0, -parent.getScrollY()); // Inject our listener proxy canvas.drawRenderNode(mNode); } @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { post(() -> { mCurrentCount++; setText(String.format("%d: Position [%d, %d, %d, %d]", mCurrentCount, left, top, right, bottom)); }); } @Override public void positionLost(long frameNumber) { post(() -> { mCurrentCount++; setText(mCurrentCount + " No position"); }); } } }