Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

catch oom exception and so on #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import java.util.concurrent.CountDownLatch
import javax.microedition.khronos.egl.EGL10
import javax.microedition.khronos.egl.EGLContext
import javax.microedition.khronos.opengles.GL10
import kotlin.collections.ArrayList

/**
* Created by tarek on 5/17/16.
Expand Down Expand Up @@ -56,6 +57,10 @@ object ScreenshotTaker {
bitmap = Bitmap.createBitmap(main.width, main.height, Bitmap.Config.ARGB_8888)
} catch (e: IllegalArgumentException) {
return null
} catch (e: OutOfMemoryError) {
return null
} catch (t: Throwable) {
return null
}

drawRootsToBitmap(viewRoots, bitmap, ignoredViews)
Expand All @@ -74,150 +79,164 @@ object ScreenshotTaker {

private fun drawRootToBitmap(rootViewInfo: RootViewInfo, bitmap: Bitmap,
ignoredViews: Array<out View>?) {
try {
// support dim screen
if (rootViewInfo.layoutParams!!.flags and WindowManager.LayoutParams.FLAG_DIM_BEHIND
== WindowManager.LayoutParams.FLAG_DIM_BEHIND) {
val dimCanvas = Canvas(bitmap)

// support dim screen
if (rootViewInfo.layoutParams!!.flags and WindowManager.LayoutParams.FLAG_DIM_BEHIND
== WindowManager.LayoutParams.FLAG_DIM_BEHIND) {
val dimCanvas = Canvas(bitmap)
val alpha = (255 * rootViewInfo.layoutParams.dimAmount).toInt()
dimCanvas.drawARGB(alpha, 0, 0, 0)
}

val alpha = (255 * rootViewInfo.layoutParams.dimAmount).toInt()
dimCanvas.drawARGB(alpha, 0, 0, 0)
}
val canvas = Canvas(bitmap)
canvas.translate(rootViewInfo.left.toFloat(), rootViewInfo.top.toFloat())

val canvas = Canvas(bitmap)
canvas.translate(rootViewInfo.left.toFloat(), rootViewInfo.top.toFloat())
if (ignoredViews != null) {

if (ignoredViews != null) {
val ignoredViewsVisibility = IntArray(ignoredViews.size)

val ignoredViewsVisibility = IntArray(ignoredViews.size)
for (i in ignoredViews.indices) {
ignoredViewsVisibility[i] = ignoredViews[i].visibility
ignoredViews[i].visibility = View.INVISIBLE
}

for (i in ignoredViews.indices) {
ignoredViewsVisibility[i] = ignoredViews[i].visibility
ignoredViews[i].visibility = View.INVISIBLE
}
rootViewInfo.view.draw(canvas)
//Draw undrawable views
drawUnDrawableViews(rootViewInfo.view, canvas)

rootViewInfo.view.draw(canvas)
//Draw undrawable views
drawUnDrawableViews(rootViewInfo.view, canvas)
for (i in ignoredViews.indices) {
ignoredViews[i].visibility = ignoredViewsVisibility[i]

for (i in ignoredViews.indices) {
ignoredViews[i].visibility = ignoredViewsVisibility[i]
}

}

} catch (t: Throwable) {
t.printStackTrace()
}
}

private fun drawUnDrawableViews(v: View, canvas: Canvas): ArrayList<View> {
try {
if (v !is ViewGroup) {
val viewArrayList = ArrayList<View>()
viewArrayList.add(v)
return viewArrayList
}

if (v !is ViewGroup) {
val viewArrayList = ArrayList<View>()
viewArrayList.add(v)
return viewArrayList
}
val result = ArrayList<View>()

val result = ArrayList<View>()
val viewGroup = v
for (i in 0 until viewGroup.childCount) {

val viewGroup = v
for (i in 0 until viewGroup.childCount) {
val child = viewGroup.getChildAt(i)

val child = viewGroup.getChildAt(i)
val viewArrayList = ArrayList<View>()
viewArrayList.add(v)
viewArrayList.addAll(drawUnDrawableViews(child, canvas))

val viewArrayList = ArrayList<View>()
viewArrayList.add(v)
viewArrayList.addAll(drawUnDrawableViews(child, canvas))
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && child is TextureView) {
drawTextureView(child, canvas)
}

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && child is TextureView) {
drawTextureView(child, canvas)
}
if (child is GLSurfaceView) {
drawGLSurfaceView(child, canvas)
}

if (child is GLSurfaceView) {
drawGLSurfaceView(child, canvas)
result.addAll(viewArrayList)
}

result.addAll(viewArrayList)
return result
} catch (t: Throwable) {
t.printStackTrace()
}
return result
return ArrayList()
}

private fun drawGLSurfaceView(surfaceView: GLSurfaceView, canvas: Canvas) {
Logger.d("Drawing GLSurfaceView")

if (surfaceView.windowToken != null) {
val location = IntArray(2)

surfaceView.getLocationOnScreen(location)
val width = surfaceView.width
val height = surfaceView.height

val x = 0
val y = 0
val b = IntArray(width * (y + height))

val ib = IntBuffer.wrap(b)
ib.position(0)

//To wait for the async call to finish before going forward
val countDownLatch = CountDownLatch(1)
surfaceView.queueEvent {
val egl = EGLContext.getEGL() as EGL10
egl.eglWaitGL()
val gl = egl.eglGetCurrentContext().gl as GL10

gl.glFinish()
try {
Logger.d("Drawing GLSurfaceView")
if (surfaceView.windowToken != null) {
val location = IntArray(2)

surfaceView.getLocationOnScreen(location)
val width = surfaceView.width
val height = surfaceView.height

val x = 0
val y = 0
val b = IntArray(width * (y + height))

val ib = IntBuffer.wrap(b)
ib.position(0)

//To wait for the async call to finish before going forward
val countDownLatch = CountDownLatch(1)
surfaceView.queueEvent {
val egl = EGLContext.getEGL() as EGL10
egl.eglWaitGL()
val gl = egl.eglGetCurrentContext().gl as GL10

gl.glFinish()

try {
Thread.sleep(200)
} catch (e: InterruptedException) {
e.printStackTrace()
}

gl.glReadPixels(x, 0, width, y + height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib)
countDownLatch.countDown()
}

try {
Thread.sleep(200)
countDownLatch.await()
} catch (e: InterruptedException) {
e.printStackTrace()
}

gl.glReadPixels(x, 0, width, y + height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib)
countDownLatch.countDown()
}

try {
countDownLatch.await()
} catch (e: InterruptedException) {
e.printStackTrace()
}

val bt = IntArray(width * height)
var i = 0
var k = 0
while (i < height) {
for (j in 0 until width) {
val pix = b[i * width + j]
val pb = pix shr 16 and 0xFF
val pr = pix shl 16 and 0xFF0000
val pix1 = pix and 0xFF00FF00.toInt() or pr or pb
bt[(height - k - 1) * width + j] = pix1
val bt = IntArray(width * height)
var i = 0
var k = 0
while (i < height) {
for (j in 0 until width) {
val pix = b[i * width + j]
val pb = pix shr 16 and 0xFF
val pr = pix shl 16 and 0xFF0000
val pix1 = pix and 0xFF00FF00.toInt() or pr or pb
bt[(height - k - 1) * width + j] = pix1
}
i++
k++
}
i++
k++
}

val sb = Bitmap.createBitmap(bt, width, height, Bitmap.Config.ARGB_8888)
val paint = Paint()
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)
canvas.drawBitmap(sb, location[0].toFloat(), location[1].toFloat(), paint)
sb.recycle()
val sb = Bitmap.createBitmap(bt, width, height, Bitmap.Config.ARGB_8888)
val paint = Paint()
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)
canvas.drawBitmap(sb, location[0].toFloat(), location[1].toFloat(), paint)
sb.recycle()
}
} catch (t: Throwable) {
t.printStackTrace()
}
}

@RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private fun drawTextureView(textureView: TextureView, canvas: Canvas) {
Logger.d("Drawing TextureView")

val textureViewLocation = IntArray(2)
textureView.getLocationOnScreen(textureViewLocation)
val textureViewBitmap = textureView.bitmap
if (textureViewBitmap != null) {
val paint = Paint()
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)
canvas.drawBitmap(textureViewBitmap, textureViewLocation[0].toFloat(), textureViewLocation[1].toFloat(), paint)
textureViewBitmap.recycle()
try {
Logger.d("Drawing TextureView")
val textureViewLocation = IntArray(2)
textureView.getLocationOnScreen(textureViewLocation)
val textureViewBitmap = textureView.bitmap
if (textureViewBitmap != null) {
val paint = Paint()
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)
canvas.drawBitmap(textureViewBitmap, textureViewLocation[0].toFloat(), textureViewLocation[1].toFloat(), paint)
textureViewBitmap.recycle()
}
} catch (t: Throwable) {
t.printStackTrace()
}
}

}