summaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2014-12-16 22:56:46 +0900
committerTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2014-12-17 19:03:21 +0900
commit33e53de6ca2253ebfc1bc0501ab992cb915e16df (patch)
treef69ae7b8ad6ca34875a906dd709233ffa8210562 /android
parentRevert "reportbuilder: re-add numerous bits of dead code needed by bug fix" (diff)
downloadcore-33e53de6ca2253ebfc1bc0501ab992cb915e16df.tar.gz
core-33e53de6ca2253ebfc1bc0501ab992cb915e16df.zip
android: remove old and unused LOAndroid and LOAndroid2
Change-Id: Ib25c4bb29081ae51a3b06a6fe2af76749ec8ea46
Diffstat (limited to 'android')
-rw-r--r--android/experimental/LOAndroid/.gitignore4
-rw-r--r--android/experimental/LOAndroid/.idea/.name1
-rw-r--r--android/experimental/LOAndroid/.idea/compiler.xml23
-rw-r--r--android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml3
-rw-r--r--android/experimental/LOAndroid/.idea/encodings.xml5
-rw-r--r--android/experimental/LOAndroid/.idea/gradle.xml18
-rw-r--r--android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml10
-rw-r--r--android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml11
-rw-r--r--android/experimental/LOAndroid/.idea/misc.xml146
-rw-r--r--android/experimental/LOAndroid/.idea/modules.xml10
-rw-r--r--android/experimental/LOAndroid/.idea/scopes/scope_settings.xml5
-rw-r--r--android/experimental/LOAndroid/.idea/vcs.xml7
-rw-r--r--android/experimental/LOAndroid/LOAndroid.iml12
-rw-r--r--android/experimental/LOAndroid/app/.gitignore1
-rw-r--r--android/experimental/LOAndroid/app/app.iml77
-rw-r--r--android/experimental/LOAndroid/app/build.gradle24
-rw-r--r--android/experimental/LOAndroid/app/proguard-rules.txt17
-rw-r--r--android/experimental/LOAndroid/app/src/main/AndroidManifest.xml25
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java22
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java36
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java26
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java14
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java46
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java420
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java368
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java69
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java35
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java28
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java51
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java777
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java78
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java95
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java54
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java354
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java1000
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java374
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java22
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java91
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java1461
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java207
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java324
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java722
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java692
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java21
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java130
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java49
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java33
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java123
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java51
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java33
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java126
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java80
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java297
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java322
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java153
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java148
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java69
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java75
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java51
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java177
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java306
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java34
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java36
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java51
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java115
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java43
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java55
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java14
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java16
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java169
-rw-r--r--android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java86
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.pngbin9397 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.pngbin1864 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.pngbin5237 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.pngbin1533 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.pngbin14383 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.pngbin2049 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.pngbin19388 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml15
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/menu/main.xml9
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml6
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/values/colors.xml95
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/values/dimens.xml5
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/values/strings.xml8
-rw-r--r--android/experimental/LOAndroid/app/src/main/res/values/styles.xml8
-rw-r--r--android/experimental/LOAndroid/build.gradle16
-rw-r--r--android/experimental/LOAndroid/gradle.properties18
-rw-r--r--android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jarbin49896 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties6
-rw-r--r--android/experimental/LOAndroid/gradlew164
-rw-r--r--android/experimental/LOAndroid/gradlew.bat90
-rw-r--r--android/experimental/LOAndroid/settings.gradle1
-rw-r--r--android/experimental/LOAndroid2/.gitignore4
-rw-r--r--android/experimental/LOAndroid2/.idea/.name1
-rw-r--r--android/experimental/LOAndroid2/.idea/compiler.xml23
-rw-r--r--android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml3
-rw-r--r--android/experimental/LOAndroid2/.idea/encodings.xml5
-rw-r--r--android/experimental/LOAndroid2/.idea/gradle.xml18
-rw-r--r--android/experimental/LOAndroid2/.idea/misc.xml41
-rw-r--r--android/experimental/LOAndroid2/.idea/modules.xml11
-rw-r--r--android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml5
-rw-r--r--android/experimental/LOAndroid2/.idea/vcs.xml7
-rw-r--r--android/experimental/LOAndroid2/LOAndroid2.iml19
-rw-r--r--android/experimental/LOAndroid2/app/.gitignore1
-rw-r--r--android/experimental/LOAndroid2/app/app.iml66
-rw-r--r--android/experimental/LOAndroid2/app/build.gradle23
-rw-r--r--android/experimental/LOAndroid2/app/proguard-rules.txt17
-rw-r--r--android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml24
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java67
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java131
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java157
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java102
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java44
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java105
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java72
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java58
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java85
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java170
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java218
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java99
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java279
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java181
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java398
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java242
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java15
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java103
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java242
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java81
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java534
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java689
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java230
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java250
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java124
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java125
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java96
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java139
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java425
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java127
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java15
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java117
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java73
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java76
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java256
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java51
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java306
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java80
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java160
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java271
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java921
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java332
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java140
-rw-r--r--android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java43
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.pngbin20684 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.pngbin20697 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.pngbin22661 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.pngbin27485 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.pngbin293 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.pngbin28043 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.pngbin33266 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.pngbin293 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.pngbin9942 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.pngbin11499 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.pngbin213 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.pngbin18445 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.pngbin77517 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.pngbin9397 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.pngbin1864 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.pngbin13936 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.pngbin4475 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.pngbin4380 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.pngbin15370 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.pngbin4380 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.pngbin18308 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.pngbin20684 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.pngbin20697 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.pngbin203346 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.pngbin18445 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.pngbin5237 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.pngbin1533 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.pngbin13936 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.pngbin3255 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.pngbin881 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.pngbin19535 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.pngbin20684 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.pngbin20697 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.pngbin18445 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.pngbin14383 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.pngbin2049 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.pngbin13936 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.pngbin19535 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.pngbin19388 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml15
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/menu/main.xml8
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml6
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/values/colors.xml95
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml5
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/values/strings.xml8
-rw-r--r--android/experimental/LOAndroid2/app/src/main/res/values/styles.xml8
-rw-r--r--android/experimental/LOAndroid2/build.gradle16
-rw-r--r--android/experimental/LOAndroid2/gradle.properties18
-rw-r--r--android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jarbin49896 -> 0 bytes
-rw-r--r--android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xandroid/experimental/LOAndroid2/gradlew164
-rw-r--r--android/experimental/LOAndroid2/gradlew.bat90
-rw-r--r--android/experimental/LOAndroid2/settings.gradle1
205 files changed, 0 insertions, 20206 deletions
diff --git a/android/experimental/LOAndroid/.gitignore b/android/experimental/LOAndroid/.gitignore
deleted file mode 100644
index d6bfc95b184b..000000000000
--- a/android/experimental/LOAndroid/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.gradle
-/local.properties
-/.idea/workspace.xml
-.DS_Store
diff --git a/android/experimental/LOAndroid/.idea/.name b/android/experimental/LOAndroid/.idea/.name
deleted file mode 100644
index 3300c569c980..000000000000
--- a/android/experimental/LOAndroid/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-LOAndroid \ No newline at end of file
diff --git a/android/experimental/LOAndroid/.idea/compiler.xml b/android/experimental/LOAndroid/.idea/compiler.xml
deleted file mode 100644
index 217af471a9e6..000000000000
--- a/android/experimental/LOAndroid/.idea/compiler.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="CompilerConfiguration">
- <option name="DEFAULT_COMPILER" value="Javac" />
- <resourceExtensions />
- <wildcardResourcePatterns>
- <entry name="!?*.java" />
- <entry name="!?*.form" />
- <entry name="!?*.class" />
- <entry name="!?*.groovy" />
- <entry name="!?*.scala" />
- <entry name="!?*.flex" />
- <entry name="!?*.kt" />
- <entry name="!?*.clj" />
- </wildcardResourcePatterns>
- <annotationProcessing>
- <profile default="true" name="Default" enabled="false">
- <processorPath useClasspath="true" />
- </profile>
- </annotationProcessing>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml b/android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3377d4..000000000000
--- a/android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<component name="CopyrightManager">
- <settings default="" />
-</component> \ No newline at end of file
diff --git a/android/experimental/LOAndroid/.idea/encodings.xml b/android/experimental/LOAndroid/.idea/encodings.xml
deleted file mode 100644
index e206d70d8595..000000000000
--- a/android/experimental/LOAndroid/.idea/encodings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
-</project>
-
diff --git a/android/experimental/LOAndroid/.idea/gradle.xml b/android/experimental/LOAndroid/.idea/gradle.xml
deleted file mode 100644
index 736c7b5cffcc..000000000000
--- a/android/experimental/LOAndroid/.idea/gradle.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="GradleSettings">
- <option name="linkedExternalProjectsSettings">
- <GradleProjectSettings>
- <option name="distributionType" value="DEFAULT_WRAPPED" />
- <option name="externalProjectPath" value="$PROJECT_DIR$" />
- <option name="modules">
- <set>
- <option value="$PROJECT_DIR$" />
- <option value="$PROJECT_DIR$/app" />
- </set>
- </option>
- </GradleProjectSettings>
- </option>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml b/android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml
deleted file mode 100644
index 970e5fa480a9..000000000000
--- a/android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<component name="libraryTable">
- <library name="appcompat-v7-19.1.0">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/app/build/exploded-aar/com.android.support/appcompat-v7/19.1.0/classes.jar!/" />
- <root url="file://$PROJECT_DIR$/app/build/exploded-aar/com.android.support/appcompat-v7/19.1.0/res" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
-</component> \ No newline at end of file
diff --git a/android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml b/android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml
deleted file mode 100644
index 1ca1ac68ad96..000000000000
--- a/android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
- <library name="support-v4-19.1.0">
- <CLASSES>
- <root url="jar://$USER_HOME$/Programs/android-sdk-linux/extras/android/m2repository/com/android/support/support-v4/19.1.0/support-v4-19.1.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$USER_HOME$/Programs/android-sdk-linux/extras/android/m2repository/com/android/support/support-v4/19.1.0/support-v4-19.1.0-sources.jar!/" />
- </SOURCES>
- </library>
-</component> \ No newline at end of file
diff --git a/android/experimental/LOAndroid/.idea/misc.xml b/android/experimental/LOAndroid/.idea/misc.xml
deleted file mode 100644
index 589a3ed5fd78..000000000000
--- a/android/experimental/LOAndroid/.idea/misc.xml
+++ /dev/null
@@ -1,146 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="DaemonCodeAnalyzer">
- <disable_hints />
- </component>
- <component name="EntryPointsManager">
- <entry_points version="2.0" />
- </component>
- <component name="ProjectInspectionProfilesVisibleTreeState">
- <entry key="Project Default">
- <profile-state>
- <expanded-state>
- <State>
- <id />
- </State>
- </expanded-state>
- <selected-state>
- <State>
- <id>Abstraction issues</id>
- </State>
- </selected-state>
- </profile-state>
- </entry>
- </component>
- <component name="ProjectLevelVcsManager" settingsEditedManually="false">
- <OptionsSetting value="true" id="Add" />
- <OptionsSetting value="true" id="Remove" />
- <OptionsSetting value="true" id="Checkout" />
- <OptionsSetting value="true" id="Update" />
- <OptionsSetting value="true" id="Status" />
- <OptionsSetting value="true" id="Edit" />
- <ConfirmationsSetting value="0" id="Add" />
- <ConfirmationsSetting value="0" id="Remove" />
- </component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/build/classes" />
- </component>
- <component name="RunManager">
- <configuration default="true" type="Remote" factoryName="Remote">
- <option name="USE_SOCKET_TRANSPORT" value="true" />
- <option name="SERVER_MODE" value="false" />
- <option name="SHMEM_ADDRESS" value="javadebug" />
- <option name="HOST" value="localhost" />
- <option name="PORT" value="5005" />
- <method />
- </configuration>
- <configuration default="true" type="TestNG" factoryName="TestNG">
- <module name="" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="SUITE_NAME" />
- <option name="PACKAGE_NAME" />
- <option name="MAIN_CLASS_NAME" />
- <option name="METHOD_NAME" />
- <option name="GROUP_NAME" />
- <option name="TEST_OBJECT" value="CLASS" />
- <option name="VM_PARAMETERS" value="-ea" />
- <option name="PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="OUTPUT_DIRECTORY" />
- <option name="ANNOTATION_TYPE" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <option name="TEST_SEARCH_SCOPE">
- <value defaultName="moduleWithDependencies" />
- </option>
- <option name="USE_DEFAULT_REPORTERS" value="false" />
- <option name="PROPERTIES_FILE" />
- <envs />
- <properties />
- <listeners />
- <method />
- </configuration>
- <configuration default="true" type="Applet" factoryName="Applet">
- <module name="" />
- <option name="MAIN_CLASS_NAME" />
- <option name="HTML_FILE_NAME" />
- <option name="HTML_USED" value="false" />
- <option name="WIDTH" value="400" />
- <option name="HEIGHT" value="300" />
- <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
- <option name="VM_PARAMETERS" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <method />
- </configuration>
- <configuration default="true" type="Application" factoryName="Application">
- <option name="MAIN_CLASS_NAME" />
- <option name="VM_PARAMETERS" />
- <option name="PROGRAM_PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="" />
- <envs />
- <method />
- </configuration>
- <configuration default="true" type="JUnit" factoryName="JUnit">
- <module name="" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="PACKAGE_NAME" />
- <option name="MAIN_CLASS_NAME" />
- <option name="METHOD_NAME" />
- <option name="TEST_OBJECT" value="class" />
- <option name="VM_PARAMETERS" value="-ea" />
- <option name="PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <option name="TEST_SEARCH_SCOPE">
- <value defaultName="moduleWithDependencies" />
- </option>
- <envs />
- <patterns />
- <method />
- </configuration>
- <list size="0" />
- <configuration name="&lt;template&gt;" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
- <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
- </configuration>
- <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
- <Host>localhost</Host>
- <Port>5050</Port>
- </configuration>
- </component>
- <component name="masterDetails">
- <states>
- <state key="ScopeChooserConfigurable.UI">
- <settings>
- <splitter-proportions>
- <option name="proportions">
- <list>
- <option value="0.2" />
- </list>
- </option>
- </splitter-proportions>
- </settings>
- </state>
- </states>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid/.idea/modules.xml b/android/experimental/LOAndroid/.idea/modules.xml
deleted file mode 100644
index f08135d5d6bf..000000000000
--- a/android/experimental/LOAndroid/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="ProjectModuleManager">
- <modules>
- <module fileurl="file://$PROJECT_DIR$/LOAndroid.iml" filepath="$PROJECT_DIR$/LOAndroid.iml" />
- <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
- </modules>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid/.idea/scopes/scope_settings.xml b/android/experimental/LOAndroid/.idea/scopes/scope_settings.xml
deleted file mode 100644
index 922003b8433b..000000000000
--- a/android/experimental/LOAndroid/.idea/scopes/scope_settings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<component name="DependencyValidationManager">
- <state>
- <option name="SKIP_IMPORT_STATEMENTS" value="false" />
- </state>
-</component> \ No newline at end of file
diff --git a/android/experimental/LOAndroid/.idea/vcs.xml b/android/experimental/LOAndroid/.idea/vcs.xml
deleted file mode 100644
index def6a6a18457..000000000000
--- a/android/experimental/LOAndroid/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="VcsDirectoryMappings">
- <mapping directory="" vcs="" />
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid/LOAndroid.iml b/android/experimental/LOAndroid/LOAndroid.iml
deleted file mode 100644
index edb62a65fa47..000000000000
--- a/android/experimental/LOAndroid/LOAndroid.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module>
-
diff --git a/android/experimental/LOAndroid/app/.gitignore b/android/experimental/LOAndroid/app/.gitignore
deleted file mode 100644
index 796b96d1c402..000000000000
--- a/android/experimental/LOAndroid/app/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/android/experimental/LOAndroid/app/app.iml b/android/experimental/LOAndroid/app/app.iml
deleted file mode 100644
index d3a780b91527..000000000000
--- a/android/experimental/LOAndroid/app/app.iml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="LOAndroid" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
- <component name="FacetManager">
- <facet type="android-gradle" name="Android-Gradle">
- <configuration>
- <option name="GRADLE_PROJECT_PATH" value=":app" />
- </configuration>
- </facet>
- <facet type="android" name="Android">
- <configuration>
- <option name="SELECTED_BUILD_VARIANT" value="debug" />
- <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
- <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
- <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
- <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
- <option name="ALLOW_USER_CONFIGURATION" value="false" />
- <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
- <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
- <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
- <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
- </configuration>
- </facet>
- </component>
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build/classes/debug" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/build/source/r/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/res/rs/test/debug" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
- <excludeFolder url="file://$MODULE_DIR$/build/apk" />
- <excludeFolder url="file://$MODULE_DIR$/build/assets" />
- <excludeFolder url="file://$MODULE_DIR$/build/bundles" />
- <excludeFolder url="file://$MODULE_DIR$/build/classes" />
- <excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" />
- <excludeFolder url="file://$MODULE_DIR$/build/incremental" />
- <excludeFolder url="file://$MODULE_DIR$/build/libs" />
- <excludeFolder url="file://$MODULE_DIR$/build/manifests" />
- <excludeFolder url="file://$MODULE_DIR$/build/res" />
- <excludeFolder url="file://$MODULE_DIR$/build/symbols" />
- <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
- </content>
- <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" exported="" name="appcompat-v7-19.1.0" level="project" />
- <orderEntry type="library" exported="" name="support-v4-19.1.0" level="project" />
- </component>
-</module>
-
diff --git a/android/experimental/LOAndroid/app/build.gradle b/android/experimental/LOAndroid/app/build.gradle
deleted file mode 100644
index 7e98dd4c48c9..000000000000
--- a/android/experimental/LOAndroid/app/build.gradle
+++ /dev/null
@@ -1,24 +0,0 @@
-apply plugin: 'android'
-
-android {
- compileSdkVersion 19
- buildToolsVersion "19.1.0"
-
- defaultConfig {
- minSdkVersion 15
- targetSdkVersion 19
- versionCode 1
- versionName "1.0"
- }
- buildTypes {
- release {
- runProguard false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
- }
- }
-}
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile 'com.android.support:appcompat-v7:19.+'
-}
diff --git a/android/experimental/LOAndroid/app/proguard-rules.txt b/android/experimental/LOAndroid/app/proguard-rules.txt
deleted file mode 100644
index 0b0be289afc1..000000000000
--- a/android/experimental/LOAndroid/app/proguard-rules.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /home/quikee/Programs/android-sdk-linux/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#} \ No newline at end of file
diff --git a/android/experimental/LOAndroid/app/src/main/AndroidManifest.xml b/android/experimental/LOAndroid/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 3120a69b4247..000000000000
--- a/android/experimental/LOAndroid/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.libreoffice" >
-
- <!-- App requires OpenGL ES 2.0 -->
- <uses-feature android:glEsVersion="0x00020000" android:required="true" />
-
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:hardwareAccelerated="true"
- android:theme="@style/AppTheme" >
- <activity
- android:name="org.libreoffice.MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java
deleted file mode 100644
index cd429d66a2ad..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.libreoffice;
-
-
-import org.mozilla.gecko.gfx.LayerView;
-
-public class LOKitShell {
- public static int getDpi() {
- return 96;
- }
-
- public static int getScreenDepth() {
- return 24;
- }
-
- public static LayerView getLayerView() {
- return null;
- }
-
- public static float computeRenderIntegrity() {
- return 0.0f;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java b/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java
deleted file mode 100644
index 1963ad2c2b43..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.libreoffice;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-
-
-public class MainActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java b/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java
deleted file mode 100644
index 5721df2806b3..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.libreoffice;
-
-import android.content.Context;
-import android.os.Handler;
-import android.util.AttributeSet;
-
-import org.mozilla.gecko.gfx.LayerView;
-import org.mozilla.gecko.util.ThreadUtils;
-
-public class MainLayerView extends LayerView {
-
- public MainLayerView(Context context) {
- super(context);
- init(context);
- }
-
- public MainLayerView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- private void init(Context context) {
- ThreadUtils.setUiThread(Thread.currentThread(), new Handler());
- }
-
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java
deleted file mode 100644
index 41a71dfa5f88..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko;
-
-import android.view.MotionEvent;
-import android.view.View;
-
-public interface TouchEventInterceptor extends View.OnTouchListener {
- /** Override this method for a chance to consume events before the view or its children */
- public boolean onInterceptTouchEvent(View view, MotionEvent event);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java
deleted file mode 100644
index 40d1817c9301..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-public final class ZoomConstraints {
- private final boolean mAllowZoom;
- private final float mDefaultZoom;
- private final float mMinZoom;
- private final float mMaxZoom;
-
- public ZoomConstraints(boolean allowZoom) {
- mAllowZoom = allowZoom;
- mDefaultZoom = 0.0f;
- mMinZoom = 0.0f;
- mMaxZoom = 0.0f;
- }
-
- ZoomConstraints(JSONObject message) throws JSONException {
- mAllowZoom = message.getBoolean("allowZoom");
- mDefaultZoom = (float)message.getDouble("defaultZoom");
- mMinZoom = (float)message.getDouble("minZoom");
- mMaxZoom = (float)message.getDouble("maxZoom");
- }
-
- public final boolean getAllowZoom() {
- return mAllowZoom;
- }
-
- public final float getDefaultZoom() {
- return mDefaultZoom;
- }
-
- public final float getMinZoom() {
- return mMinZoom;
- }
-
- public final float getMaxZoom() {
- return mMaxZoom;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java
deleted file mode 100644
index 103ee5173539..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.PrefsHelper;
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.util.FloatUtils;
-
-import org.json.JSONArray;
-
-import android.util.Log;
-import android.view.View;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This class represents the physics for one axis of movement (i.e. either
- * horizontal or vertical). It tracks the different properties of movement
- * like displacement, velocity, viewport dimensions, etc. pertaining to
- * a particular axis.
- */
-abstract class Axis {
- private static final String LOGTAG = "GeckoAxis";
-
- private static final String PREF_SCROLLING_FRICTION_SLOW = "ui.scrolling.friction_slow";
- private static final String PREF_SCROLLING_FRICTION_FAST = "ui.scrolling.friction_fast";
- private static final String PREF_SCROLLING_MAX_EVENT_ACCELERATION = "ui.scrolling.max_event_acceleration";
- private static final String PREF_SCROLLING_OVERSCROLL_DECEL_RATE = "ui.scrolling.overscroll_decel_rate";
- private static final String PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT = "ui.scrolling.overscroll_snap_limit";
- private static final String PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE = "ui.scrolling.min_scrollable_distance";
-
- // This fraction of velocity remains after every animation frame when the velocity is low.
- private static float FRICTION_SLOW;
- // This fraction of velocity remains after every animation frame when the velocity is high.
- private static float FRICTION_FAST;
- // Below this velocity (in pixels per frame), the friction starts increasing from FRICTION_FAST
- // to FRICTION_SLOW.
- private static float VELOCITY_THRESHOLD;
- // The maximum velocity change factor between events, per ms, in %.
- // Direction changes are excluded.
- private static float MAX_EVENT_ACCELERATION;
-
- // The rate of deceleration when the surface has overscrolled.
- private static float OVERSCROLL_DECEL_RATE;
- // The percentage of the surface which can be overscrolled before it must snap back.
- private static float SNAP_LIMIT;
-
- // The minimum amount of space that must be present for an axis to be considered scrollable,
- // in pixels.
- private static float MIN_SCROLLABLE_DISTANCE;
-
- private static float getFloatPref(Map<String, Integer> prefs, String prefName, int defaultValue) {
- Integer value = (prefs == null ? null : prefs.get(prefName));
- return (float)(value == null || value < 0 ? defaultValue : value) / 1000f;
- }
-
- private static int getIntPref(Map<String, Integer> prefs, String prefName, int defaultValue) {
- Integer value = (prefs == null ? null : prefs.get(prefName));
- return (value == null || value < 0 ? defaultValue : value);
- }
-
- static void initPrefs() {
- final String[] prefs = { PREF_SCROLLING_FRICTION_FAST,
- PREF_SCROLLING_FRICTION_SLOW,
- PREF_SCROLLING_MAX_EVENT_ACCELERATION,
- PREF_SCROLLING_OVERSCROLL_DECEL_RATE,
- PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT,
- PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE };
-
- /*PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() {
- Map<String, Integer> mPrefs = new HashMap<String, Integer>();
-
- @Override public void prefValue(String name, int value) {
- mPrefs.put(name, value);
- }
-
- @Override public void finish() {
- setPrefs(mPrefs);
- }
- });*/
- }
-
- static final float MS_PER_FRAME = 1000.0f / 60.0f;
- static final long NS_PER_FRAME = Math.round(1000000000f / 60f);
- private static final float FRAMERATE_MULTIPLIER = (1000f/60f) / MS_PER_FRAME;
- private static final int FLING_VELOCITY_POINTS = 8;
-
- // The values we use for friction are based on a 16.6ms frame, adjust them to currentNsPerFrame:
- static float getFrameAdjustedFriction(float baseFriction, long currentNsPerFrame) {
- float framerateMultiplier = (float)currentNsPerFrame / NS_PER_FRAME;
- return (float)Math.pow(Math.E, (Math.log(baseFriction) / framerateMultiplier));
- }
-
- static void setPrefs(Map<String, Integer> prefs) {
- FRICTION_SLOW = getFloatPref(prefs, PREF_SCROLLING_FRICTION_SLOW, 850);
- FRICTION_FAST = getFloatPref(prefs, PREF_SCROLLING_FRICTION_FAST, 970);
- VELOCITY_THRESHOLD = 10 / FRAMERATE_MULTIPLIER;
- MAX_EVENT_ACCELERATION = getFloatPref(prefs, PREF_SCROLLING_MAX_EVENT_ACCELERATION, /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() > 300 ? 100 : 40);
- OVERSCROLL_DECEL_RATE = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_DECEL_RATE, 40);
- SNAP_LIMIT = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT, 300);
- MIN_SCROLLABLE_DISTANCE = getFloatPref(prefs, PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE, 500);
- Log.i(LOGTAG, "Prefs: " + FRICTION_SLOW + "," + FRICTION_FAST + "," + VELOCITY_THRESHOLD + ","
- + MAX_EVENT_ACCELERATION + "," + OVERSCROLL_DECEL_RATE + "," + SNAP_LIMIT + "," + MIN_SCROLLABLE_DISTANCE);
- }
-
- static {
- // set the scrolling parameters to default values on startup
- setPrefs(null);
- }
-
- private enum FlingStates {
- STOPPED,
- PANNING,
- FLINGING,
- }
-
- private enum Overscroll {
- NONE,
- MINUS, // Overscrolled in the negative direction
- PLUS, // Overscrolled in the positive direction
- BOTH, // Overscrolled in both directions (page is zoomed to smaller than screen)
- }
-
- private final SubdocumentScrollHelper mSubscroller;
-
- private int mOverscrollMode; /* Default to only overscrolling if we're allowed to scroll in a direction */
- private float mFirstTouchPos; /* Position of the first touch event on the current drag. */
- private float mTouchPos; /* Position of the most recent touch event on the current drag. */
- private float mLastTouchPos; /* Position of the touch event before touchPos. */
- private float mVelocity; /* Velocity in this direction; pixels per animation frame. */
- private float[] mRecentVelocities; /* Circular buffer of recent velocities since last touch start. */
- private int mRecentVelocityCount; /* Number of values put into mRecentVelocities (unbounded). */
- private boolean mScrollingDisabled; /* Whether movement on this axis is locked. */
- private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */
- private float mDisplacement;
-
- private FlingStates mFlingState = FlingStates.STOPPED; /* The fling state we're in on this axis. */
-
- protected abstract float getOrigin();
- protected abstract float getViewportLength();
- protected abstract float getPageStart();
- protected abstract float getPageLength();
- protected abstract float getMarginStart();
- protected abstract float getMarginEnd();
- protected abstract boolean marginsHidden();
-
- Axis(SubdocumentScrollHelper subscroller) {
- mSubscroller = subscroller;
- mOverscrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS;
- mRecentVelocities = new float[FLING_VELOCITY_POINTS];
- }
-
- // Implementors can override these to show effects when the axis overscrolls
- protected void overscrollFling(float velocity) { }
- protected void overscrollPan(float displacement) { }
-
- public void setOverScrollMode(int overscrollMode) {
- mOverscrollMode = overscrollMode;
- }
-
- public int getOverScrollMode() {
- return mOverscrollMode;
- }
-
- private float getViewportEnd() {
- return getOrigin() + getViewportLength();
- }
-
- private float getPageEnd() {
- return getPageStart() + getPageLength();
- }
-
- void startTouch(float pos) {
- mVelocity = 0.0f;
- mScrollingDisabled = false;
- mFirstTouchPos = mTouchPos = mLastTouchPos = pos;
- mRecentVelocityCount = 0;
- }
-
- float panDistance(float currentPos) {
- return currentPos - mFirstTouchPos;
- }
-
- void setScrollingDisabled(boolean disabled) {
- mScrollingDisabled = disabled;
- }
-
- void saveTouchPos() {
- mLastTouchPos = mTouchPos;
- }
-
- void updateWithTouchAt(float pos, float timeDelta) {
- float newVelocity = (mTouchPos - pos) / timeDelta * MS_PER_FRAME;
-
- mRecentVelocities[mRecentVelocityCount % FLING_VELOCITY_POINTS] = newVelocity;
- mRecentVelocityCount++;
-
- // If there's a direction change, or current velocity is very low,
- // allow setting of the velocity outright. Otherwise, use the current
- // velocity and a maximum change factor to set the new velocity.
- boolean curVelocityIsLow = Math.abs(mVelocity) < 1.0f / FRAMERATE_MULTIPLIER;
- boolean directionChange = (mVelocity > 0) != (newVelocity > 0);
- if (curVelocityIsLow || (directionChange && !FloatUtils.fuzzyEquals(newVelocity, 0.0f))) {
- mVelocity = newVelocity;
- } else {
- float maxChange = Math.abs(mVelocity * timeDelta * MAX_EVENT_ACCELERATION);
- mVelocity = Math.min(mVelocity + maxChange, Math.max(mVelocity - maxChange, newVelocity));
- }
-
- mTouchPos = pos;
- }
-
- boolean overscrolled() {
- return getOverscroll() != Overscroll.NONE;
- }
-
- private Overscroll getOverscroll() {
- boolean minus = (getOrigin() < getPageStart());
- boolean plus = (getViewportEnd() > getPageEnd());
- if (minus && plus) {
- return Overscroll.BOTH;
- } else if (minus) {
- return Overscroll.MINUS;
- } else if (plus) {
- return Overscroll.PLUS;
- } else {
- return Overscroll.NONE;
- }
- }
-
- // Returns the amount that the page has been overscrolled. If the page hasn't been
- // overscrolled on this axis, returns 0.
- private float getExcess() {
- switch (getOverscroll()) {
- case MINUS: return getPageStart() - getOrigin();
- case PLUS: return getViewportEnd() - getPageEnd();
- case BOTH: return (getViewportEnd() - getPageEnd()) + (getPageStart() - getOrigin());
- default: return 0.0f;
- }
- }
-
- /*
- * Returns true if the page is zoomed in to some degree along this axis such that scrolling is
- * possible and this axis has not been scroll locked while panning. Otherwise, returns false.
- */
- boolean scrollable() {
- // If we're scrolling a subdocument, ignore the viewport length restrictions (since those
- // apply to the top-level document) and only take into account axis locking.
- if (mSubscroller.scrolling()) {
- return !mScrollingDisabled;
- }
-
- // if we are axis locked, return false
- if (mScrollingDisabled) {
- return false;
- }
-
- // if there are margins on this axis but they are currently hidden,
- // we must be able to scroll in order to make them visible, so allow
- // scrolling in that case
- if (marginsHidden()) {
- return true;
- }
-
- // there is scrollable space, and we're not disabled, or the document fits the viewport
- // but we always allow overscroll anyway
- return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE ||
- getOverScrollMode() == View.OVER_SCROLL_ALWAYS;
- }
-
- /*
- * Returns the resistance, as a multiplier, that should be taken into account when
- * tracking or pinching.
- */
- float getEdgeResistance(boolean forPinching) {
- float excess = getExcess();
- if (excess > 0.0f && (getOverscroll() == Overscroll.BOTH || !forPinching)) {
- // excess can be greater than viewport length, but the resistance
- // must never drop below 0.0
- return Math.max(0.0f, SNAP_LIMIT - excess / getViewportLength());
- }
- return 1.0f;
- }
-
- /* Returns the velocity. If the axis is locked, returns 0. */
- float getRealVelocity() {
- return scrollable() ? mVelocity : 0f;
- }
-
- void startPan() {
- mFlingState = FlingStates.PANNING;
- }
-
- private float calculateFlingVelocity() {
- int usablePoints = Math.min(mRecentVelocityCount, FLING_VELOCITY_POINTS);
- if (usablePoints <= 1) {
- return mVelocity;
- }
- float average = 0;
- for (int i = 0; i < usablePoints; i++) {
- average += mRecentVelocities[i];
- }
- return average / usablePoints;
- }
-
- void startFling(boolean stopped) {
- mDisableSnap = mSubscroller.scrolling();
-
- if (stopped) {
- mFlingState = FlingStates.STOPPED;
- } else {
- mVelocity = calculateFlingVelocity();
- mFlingState = FlingStates.FLINGING;
- }
- }
-
- /* Advances a fling animation by one step. */
- boolean advanceFling(long realNsPerFrame) {
- if (mFlingState != FlingStates.FLINGING) {
- return false;
- }
- if (mSubscroller.scrolling() && !mSubscroller.lastScrollSucceeded()) {
- // if the subdocument stopped scrolling, it's because it reached the end
- // of the subdocument. we don't do overscroll on subdocuments, so there's
- // no point in continuing this fling.
- return false;
- }
-
- float excess = getExcess();
- Overscroll overscroll = getOverscroll();
- boolean decreasingOverscroll = false;
- if ((overscroll == Overscroll.MINUS && mVelocity > 0) ||
- (overscroll == Overscroll.PLUS && mVelocity < 0))
- {
- decreasingOverscroll = true;
- }
-
- if (mDisableSnap || FloatUtils.fuzzyEquals(excess, 0.0f) || decreasingOverscroll) {
- // If we aren't overscrolled, just apply friction.
- if (Math.abs(mVelocity) >= VELOCITY_THRESHOLD) {
- mVelocity *= getFrameAdjustedFriction(FRICTION_FAST, realNsPerFrame);
- } else {
- float t = mVelocity / VELOCITY_THRESHOLD;
- mVelocity *= FloatUtils.interpolate(getFrameAdjustedFriction(FRICTION_SLOW, realNsPerFrame),
- getFrameAdjustedFriction(FRICTION_FAST, realNsPerFrame), t);
- }
- } else {
- // Otherwise, decrease the velocity linearly.
- float elasticity = 1.0f - excess / (getViewportLength() * SNAP_LIMIT);
- float overscrollDecelRate = getFrameAdjustedFriction(OVERSCROLL_DECEL_RATE, realNsPerFrame);
- if (overscroll == Overscroll.MINUS) {
- mVelocity = Math.min((mVelocity + overscrollDecelRate) * elasticity, 0.0f);
- } else { // must be Overscroll.PLUS
- mVelocity = Math.max((mVelocity - overscrollDecelRate) * elasticity, 0.0f);
- }
- }
-
- return true;
- }
-
- void stopFling() {
- mVelocity = 0.0f;
- mFlingState = FlingStates.STOPPED;
- }
-
- // Performs displacement of the viewport position according to the current velocity.
- void displace() {
- // if this isn't scrollable just return
- if (!scrollable())
- return;
-
- if (mFlingState == FlingStates.PANNING)
- mDisplacement += (mLastTouchPos - mTouchPos) * getEdgeResistance(false);
- else
- mDisplacement += mVelocity * getEdgeResistance(false);
-
- // if overscroll is disabled and we're trying to overscroll, reset the displacement
- // to remove any excess. Using getExcess alone isn't enough here since it relies on
- // getOverscroll which doesn't take into account any new displacment being applied.
- // If we using a subscroller, we don't want to alter the scrolling being done
- if (getOverScrollMode() == View.OVER_SCROLL_NEVER && !mSubscroller.scrolling()) {
- float originalDisplacement = mDisplacement;
-
- if (mDisplacement + getOrigin() < getPageStart() - getMarginStart()) {
- mDisplacement = getPageStart() - getMarginStart() - getOrigin();
- } else if (mDisplacement + getViewportEnd() > getPageEnd() + getMarginEnd()) {
- mDisplacement = getPageEnd() - getMarginEnd() - getViewportEnd();
- }
-
- // Return the amount of overscroll so that the overscroll controller can draw it for us
- if (originalDisplacement != mDisplacement) {
- if (mFlingState == FlingStates.FLINGING) {
- overscrollFling(mVelocity / MS_PER_FRAME * 1000);
- stopFling();
- } else if (mFlingState == FlingStates.PANNING) {
- overscrollPan(originalDisplacement - mDisplacement);
- }
- }
- }
- }
-
- float resetDisplacement() {
- float d = mDisplacement;
- mDisplacement = 0.0f;
- return d;
- }
-
- void setAutoscrollVelocity(float velocity) {
- if (mFlingState != FlingStates.STOPPED) {
- Log.e(LOGTAG, "Setting autoscroll velocity while in a fling is not allowed!");
- return;
- }
- mVelocity = velocity;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java
deleted file mode 100644
index 9dba802f6d38..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.util.ThreadUtils;
-import org.mozilla.gecko.util.UiAsyncTask;
-//import org.mozilla.gecko.util.GeckoJarReader;
-//import org.mozilla.gecko.R;
-
-import org.libreoffice.R;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.util.Base64;
-import android.util.Log;
-import android.text.TextUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.lang.NoSuchFieldException;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-public final class BitmapUtils {
- private static final String LOGTAG = "GeckoBitmapUtils";
-
- private BitmapUtils() {}
-
- public interface BitmapLoader {
- public void onBitmapFound(Drawable d);
- }
-
- public static void getDrawable(final Context context, final String data, final BitmapLoader loader) {
- if (TextUtils.isEmpty(data)) {
- loader.onBitmapFound(null);
- return;
- }
-
- if (data.startsWith("data")) {
- BitmapDrawable d = new BitmapDrawable(context.getResources(), getBitmapFromDataURI(data));
- loader.onBitmapFound(d);
- return;
- }
-
- if (data.startsWith("jar:") || data.startsWith("file://")) {
- (new UiAsyncTask<Void, Void, Drawable>(ThreadUtils.getBackgroundHandler()) {
- @Override
- public Drawable doInBackground(Void... params) {
- try {
- //if (data.startsWith("jar:jar")) {
- // return GeckoJarReader.getBitmapDrawable(context.getResources(), data);
- //}
-
- // Don't attempt to validate the JAR signature when loading an add-on icon
- //if (data.startsWith("jar:file")) {
- // return GeckoJarReader.getBitmapDrawable(context.getResources(), Uri.decode(data));
- //}
-
- URL url = new URL(data);
- InputStream is = (InputStream) url.getContent();
- try {
- return Drawable.createFromStream(is, "src");
- } finally {
- is.close();
- }
- } catch (Exception e) {
- Log.w(LOGTAG, "Unable to set icon", e);
- }
- return null;
- }
-
- @Override
- public void onPostExecute(Drawable drawable) {
- loader.onBitmapFound(drawable);
- }
- }).execute();
- return;
- }
-
- if(data.startsWith("-moz-icon://")) {
- Uri imageUri = Uri.parse(data);
- String resource = imageUri.getSchemeSpecificPart();
- resource = resource.substring(resource.lastIndexOf('/') + 1);
-
- try {
- Drawable d = context.getPackageManager().getApplicationIcon(resource);
- loader.onBitmapFound(d);
- } catch(Exception ex) { }
-
- return;
- }
-
- if(data.startsWith("drawable://")) {
- Uri imageUri = Uri.parse(data);
- int id = getResource(imageUri, R.drawable.ic_status_logo);
- Drawable d = context.getResources().getDrawable(id);
-
- loader.onBitmapFound(d);
- return;
- }
-
- loader.onBitmapFound(null);
- }
-
- public static Bitmap decodeByteArray(byte[] bytes) {
- return decodeByteArray(bytes, null);
- }
-
- public static Bitmap decodeByteArray(byte[] bytes, BitmapFactory.Options options) {
- return decodeByteArray(bytes, 0, bytes.length, options);
- }
-
- public static Bitmap decodeByteArray(byte[] bytes, int offset, int length) {
- return decodeByteArray(bytes, offset, length, null);
- }
-
- public static Bitmap decodeByteArray(byte[] bytes, int offset, int length, BitmapFactory.Options options) {
- if (bytes.length <= 0) {
- throw new IllegalArgumentException("bytes.length " + bytes.length
- + " must be a positive number");
- }
-
- Bitmap bitmap = null;
- try {
- bitmap = BitmapFactory.decodeByteArray(bytes, offset, length, options);
- } catch (OutOfMemoryError e) {
- Log.e(LOGTAG, "decodeByteArray(bytes.length=" + bytes.length
- + ", options= " + options + ") OOM!", e);
- return null;
- }
-
- if (bitmap == null) {
- Log.w(LOGTAG, "decodeByteArray() returning null because BitmapFactory returned null");
- return null;
- }
-
- if (bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
- Log.w(LOGTAG, "decodeByteArray() returning null because BitmapFactory returned "
- + "a bitmap with dimensions " + bitmap.getWidth()
- + "x" + bitmap.getHeight());
- return null;
- }
-
- return bitmap;
- }
-
- public static Bitmap decodeStream(InputStream inputStream) {
- try {
- return BitmapFactory.decodeStream(inputStream);
- } catch (OutOfMemoryError e) {
- Log.e(LOGTAG, "decodeStream() OOM!", e);
- return null;
- }
- }
-
- public static Bitmap decodeUrl(Uri uri) {
- return decodeUrl(uri.toString());
- }
-
- public static Bitmap decodeUrl(String urlString) {
- URL url;
-
- try {
- url = new URL(urlString);
- } catch(MalformedURLException e) {
- Log.w(LOGTAG, "decodeUrl: malformed URL " + urlString);
- return null;
- }
-
- return decodeUrl(url);
- }
-
- public static Bitmap decodeUrl(URL url) {
- InputStream stream = null;
-
- try {
- stream = url.openStream();
- } catch(IOException e) {
- Log.w(LOGTAG, "decodeUrl: IOException downloading " + url);
- return null;
- }
-
- if (stream == null) {
- Log.w(LOGTAG, "decodeUrl: stream not found downloading " + url);
- return null;
- }
-
- Bitmap bitmap = decodeStream(stream);
-
- try {
- stream.close();
- } catch(IOException e) {
- Log.w(LOGTAG, "decodeUrl: IOException closing stream " + url, e);
- }
-
- return bitmap;
- }
-
- public static Bitmap decodeResource(Context context, int id) {
- return decodeResource(context, id, null);
- }
-
- public static Bitmap decodeResource(Context context, int id, BitmapFactory.Options options) {
- Resources resources = context.getResources();
- try {
- return BitmapFactory.decodeResource(resources, id, options);
- } catch (OutOfMemoryError e) {
- Log.e(LOGTAG, "decodeResource() OOM! Resource id=" + id, e);
- return null;
- }
- }
-
- public static int getDominantColor(Bitmap source) {
- return getDominantColor(source, true);
- }
-
- public static int getDominantColor(Bitmap source, boolean applyThreshold) {
- if (source == null)
- return Color.argb(255,255,255,255);
-
- // Keep track of how many times a hue in a given bin appears in the image.
- // Hue values range [0 .. 360), so dividing by 10, we get 36 bins.
- int[] colorBins = new int[36];
-
- // The bin with the most colors. Initialize to -1 to prevent accidentally
- // thinking the first bin holds the dominant color.
- int maxBin = -1;
-
- // Keep track of sum hue/saturation/value per hue bin, which we'll use to
- // compute an average to for the dominant color.
- float[] sumHue = new float[36];
- float[] sumSat = new float[36];
- float[] sumVal = new float[36];
- float[] hsv = new float[3];
-
- int height = source.getHeight();
- int width = source.getWidth();
- int[] pixels = new int[width * height];
- source.getPixels(pixels, 0, width, 0, 0, width, height);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- int c = pixels[col + row * width];
- // Ignore pixels with a certain transparency.
- if (Color.alpha(c) < 128)
- continue;
-
- Color.colorToHSV(c, hsv);
-
- // If a threshold is applied, ignore arbitrarily chosen values for "white" and "black".
- if (applyThreshold && (hsv[1] <= 0.35f || hsv[2] <= 0.35f))
- continue;
-
- // We compute the dominant color by putting colors in bins based on their hue.
- int bin = (int) Math.floor(hsv[0] / 10.0f);
-
- // Update the sum hue/saturation/value for this bin.
- sumHue[bin] = sumHue[bin] + hsv[0];
- sumSat[bin] = sumSat[bin] + hsv[1];
- sumVal[bin] = sumVal[bin] + hsv[2];
-
- // Increment the number of colors in this bin.
- colorBins[bin]++;
-
- // Keep track of the bin that holds the most colors.
- if (maxBin < 0 || colorBins[bin] > colorBins[maxBin])
- maxBin = bin;
- }
- }
-
- // maxBin may never get updated if the image holds only transparent and/or black/white pixels.
- if (maxBin < 0)
- return Color.argb(255,255,255,255);
-
- // Return a color with the average hue/saturation/value of the bin with the most colors.
- hsv[0] = sumHue[maxBin]/colorBins[maxBin];
- hsv[1] = sumSat[maxBin]/colorBins[maxBin];
- hsv[2] = sumVal[maxBin]/colorBins[maxBin];
- return Color.HSVToColor(hsv);
- }
-
- /**
- * Decodes a bitmap from a Base64 data URI.
- *
- * @param dataURI a Base64-encoded data URI string
- * @return the decoded bitmap, or null if the data URI is invalid
- */
- public static Bitmap getBitmapFromDataURI(String dataURI) {
- String base64 = dataURI.substring(dataURI.indexOf(',') + 1);
- try {
- byte[] raw = Base64.decode(base64, Base64.DEFAULT);
- return BitmapUtils.decodeByteArray(raw);
- } catch (Exception e) {
- Log.e(LOGTAG, "exception decoding bitmap from data URI: " + dataURI, e);
- }
- return null;
- }
-
- public static Bitmap getBitmapFromDrawable(Drawable drawable) {
- if (drawable instanceof BitmapDrawable) {
- return ((BitmapDrawable) drawable).getBitmap();
- }
-
- int width = drawable.getIntrinsicWidth();
- width = width > 0 ? width : 1;
- int height = drawable.getIntrinsicHeight();
- height = height > 0 ? height : 1;
-
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
-
- return bitmap;
- }
-
- public static int getResource(Uri resourceUrl, int defaultIcon) {
- int icon = defaultIcon;
-
- final String scheme = resourceUrl.getScheme();
- if ("drawable".equals(scheme)) {
- String resource = resourceUrl.getSchemeSpecificPart();
- resource = resource.substring(resource.lastIndexOf('/') + 1);
-
- try {
- return Integer.parseInt(resource);
- } catch(NumberFormatException ex) {
- // This isn't a resource id, try looking for a string
- }
-
- try {
- final Class<R.drawable> drawableClass = R.drawable.class;
- final Field f = drawableClass.getField(resource);
- icon = f.getInt(null);
- } catch (final NoSuchFieldException e1) {
-
- // just means the resource doesn't exist for fennec. Check in Android resources
- try {
- final Class<android.R.drawable> drawableClass = android.R.drawable.class;
- final Field f = drawableClass.getField(resource);
- icon = f.getInt(null);
- } catch (final NoSuchFieldException e2) {
- // This drawable doesn't seem to exist...
- } catch(Exception e3) {
- Log.i(LOGTAG, "Exception getting drawable", e3);
- }
-
- } catch (Exception e4) {
- Log.i(LOGTAG, "Exception getting drawable", e4);
- }
-
- resourceUrl = null;
- }
- return icon;
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java
deleted file mode 100644
index 307f41204256..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.mozglue.DirectBufferAllocator;
-
-import android.graphics.Bitmap;
-import android.util.Log;
-
-import java.nio.ByteBuffer;
-
-/** A Cairo image that simply saves a buffer of pixel data. */
-public class BufferedCairoImage extends CairoImage {
- private ByteBuffer mBuffer;
- private IntSize mSize;
- private int mFormat;
-
- private static String LOGTAG = "GeckoBufferedCairoImage";
-
- /** Creates a buffered Cairo image from a byte buffer. */
- public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) {
- setBuffer(inBuffer, inWidth, inHeight, inFormat);
- }
-
- /** Creates a buffered Cairo image from an Android bitmap. */
- public BufferedCairoImage(Bitmap bitmap) {
- setBitmap(bitmap);
- }
-
- private synchronized void freeBuffer() {
- mBuffer = DirectBufferAllocator.free(mBuffer);
- }
-
- @Override
- public void destroy() {
- try {
- freeBuffer();
- } catch (Exception ex) {
- Log.e(LOGTAG, "error clearing buffer: ", ex);
- }
- }
-
- @Override
- public ByteBuffer getBuffer() { return mBuffer; }
- @Override
- public IntSize getSize() { return mSize; }
- @Override
- public int getFormat() { return mFormat; }
-
-
- public void setBuffer(ByteBuffer buffer, int width, int height, int format) {
- freeBuffer();
- mBuffer = buffer;
- mSize = new IntSize(width, height);
- mFormat = format;
- }
-
- public void setBitmap(Bitmap bitmap) {
- mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig());
- mSize = new IntSize(bitmap.getWidth(), bitmap.getHeight());
-
- int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat);
- mBuffer = DirectBufferAllocator.allocate(mSize.getArea() * bpp);
- bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java
deleted file mode 100644
index 472c1d29f792..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import javax.microedition.khronos.opengles.GL10;
-
-/** Information needed to render Cairo bitmaps using OpenGL ES. */
-public class CairoGLInfo {
- public final int internalFormat;
- public final int format;
- public final int type;
-
- public CairoGLInfo(int cairoFormat) {
- switch (cairoFormat) {
- case CairoImage.FORMAT_ARGB32:
- internalFormat = format = GL10.GL_RGBA; type = GL10.GL_UNSIGNED_BYTE;
- break;
- case CairoImage.FORMAT_RGB24:
- internalFormat = format = GL10.GL_RGB; type = GL10.GL_UNSIGNED_BYTE;
- break;
- case CairoImage.FORMAT_RGB16_565:
- internalFormat = format = GL10.GL_RGB; type = GL10.GL_UNSIGNED_SHORT_5_6_5;
- break;
- case CairoImage.FORMAT_A8:
- case CairoImage.FORMAT_A1:
- throw new RuntimeException("Cairo FORMAT_A1 and FORMAT_A8 unsupported");
- default:
- throw new RuntimeException("Unknown Cairo format");
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java
deleted file mode 100644
index 5a18a4bb1995..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import java.nio.ByteBuffer;
-
-/*
- * A bitmap with pixel data in one of the formats that Cairo understands.
- */
-public abstract class CairoImage {
- public abstract ByteBuffer getBuffer();
-
- public abstract void destroy();
-
- public abstract IntSize getSize();
- public abstract int getFormat();
-
- public static final int FORMAT_INVALID = -1;
- public static final int FORMAT_ARGB32 = 0;
- public static final int FORMAT_RGB24 = 1;
- public static final int FORMAT_A8 = 2;
- public static final int FORMAT_A1 = 3;
- public static final int FORMAT_RGB16_565 = 4;
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java
deleted file mode 100644
index 48c449f05e5c..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Bitmap;
-
-/**
- * Utility methods useful when displaying Cairo bitmaps using OpenGL ES.
- */
-public class CairoUtils {
- private CairoUtils() { /* Don't call me. */ }
-
- public static int bitsPerPixelForCairoFormat(int cairoFormat) {
- switch (cairoFormat) {
- case CairoImage.FORMAT_A1: return 1;
- case CairoImage.FORMAT_A8: return 8;
- case CairoImage.FORMAT_RGB16_565: return 16;
- case CairoImage.FORMAT_RGB24: return 24;
- case CairoImage.FORMAT_ARGB32: return 32;
- default:
- throw new RuntimeException("Unknown Cairo format");
- }
- }
-
- public static int bitmapConfigToCairoFormat(Bitmap.Config config) {
- if (config == null)
- return CairoImage.FORMAT_ARGB32; /* Droid Pro fix. */
-
- switch (config) {
- case ALPHA_8: return CairoImage.FORMAT_A8;
- case ARGB_4444: throw new RuntimeException("ARGB_444 unsupported");
- case ARGB_8888: return CairoImage.FORMAT_ARGB32;
- case RGB_565: return CairoImage.FORMAT_RGB16_565;
- default: throw new RuntimeException("Unknown Skia bitmap config");
- }
- }
-
- public static Bitmap.Config cairoFormatTobitmapConfig(int format) {
- switch (format) {
- case CairoImage.FORMAT_A8: return Bitmap.Config.ALPHA_8;
- case CairoImage.FORMAT_ARGB32: return Bitmap.Config.ARGB_8888;
- case CairoImage.FORMAT_RGB16_565: return Bitmap.Config.RGB_565;
- default:
- throw new RuntimeException("Unknown CairoImage format");
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java
deleted file mode 100644
index f101dfbdb75f..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java
+++ /dev/null
@@ -1,777 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.PrefsHelper;
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.util.FloatUtils;
-
-import org.json.JSONArray;
-
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.util.FloatMath;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-
-final class DisplayPortCalculator {
- private static final String LOGTAG = "GeckoDisplayPort";
- private static final PointF ZERO_VELOCITY = new PointF(0, 0);
-
- // Keep this in sync with the TILEDLAYERBUFFER_TILE_SIZE defined in gfx/layers/TiledLayerBuffer.h
- private static final int TILE_SIZE = 256;
-
- private static final String PREF_DISPLAYPORT_STRATEGY = "gfx.displayport.strategy";
- private static final String PREF_DISPLAYPORT_FM_MULTIPLIER = "gfx.displayport.strategy_fm.multiplier";
- private static final String PREF_DISPLAYPORT_FM_DANGER_X = "gfx.displayport.strategy_fm.danger_x";
- private static final String PREF_DISPLAYPORT_FM_DANGER_Y = "gfx.displayport.strategy_fm.danger_y";
- private static final String PREF_DISPLAYPORT_VB_MULTIPLIER = "gfx.displayport.strategy_vb.multiplier";
- private static final String PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_vb.threshold";
- private static final String PREF_DISPLAYPORT_VB_REVERSE_BUFFER = "gfx.displayport.strategy_vb.reverse_buffer";
- private static final String PREF_DISPLAYPORT_VB_DANGER_X_BASE = "gfx.displayport.strategy_vb.danger_x_base";
- private static final String PREF_DISPLAYPORT_VB_DANGER_Y_BASE = "gfx.displayport.strategy_vb.danger_y_base";
- private static final String PREF_DISPLAYPORT_VB_DANGER_X_INCR = "gfx.displayport.strategy_vb.danger_x_incr";
- private static final String PREF_DISPLAYPORT_VB_DANGER_Y_INCR = "gfx.displayport.strategy_vb.danger_y_incr";
- private static final String PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_pb.threshold";
-
- private static DisplayPortStrategy sStrategy = new VelocityBiasStrategy(null);
-
- static DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
- return sStrategy.calculate(metrics, (velocity == null ? ZERO_VELOCITY : velocity));
- }
-
- static boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
- if (displayPort == null) {
- return true;
- }
- return sStrategy.aboutToCheckerboard(metrics, (velocity == null ? ZERO_VELOCITY : velocity), displayPort);
- }
-
- static boolean drawTimeUpdate(long millis, int pixels) {
- return sStrategy.drawTimeUpdate(millis, pixels);
- }
-
- static void resetPageState() {
- sStrategy.resetPageState();
- }
-
- static void initPrefs() {
- final String[] prefs = { PREF_DISPLAYPORT_STRATEGY,
- PREF_DISPLAYPORT_FM_MULTIPLIER,
- PREF_DISPLAYPORT_FM_DANGER_X,
- PREF_DISPLAYPORT_FM_DANGER_Y,
- PREF_DISPLAYPORT_VB_MULTIPLIER,
- PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD,
- PREF_DISPLAYPORT_VB_REVERSE_BUFFER,
- PREF_DISPLAYPORT_VB_DANGER_X_BASE,
- PREF_DISPLAYPORT_VB_DANGER_Y_BASE,
- PREF_DISPLAYPORT_VB_DANGER_X_INCR,
- PREF_DISPLAYPORT_VB_DANGER_Y_INCR,
- PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD };
-
- /*PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() {
- private Map<String, Integer> mValues = new HashMap<String, Integer>();
-
- @Override public void prefValue(String pref, int value) {
- mValues.put(pref, value);
- }
-
- @Override public void finish() {
- setStrategy(mValues);
- }
- });*/
- }
-
- /**
- * Set the active strategy to use.
- * See the gfx.displayport.strategy pref in mobile/android/app/mobile.js to see the
- * mapping between ints and strategies.
- */
- static boolean setStrategy(Map<String, Integer> prefs) {
- Integer strategy = prefs.get(PREF_DISPLAYPORT_STRATEGY);
- if (strategy == null) {
- return false;
- }
-
- switch (strategy) {
- case 0:
- sStrategy = new FixedMarginStrategy(prefs);
- break;
- case 1:
- sStrategy = new VelocityBiasStrategy(prefs);
- break;
- case 2:
- sStrategy = new DynamicResolutionStrategy(prefs);
- break;
- case 3:
- sStrategy = new NoMarginStrategy(prefs);
- break;
- case 4:
- sStrategy = new PredictionBiasStrategy(prefs);
- break;
- default:
- Log.e(LOGTAG, "Invalid strategy index specified");
- return false;
- }
- Log.i(LOGTAG, "Set strategy " + sStrategy.toString());
- return true;
- }
-
- private static float getFloatPref(Map<String, Integer> prefs, String prefName, int defaultValue) {
- Integer value = (prefs == null ? null : prefs.get(prefName));
- return (float)(value == null || value < 0 ? defaultValue : value) / 1000f;
- }
-
- private static abstract class DisplayPortStrategy {
- /** Calculates a displayport given a viewport and panning velocity. */
- public abstract DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity);
- /** Returns true if a checkerboard is about to be visible and we should not throttle drawing. */
- public abstract boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort);
- /** Notify the strategy of a new recorded draw time. Return false to turn off draw time recording. */
- public boolean drawTimeUpdate(long millis, int pixels) { return false; }
- /** Reset any page-specific state stored, as the page being displayed has changed. */
- public void resetPageState() {}
- }
-
- /**
- * Return the dimensions for a rect that has area (width*height) that does not exceed the page size in the
- * given metrics object. The area in the returned FloatSize may be less than width*height if the page is
- * small, but it will never be larger than width*height.
- * Note that this process may change the relative aspect ratio of the given dimensions.
- */
- private static FloatSize reshapeForPage(float width, float height, ImmutableViewportMetrics metrics) {
- // figure out how much of the desired buffer amount we can actually use on the horizontal axis
- float usableWidth = Math.min(width, metrics.getPageWidth());
- // if we reduced the buffer amount on the horizontal axis, we should take that saved memory and
- // use it on the vertical axis
- float extraUsableHeight = (float)Math.floor(((width - usableWidth) * height) / usableWidth);
- float usableHeight = Math.min(height + extraUsableHeight, metrics.getPageHeight());
- if (usableHeight < height && usableWidth == width) {
- // and the reverse - if we shrunk the buffer on the vertical axis we can add it to the horizontal
- float extraUsableWidth = (float)Math.floor(((height - usableHeight) * width) / usableHeight);
- usableWidth = Math.min(width + extraUsableWidth, metrics.getPageWidth());
- }
- return new FloatSize(usableWidth, usableHeight);
- }
-
- /**
- * Expand the given rect in all directions by a "danger zone". The size of the danger zone on an axis
- * is the size of the view on that axis multiplied by the given multiplier. The expanded rect is then
- * clamped to page bounds and returned.
- */
- private static RectF expandByDangerZone(RectF rect, float dangerZoneXMultiplier, float dangerZoneYMultiplier, ImmutableViewportMetrics metrics) {
- // calculate the danger zone amounts in pixels
- float dangerZoneX = metrics.getWidth() * dangerZoneXMultiplier;
- float dangerZoneY = metrics.getHeight() * dangerZoneYMultiplier;
- rect = RectUtils.expand(rect, dangerZoneX, dangerZoneY);
- // clamp to page bounds
- return clampToPageBounds(rect, metrics);
- }
-
- /**
- * Expand the given margins such that when they are applied on the viewport, the resulting rect
- * does not have any partial tiles, except when it is clipped by the page bounds. This assumes
- * the tiles are TILE_SIZE by TILE_SIZE and start at the origin, such that there will always be
- * a tile at (0,0)-(TILE_SIZE,TILE_SIZE)).
- */
- private static DisplayPortMetrics getTileAlignedDisplayPortMetrics(RectF margins, float zoom, ImmutableViewportMetrics metrics) {
- float left = metrics.viewportRectLeft - margins.left;
- float top = metrics.viewportRectTop - margins.top;
- float right = metrics.viewportRectRight + margins.right;
- float bottom = metrics.viewportRectBottom + margins.bottom;
- left = Math.max(metrics.pageRectLeft, TILE_SIZE * FloatMath.floor(left / TILE_SIZE));
- top = Math.max(metrics.pageRectTop, TILE_SIZE * FloatMath.floor(top / TILE_SIZE));
- right = Math.min(metrics.pageRectRight, TILE_SIZE * FloatMath.ceil(right / TILE_SIZE));
- bottom = Math.min(metrics.pageRectBottom, TILE_SIZE * FloatMath.ceil(bottom / TILE_SIZE));
- return new DisplayPortMetrics(left, top, right, bottom, zoom);
- }
-
- /**
- * Adjust the given margins so if they are applied on the viewport in the metrics, the resulting rect
- * does not exceed the page bounds. This code will maintain the total margin amount for a given axis;
- * it assumes that margins.left + metrics.getWidth() + margins.right is less than or equal to
- * metrics.getPageWidth(); and the same for the y axis.
- */
- private static RectF shiftMarginsForPageBounds(RectF margins, ImmutableViewportMetrics metrics) {
- // check how much we're overflowing in each direction. note that at most one of leftOverflow
- // and rightOverflow can be greater than zero, and at most one of topOverflow and bottomOverflow
- // can be greater than zero, because of the assumption described in the method javadoc.
- float leftOverflow = metrics.pageRectLeft - (metrics.viewportRectLeft - margins.left);
- float rightOverflow = (metrics.viewportRectRight + margins.right) - metrics.pageRectRight;
- float topOverflow = metrics.pageRectTop - (metrics.viewportRectTop - margins.top);
- float bottomOverflow = (metrics.viewportRectBottom + margins.bottom) - metrics.pageRectBottom;
-
- // if the margins overflow the page bounds, shift them to other side on the same axis
- if (leftOverflow > 0) {
- margins.left -= leftOverflow;
- margins.right += leftOverflow;
- } else if (rightOverflow > 0) {
- margins.right -= rightOverflow;
- margins.left += rightOverflow;
- }
- if (topOverflow > 0) {
- margins.top -= topOverflow;
- margins.bottom += topOverflow;
- } else if (bottomOverflow > 0) {
- margins.bottom -= bottomOverflow;
- margins.top += bottomOverflow;
- }
- return margins;
- }
-
- /**
- * Clamp the given rect to the page bounds and return it.
- */
- private static RectF clampToPageBounds(RectF rect, ImmutableViewportMetrics metrics) {
- if (rect.top < metrics.pageRectTop) rect.top = metrics.pageRectTop;
- if (rect.left < metrics.pageRectLeft) rect.left = metrics.pageRectLeft;
- if (rect.right > metrics.pageRectRight) rect.right = metrics.pageRectRight;
- if (rect.bottom > metrics.pageRectBottom) rect.bottom = metrics.pageRectBottom;
- return rect;
- }
-
- /**
- * This class implements the variation where we basically don't bother with a display port.
- */
- private static class NoMarginStrategy extends DisplayPortStrategy {
- NoMarginStrategy(Map<String, Integer> prefs) {
- // no prefs in this strategy
- }
-
- @Override
- public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
- return new DisplayPortMetrics(metrics.viewportRectLeft,
- metrics.viewportRectTop,
- metrics.viewportRectRight,
- metrics.viewportRectBottom,
- metrics.zoomFactor);
- }
-
- @Override
- public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
- return true;
- }
-
- @Override
- public String toString() {
- return "NoMarginStrategy";
- }
- }
-
- /**
- * This class implements the variation where we use a fixed-size margin on the display port.
- * The margin is always 300 pixels in all directions, except when we are (a) approaching a page
- * boundary, and/or (b) if we are limited by the page size. In these cases we try to maintain
- * the area of the display port by (a) shifting the buffer to the other side on the same axis,
- * and/or (b) increasing the buffer on the other axis to compensate for the reduced buffer on
- * one axis.
- */
- private static class FixedMarginStrategy extends DisplayPortStrategy {
- // The length of each axis of the display port will be the corresponding view length
- // multiplied by this factor.
- private final float SIZE_MULTIPLIER;
-
- // If the visible rect is within the danger zone (measured as a fraction of the view size
- // from the edge of the displayport) we start redrawing to minimize checkerboarding.
- private final float DANGER_ZONE_X_MULTIPLIER;
- private final float DANGER_ZONE_Y_MULTIPLIER;
-
- FixedMarginStrategy(Map<String, Integer> prefs) {
- SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_MULTIPLIER, 2000);
- DANGER_ZONE_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_DANGER_X, 100);
- DANGER_ZONE_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_DANGER_Y, 200);
- }
-
- @Override
- public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
- float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER;
- float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER;
-
- // we need to avoid having a display port that is larger than the page, or we will end up
- // painting things outside the page bounds (bug 729169). we simultaneously need to make
- // the display port as large as possible so that we redraw less. reshape the display
- // port dimensions to accomplish this.
- FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics);
- float horizontalBuffer = usableSize.width - metrics.getWidth();
- float verticalBuffer = usableSize.height - metrics.getHeight();
-
- // and now calculate the display port margins based on how much buffer we've decided to use and
- // the page bounds, ensuring we use all of the available buffer amounts on one side or the other
- // on any given axis. (i.e. if we're scrolled to the top of the page, the vertical buffer is
- // entirely below the visible viewport, but if we're halfway down the page, the vertical buffer
- // is split).
- RectF margins = new RectF();
- margins.left = horizontalBuffer / 2.0f;
- margins.right = horizontalBuffer - margins.left;
- margins.top = verticalBuffer / 2.0f;
- margins.bottom = verticalBuffer - margins.top;
- margins = shiftMarginsForPageBounds(margins, metrics);
-
- return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
- }
-
- @Override
- public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
- // Increase the size of the viewport based on the danger zone multiplier (and clamp to page
- // boundaries), and intersect it with the current displayport to determine whether we're
- // close to checkerboarding.
- RectF adjustedViewport = expandByDangerZone(metrics.getViewport(), DANGER_ZONE_X_MULTIPLIER, DANGER_ZONE_Y_MULTIPLIER, metrics);
- return !displayPort.contains(adjustedViewport);
- }
-
- @Override
- public String toString() {
- return "FixedMarginStrategy mult=" + SIZE_MULTIPLIER + ", dangerX=" + DANGER_ZONE_X_MULTIPLIER + ", dangerY=" + DANGER_ZONE_Y_MULTIPLIER;
- }
- }
-
- /**
- * This class implements the variation with a small fixed-size margin with velocity bias.
- * In this variation, the default margins are pretty small relative to the view size, but
- * they are affected by the panning velocity. Specifically, if we are panning on one axis,
- * we remove the margins on the other axis because we are likely axis-locked. Also once
- * we are panning in one direction above a certain threshold velocity, we shift the buffer
- * so that it is almost entirely in the direction of the pan, with a little bit in the
- * reverse direction.
- */
- private static class VelocityBiasStrategy extends DisplayPortStrategy {
- // The length of each axis of the display port will be the corresponding view length
- // multiplied by this factor.
- private final float SIZE_MULTIPLIER;
- // The velocity above which we apply the velocity bias
- private final float VELOCITY_THRESHOLD;
- // How much of the buffer to keep in the reverse direction of the velocity
- private final float REVERSE_BUFFER;
- // If the visible rect is within the danger zone we start redrawing to minimize
- // checkerboarding. the danger zone amount is a linear function of the form:
- // viewportsize * (base + velocity * incr)
- // where base and incr are configurable values.
- private final float DANGER_ZONE_BASE_X_MULTIPLIER;
- private final float DANGER_ZONE_BASE_Y_MULTIPLIER;
- private final float DANGER_ZONE_INCR_X_MULTIPLIER;
- private final float DANGER_ZONE_INCR_Y_MULTIPLIER;
-
- VelocityBiasStrategy(Map<String, Integer> prefs) {
- SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_MULTIPLIER, 2000);
- VELOCITY_THRESHOLD = /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() * getFloatPref(prefs, PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD, 32);
- REVERSE_BUFFER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_REVERSE_BUFFER, 200);
- DANGER_ZONE_BASE_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_X_BASE, 1000);
- DANGER_ZONE_BASE_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_Y_BASE, 1000);
- DANGER_ZONE_INCR_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_X_INCR, 0);
- DANGER_ZONE_INCR_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_Y_INCR, 0);
- }
-
- /**
- * Split the given amounts into margins based on the VELOCITY_THRESHOLD and REVERSE_BUFFER values.
- * If the velocity is above the VELOCITY_THRESHOLD on an axis, split the amount into REVERSE_BUFFER
- * and 1.0 - REVERSE_BUFFER fractions. The REVERSE_BUFFER fraction is set as the margin in the
- * direction opposite to the velocity, and the remaining fraction is set as the margin in the direction
- * of the velocity. If the velocity is lower than VELOCITY_THRESHOLD, split the amount evenly into the
- * two margins on that axis.
- */
- private RectF velocityBiasedMargins(float xAmount, float yAmount, PointF velocity) {
- RectF margins = new RectF();
-
- if (velocity.x > VELOCITY_THRESHOLD) {
- margins.left = xAmount * REVERSE_BUFFER;
- } else if (velocity.x < -VELOCITY_THRESHOLD) {
- margins.left = xAmount * (1.0f - REVERSE_BUFFER);
- } else {
- margins.left = xAmount / 2.0f;
- }
- margins.right = xAmount - margins.left;
-
- if (velocity.y > VELOCITY_THRESHOLD) {
- margins.top = yAmount * REVERSE_BUFFER;
- } else if (velocity.y < -VELOCITY_THRESHOLD) {
- margins.top = yAmount * (1.0f - REVERSE_BUFFER);
- } else {
- margins.top = yAmount / 2.0f;
- }
- margins.bottom = yAmount - margins.top;
-
- return margins;
- }
-
- @Override
- public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
- float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER;
- float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER;
-
- // but if we're panning on one axis, set the margins for the other axis to zero since we are likely
- // axis locked and won't be displaying that extra area.
- if (Math.abs(velocity.x) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.y, 0)) {
- displayPortHeight = metrics.getHeight();
- } else if (Math.abs(velocity.y) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.x, 0)) {
- displayPortWidth = metrics.getWidth();
- }
-
- // we need to avoid having a display port that is larger than the page, or we will end up
- // painting things outside the page bounds (bug 729169).
- displayPortWidth = Math.min(displayPortWidth, metrics.getPageWidth());
- displayPortHeight = Math.min(displayPortHeight, metrics.getPageHeight());
- float horizontalBuffer = displayPortWidth - metrics.getWidth();
- float verticalBuffer = displayPortHeight - metrics.getHeight();
-
- // split the buffer amounts into margins based on velocity, and shift it to
- // take into account the page bounds
- RectF margins = velocityBiasedMargins(horizontalBuffer, verticalBuffer, velocity);
- margins = shiftMarginsForPageBounds(margins, metrics);
-
- return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
- }
-
- @Override
- public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
- // calculate the danger zone amounts based on the prefs
- float dangerZoneX = metrics.getWidth() * (DANGER_ZONE_BASE_X_MULTIPLIER + (velocity.x * DANGER_ZONE_INCR_X_MULTIPLIER));
- float dangerZoneY = metrics.getHeight() * (DANGER_ZONE_BASE_Y_MULTIPLIER + (velocity.y * DANGER_ZONE_INCR_Y_MULTIPLIER));
- // clamp it such that when added to the viewport, they don't exceed page size.
- // this is a prerequisite to calling shiftMarginsForPageBounds as we do below.
- dangerZoneX = Math.min(dangerZoneX, metrics.getPageWidth() - metrics.getWidth());
- dangerZoneY = Math.min(dangerZoneY, metrics.getPageHeight() - metrics.getHeight());
-
- // split the danger zone into margins based on velocity, and ensure it doesn't exceed
- // page bounds.
- RectF dangerMargins = velocityBiasedMargins(dangerZoneX, dangerZoneY, velocity);
- dangerMargins = shiftMarginsForPageBounds(dangerMargins, metrics);
-
- // we're about to checkerboard if the current viewport area + the danger zone margins
- // fall out of the current displayport anywhere.
- RectF adjustedViewport = new RectF(
- metrics.viewportRectLeft - dangerMargins.left,
- metrics.viewportRectTop - dangerMargins.top,
- metrics.viewportRectRight + dangerMargins.right,
- metrics.viewportRectBottom + dangerMargins.bottom);
- return !displayPort.contains(adjustedViewport);
- }
-
- @Override
- public String toString() {
- return "VelocityBiasStrategy mult=" + SIZE_MULTIPLIER + ", threshold=" + VELOCITY_THRESHOLD + ", reverse=" + REVERSE_BUFFER
- + ", dangerBaseX=" + DANGER_ZONE_BASE_X_MULTIPLIER + ", dangerBaseY=" + DANGER_ZONE_BASE_Y_MULTIPLIER
- + ", dangerIncrX=" + DANGER_ZONE_INCR_Y_MULTIPLIER + ", dangerIncrY=" + DANGER_ZONE_INCR_Y_MULTIPLIER;
- }
- }
-
- /**
- * This class implements the variation where we draw more of the page at low resolution while panning.
- * In this variation, as we pan faster, we increase the page area we are drawing, but reduce the draw
- * resolution to compensate. This results in the same device-pixel area drawn; the compositor then
- * scales this up to the viewport zoom level. This results in a large area of the page drawn but it
- * looks blurry. The assumption is that drawing extra that we never display is better than checkerboarding,
- * where we draw less but never even show it on the screen.
- */
- private static class DynamicResolutionStrategy extends DisplayPortStrategy {
- // The length of each axis of the display port will be the corresponding view length
- // multiplied by this factor.
- private static final float SIZE_MULTIPLIER = 1.5f;
-
- // The velocity above which we start zooming out the display port to keep up
- // with the panning.
- private static final float VELOCITY_EXPANSION_THRESHOLD = /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() / 16f;
-
- // How much we increase the display port based on velocity. Assuming no friction and
- // splitting (see below), this should be the number of frames (@60fps) between us
- // calculating the display port and the draw of the *next* display port getting composited
- // and displayed on the screen. This is because the timeline looks like this:
- // Java: pan pan pan pan pan pan ! pan pan pan pan pan pan !
- // Gecko: \-> draw -> composite / \-> draw -> composite /
- // The display port calculated on the first "pan" gets composited to the screen at the
- // first exclamation mark, and remains on the screen until the second exclamation mark.
- // In order to avoid checkerboarding, that display port must be able to contain all of
- // the panning until the second exclamation mark, which encompasses two entire draw/composite
- // cycles.
- // If we take into account friction, our velocity multiplier should be reduced as the
- // amount of pan will decrease each time. If we take into account display port splitting,
- // it should be increased as the splitting means some of the display port will be used to
- // draw in the opposite direction of the velocity. For now I'm assuming these two cancel
- // each other out.
- private static final float VELOCITY_MULTIPLIER = 60.0f;
-
- // The following constants adjust how biased the display port is in the direction of panning.
- // When panning fast (above the FAST_THRESHOLD) we use the fast split factor to split the
- // display port "buffer" area, otherwise we use the slow split factor. This is based on the
- // assumption that if the user is panning fast, they are less likely to reverse directions
- // and go backwards, so we should spend more of our display port buffer in the direction of
- // panning.
- private static final float VELOCITY_FAST_THRESHOLD = VELOCITY_EXPANSION_THRESHOLD * 2.0f;
- private static final float FAST_SPLIT_FACTOR = 0.95f;
- private static final float SLOW_SPLIT_FACTOR = 0.8f;
-
- // The following constants are used for viewport prediction; we use them to estimate where
- // the viewport will be soon and whether or not we should trigger a draw right now. "soon"
- // in the previous sentence really refers to the amount of time it would take to draw and
- // composite from the point at which we do the calculation, and that is not really a known
- // quantity. The velocity multiplier is how much we multiply the velocity by; it has the
- // same caveats as the VELOCITY_MULTIPLIER above except that it only needs to take into account
- // one draw/composite cycle instead of two. The danger zone multiplier is a multiplier of the
- // viewport size that we use as an extra "danger zone" around the viewport; if this danger
- // zone falls outside the display port then we are approaching the point at which we will
- // checkerboard, and hence should start drawing. Note that if DANGER_ZONE_MULTIPLIER is
- // greater than (SIZE_MULTIPLIER - 1.0f), then at zero velocity we will always be in the
- // danger zone, and thus will be constantly drawing.
- private static final float PREDICTION_VELOCITY_MULTIPLIER = 30.0f;
- private static final float DANGER_ZONE_MULTIPLIER = 0.20f; // must be less than (SIZE_MULTIPLIER - 1.0f)
-
- DynamicResolutionStrategy(Map<String, Integer> prefs) {
- // ignore prefs for now
- }
-
- @Override
- public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
- float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER;
- float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER;
-
- // for resolution calculation purposes, we need to know what the adjusted display port dimensions
- // would be if we had zero velocity, so calculate that here before we increase the display port
- // based on velocity.
- FloatSize reshapedSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics);
-
- // increase displayPortWidth and displayPortHeight based on the velocity, but maintaining their
- // relative aspect ratio.
- if (velocity.length() > VELOCITY_EXPANSION_THRESHOLD) {
- float velocityFactor = Math.max(Math.abs(velocity.x) / displayPortWidth,
- Math.abs(velocity.y) / displayPortHeight);
- velocityFactor *= VELOCITY_MULTIPLIER;
-
- displayPortWidth += (displayPortWidth * velocityFactor);
- displayPortHeight += (displayPortHeight * velocityFactor);
- }
-
- // at this point, displayPortWidth and displayPortHeight are how much of the page (in device pixels)
- // we want to be rendered by Gecko. Note here "device pixels" is equivalent to CSS pixels multiplied
- // by metrics.zoomFactor
-
- // we need to avoid having a display port that is larger than the page, or we will end up
- // painting things outside the page bounds (bug 729169). we simultaneously need to make
- // the display port as large as possible so that we redraw less. reshape the display
- // port dimensions to accomplish this. this may change the aspect ratio of the display port,
- // but we are assuming that this is desirable because the advantages from pre-drawing will
- // outweigh the disadvantages from any buffer reallocations that might occur.
- FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics);
- float horizontalBuffer = usableSize.width - metrics.getWidth();
- float verticalBuffer = usableSize.height - metrics.getHeight();
-
- // at this point, horizontalBuffer and verticalBuffer are the dimensions of the buffer area we have.
- // the buffer area is the off-screen area that is part of the display port and will be pre-drawn in case
- // the user scrolls there. we now need to split the buffer area on each axis so that we know
- // what the exact margins on each side will be. first we split the buffer amount based on the direction
- // we're moving, so that we have a larger buffer in the direction of travel.
- RectF margins = new RectF();
- margins.left = splitBufferByVelocity(horizontalBuffer, velocity.x);
- margins.right = horizontalBuffer - margins.left;
- margins.top = splitBufferByVelocity(verticalBuffer, velocity.y);
- margins.bottom = verticalBuffer - margins.top;
-
- // then, we account for running into the page bounds - so that if we hit the top of the page, we need
- // to drop the top margin and move that amount to the bottom margin.
- margins = shiftMarginsForPageBounds(margins, metrics);
-
- // finally, we calculate the resolution we want to render the display port area at. We do this
- // so that as we expand the display port area (because of velocity), we reduce the resolution of
- // the painted area so as to maintain the size of the buffer Gecko is painting into. we calculate
- // the reduction in resolution by comparing the display port size with and without the velocity
- // changes applied.
- // this effectively means that as we pan faster and faster, the display port grows, but we paint
- // at lower resolutions. this paints more area to reduce checkerboard at the cost of increasing
- // compositor-scaling and blurriness. Once we stop panning, the blurriness must be entirely gone.
- // Note that usable* could be less than base* if we are pinch-zoomed out into overscroll, so we
- // clamp it to make sure this doesn't increase our display resolution past metrics.zoomFactor.
- float scaleFactor = Math.min(reshapedSize.width / usableSize.width, reshapedSize.height / usableSize.height);
- float displayResolution = metrics.zoomFactor * Math.min(1.0f, scaleFactor);
-
- DisplayPortMetrics dpMetrics = new DisplayPortMetrics(
- metrics.viewportRectLeft - margins.left,
- metrics.viewportRectTop - margins.top,
- metrics.viewportRectRight + margins.right,
- metrics.viewportRectBottom + margins.bottom,
- displayResolution);
- return dpMetrics;
- }
-
- /**
- * Split the given buffer amount into two based on the velocity.
- * Given an amount of total usable buffer on an axis, this will
- * return the amount that should be used on the left/top side of
- * the axis (the side which a negative velocity vector corresponds
- * to).
- */
- private float splitBufferByVelocity(float amount, float velocity) {
- // if no velocity, so split evenly
- if (FloatUtils.fuzzyEquals(velocity, 0)) {
- return amount / 2.0f;
- }
- // if we're moving quickly, assign more of the amount in that direction
- // since is is less likely that we will reverse direction immediately
- if (velocity < -VELOCITY_FAST_THRESHOLD) {
- return amount * FAST_SPLIT_FACTOR;
- }
- if (velocity > VELOCITY_FAST_THRESHOLD) {
- return amount * (1.0f - FAST_SPLIT_FACTOR);
- }
- // if we're moving slowly, then assign less of the amount in that direction
- if (velocity < 0) {
- return amount * SLOW_SPLIT_FACTOR;
- } else {
- return amount * (1.0f - SLOW_SPLIT_FACTOR);
- }
- }
-
- @Override
- public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
- // Expand the viewport based on our velocity (and clamp it to page boundaries).
- // Then intersect it with the last-requested displayport to determine whether we're
- // close to checkerboarding.
-
- RectF predictedViewport = metrics.getViewport();
-
- // first we expand the viewport in the direction we're moving based on some
- // multiple of the current velocity.
- if (velocity.length() > 0) {
- if (velocity.x < 0) {
- predictedViewport.left += velocity.x * PREDICTION_VELOCITY_MULTIPLIER;
- } else if (velocity.x > 0) {
- predictedViewport.right += velocity.x * PREDICTION_VELOCITY_MULTIPLIER;
- }
-
- if (velocity.y < 0) {
- predictedViewport.top += velocity.y * PREDICTION_VELOCITY_MULTIPLIER;
- } else if (velocity.y > 0) {
- predictedViewport.bottom += velocity.y * PREDICTION_VELOCITY_MULTIPLIER;
- }
- }
-
- // then we expand the viewport evenly in all directions just to have an extra
- // safety zone. this also clamps it to page bounds.
- predictedViewport = expandByDangerZone(predictedViewport, DANGER_ZONE_MULTIPLIER, DANGER_ZONE_MULTIPLIER, metrics);
- return !displayPort.contains(predictedViewport);
- }
-
- @Override
- public String toString() {
- return "DynamicResolutionStrategy";
- }
- }
-
- /**
- * This class implements the variation where we use the draw time to predict where we will be when
- * a draw completes, and draw that instead of where we are now. In this variation, when our panning
- * speed drops below a certain threshold, we draw 9 viewports' worth of content so that the user can
- * pan in any direction without encountering checkerboarding.
- * Once the user is panning, we modify the displayport to encompass an area range of where we think
- * the user will be when the draw completes. This heuristic relies on both the estimated draw time
- * the panning velocity; unexpected changes in either of these values will cause the heuristic to
- * fail and show checkerboard.
- */
- private static class PredictionBiasStrategy extends DisplayPortStrategy {
- private static float VELOCITY_THRESHOLD;
-
- private int mPixelArea; // area of the viewport, used in draw time calculations
- private int mMinFramesToDraw; // minimum number of frames we take to draw
- private int mMaxFramesToDraw; // maximum number of frames we take to draw
-
- PredictionBiasStrategy(Map<String, Integer> prefs) {
- VELOCITY_THRESHOLD = /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() * getFloatPref(prefs, PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD, 16);
- resetPageState();
- }
-
- @Override
- public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
- float width = metrics.getWidth();
- float height = metrics.getHeight();
- mPixelArea = (int)(width * height);
-
- if (velocity.length() < VELOCITY_THRESHOLD) {
- // if we're going slow, expand the displayport to 9x viewport size
- RectF margins = new RectF(width, height, width, height);
- return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
- }
-
- // figure out how far we expect to be
- float minDx = velocity.x * mMinFramesToDraw;
- float minDy = velocity.y * mMinFramesToDraw;
- float maxDx = velocity.x * mMaxFramesToDraw;
- float maxDy = velocity.y * mMaxFramesToDraw;
-
- // figure out how many pixels we will be drawing when we draw the above-calculated range.
- // this will be larger than the viewport area.
- float pixelsToDraw = (width + Math.abs(maxDx - minDx)) * (height + Math.abs(maxDy - minDy));
- // adjust how far we will get because of the time spent drawing all these extra pixels. this
- // will again increase the number of pixels drawn so really we could keep iterating this over
- // and over, but once seems enough for now.
- maxDx = maxDx * pixelsToDraw / mPixelArea;
- maxDy = maxDy * pixelsToDraw / mPixelArea;
-
- // and finally generate the displayport. the min/max stuff takes care of
- // negative velocities as well as positive.
- RectF margins = new RectF(
- -Math.min(minDx, maxDx),
- -Math.min(minDy, maxDy),
- Math.max(minDx, maxDx),
- Math.max(minDy, maxDy));
- return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
- }
-
- @Override
- public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
- // the code below is the same as in calculate() but is awkward to refactor since it has multiple outputs.
- // refer to the comments in calculate() to understand what this is doing.
- float minDx = velocity.x * mMinFramesToDraw;
- float minDy = velocity.y * mMinFramesToDraw;
- float maxDx = velocity.x * mMaxFramesToDraw;
- float maxDy = velocity.y * mMaxFramesToDraw;
- float pixelsToDraw = (metrics.getWidth() + Math.abs(maxDx - minDx)) * (metrics.getHeight() + Math.abs(maxDy - minDy));
- maxDx = maxDx * pixelsToDraw / mPixelArea;
- maxDy = maxDy * pixelsToDraw / mPixelArea;
-
- // now that we have an idea of how far we will be when the draw completes, take the farthest
- // end of that range and see if it falls outside the displayport bounds. if it does, allow
- // the draw to go through
- RectF predictedViewport = metrics.getViewport();
- predictedViewport.left += maxDx;
- predictedViewport.top += maxDy;
- predictedViewport.right += maxDx;
- predictedViewport.bottom += maxDy;
-
- predictedViewport = clampToPageBounds(predictedViewport, metrics);
- return !displayPort.contains(predictedViewport);
- }
-
- @Override
- public boolean drawTimeUpdate(long millis, int pixels) {
- // calculate the number of frames it took to draw a viewport-sized area
- float normalizedTime = (float)mPixelArea * (float)millis / (float)pixels;
- int normalizedFrames = (int)FloatMath.ceil(normalizedTime * 60f / 1000f);
- // broaden our range on how long it takes to draw if the draw falls outside
- // the range. this allows it to grow gradually. this heuristic may need to
- // be tweaked into more of a floating window average or something.
- if (normalizedFrames <= mMinFramesToDraw) {
- mMinFramesToDraw--;
- } else if (normalizedFrames > mMaxFramesToDraw) {
- mMaxFramesToDraw++;
- } else {
- return true;
- }
- Log.d(LOGTAG, "Widened draw range to [" + mMinFramesToDraw + ", " + mMaxFramesToDraw + "]");
- return true;
- }
-
- @Override
- public void resetPageState() {
- mMinFramesToDraw = 0;
- mMaxFramesToDraw = 2;
- }
-
- @Override
- public String toString() {
- return "PredictionBiasStrategy threshold=" + VELOCITY_THRESHOLD;
- }
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java
deleted file mode 100644
index 741136f90a53..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
-import org.mozilla.gecko.util.FloatUtils;
-
-import android.graphics.RectF;
-
-/*
- * This class keeps track of the area we request Gecko to paint, as well
- * as the resolution of the paint. The area may be different from the visible
- * area of the page, and the resolution may be different from the resolution
- * used in the compositor to render the page. This is so that we can ask Gecko
- * to paint a much larger area without using extra memory, and then render some
- * subsection of that with compositor scaling.
- */
-public final class DisplayPortMetrics {
- //@WrapElementForJNI
- public final float resolution;
- //@WrapElementForJNI
- private final RectF mPosition;
-
- public DisplayPortMetrics() {
- this(0, 0, 0, 0, 1);
- }
-
- //@WrapElementForJNI
- public DisplayPortMetrics(float left, float top, float right, float bottom, float resolution) {
- this.resolution = resolution;
- mPosition = new RectF(left, top, right, bottom);
- }
-
- public float getLeft() {
- return mPosition.left;
- }
-
- public float getTop() {
- return mPosition.top;
- }
-
- public float getRight() {
- return mPosition.right;
- }
-
- public float getBottom() {
- return mPosition.bottom;
- }
-
- public boolean contains(RectF rect) {
- return mPosition.contains(rect);
- }
-
- public boolean fuzzyEquals(DisplayPortMetrics metrics) {
- return RectUtils.fuzzyEquals(mPosition, metrics.mPosition)
- && FloatUtils.fuzzyEquals(resolution, metrics.resolution);
- }
-
- public String toJSON() {
- StringBuilder sb = new StringBuilder(256);
- sb.append("{ \"left\": ").append(mPosition.left)
- .append(", \"top\": ").append(mPosition.top)
- .append(", \"right\": ").append(mPosition.right)
- .append(", \"bottom\": ").append(mPosition.bottom)
- .append(", \"resolution\": ").append(resolution)
- .append('}');
- return sb.toString();
- }
-
- @Override
- public String toString() {
- return "DisplayPortMetrics v=(" + mPosition.left + "," + mPosition.top + "," + mPosition.right + ","
- + mPosition.bottom + ") z=" + resolution;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java
deleted file mode 100644
index ce868f18ce2f..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.os.SystemClock;
-
-/**
- * A custom-built data structure to assist with measuring draw times.
- *
- * This class maintains a fixed-size circular buffer of DisplayPortMetrics
- * objects and associated timestamps. It provides only three operations, which
- * is all we require for our purposes of measuring draw times. Note
- * in particular that the class is designed so that even though it is
- * accessed from multiple threads, it does not require synchronization;
- * any concurrency errors that result from this are handled gracefully.
- *
- * Assuming an unrolled buffer so that mTail is greater than mHead, the data
- * stored in the buffer at entries [mHead, mTail) will never be modified, and
- * so are "safe" to read. If this reading is done on the same thread that
- * owns mHead, then reading the range [mHead, mTail) is guaranteed to be safe
- * since the range itself will not shrink.
- */
-final class DrawTimingQueue {
- private static final String LOGTAG = "GeckoDrawTimingQueue";
- private static final int BUFFER_SIZE = 16;
-
- private final DisplayPortMetrics[] mMetrics;
- private final long[] mTimestamps;
-
- private int mHead;
- private int mTail;
-
- DrawTimingQueue() {
- mMetrics = new DisplayPortMetrics[BUFFER_SIZE];
- mTimestamps = new long[BUFFER_SIZE];
- mHead = BUFFER_SIZE - 1;
- mTail = 0;
- }
-
- /**
- * Add a new entry to the tail of the queue. If the buffer is full,
- * do nothing. This must only be called from the Java UI thread.
- */
- boolean add(DisplayPortMetrics metrics) {
- if (mHead == mTail) {
- return false;
- }
- mMetrics[mTail] = metrics;
- mTimestamps[mTail] = SystemClock.uptimeMillis();
- mTail = (mTail + 1) % BUFFER_SIZE;
- return true;
- }
-
- /**
- * Find the timestamp associated with the given metrics, AND remove
- * all metrics objects from the start of the queue up to and including
- * the one provided. Note that because of draw coalescing, the metrics
- * object passed in here may not be the one at the head of the queue,
- * and so we must iterate our way through the list to find it.
- * This must only be called from the compositor thread.
- */
- long findTimeFor(DisplayPortMetrics metrics) {
- // keep a copy of the tail pointer so that we ignore new items
- // added to the queue while we are searching. this is fine because
- // the one we are looking for will either have been added already
- // or will not be in the queue at all.
- int tail = mTail;
- // walk through the "safe" range from mHead to tail; these entries
- // will not be modified unless we change mHead.
- int i = (mHead + 1) % BUFFER_SIZE;
- while (i != tail) {
- if (mMetrics[i].fuzzyEquals(metrics)) {
- // found it, copy out the timestamp to a local var BEFORE
- // changing mHead or add could clobber the timestamp.
- long timestamp = mTimestamps[i];
- mHead = i;
- return timestamp;
- }
- i = (i + 1) % BUFFER_SIZE;
- }
- return -1;
- }
-
- /**
- * Reset the buffer to empty.
- * This must only be called from the compositor thread.
- */
- void reset() {
- // we can only modify mHead on this thread.
- mHead = (mTail + BUFFER_SIZE - 1) % BUFFER_SIZE;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java
deleted file mode 100644
index 4b495ab77ecc..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.util.FloatUtils;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-public class FloatSize {
- public final float width, height;
-
- public FloatSize(FloatSize size) { width = size.width; height = size.height; }
- public FloatSize(IntSize size) { width = size.width; height = size.height; }
- public FloatSize(float aWidth, float aHeight) { width = aWidth; height = aHeight; }
-
- public FloatSize(JSONObject json) {
- try {
- width = (float)json.getDouble("width");
- height = (float)json.getDouble("height");
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String toString() { return "(" + width + "," + height + ")"; }
-
- public boolean isPositive() {
- return (width > 0 && height > 0);
- }
-
- public boolean fuzzyEquals(FloatSize size) {
- return (FloatUtils.fuzzyEquals(size.width, width) &&
- FloatUtils.fuzzyEquals(size.height, height));
- }
-
- public FloatSize scale(float factor) {
- return new FloatSize(width * factor, height * factor);
- }
-
- /*
- * Returns the size that represents a linear transition between this size and `to` at time `t`,
- * which is on the scale [0, 1).
- */
- public FloatSize interpolate(FloatSize to, float t) {
- return new FloatSize(FloatUtils.interpolate(width, to.width, t),
- FloatUtils.interpolate(height, to.height, t));
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java
deleted file mode 100644
index be6118894e6a..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-//import org.mozilla.gecko.GeckoThread;
-//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.util.Log;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-
-/**
- * EGLPreloadingThread is purely a preloading optimization, not something
- * we rely on for anything else than performance. We will be initializing
- * EGL in GLController::initEGL() when we need it, but having EGL initialization
- * already previously done by EGLPreloadingThread::run() will make it much
- * faster for GLController to do again.
- *
- * For example, here are some timings recorded on two devices:
- *
- * Device | EGLPreloadingThread::run() | GLController::initEGL()
- * -----------------------+----------------------------+------------------------
- * Nexus S (Android 2.3) | ~ 80 ms | < 0.1 ms
- * Nexus 10 (Android 4.3) | ~ 35 ms | < 0.1 ms
- */
-class EGLPreloadingThread extends Thread
-{
- private static final String LOGTAG = "EGLPreloadingThread";
- private EGL10 mEGL;
- private EGLDisplay mEGLDisplay;
-
- public EGLPreloadingThread()
- {
- }
-
- @Override
- public void run()
- {
- mEGL = (EGL10)EGLContext.getEGL();
- mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
- if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) {
- Log.w(LOGTAG, "Can't get EGL display!");
- return;
- }
-
- int[] returnedVersion = new int[2];
- if (!mEGL.eglInitialize(mEGLDisplay, returnedVersion)) {
- Log.w(LOGTAG, "eglInitialize failed");
- return;
- }
- }
-}
-
-/**
- * This class is a singleton that tracks EGL and compositor things over
- * the lifetime of Fennec running.
- * We only ever create one C++ compositor over Fennec's lifetime, but
- * most of the Java-side objects (e.g. LayerView, GeckoLayerClient,
- * LayerRenderer) can all get destroyed and re-created if the GeckoApp
- * activity is destroyed. This GLController is never destroyed, so that
- * the mCompositorCreated field and other state variables are always
- * accurate.
- */
-public class GLController {
- private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
- private static final String LOGTAG = "GeckoGLController";
-
- private static GLController sInstance;
-
- private LayerView mView;
- private boolean mServerSurfaceValid;
- private int mWidth, mHeight;
-
- /* This is written by the compositor thread (while the UI thread
- * is blocked on it) and read by the UI thread. */
- private volatile boolean mCompositorCreated;
-
- private EGL10 mEGL;
- private EGLDisplay mEGLDisplay;
- private EGLConfig mEGLConfig;
- private EGLPreloadingThread mEGLPreloadingThread;
- private EGLSurface mEGLSurfaceForCompositor;
-
- private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4;
-
- private static final int[] CONFIG_SPEC_16BPP = {
- EGL10.EGL_RED_SIZE, 5,
- EGL10.EGL_GREEN_SIZE, 6,
- EGL10.EGL_BLUE_SIZE, 5,
- EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
- EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
- EGL10.EGL_NONE
- };
-
- private static final int[] CONFIG_SPEC_24BPP = {
- EGL10.EGL_RED_SIZE, 8,
- EGL10.EGL_GREEN_SIZE, 8,
- EGL10.EGL_BLUE_SIZE, 8,
- EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
- EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
- EGL10.EGL_NONE
- };
-
- private GLController() {
- mEGLPreloadingThread = new EGLPreloadingThread();
- mEGLPreloadingThread.start();
- }
-
- static GLController getInstance(LayerView view) {
- if (sInstance == null) {
- sInstance = new GLController();
- }
- sInstance.mView = view;
- return sInstance;
- }
-
- synchronized void serverSurfaceDestroyed() {
- ThreadUtils.assertOnUiThread();
- Log.w(LOGTAG, "GLController::serverSurfaceDestroyed() with mCompositorCreated=" + mCompositorCreated);
-
- mServerSurfaceValid = false;
-
- if (mEGLSurfaceForCompositor != null) {
- mEGL.eglDestroySurface(mEGLDisplay, mEGLSurfaceForCompositor);
- mEGLSurfaceForCompositor = null;
- }
-
- // We need to coordinate with Gecko when pausing composition, to ensure
- // that Gecko never executes a draw event while the compositor is paused.
- // This is sent synchronously to make sure that we don't attempt to use
- // any outstanding Surfaces after we call this (such as from a
- // serverSurfaceDestroyed notification), and to make sure that any in-flight
- // Gecko draw events have been processed. When this returns, composition is
- // definitely paused -- it'll synchronize with the Gecko event loop, which
- // in turn will synchronize with the compositor thread.
- if (mCompositorCreated) {
- //GeckoAppShell.sendEventToGeckoSync(GeckoEvent.createCompositorPauseEvent());
- }
- Log.w(LOGTAG, "done GLController::serverSurfaceDestroyed()");
- }
-
- synchronized void serverSurfaceChanged(int newWidth, int newHeight) {
- ThreadUtils.assertOnUiThread();
- Log.w(LOGTAG, "GLController::serverSurfaceChanged(" + newWidth + ", " + newHeight + ")");
-
- mWidth = newWidth;
- mHeight = newHeight;
- mServerSurfaceValid = true;
-
- // we defer to a runnable the task of updating the compositor, because this is going to
- // call back into createEGLSurfaceForCompositor, which will try to create an EGLSurface
- // against mView, which we suspect might fail if called too early. By posting this to
- // mView, we hope to ensure that it is deferred until mView is actually "ready" for some
- // sense of "ready".
- mView.post(new Runnable() {
- @Override
- public void run() {
- updateCompositor();
- }
- });
- }
-
- void updateCompositor() {
- ThreadUtils.assertOnUiThread();
- Log.w(LOGTAG, "GLController::updateCompositor with mCompositorCreated=" + mCompositorCreated);
-
- if (mCompositorCreated) {
- // If the compositor has already been created, just resume it instead. We don't need
- // to block here because if the surface is destroyed before the compositor grabs it,
- // we can handle that gracefully (i.e. the compositor will remain paused).
- resumeCompositor(mWidth, mHeight);
- Log.w(LOGTAG, "done GLController::updateCompositor with compositor resume");
- return;
- }
-
- if (!AttemptPreallocateEGLSurfaceForCompositor()) {
- return;
- }
-
- // Only try to create the compositor if we have a valid surface and gecko is up. When these
- // two conditions are satisfied, we can be relatively sure that the compositor creation will
- // happen without needing to block anywhere. Do it with a sync gecko event so that the
- // android doesn't have a chance to destroy our surface in between.
- /*if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
- GeckoAppShell.sendEventToGeckoSync(GeckoEvent.createCompositorCreateEvent(mWidth, mHeight));
- }*/
- Log.w(LOGTAG, "done GLController::updateCompositor");
- }
-
- void compositorCreated() {
- Log.w(LOGTAG, "GLController::compositorCreated");
- // This is invoked on the compositor thread, while the java UI thread
- // is blocked on the gecko sync event in updateCompositor() above
- mCompositorCreated = true;
- }
-
- public boolean isServerSurfaceValid() {
- return mServerSurfaceValid;
- }
-
- public boolean isCompositorCreated() {
- return mCompositorCreated;
- }
-
- private void initEGL() {
- if (mEGL != null) {
- return;
- }
-
- // This join() should not be necessary, but makes this code a bit easier to think about.
- // The EGLPreloadingThread should long be done by now, and even if it's not,
- // it shouldn't be a problem to be initalizing EGL from two different threads.
- // Still, having this join() here means that we don't have to wonder about what
- // kind of caveats might exist with EGL initialization reentrancy on various drivers.
- try {
- mEGLPreloadingThread.join();
- } catch (InterruptedException e) {
- Log.w(LOGTAG, "EGLPreloadingThread interrupted", e);
- }
-
- mEGL = (EGL10)EGLContext.getEGL();
-
- mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
- if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) {
- Log.w(LOGTAG, "Can't get EGL display!");
- return;
- }
-
- // while calling eglInitialize here should not be necessary as it was already called
- // by the EGLPreloadingThread, it really doesn't cost much to call it again here,
- // and makes this code easier to think about: EGLPreloadingThread is only a
- // preloading optimization, not something we rely on for anything else.
- //
- // Also note that while calling eglInitialize isn't necessary on Android 4.x
- // (at least Android's HardwareRenderer does it for us already), it is necessary
- // on Android 2.x.
- int[] returnedVersion = new int[2];
- if (!mEGL.eglInitialize(mEGLDisplay, returnedVersion)) {
- Log.w(LOGTAG, "eglInitialize failed");
- return;
- }
-
- mEGLConfig = chooseConfig();
- }
-
- private EGLConfig chooseConfig() {
- int[] desiredConfig;
- int rSize, gSize, bSize;
- int[] numConfigs = new int[1];
-
- switch (/*GeckoAppShell*/LOKitShell.getScreenDepth()) {
- case 24:
- desiredConfig = CONFIG_SPEC_24BPP;
- rSize = gSize = bSize = 8;
- break;
- case 16:
- default:
- desiredConfig = CONFIG_SPEC_16BPP;
- rSize = 5; gSize = 6; bSize = 5;
- break;
- }
-
- if (!mEGL.eglChooseConfig(mEGLDisplay, desiredConfig, null, 0, numConfigs) ||
- numConfigs[0] <= 0) {
- throw new GLControllerException("No available EGL configurations " +
- getEGLError());
- }
-
- EGLConfig[] configs = new EGLConfig[numConfigs[0]];
- if (!mEGL.eglChooseConfig(mEGLDisplay, desiredConfig, configs, numConfigs[0], numConfigs)) {
- throw new GLControllerException("No EGL configuration for that specification " +
- getEGLError());
- }
-
- // Select the first configuration that matches the screen depth.
- int[] red = new int[1], green = new int[1], blue = new int[1];
- for (EGLConfig config : configs) {
- mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_RED_SIZE, red);
- mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_GREEN_SIZE, green);
- mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_BLUE_SIZE, blue);
- if (red[0] == rSize && green[0] == gSize && blue[0] == bSize) {
- return config;
- }
- }
-
- throw new GLControllerException("No suitable EGL configuration found");
- }
-
- private synchronized boolean AttemptPreallocateEGLSurfaceForCompositor() {
- if (mEGLSurfaceForCompositor == null) {
- initEGL();
- try {
- mEGLSurfaceForCompositor = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mView.getNativeWindow(), null);
- // In failure cases, eglCreateWindowSurface should return EGL_NO_SURFACE.
- // We currently normalize this to null, and compare to null in all our checks.
- if (mEGLSurfaceForCompositor == EGL10.EGL_NO_SURFACE) {
- mEGLSurfaceForCompositor = null;
- }
- } catch (Exception e) {
- Log.e(LOGTAG, "eglCreateWindowSurface threw", e);
- }
- }
- if (mEGLSurfaceForCompositor == null) {
- Log.w(LOGTAG, "eglCreateWindowSurface returned no surface!");
- }
- return mEGLSurfaceForCompositor != null;
- }
-
- // @WrapElementForJNI(allowMultithread = true, stubName = "CreateEGLSurfaceForCompositorWrapper")
- private synchronized EGLSurface createEGLSurfaceForCompositor() {
- AttemptPreallocateEGLSurfaceForCompositor();
- EGLSurface result = mEGLSurfaceForCompositor;
- mEGLSurfaceForCompositor = null;
- return result;
- }
-
- private String getEGLError() {
- return "Error " + (mEGL == null ? "(no mEGL)" : mEGL.eglGetError());
- }
-
- void resumeCompositor(int width, int height) {
- Log.w(LOGTAG, "GLController::resumeCompositor(" + width + ", " + height + ") and mCompositorCreated=" + mCompositorCreated);
- // Asking Gecko to resume the compositor takes too long (see
- // https://bugzilla.mozilla.org/show_bug.cgi?id=735230#c23), so we
- // resume the compositor directly. We still need to inform Gecko about
- // the compositor resuming, so that Gecko knows that it can now draw.
- // It is important to not notify Gecko until after the compositor has
- // been resumed, otherwise Gecko may send updates that get dropped.
- if (mCompositorCreated) {
- //GeckoAppShell.scheduleResumeComposition(width, height);
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createCompositorResumeEvent());
- }
- Log.w(LOGTAG, "done GLController::resumeCompositor");
- }
-
- public static class GLControllerException extends RuntimeException {
- public static final long serialVersionUID = 1L;
-
- GLControllerException(String e) {
- super(e);
- }
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
deleted file mode 100644
index 049b1fe59564..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ /dev/null
@@ -1,1000 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-//import org.mozilla.gecko.Tab;
-//import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.ZoomConstraints;
-//import org.mozilla.gecko.mozglue.RobocopTarget;
-//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
-import org.mozilla.gecko.util.EventDispatcher;
-import org.mozilla.gecko.util.FloatUtils;
-
-import android.content.Context;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.os.SystemClock;
-import android.util.DisplayMetrics;
-import android.util.Log;
-
-public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
-{
- private static final String LOGTAG = "GeckoLayerClient";
-
- private LayerRenderer mLayerRenderer;
- private boolean mLayerRendererInitialized;
-
- private Context mContext;
- private IntSize mScreenSize;
- private IntSize mWindowSize;
- private DisplayPortMetrics mDisplayPort;
-
- private boolean mRecordDrawTimes;
- private final DrawTimingQueue mDrawTimingQueue;
-
- private VirtualLayer mRootLayer;
-
- /* The Gecko viewport as per the UI thread. Must be touched only on the UI thread.
- * If any events being sent to Gecko that are relative to the Gecko viewport position,
- * they must (a) be relative to this viewport, and (b) be sent on the UI thread to
- * avoid races. As long as these two conditions are satisfied, and the events being
- * sent to Gecko are processed in FIFO order, the events will properly be relative
- * to the Gecko viewport position. Note that if Gecko updates its viewport independently,
- * we get notified synchronously and also update this on the UI thread.
- */
- private ImmutableViewportMetrics mGeckoViewport;
-
- /*
- * The viewport metrics being used to draw the current frame. This is only
- * accessed by the compositor thread, and so needs no synchronisation.
- */
- private ImmutableViewportMetrics mFrameMetrics;
-
- private DrawListener mDrawListener;
-
- /* Used as temporaries by syncViewportInfo */
- private final ViewTransform mCurrentViewTransform;
- private final RectF mCurrentViewTransformMargins;
-
- /* Used as the return value of progressiveUpdateCallback */
- private final ProgressiveUpdateData mProgressiveUpdateData;
- private DisplayPortMetrics mProgressiveUpdateDisplayPort;
- private boolean mLastProgressiveUpdateWasLowPrecision;
- private boolean mProgressiveUpdateWasInDanger;
-
- private boolean mForceRedraw;
-
- /* The current viewport metrics.
- * This is volatile so that we can read and write to it from different threads.
- * We avoid synchronization to make getting the viewport metrics from
- * the compositor as cheap as possible. The viewport is immutable so
- * we don't need to worry about anyone mutating it while we're reading from it.
- * Specifically:
- * 1) reading mViewportMetrics from any thread is fine without synchronization
- * 2) writing to mViewportMetrics requires synchronizing on the layer controller object
- * 3) whenver reading multiple fields from mViewportMetrics without synchronization (i.e. in
- * case 1 above) you should always frist grab a local copy of the reference, and then use
- * that because mViewportMetrics might get reassigned in between reading the different
- * fields. */
- private volatile ImmutableViewportMetrics mViewportMetrics;
- private OnMetricsChangedListener mViewportChangeListener;
-
- private ZoomConstraints mZoomConstraints;
-
- private boolean mGeckoIsReady;
-
- private final PanZoomController mPanZoomController;
- private final LayerMarginsAnimator mMarginsAnimator;
- private LayerView mView;
-
- /* This flag is true from the time that browser.js detects a first-paint is about to start,
- * to the time that we receive the first-paint composite notification from the compositor.
- * Note that there is a small race condition with this; if there are two paints that both
- * have the first-paint flag set, and the second paint happens concurrently with the
- * composite for the first paint, then this flag may be set to true prematurely. Fixing this
- * is possible but risky; see https://bugzilla.mozilla.org/show_bug.cgi?id=797615#c751
- */
- private volatile boolean mContentDocumentIsDisplayed;
-
- public GeckoLayerClient(Context context, LayerView view, EventDispatcher eventDispatcher) {
- // we can fill these in with dummy values because they are always written
- // to before being read
- mContext = context;
- mScreenSize = new IntSize(0, 0);
- mWindowSize = new IntSize(0, 0);
- mDisplayPort = new DisplayPortMetrics();
- mRecordDrawTimes = true;
- mDrawTimingQueue = new DrawTimingQueue();
- mCurrentViewTransform = new ViewTransform(0, 0, 1);
- mCurrentViewTransformMargins = new RectF();
- mProgressiveUpdateData = new ProgressiveUpdateData();
- mProgressiveUpdateDisplayPort = new DisplayPortMetrics();
- mLastProgressiveUpdateWasLowPrecision = false;
- mProgressiveUpdateWasInDanger = false;
-
- mForceRedraw = true;
- DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
- mViewportMetrics = new ImmutableViewportMetrics(displayMetrics)
- .setViewportSize(view.getWidth(), view.getHeight());
- mZoomConstraints = new ZoomConstraints(false);
-
- /*Tab tab = Tabs.getInstance().getSelectedTab();
- if (tab != null) {
- mZoomConstraints = tab.getZoomConstraints();
- mViewportMetrics = mViewportMetrics.setIsRTL(tab.getIsRTL());
- }*/
-
- mFrameMetrics = mViewportMetrics;
-
- mPanZoomController = PanZoomController.Factory.create(this, view, eventDispatcher);
- mMarginsAnimator = new LayerMarginsAnimator(this, view);
- mView = view;
- mView.setListener(this);
- mContentDocumentIsDisplayed = true;
- }
-
- public void setOverscrollHandler(final Overscroll listener) {
- mPanZoomController.setOverscrollHandler(listener);
- }
-
- /** Attaches to root layer so that Gecko appears. */
- public void notifyGeckoReady() {
- mGeckoIsReady = true;
-
- mRootLayer = new VirtualLayer(new IntSize(mView.getWidth(), mView.getHeight()));
- mLayerRenderer = mView.getRenderer();
-
- sendResizeEventIfNecessary(true);
-
- DisplayPortCalculator.initPrefs();
-
- // Gecko being ready is one of the two conditions (along with having an available
- // surface) that cause us to create the compositor. So here, now that we know gecko
- // is ready, call updateCompositor() to see if we can actually do the creation.
- // This needs to run on the UI thread so that the surface validity can't change on
- // us while we're in the middle of creating the compositor.
- mView.post(new Runnable() {
- @Override
- public void run() {
- mView.getGLController().updateCompositor();
- }
- });
- }
-
- public void destroy() {
- mPanZoomController.destroy();
- mMarginsAnimator.destroy();
- }
-
- /**
- * Returns true if this client is fine with performing a redraw operation or false if it
- * would prefer that the action didn't take place.
- */
- private boolean getRedrawHint() {
- if (mForceRedraw) {
- mForceRedraw = false;
- return true;
- }
-
- if (!mPanZoomController.getRedrawHint()) {
- return false;
- }
-
- return DisplayPortCalculator.aboutToCheckerboard(mViewportMetrics,
- mPanZoomController.getVelocityVector(), mDisplayPort);
- }
-
- Layer getRoot() {
- return mGeckoIsReady ? mRootLayer : null;
- }
-
- public LayerView getView() {
- return mView;
- }
-
- public FloatSize getViewportSize() {
- return mViewportMetrics.getSize();
- }
-
- /**
- * The view calls this function to indicate that the viewport changed size. It must hold the
- * monitor while calling it.
- *
- * TODO: Refactor this to use an interface. Expose that interface only to the view and not
- * to the layer client. That way, the layer client won't be tempted to call this, which might
- * result in an infinite loop.
- */
- void setViewportSize(int width, int height) {
- mViewportMetrics = mViewportMetrics.setViewportSize(width, height);
-
- if (mGeckoIsReady) {
- // here we send gecko a resize message. The code in browser.js is responsible for
- // picking up on that resize event, modifying the viewport as necessary, and informing
- // us of the new viewport.
- sendResizeEventIfNecessary(true);
- // the following call also sends gecko a message, which will be processed after the resize
- // message above has updated the viewport. this message ensures that if we have just put
- // focus in a text field, we scroll the content so that the text field is in view.
-
- //GeckoAppShell.viewSizeChanged();
- }
- }
-
- PanZoomController getPanZoomController() {
- return mPanZoomController;
- }
-
- LayerMarginsAnimator getLayerMarginsAnimator() {
- return mMarginsAnimator;
- }
-
- /* Informs Gecko that the screen size has changed. */
- private void sendResizeEventIfNecessary(boolean force) {
- DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
-
- IntSize newScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels);
- IntSize newWindowSize = new IntSize(mView.getWidth(), mView.getHeight());
-
- boolean screenSizeChanged = !mScreenSize.equals(newScreenSize);
- boolean windowSizeChanged = !mWindowSize.equals(newWindowSize);
-
- if (!force && !screenSizeChanged && !windowSizeChanged) {
- return;
- }
-
- mScreenSize = newScreenSize;
- mWindowSize = newWindowSize;
-
- if (screenSizeChanged) {
- Log.d(LOGTAG, "Screen-size changed to " + mScreenSize);
- }
-
- if (windowSizeChanged) {
- Log.d(LOGTAG, "Window-size changed to " + mWindowSize);
- }
-
- /*GeckoEvent event = GeckoEvent.createSizeChangedEvent(mWindowSize.width, mWindowSize.height,
- mScreenSize.width, mScreenSize.height);
- GeckoAppShell.sendEventToGecko(event);
- GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Window:Resize", ""));*/
- }
-
- /** Sets the current page rect. You must hold the monitor while calling this. */
- private void setPageRect(RectF rect, RectF cssRect) {
- // Since the "rect" is always just a multiple of "cssRect" we don't need to
- // check both; this function assumes that both "rect" and "cssRect" are relative
- // the zoom factor in mViewportMetrics.
- if (mViewportMetrics.getCssPageRect().equals(cssRect))
- return;
-
- mViewportMetrics = mViewportMetrics.setPageRect(rect, cssRect);
-
- // Page size is owned by the layer client, so no need to notify it of
- // this change.
-
- post(new Runnable() {
- @Override
- public void run() {
- mPanZoomController.pageRectUpdated();
- mView.requestRender();
- }
- });
- }
-
- /**
- * Derives content document fixed position margins/fixed layer margins from
- * the view margins in the given metrics object.
- */
- private void getFixedMargins(ImmutableViewportMetrics metrics, RectF fixedMargins) {
- fixedMargins.left = 0;
- fixedMargins.top = 0;
- fixedMargins.right = 0;
- fixedMargins.bottom = 0;
-
- // The maximum margins are determined by the scrollable area of the page.
- float maxMarginWidth = Math.max(0, metrics.getPageWidth() - metrics.getWidthWithoutMargins());
- float maxMarginHeight = Math.max(0, metrics.getPageHeight() - metrics.getHeightWithoutMargins());
-
- // If the margins can't fully hide, they're pinned on - in which case,
- // fixed margins should always be zero.
- if (maxMarginWidth < metrics.marginLeft + metrics.marginRight) {
- maxMarginWidth = 0;
- }
- if (maxMarginHeight < metrics.marginTop + metrics.marginBottom) {
- maxMarginHeight = 0;
- }
-
- PointF offset = metrics.getMarginOffset();
- RectF overscroll = metrics.getOverscroll();
- if (offset.x >= 0) {
- fixedMargins.right = Math.max(0, Math.min(offset.x - overscroll.right, maxMarginWidth));
- } else {
- fixedMargins.left = Math.max(0, Math.min(-offset.x - overscroll.left, maxMarginWidth));
- }
- if (offset.y >= 0) {
- fixedMargins.bottom = Math.max(0, Math.min(offset.y - overscroll.bottom, maxMarginHeight));
- } else {
- fixedMargins.top = Math.max(0, Math.min(-offset.y - overscroll.top, maxMarginHeight));
- }
-
- // Adjust for overscroll. If we're overscrolled on one side, add that
- // distance to the margins of the other side (limiting to the maximum
- // margin size calculated above).
- if (overscroll.left > 0) {
- fixedMargins.right = Math.min(maxMarginWidth - fixedMargins.left,
- fixedMargins.right + overscroll.left);
- } else if (overscroll.right > 0) {
- fixedMargins.left = Math.min(maxMarginWidth - fixedMargins.right,
- fixedMargins.left + overscroll.right);
- }
- if (overscroll.top > 0) {
- fixedMargins.bottom = Math.min(maxMarginHeight - fixedMargins.top,
- fixedMargins.bottom + overscroll.top);
- } else if (overscroll.bottom > 0) {
- fixedMargins.top = Math.min(maxMarginHeight - fixedMargins.bottom,
- fixedMargins.top + overscroll.bottom);
- }
- }
-
- private void adjustViewport(DisplayPortMetrics displayPort) {
- ImmutableViewportMetrics metrics = getViewportMetrics();
- ImmutableViewportMetrics clampedMetrics = metrics.clamp();
-
- RectF margins = new RectF();
- getFixedMargins(metrics, margins);
- clampedMetrics = clampedMetrics.setMargins(
- margins.left, margins.top, margins.right, margins.bottom);
-
- if (displayPort == null) {
- displayPort = DisplayPortCalculator.calculate(metrics, mPanZoomController.getVelocityVector());
- }
-
- mDisplayPort = displayPort;
- mGeckoViewport = clampedMetrics;
-
- if (mRecordDrawTimes) {
- mDrawTimingQueue.add(displayPort);
- }
-
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(clampedMetrics, displayPort));
- }
-
- /** Aborts any pan/zoom animation that is currently in progress. */
- private void abortPanZoomAnimation() {
- if (mPanZoomController != null) {
- post(new Runnable() {
- @Override
- public void run() {
- mPanZoomController.abortAnimation();
- }
- });
- }
- }
-
- /**
- * The different types of Viewport messages handled. All viewport events
- * expect a display-port to be returned, but can handle one not being
- * returned.
- */
- private enum ViewportMessageType {
- UPDATE, // The viewport has changed and should be entirely updated
- PAGE_SIZE // The viewport's page-size has changed
- }
-
- /** Viewport message handler. */
- private DisplayPortMetrics handleViewportMessage(ImmutableViewportMetrics messageMetrics, ViewportMessageType type) {
- synchronized (getLock()) {
- ImmutableViewportMetrics newMetrics;
- ImmutableViewportMetrics oldMetrics = getViewportMetrics();
-
- switch (type) {
- default:
- case UPDATE:
- // Keep the old viewport size
- newMetrics = messageMetrics.setViewportSize(oldMetrics.getWidth(), oldMetrics.getHeight());
- if (!oldMetrics.fuzzyEquals(newMetrics)) {
- abortPanZoomAnimation();
- }
- break;
- case PAGE_SIZE:
- // adjust the page dimensions to account for differences in zoom
- // between the rendered content (which is what Gecko tells us)
- // and our zoom level (which may have diverged).
- float scaleFactor = oldMetrics.zoomFactor / messageMetrics.zoomFactor;
- newMetrics = oldMetrics.setPageRect(RectUtils.scale(messageMetrics.getPageRect(), scaleFactor), messageMetrics.getCssPageRect());
- break;
- }
-
- // Update the Gecko-side viewport metrics. Make sure to do this
- // before modifying the metrics below.
- final ImmutableViewportMetrics geckoMetrics = newMetrics.clamp();
- post(new Runnable() {
- @Override
- public void run() {
- mGeckoViewport = geckoMetrics;
- }
- });
-
- setViewportMetrics(newMetrics, type == ViewportMessageType.UPDATE);
- mDisplayPort = DisplayPortCalculator.calculate(getViewportMetrics(), null);
- }
- return mDisplayPort;
- }
-
- //@WrapElementForJNI
- DisplayPortMetrics getDisplayPort(boolean pageSizeUpdate, boolean isBrowserContentDisplayed, int tabId, ImmutableViewportMetrics metrics) {
- /**Tabs tabs = Tabs.getInstance();
- if (isBrowserContentDisplayed && tabs.isSelectedTabId(tabId)) {
- // for foreground tabs, send the viewport update unless the document
- // displayed is different from the content document. In that case, just
- // calculate the display port.
- return handleViewportMessage(metrics, pageSizeUpdate ? ViewportMessageType.PAGE_SIZE : ViewportMessageType.UPDATE);
- } else*/ {
- // for background tabs, request a new display port calculation, so that
- // when we do switch to that tab, we have the correct display port and
- // don't need to draw twice (once to allow the first-paint viewport to
- // get to java, and again once java figures out the display port).
- return DisplayPortCalculator.calculate(metrics, null);
- }
- }
-
- //@WrapElementForJNI
- void contentDocumentChanged() {
- mContentDocumentIsDisplayed = false;
- }
-
- //@WrapElementForJNI
- boolean isContentDocumentDisplayed() {
- return mContentDocumentIsDisplayed;
- }
-
- // This is called on the Gecko thread to determine if we're still interested
- // in the update of this display-port to continue. We can return true here
- // to abort the current update and continue with any subsequent ones. This
- // is useful for slow-to-render pages when the display-port starts lagging
- // behind enough that continuing to draw it is wasted effort.
- //@WrapElementForJNI(allowMultithread = true)
- public ProgressiveUpdateData progressiveUpdateCallback(boolean aHasPendingNewThebesContent,
- float x, float y, float width, float height,
- float resolution, boolean lowPrecision) {
- // Reset the checkerboard risk flag when switching to low precision
- // rendering.
- if (lowPrecision && !mLastProgressiveUpdateWasLowPrecision) {
- // Skip low precision rendering until we're at risk of checkerboarding.
- if (!mProgressiveUpdateWasInDanger) {
- mProgressiveUpdateData.abort = true;
- return mProgressiveUpdateData;
- }
- mProgressiveUpdateWasInDanger = false;
- }
- mLastProgressiveUpdateWasLowPrecision = lowPrecision;
-
- // Grab a local copy of the last display-port sent to Gecko and the
- // current viewport metrics to avoid races when accessing them.
- DisplayPortMetrics displayPort = mDisplayPort;
- ImmutableViewportMetrics viewportMetrics = mViewportMetrics;
- mProgressiveUpdateData.setViewport(viewportMetrics);
- mProgressiveUpdateData.abort = false;
-
- // Always abort updates if the resolution has changed. There's no use
- // in drawing at the incorrect resolution.
- if (!FloatUtils.fuzzyEquals(resolution, viewportMetrics.zoomFactor)) {
- Log.d(LOGTAG, "Aborting draw due to resolution change: " + resolution + " != " + viewportMetrics.zoomFactor);
- mProgressiveUpdateData.abort = true;
- return mProgressiveUpdateData;
- }
-
- // Store the high precision displayport for comparison when doing low
- // precision updates.
- if (!lowPrecision) {
- if (!FloatUtils.fuzzyEquals(resolution, mProgressiveUpdateDisplayPort.resolution) ||
- !FloatUtils.fuzzyEquals(x, mProgressiveUpdateDisplayPort.getLeft()) ||
- !FloatUtils.fuzzyEquals(y, mProgressiveUpdateDisplayPort.getTop()) ||
- !FloatUtils.fuzzyEquals(x + width, mProgressiveUpdateDisplayPort.getRight()) ||
- !FloatUtils.fuzzyEquals(y + height, mProgressiveUpdateDisplayPort.getBottom())) {
- mProgressiveUpdateDisplayPort =
- new DisplayPortMetrics(x, y, x+width, y+height, resolution);
- }
- }
-
- // If we're not doing low precision draws and we're about to
- // checkerboard, enable low precision drawing.
- if (!lowPrecision && !mProgressiveUpdateWasInDanger) {
- if (DisplayPortCalculator.aboutToCheckerboard(viewportMetrics,
- mPanZoomController.getVelocityVector(), mProgressiveUpdateDisplayPort)) {
- mProgressiveUpdateWasInDanger = true;
- }
- }
-
- // XXX All sorts of rounding happens inside Gecko that becomes hard to
- // account exactly for. Given we align the display-port to tile
- // boundaries (and so they rarely vary by sub-pixel amounts), just
- // check that values are within a couple of pixels of the
- // display-port bounds.
-
- // Never abort drawing if we can't be sure we've sent a more recent
- // display-port. If we abort updating when we shouldn't, we can end up
- // with blank regions on the screen and we open up the risk of entering
- // an endless updating cycle.
- if (Math.abs(displayPort.getLeft() - mProgressiveUpdateDisplayPort.getLeft()) <= 2 &&
- Math.abs(displayPort.getTop() - mProgressiveUpdateDisplayPort.getTop()) <= 2 &&
- Math.abs(displayPort.getBottom() - mProgressiveUpdateDisplayPort.getBottom()) <= 2 &&
- Math.abs(displayPort.getRight() - mProgressiveUpdateDisplayPort.getRight()) <= 2) {
- return mProgressiveUpdateData;
- }
-
- // Abort updates when the display-port no longer contains the visible
- // area of the page (that is, the viewport cropped by the page
- // boundaries).
- // XXX This makes the assumption that we never let the visible area of
- // the page fall outside of the display-port.
- if (Math.max(viewportMetrics.viewportRectLeft, viewportMetrics.pageRectLeft) + 1 < x ||
- Math.max(viewportMetrics.viewportRectTop, viewportMetrics.pageRectTop) + 1 < y ||
- Math.min(viewportMetrics.viewportRectRight, viewportMetrics.pageRectRight) - 1 > x + width ||
- Math.min(viewportMetrics.viewportRectBottom, viewportMetrics.pageRectBottom) - 1 > y + height) {
- Log.d(LOGTAG, "Aborting update due to viewport not in display-port");
- mProgressiveUpdateData.abort = true;
-
- // Enable low-precision drawing, as we're likely to be in danger if
- // this situation has been encountered.
- mProgressiveUpdateWasInDanger = true;
-
- return mProgressiveUpdateData;
- }
-
- // Abort drawing stale low-precision content if there's a more recent
- // display-port in the pipeline.
- if (lowPrecision && !aHasPendingNewThebesContent) {
- mProgressiveUpdateData.abort = true;
- }
- return mProgressiveUpdateData;
- }
-
- void setZoomConstraints(ZoomConstraints constraints) {
- mZoomConstraints = constraints;
- }
-
- void setIsRTL(boolean aIsRTL) {
- synchronized (getLock()) {
- ImmutableViewportMetrics newMetrics = getViewportMetrics().setIsRTL(aIsRTL);
- setViewportMetrics(newMetrics, false);
- }
- }
-
- /** The compositor invokes this function just before compositing a frame where the document
- * is different from the document composited on the last frame. In these cases, the viewport
- * information we have in Java is no longer valid and needs to be replaced with the new
- * viewport information provided. setPageRect will never be invoked on the same frame that
- * this function is invoked on; and this function will always be called prior to syncViewportInfo.
- */
- //@WrapElementForJNI(allowMultithread = true)
- public void setFirstPaintViewport(float offsetX, float offsetY, float zoom,
- float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) {
- synchronized (getLock()) {
- ImmutableViewportMetrics currentMetrics = getViewportMetrics();
-
- //Tab tab = Tabs.getInstance().getSelectedTab();
-
- RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
- RectF pageRect = RectUtils.scaleAndRound(cssPageRect, zoom);
-
- final ImmutableViewportMetrics newMetrics = currentMetrics
- .setViewportOrigin(offsetX, offsetY)
- .setZoomFactor(zoom)
- .setPageRect(pageRect, cssPageRect)
- /*.setIsRTL(tab.getIsRTL())*/;
- // Since we have switched to displaying a different document, we need to update any
- // viewport-related state we have lying around. This includes mGeckoViewport and
- // mViewportMetrics. Usually this information is updated via handleViewportMessage
- // while we remain on the same document.
- post(new Runnable() {
- @Override
- public void run() {
- mGeckoViewport = newMetrics;
- }
- });
-
- setViewportMetrics(newMetrics);
-
- //mView.setBackgroundColor(tab.getBackgroundColor());
- //setZoomConstraints(tab.getZoomConstraints());
-
- // At this point, we have just switched to displaying a different document than we
- // we previously displaying. This means we need to abort any panning/zooming animations
- // that are in progress and send an updated display port request to browser.js as soon
- // as possible. The call to PanZoomController.abortAnimation accomplishes this by calling the
- // forceRedraw function, which sends the viewport to gecko. The display port request is
- // actually a full viewport update, which is fine because if browser.js has somehow moved to
- // be out of sync with this first-paint viewport, then we force them back in sync.
- abortPanZoomAnimation();
-
- // Indicate that the document is about to be composited so the
- // LayerView background can be removed.
- if (mView.getPaintState() == LayerView.PAINT_START) {
- mView.setPaintState(LayerView.PAINT_BEFORE_FIRST);
- }
- }
- DisplayPortCalculator.resetPageState();
- mDrawTimingQueue.reset();
-
- mContentDocumentIsDisplayed = true;
- }
-
- /** The compositor invokes this function whenever it determines that the page rect
- * has changed (based on the information it gets from layout). If setFirstPaintViewport
- * is invoked on a frame, then this function will not be. For any given frame, this
- * function will be invoked before syncViewportInfo.
- */
- //@WrapElementForJNI(allowMultithread = true)
- public void setPageRect(float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) {
- synchronized (getLock()) {
- RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
- float ourZoom = getViewportMetrics().zoomFactor;
- setPageRect(RectUtils.scale(cssPageRect, ourZoom), cssPageRect);
- // Here the page size of the document has changed, but the document being displayed
- // is still the same. Therefore, we don't need to send anything to browser.js; any
- // changes we need to make to the display port will get sent the next time we call
- // adjustViewport().
- }
- }
-
- /** The compositor invokes this function on every frame to figure out what part of the
- * page to display, and to inform Java of the current display port. Since it is called
- * on every frame, it needs to be ultra-fast.
- * It avoids taking any locks or allocating any objects. We keep around a
- * mCurrentViewTransform so we don't need to allocate a new ViewTransform
- * every time we're called. NOTE: we might be able to return a ImmutableViewportMetrics
- * which would avoid the copy into mCurrentViewTransform.
- */
- //@WrapElementForJNI(allowMultithread = true)
- public ViewTransform syncViewportInfo(int x, int y, int width, int height, float resolution, boolean layersUpdated) {
- // getViewportMetrics is thread safe so we don't need to synchronize.
- // We save the viewport metrics here, so we later use it later in
- // createFrame (which will be called by nsWindow::DrawWindowUnderlay on
- // the native side, by the compositor). The viewport
- // metrics can change between here and there, as it's accessed outside
- // of the compositor thread.
- mFrameMetrics = getViewportMetrics();
-
- mCurrentViewTransform.x = mFrameMetrics.viewportRectLeft;
- mCurrentViewTransform.y = mFrameMetrics.viewportRectTop;
- mCurrentViewTransform.scale = mFrameMetrics.zoomFactor;
-
- // Adjust the fixed layer margins so that overscroll subtracts from them.
- getFixedMargins(mFrameMetrics, mCurrentViewTransformMargins);
- mCurrentViewTransform.fixedLayerMarginLeft = mCurrentViewTransformMargins.left;
- mCurrentViewTransform.fixedLayerMarginTop = mCurrentViewTransformMargins.top;
- mCurrentViewTransform.fixedLayerMarginRight = mCurrentViewTransformMargins.right;
- mCurrentViewTransform.fixedLayerMarginBottom = mCurrentViewTransformMargins.bottom;
-
- // Offset the view transform so that it renders in the correct place.
- PointF offset = mFrameMetrics.getMarginOffset();
- mCurrentViewTransform.offsetX = offset.x;
- mCurrentViewTransform.offsetY = offset.y;
-
- mRootLayer.setPositionAndResolution(
- Math.round(x + mCurrentViewTransform.offsetX),
- Math.round(y + mCurrentViewTransform.offsetY),
- Math.round(x + width + mCurrentViewTransform.offsetX),
- Math.round(y + height + mCurrentViewTransform.offsetY),
- resolution);
-
- if (layersUpdated && mRecordDrawTimes) {
- // If we got a layers update, that means a draw finished. Check to see if the area drawn matches
- // one of our requested displayports; if it does calculate the draw time and notify the
- // DisplayPortCalculator
- DisplayPortMetrics drawn = new DisplayPortMetrics(x, y, x + width, y + height, resolution);
- long time = mDrawTimingQueue.findTimeFor(drawn);
- if (time >= 0) {
- long now = SystemClock.uptimeMillis();
- time = now - time;
- mRecordDrawTimes = DisplayPortCalculator.drawTimeUpdate(time, width * height);
- }
- }
-
- if (layersUpdated && mDrawListener != null) {
- /* Used by robocop for testing purposes */
- mDrawListener.drawFinished();
- }
-
- return mCurrentViewTransform;
- }
-
- //@WrapElementForJNI(allowMultithread = true)
- public ViewTransform syncFrameMetrics(float offsetX, float offsetY, float zoom,
- float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom,
- boolean layersUpdated, int x, int y, int width, int height, float resolution,
- boolean isFirstPaint)
- {
- if (isFirstPaint) {
- setFirstPaintViewport(offsetX, offsetY, zoom,
- cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
- }
-
- return syncViewportInfo(x, y, width, height, resolution, layersUpdated);
- }
-
- //@WrapElementForJNI(allowMultithread = true)
- public LayerRenderer.Frame createFrame() {
- // Create the shaders and textures if necessary.
- if (!mLayerRendererInitialized) {
- mLayerRenderer.checkMonitoringEnabled();
- mLayerRenderer.createDefaultProgram();
- mLayerRendererInitialized = true;
- }
-
- return mLayerRenderer.createFrame(mFrameMetrics);
- }
-
- //@WrapElementForJNI(allowMultithread = true)
- public void activateProgram() {
- mLayerRenderer.activateDefaultProgram();
- }
-
- //@WrapElementForJNI(allowMultithread = true)
- public void deactivateProgram() {
- mLayerRenderer.deactivateDefaultProgram();
- }
-
- private void geometryChanged(DisplayPortMetrics displayPort) {
- /* Let Gecko know if the screensize has changed */
- sendResizeEventIfNecessary(false);
- if (getRedrawHint()) {
- adjustViewport(displayPort);
- }
- }
-
- /** Implementation of LayerView.Listener */
- @Override
- public void renderRequested() {
- try {
- //GeckoAppShell.scheduleComposite();
- } catch (UnsupportedOperationException uoe) {
- // In some very rare cases this gets called before libxul is loaded,
- // so catch and ignore the exception that will throw. See bug 837821
- Log.d(LOGTAG, "Dropping renderRequested call before libxul load.");
- }
- }
-
- /** Implementation of LayerView.Listener */
- @Override
- public void sizeChanged(int width, int height) {
- // We need to make sure a draw happens synchronously at this point,
- // but resizing the surface before the SurfaceView has resized will
- // cause a visible jump.
- mView.getGLController().resumeCompositor(mWindowSize.width, mWindowSize.height);
- }
-
- /** Implementation of LayerView.Listener */
- @Override
- public void surfaceChanged(int width, int height) {
- setViewportSize(width, height);
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public ImmutableViewportMetrics getViewportMetrics() {
- return mViewportMetrics;
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public ZoomConstraints getZoomConstraints() {
- return mZoomConstraints;
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public boolean isFullScreen() {
- return mView.isFullScreen();
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public RectF getMaxMargins() {
- return mMarginsAnimator.getMaxMargins();
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public void setAnimationTarget(ImmutableViewportMetrics metrics) {
- if (mGeckoIsReady) {
- // We know what the final viewport of the animation is going to be, so
- // immediately request a draw of that area by setting the display port
- // accordingly. This way we should have the content pre-rendered by the
- // time the animation is done.
- DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(metrics, null);
- adjustViewport(displayPort);
- }
- }
-
- /** Implementation of PanZoomTarget
- * You must hold the monitor while calling this.
- */
- @Override
- public void setViewportMetrics(ImmutableViewportMetrics metrics) {
- setViewportMetrics(metrics, true);
- }
-
- /*
- * You must hold the monitor while calling this.
- */
- private void setViewportMetrics(ImmutableViewportMetrics metrics, boolean notifyGecko) {
- // This class owns the viewport size and the fixed layer margins; don't let other pieces
- // of code clobber either of them. The only place the viewport size should ever be
- // updated is in GeckoLayerClient.setViewportSize, and the only place the margins should
- // ever be updated is in GeckoLayerClient.setFixedLayerMargins; both of these assign to
- // mViewportMetrics directly.
- metrics = metrics.setViewportSize(mViewportMetrics.getWidth(), mViewportMetrics.getHeight());
- metrics = metrics.setMarginsFrom(mViewportMetrics);
- mViewportMetrics = metrics;
-
- viewportMetricsChanged(notifyGecko);
- }
-
- /*
- * You must hold the monitor while calling this.
- */
- private void viewportMetricsChanged(boolean notifyGecko) {
- if (mViewportChangeListener != null) {
- mViewportChangeListener.onMetricsChanged(mViewportMetrics);
- }
-
- mView.requestRender();
- if (notifyGecko && mGeckoIsReady) {
- geometryChanged(null);
- }
- }
-
- /*
- * Updates the viewport metrics, overriding the viewport size and margins
- * which are normally retained when calling setViewportMetrics.
- * You must hold the monitor while calling this.
- */
- void forceViewportMetrics(ImmutableViewportMetrics metrics, boolean notifyGecko, boolean forceRedraw) {
- if (forceRedraw) {
- mForceRedraw = true;
- }
- mViewportMetrics = metrics;
- viewportMetricsChanged(notifyGecko);
- }
-
- /** Implementation of PanZoomTarget
- * Scroll the viewport by a certain amount. This will take viewport margins
- * and margin animation into account. If margins are currently animating,
- * this will just go ahead and modify the viewport origin, otherwise the
- * delta will be applied to the margins and the remainder will be applied to
- * the viewport origin.
- *
- * You must hold the monitor while calling this.
- */
- @Override
- public void scrollBy(float dx, float dy) {
- // Set mViewportMetrics manually so the margin changes take.
- mViewportMetrics = mMarginsAnimator.scrollBy(mViewportMetrics, dx, dy);
- viewportMetricsChanged(true);
- }
-
- /** Implementation of PanZoomTarget
- * Notification that a subdocument has been scrolled by a certain amount.
- * This is used here to make sure that the margins are still accessible
- * during subdocument scrolling.
- *
- * You must hold the monitor while calling this.
- */
- @Override
- public void scrollMarginsBy(float dx, float dy) {
- ImmutableViewportMetrics newMarginsMetrics =
- mMarginsAnimator.scrollBy(mViewportMetrics, dx, dy);
- mViewportMetrics = mViewportMetrics.setMarginsFrom(newMarginsMetrics);
- viewportMetricsChanged(true);
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public void panZoomStopped() {
- if (mViewportChangeListener != null) {
- mViewportChangeListener.onPanZoomStopped();
- }
- }
-
- public interface OnMetricsChangedListener {
- public void onMetricsChanged(ImmutableViewportMetrics viewport);
- public void onPanZoomStopped();
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public void forceRedraw(DisplayPortMetrics displayPort) {
- mForceRedraw = true;
- if (mGeckoIsReady) {
- geometryChanged(displayPort);
- }
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public boolean post(Runnable action) {
- return mView.post(action);
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public void postRenderTask(RenderTask task) {
- mView.postRenderTask(task);
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public void removeRenderTask(RenderTask task) {
- mView.removeRenderTask(task);
- }
-
-
- /** Implementation of PanZoomTarget */
- @Override
- public boolean postDelayed(Runnable action, long delayMillis) {
- return mView.postDelayed(action, delayMillis);
- }
-
- /** Implementation of PanZoomTarget */
- @Override
- public Object getLock() {
- return this;
- }
-
- /** Implementation of PanZoomTarget
- * Converts a point from layer view coordinates to layer coordinates. In other words, given a
- * point measured in pixels from the top left corner of the layer view, returns the point in
- * pixels measured from the last scroll position we sent to Gecko, in CSS pixels. Assuming the
- * events being sent to Gecko are processed in FIFO order, this calculation should always be
- * correct.
- */
- @Override
- public PointF convertViewPointToLayerPoint(PointF viewPoint) {
- if (!mGeckoIsReady) {
- return null;
- }
-
- ImmutableViewportMetrics viewportMetrics = mViewportMetrics;
- PointF origin = viewportMetrics.getOrigin();
- PointF offset = viewportMetrics.getMarginOffset();
- origin.offset(-offset.x, -offset.y);
- float zoom = viewportMetrics.zoomFactor;
- ImmutableViewportMetrics geckoViewport = mGeckoViewport;
- PointF geckoOrigin = geckoViewport.getOrigin();
- float geckoZoom = geckoViewport.zoomFactor;
-
- // viewPoint + origin - offset gives the coordinate in device pixels from the top-left corner of the page.
- // Divided by zoom, this gives us the coordinate in CSS pixels from the top-left corner of the page.
- // geckoOrigin / geckoZoom is where Gecko thinks it is (scrollTo position) in CSS pixels from
- // the top-left corner of the page. Subtracting the two gives us the offset of the viewPoint from
- // the current Gecko coordinate in CSS pixels.
- PointF layerPoint = new PointF(
- ((viewPoint.x + origin.x) / zoom) - (geckoOrigin.x / geckoZoom),
- ((viewPoint.y + origin.y) / zoom) - (geckoOrigin.y / geckoZoom));
-
- return layerPoint;
- }
-
- public void setOnMetricsChangedListener(OnMetricsChangedListener listener) {
- mViewportChangeListener = listener;
- }
-
- /** Used by robocop for testing purposes. Not for production use! */
- //@RobocopTarget
- public void setDrawListener(DrawListener listener) {
- mDrawListener = listener;
- }
-
- /** Used by robocop for testing purposes. Not for production use! */
- //@RobocopTarget
- public static interface DrawListener {
- public void drawFinished();
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java
deleted file mode 100644
index 463bc3c4a4a5..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
-import org.mozilla.gecko.util.FloatUtils;
-
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.util.DisplayMetrics;
-
-/**
- * ImmutableViewportMetrics are used to store the viewport metrics
- * in way that we can access a version of them from multiple threads
- * without having to take a lock
- */
-public class ImmutableViewportMetrics {
-
- // We need to flatten the RectF and FloatSize structures
- // because Java doesn't have the concept of const classes
- public final float pageRectLeft;
- public final float pageRectTop;
- public final float pageRectRight;
- public final float pageRectBottom;
- public final float cssPageRectLeft;
- public final float cssPageRectTop;
- public final float cssPageRectRight;
- public final float cssPageRectBottom;
- public final float viewportRectLeft;
- public final float viewportRectTop;
- public final float viewportRectRight;
- public final float viewportRectBottom;
- public final float marginLeft;
- public final float marginTop;
- public final float marginRight;
- public final float marginBottom;
- public final float zoomFactor;
- public final boolean isRTL;
-
- public ImmutableViewportMetrics(DisplayMetrics metrics) {
- viewportRectLeft = pageRectLeft = cssPageRectLeft = 0;
- viewportRectTop = pageRectTop = cssPageRectTop = 0;
- viewportRectRight = pageRectRight = cssPageRectRight = metrics.widthPixels;
- viewportRectBottom = pageRectBottom = cssPageRectBottom = metrics.heightPixels;
- marginLeft = marginTop = marginRight = marginBottom = 0;
- zoomFactor = 1.0f;
- isRTL = false;
- }
-
- /** This constructor is used by native code in AndroidJavaWrappers.cpp, be
- * careful when modifying the signature.
- */
- //@WrapElementForJNI(allowMultithread = true)
- public ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop,
- float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft,
- float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
- float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight,
- float aViewportRectBottom, float aZoomFactor)
- {
- this(aPageRectLeft, aPageRectTop,
- aPageRectRight, aPageRectBottom, aCssPageRectLeft,
- aCssPageRectTop, aCssPageRectRight, aCssPageRectBottom,
- aViewportRectLeft, aViewportRectTop, aViewportRectRight,
- aViewportRectBottom, 0.0f, 0.0f, 0.0f, 0.0f, aZoomFactor, false);
- }
-
- private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop,
- float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft,
- float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
- float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight,
- float aViewportRectBottom, float aMarginLeft,
- float aMarginTop, float aMarginRight,
- float aMarginBottom, float aZoomFactor, boolean aIsRTL)
- {
- pageRectLeft = aPageRectLeft;
- pageRectTop = aPageRectTop;
- pageRectRight = aPageRectRight;
- pageRectBottom = aPageRectBottom;
- cssPageRectLeft = aCssPageRectLeft;
- cssPageRectTop = aCssPageRectTop;
- cssPageRectRight = aCssPageRectRight;
- cssPageRectBottom = aCssPageRectBottom;
- viewportRectLeft = aViewportRectLeft;
- viewportRectTop = aViewportRectTop;
- viewportRectRight = aViewportRectRight;
- viewportRectBottom = aViewportRectBottom;
- marginLeft = aMarginLeft;
- marginTop = aMarginTop;
- marginRight = aMarginRight;
- marginBottom = aMarginBottom;
- zoomFactor = aZoomFactor;
- isRTL = aIsRTL;
- }
-
- public float getWidth() {
- return viewportRectRight - viewportRectLeft;
- }
-
- public float getHeight() {
- return viewportRectBottom - viewportRectTop;
- }
-
- public float getWidthWithoutMargins() {
- return viewportRectRight - viewportRectLeft - marginLeft - marginRight;
- }
-
- public float getHeightWithoutMargins() {
- return viewportRectBottom - viewportRectTop - marginTop - marginBottom;
- }
-
- public PointF getOrigin() {
- return new PointF(viewportRectLeft, viewportRectTop);
- }
-
- public PointF getMarginOffset() {
- if (isRTL) {
- return new PointF(marginLeft - marginRight, marginTop);
- }
- return new PointF(marginLeft, marginTop);
- }
-
- public FloatSize getSize() {
- return new FloatSize(viewportRectRight - viewportRectLeft, viewportRectBottom - viewportRectTop);
- }
-
- public RectF getViewport() {
- return new RectF(viewportRectLeft,
- viewportRectTop,
- viewportRectRight,
- viewportRectBottom);
- }
-
- public RectF getCssViewport() {
- return RectUtils.scale(getViewport(), 1/zoomFactor);
- }
-
- public RectF getPageRect() {
- return new RectF(pageRectLeft, pageRectTop, pageRectRight, pageRectBottom);
- }
-
- public float getPageWidth() {
- return pageRectRight - pageRectLeft;
- }
-
- public float getPageWidthWithMargins() {
- return (pageRectRight - pageRectLeft) + marginLeft + marginRight;
- }
-
- public float getPageHeight() {
- return pageRectBottom - pageRectTop;
- }
-
- public float getPageHeightWithMargins() {
- return (pageRectBottom - pageRectTop) + marginTop + marginBottom;
- }
-
- public RectF getCssPageRect() {
- return new RectF(cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom);
- }
-
- public RectF getOverscroll() {
- return new RectF(Math.max(0, pageRectLeft - viewportRectLeft),
- Math.max(0, pageRectTop - viewportRectTop),
- Math.max(0, viewportRectRight - pageRectRight),
- Math.max(0, viewportRectBottom - pageRectBottom));
- }
-
- /*
- * Returns the viewport metrics that represent a linear transition between "this" and "to" at
- * time "t", which is on the scale [0, 1). This function interpolates all values stored in
- * the viewport metrics.
- */
- public ImmutableViewportMetrics interpolate(ImmutableViewportMetrics to, float t) {
- return new ImmutableViewportMetrics(
- FloatUtils.interpolate(pageRectLeft, to.pageRectLeft, t),
- FloatUtils.interpolate(pageRectTop, to.pageRectTop, t),
- FloatUtils.interpolate(pageRectRight, to.pageRectRight, t),
- FloatUtils.interpolate(pageRectBottom, to.pageRectBottom, t),
- FloatUtils.interpolate(cssPageRectLeft, to.cssPageRectLeft, t),
- FloatUtils.interpolate(cssPageRectTop, to.cssPageRectTop, t),
- FloatUtils.interpolate(cssPageRectRight, to.cssPageRectRight, t),
- FloatUtils.interpolate(cssPageRectBottom, to.cssPageRectBottom, t),
- FloatUtils.interpolate(viewportRectLeft, to.viewportRectLeft, t),
- FloatUtils.interpolate(viewportRectTop, to.viewportRectTop, t),
- FloatUtils.interpolate(viewportRectRight, to.viewportRectRight, t),
- FloatUtils.interpolate(viewportRectBottom, to.viewportRectBottom, t),
- FloatUtils.interpolate(marginLeft, to.marginLeft, t),
- FloatUtils.interpolate(marginTop, to.marginTop, t),
- FloatUtils.interpolate(marginRight, to.marginRight, t),
- FloatUtils.interpolate(marginBottom, to.marginBottom, t),
- FloatUtils.interpolate(zoomFactor, to.zoomFactor, t),
- t >= 0.5 ? to.isRTL : isRTL);
- }
-
- public ImmutableViewportMetrics setViewportSize(float width, float height) {
- if (FloatUtils.fuzzyEquals(width, getWidth()) && FloatUtils.fuzzyEquals(height, getHeight())) {
- return this;
- }
-
- return new ImmutableViewportMetrics(
- pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
- cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
- viewportRectLeft, viewportRectTop, viewportRectLeft + width, viewportRectTop + height,
- marginLeft, marginTop, marginRight, marginBottom,
- zoomFactor, isRTL);
- }
-
- public ImmutableViewportMetrics setViewportOrigin(float newOriginX, float newOriginY) {
- return new ImmutableViewportMetrics(
- pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
- cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
- newOriginX, newOriginY, newOriginX + getWidth(), newOriginY + getHeight(),
- marginLeft, marginTop, marginRight, marginBottom,
- zoomFactor, isRTL);
- }
-
- public ImmutableViewportMetrics setZoomFactor(float newZoomFactor) {
- return new ImmutableViewportMetrics(
- pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
- cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
- viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
- marginLeft, marginTop, marginRight, marginBottom,
- newZoomFactor, isRTL);
- }
-
- public ImmutableViewportMetrics offsetViewportBy(float dx, float dy) {
- return setViewportOrigin(viewportRectLeft + dx, viewportRectTop + dy);
- }
-
- public ImmutableViewportMetrics offsetViewportByAndClamp(float dx, float dy) {
- if (isRTL) {
- return setViewportOrigin(
- Math.min(pageRectRight - getWidthWithoutMargins(), Math.max(viewportRectLeft + dx, pageRectLeft)),
- Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins())));
- }
- return setViewportOrigin(
- Math.max(pageRectLeft, Math.min(viewportRectLeft + dx, pageRectRight - getWidthWithoutMargins())),
- Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins())));
- }
-
- public ImmutableViewportMetrics setPageRect(RectF pageRect, RectF cssPageRect) {
- return new ImmutableViewportMetrics(
- pageRect.left, pageRect.top, pageRect.right, pageRect.bottom,
- cssPageRect.left, cssPageRect.top, cssPageRect.right, cssPageRect.bottom,
- viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
- marginLeft, marginTop, marginRight, marginBottom,
- zoomFactor, isRTL);
- }
-
- public ImmutableViewportMetrics setMargins(float left, float top, float right, float bottom) {
- if (FloatUtils.fuzzyEquals(left, marginLeft)
- && FloatUtils.fuzzyEquals(top, marginTop)
- && FloatUtils.fuzzyEquals(right, marginRight)
- && FloatUtils.fuzzyEquals(bottom, marginBottom)) {
- return this;
- }
-
- return new ImmutableViewportMetrics(
- pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
- cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
- viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
- left, top, right, bottom, zoomFactor, isRTL);
- }
-
- public ImmutableViewportMetrics setMarginsFrom(ImmutableViewportMetrics fromMetrics) {
- return setMargins(fromMetrics.marginLeft,
- fromMetrics.marginTop,
- fromMetrics.marginRight,
- fromMetrics.marginBottom);
- }
-
- public ImmutableViewportMetrics setIsRTL(boolean aIsRTL) {
- if (isRTL == aIsRTL) {
- return this;
- }
-
- return new ImmutableViewportMetrics(
- pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
- cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
- viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
- marginLeft, marginTop, marginRight, marginBottom, zoomFactor, aIsRTL);
- }
-
- /* This will set the zoom factor and re-scale page-size and viewport offset
- * accordingly. The given focus will remain at the same point on the screen
- * after scaling.
- */
- public ImmutableViewportMetrics scaleTo(float newZoomFactor, PointF focus) {
- // cssPageRect* is invariant, since we're setting the scale factor
- // here. The page rect is based on the CSS page rect.
- float newPageRectLeft = cssPageRectLeft * newZoomFactor;
- float newPageRectTop = cssPageRectTop * newZoomFactor;
- float newPageRectRight = cssPageRectLeft + ((cssPageRectRight - cssPageRectLeft) * newZoomFactor);
- float newPageRectBottom = cssPageRectTop + ((cssPageRectBottom - cssPageRectTop) * newZoomFactor);
-
- PointF origin = getOrigin();
- origin.offset(focus.x, focus.y);
- origin = PointUtils.scale(origin, newZoomFactor / zoomFactor);
- origin.offset(-focus.x, -focus.y);
-
- return new ImmutableViewportMetrics(
- newPageRectLeft, newPageRectTop, newPageRectRight, newPageRectBottom,
- cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
- origin.x, origin.y, origin.x + getWidth(), origin.y + getHeight(),
- marginLeft, marginTop, marginRight, marginBottom,
- newZoomFactor, isRTL);
- }
-
- /** Clamps the viewport to remain within the page rect. */
- private ImmutableViewportMetrics clamp(float marginLeft, float marginTop,
- float marginRight, float marginBottom) {
- RectF newViewport = getViewport();
- PointF offset = getMarginOffset();
-
- // The viewport bounds ought to never exceed the page bounds.
- if (newViewport.right > pageRectRight + marginLeft + marginRight)
- newViewport.offset((pageRectRight + marginLeft + marginRight) - newViewport.right, 0);
- if (newViewport.left < pageRectLeft)
- newViewport.offset(pageRectLeft - newViewport.left, 0);
-
- if (newViewport.bottom > pageRectBottom + marginTop + marginBottom)
- newViewport.offset(0, (pageRectBottom + marginTop + marginBottom) - newViewport.bottom);
- if (newViewport.top < pageRectTop)
- newViewport.offset(0, pageRectTop - newViewport.top);
-
- return new ImmutableViewportMetrics(
- pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
- cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
- newViewport.left, newViewport.top, newViewport.right, newViewport.bottom,
- marginLeft, marginTop, marginRight, marginBottom,
- zoomFactor, isRTL);
- }
-
- public ImmutableViewportMetrics clamp() {
- return clamp(0, 0, 0, 0);
- }
-
- public ImmutableViewportMetrics clampWithMargins() {
- return clamp(marginLeft, marginTop,
- marginRight, marginBottom);
- }
-
- public boolean fuzzyEquals(ImmutableViewportMetrics other) {
- // Don't bother checking the pageRectXXX values because they are a product
- // of the cssPageRectXXX values and the zoomFactor, except with more rounding
- // error. Checking those is both inefficient and can lead to false negatives.
- //
- // This doesn't return false if the margins differ as none of the users
- // of this function are interested in the margins in that way.
- return FloatUtils.fuzzyEquals(cssPageRectLeft, other.cssPageRectLeft)
- && FloatUtils.fuzzyEquals(cssPageRectTop, other.cssPageRectTop)
- && FloatUtils.fuzzyEquals(cssPageRectRight, other.cssPageRectRight)
- && FloatUtils.fuzzyEquals(cssPageRectBottom, other.cssPageRectBottom)
- && FloatUtils.fuzzyEquals(viewportRectLeft, other.viewportRectLeft)
- && FloatUtils.fuzzyEquals(viewportRectTop, other.viewportRectTop)
- && FloatUtils.fuzzyEquals(viewportRectRight, other.viewportRectRight)
- && FloatUtils.fuzzyEquals(viewportRectBottom, other.viewportRectBottom)
- && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor);
- }
-
- @Override
- public String toString() {
- return "ImmutableViewportMetrics v=(" + viewportRectLeft + "," + viewportRectTop + ","
- + viewportRectRight + "," + viewportRectBottom + ") p=(" + pageRectLeft + ","
- + pageRectTop + "," + pageRectRight + "," + pageRectBottom + ") c=("
- + cssPageRectLeft + "," + cssPageRectTop + "," + cssPageRectRight + ","
- + cssPageRectBottom + ") m=(" + marginLeft + ","
- + marginTop + "," + marginRight + ","
- + marginBottom + ") z=" + zoomFactor + ", rtl=" + isRTL;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java
deleted file mode 100644
index 9b3ca381b5a4..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.os.Handler;
-import android.view.KeyEvent;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-
-public interface InputConnectionHandler
-{
- Handler getHandler(Handler defHandler);
- InputConnection onCreateInputConnection(EditorInfo outAttrs);
- boolean onKeyPreIme(int keyCode, KeyEvent event);
- boolean onKeyDown(int keyCode, KeyEvent event);
- boolean onKeyLongPress(int keyCode, KeyEvent event);
- boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event);
- boolean onKeyUp(int keyCode, KeyEvent event);
- boolean isIMEEnabled();
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java
deleted file mode 100644
index b758d732c2ed..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.util.FloatMath;
-
-public class IntSize {
- public final int width, height;
-
- public IntSize(IntSize size) { width = size.width; height = size.height; }
- public IntSize(int inWidth, int inHeight) { width = inWidth; height = inHeight; }
-
- public IntSize(FloatSize size) {
- width = Math.round(size.width);
- height = Math.round(size.height);
- }
-
- public IntSize(JSONObject json) {
- try {
- width = json.getInt("width");
- height = json.getInt("height");
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
-
- public int getArea() {
- return width * height;
- }
-
- public boolean equals(IntSize size) {
- return ((size.width == width) && (size.height == height));
- }
-
- public boolean isPositive() {
- return (width > 0 && height > 0);
- }
-
- @Override
- public String toString() { return "(" + width + "," + height + ")"; }
-
- public IntSize scale(float factor) {
- return new IntSize(Math.round(width * factor),
- Math.round(height * factor));
- }
-
- /* Returns the power of two that is greater than or equal to value */
- public static int nextPowerOfTwo(int value) {
- // code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
- if (0 == value--) {
- return 1;
- }
- value = (value >> 1) | value;
- value = (value >> 2) | value;
- value = (value >> 4) | value;
- value = (value >> 8) | value;
- value = (value >> 16) | value;
- return value + 1;
- }
-
- public IntSize nextPowerOfTwo() {
- return new IntSize(nextPowerOfTwo(width), nextPowerOfTwo(height));
- }
-
- public static boolean isPowerOfTwo(int value) {
- if (value == 0)
- return false;
- return (value & (value - 1)) == 0;
- }
-
- public static int largestPowerOfTwoLessThan(float value) {
- int val = (int)FloatMath.floor(value);
- if (val <= 0) {
- throw new IllegalArgumentException("Error: value must be > 0");
- }
- // keep dropping the least-significant set bits until only one is left
- int bestVal = val;
- while (val != 0) {
- bestVal = val;
- val &= (val - 1);
- }
- return bestVal;
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
deleted file mode 100644
index ac1bf0d3d451..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
+++ /dev/null
@@ -1,1461 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.libreoffice.LOKitShell;
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-//import org.mozilla.gecko.PrefsHelper;
-//import org.mozilla.gecko.Tab;
-//import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.ZoomConstraints;
-import org.mozilla.gecko.util.EventDispatcher;
-import org.mozilla.gecko.util.FloatUtils;
-//import org.mozilla.gecko.util.GamepadUtils;
-import org.mozilla.gecko.util.GeckoEventListener;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import org.json.JSONObject;
-
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.os.Build;
-import android.util.FloatMath;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.InputDevice;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-
-/*
- * Handles the kinetic scrolling and zooming physics for a layer controller.
- *
- * Many ideas are from Joe Hewitt's Scrollability:
- * https://github.com/joehewitt/scrollability/
- */
-class JavaPanZoomController
- extends GestureDetector.SimpleOnGestureListener
- implements PanZoomController, SimpleScaleGestureDetector.SimpleScaleGestureListener, GeckoEventListener
-{
- private static final String LOGTAG = "GeckoPanZoomController";
-
- private static String MESSAGE_ZOOM_RECT = "Browser:ZoomToRect";
- private static String MESSAGE_ZOOM_PAGE = "Browser:ZoomToPageWidth";
- private static String MESSAGE_TOUCH_LISTENER = "Tab:HasTouchListener";
-
- // Animation stops if the velocity is below this value when overscrolled or panning.
- private static final float STOPPED_THRESHOLD = 4.0f;
-
- // Animation stops is the velocity is below this threshold when flinging.
- private static final float FLING_STOPPED_THRESHOLD = 0.1f;
-
- // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans
- // between the touch-down and touch-up of a click). In units of density-independent pixels.
- public static final float PAN_THRESHOLD = 1/16f * LOKitShell.getDpi(); //GeckoAppShell.getDpi();
-
- // Angle from axis within which we stay axis-locked
- private static final double AXIS_LOCK_ANGLE = Math.PI / 6.0; // 30 degrees
-
- // Axis-lock breakout angle
- private static final double AXIS_BREAKOUT_ANGLE = Math.PI / 8.0;
-
- // The distance the user has to pan before we consider breaking out of a locked axis
- public static final float AXIS_BREAKOUT_THRESHOLD = 1/32f * LOKitShell.getDpi(); //GeckoAppShell.getDpi();
-
- // The maximum amount we allow you to zoom into a page
- private static final float MAX_ZOOM = 4.0f;
-
- // The maximum amount we would like to scroll with the mouse
- private static final float MAX_SCROLL = 0.075f * LOKitShell.getDpi();
-
- // The maximum zoom factor adjustment per frame of the AUTONAV animation
- private static final float MAX_ZOOM_DELTA = 0.125f;
-
- // The duration of the bounce animation in ns
- private static final int BOUNCE_ANIMATION_DURATION = 250000000;
-
- private enum PanZoomState {
- NOTHING, /* no touch-start events received */
- FLING, /* all touches removed, but we're still scrolling page */
- TOUCHING, /* one touch-start event received */
- PANNING_LOCKED_X, /* touch-start followed by move (i.e. panning with axis lock) X axis */
- PANNING_LOCKED_Y, /* as above for Y axis */
- PANNING, /* panning without axis lock */
- PANNING_HOLD, /* in panning, but not moving.
- * similar to TOUCHING but after starting a pan */
- PANNING_HOLD_LOCKED_X, /* like PANNING_HOLD, but axis lock still in effect for X axis */
- PANNING_HOLD_LOCKED_Y, /* as above but for Y axis */
- PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */
- ANIMATED_ZOOM, /* animated zoom to a new rect */
- BOUNCE, /* in a bounce animation */
- WAITING_LISTENERS, /* a state halfway between NOTHING and TOUCHING - the user has
- put a finger down, but we don't yet know if a touch listener has
- prevented the default actions yet. we still need to abort animations. */
- AUTONAV, /* We are scrolling using an AutonavRunnable animation. This is similar
- to the FLING state except that it must be stopped manually by the code that
- started it, and it's velocity can be updated while it's running. */
- }
-
- private enum AxisLockMode {
- STANDARD, /* Default axis locking mode that doesn't break out until finger release */
- FREE, /* No locking at all */
- STICKY /* Break out with hysteresis so that it feels as free as possible whilst locking */
- }
-
- private final PanZoomTarget mTarget;
- private final SubdocumentScrollHelper mSubscroller;
- private final Axis mX;
- private final Axis mY;
- private final TouchEventHandler mTouchEventHandler;
- private final EventDispatcher mEventDispatcher;
-
- /* The task that handles flings, autonav or bounces. */
- private PanZoomRenderTask mAnimationRenderTask;
- /* The zoom focus at the first zoom event (in page coordinates). */
- private PointF mLastZoomFocus;
- /* The time the last motion event took place. */
- private long mLastEventTime;
- /* Current state the pan/zoom UI is in. */
- private PanZoomState mState;
- /* The per-frame zoom delta for the currently-running AUTONAV animation. */
- private float mAutonavZoomDelta;
- /* The user selected panning mode */
- private AxisLockMode mMode;
- /* A medium-length tap/press is happening */
- private boolean mMediumPress;
- /* Used to change the scrollY direction */
- private boolean mNegateWheelScrollY;
- /* Whether the current event has been default-prevented. */
- private boolean mDefaultPrevented;
-
- // Handler to be notified when overscroll occurs
- private Overscroll mOverscroll;
-
- public JavaPanZoomController(PanZoomTarget target, View view, EventDispatcher eventDispatcher) {
- mTarget = target;
- mSubscroller = new SubdocumentScrollHelper(eventDispatcher);
- mX = new AxisX(mSubscroller);
- mY = new AxisY(mSubscroller);
- mTouchEventHandler = new TouchEventHandler(view.getContext(), view, this);
-
- checkMainThread();
-
- setState(PanZoomState.NOTHING);
-
- mEventDispatcher = eventDispatcher;
- registerEventListener(MESSAGE_ZOOM_RECT);
- registerEventListener(MESSAGE_ZOOM_PAGE);
- registerEventListener(MESSAGE_TOUCH_LISTENER);
-
- mMode = AxisLockMode.STANDARD;
-
- String[] prefs = { "ui.scrolling.axis_lock_mode",
- "ui.scrolling.negate_wheel_scrollY",
- "ui.scrolling.gamepad_dead_zone" };
- mNegateWheelScrollY = false;
-
- /*PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() {
- @Override public void prefValue(String pref, String value) {
- if (pref.equals("ui.scrolling.axis_lock_mode")) {
- if (value.equals("standard")) {
- mMode = AxisLockMode.STANDARD;
- } else if (value.equals("free")) {
- mMode = AxisLockMode.FREE;
- } else {
- mMode = AxisLockMode.STICKY;
- }
- }
- }
-
- @Override public void prefValue(String pref, int value) {
- if (pref.equals("ui.scrolling.gamepad_dead_zone")) {
- GamepadUtils.overrideDeadZoneThreshold((float)value / 1000f);
- }
- }
-
- @Override public void prefValue(String pref, boolean value) {
- if (pref.equals("ui.scrolling.negate_wheel_scrollY")) {
- mNegateWheelScrollY = value;
- }
- }
-
- @Override
- public boolean isObserver() {
- return true;
- }
- });*/
-
- Axis.initPrefs();
- }
-
- @Override
- public void destroy() {
- unregisterEventListener(MESSAGE_ZOOM_RECT);
- unregisterEventListener(MESSAGE_ZOOM_PAGE);
- unregisterEventListener(MESSAGE_TOUCH_LISTENER);
- mSubscroller.destroy();
- mTouchEventHandler.destroy();
- }
-
- private final static float easeOut(float t) {
- // ease-out approx.
- // -(t-1)^2+1
- t = t-1;
- return -t*t+1;
- }
-
- private void registerEventListener(String event) {
- mEventDispatcher.registerEventListener(event, this);
- }
-
- private void unregisterEventListener(String event) {
- mEventDispatcher.unregisterEventListener(event, this);
- }
-
- private void setState(PanZoomState state) {
- if (state != mState) {
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PanZoom:StateChange", state.toString()));
- mState = state;
-
- // Let the target know we've finished with it (for now)
- if (state == PanZoomState.NOTHING) {
- mTarget.panZoomStopped();
- }
- }
- }
-
- private ImmutableViewportMetrics getMetrics() {
- return mTarget.getViewportMetrics();
- }
-
- private void checkMainThread() {
- if (!ThreadUtils.isOnUiThread()) {
- // log with full stack trace
- Log.e(LOGTAG, "Uh-oh, we're running on the wrong thread!", new Exception());
- }
- }
-
- @Override
- public void handleMessage(String event, JSONObject message) {
- try {
- if (MESSAGE_ZOOM_RECT.equals(event)) {
- float x = (float)message.getDouble("x");
- float y = (float)message.getDouble("y");
- final RectF zoomRect = new RectF(x, y,
- x + (float)message.getDouble("w"),
- y + (float)message.getDouble("h"));
- if (message.optBoolean("animate", true)) {
- mTarget.post(new Runnable() {
- @Override
- public void run() {
- animatedZoomTo(zoomRect);
- }
- });
- } else {
- mTarget.setViewportMetrics(getMetricsToZoomTo(zoomRect));
- }
- } else if (MESSAGE_ZOOM_PAGE.equals(event)) {
- ImmutableViewportMetrics metrics = getMetrics();
- RectF cssPageRect = metrics.getCssPageRect();
-
- RectF viewableRect = metrics.getCssViewport();
- float y = viewableRect.top;
- // attempt to keep zoom keep focused on the center of the viewport
- float newHeight = viewableRect.height() * cssPageRect.width() / viewableRect.width();
- float dh = viewableRect.height() - newHeight; // increase in the height
- final RectF r = new RectF(0.0f,
- y + dh/2,
- cssPageRect.width(),
- y + dh/2 + newHeight);
- if (message.optBoolean("animate", true)) {
- mTarget.post(new Runnable() {
- @Override
- public void run() {
- animatedZoomTo(r);
- }
- });
- } else {
- mTarget.setViewportMetrics(getMetricsToZoomTo(r));
- }
- } else if (MESSAGE_TOUCH_LISTENER.equals(event)) {
- /*int tabId = message.getInt("tabID");
- final Tab tab = Tabs.getInstance().getTab(tabId);
- tab.setHasTouchListeners(true);
- mTarget.post(new Runnable() {
- @Override
- public void run() {
- if (Tabs.getInstance().isSelectedTab(tab))
- mTouchEventHandler.setWaitForTouchListeners(true);
- }
- });*/
- }
- } catch (Exception e) {
- Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
- }
- }
-
- /** This function MUST be called on the UI thread */
- @Override
- public boolean onKeyEvent(KeyEvent event) {
- if (Build.VERSION.SDK_INT <= 11) {
- return false;
- }
-
- if ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD
- && event.getAction() == KeyEvent.ACTION_DOWN) {
-
- switch (event.getKeyCode()) {
- case KeyEvent.KEYCODE_ZOOM_IN:
- return animatedScale(0.2f);
- case KeyEvent.KEYCODE_ZOOM_OUT:
- return animatedScale(-0.2f);
- }
- }
- return false;
- }
-
- /** This function MUST be called on the UI thread */
- @Override
- public boolean onMotionEvent(MotionEvent event) {
- if (Build.VERSION.SDK_INT <= 11) {
- return false;
- }
-
- switch (event.getSource() & InputDevice.SOURCE_CLASS_MASK) {
- case InputDevice.SOURCE_CLASS_POINTER:
- switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_SCROLL: return handlePointerScroll(event);
- }
- break;
- case InputDevice.SOURCE_CLASS_JOYSTICK:
- switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_MOVE: return handleJoystickNav(event);
- }
- break;
- }
- return false;
- }
-
- /** This function MUST be called on the UI thread */
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- return mTouchEventHandler.handleEvent(event);
- }
-
- boolean handleEvent(MotionEvent event, boolean defaultPrevented) {
- mDefaultPrevented = defaultPrevented;
-
- switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN: return handleTouchStart(event);
- case MotionEvent.ACTION_MOVE: return handleTouchMove(event);
- case MotionEvent.ACTION_UP: return handleTouchEnd(event);
- case MotionEvent.ACTION_CANCEL: return handleTouchCancel(event);
- }
- return false;
- }
-
- /** This function MUST be called on the UI thread */
- @Override
- public void notifyDefaultActionPrevented(boolean prevented) {
- mTouchEventHandler.handleEventListenerAction(!prevented);
- }
-
- /** This function must be called from the UI thread. */
- @Override
- public void abortAnimation() {
- checkMainThread();
- // this happens when gecko changes the viewport on us or if the device is rotated.
- // if that's the case, abort any animation in progress and re-zoom so that the page
- // snaps to edges. for other cases (where the user's finger(s) are down) don't do
- // anything special.
- switch (mState) {
- case FLING:
- mX.stopFling();
- mY.stopFling();
- // fall through
- case BOUNCE:
- case ANIMATED_ZOOM:
- // the zoom that's in progress likely makes no sense any more (such as if
- // the screen orientation changed) so abort it
- setState(PanZoomState.NOTHING);
- // fall through
- case NOTHING:
- // Don't do animations here; they're distracting and can cause flashes on page
- // transitions.
- synchronized (mTarget.getLock()) {
- mTarget.setViewportMetrics(getValidViewportMetrics());
- mTarget.forceRedraw(null);
- }
- break;
- }
- }
-
- /** This function must be called on the UI thread. */
- public void startingNewEventBlock(MotionEvent event, boolean waitingForTouchListeners) {
- checkMainThread();
- mSubscroller.cancel();
- if (waitingForTouchListeners && (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
- // this is the first touch point going down, so we enter the pending state
- // seting the state will kill any animations in progress, possibly leaving
- // the page in overscroll
- setState(PanZoomState.WAITING_LISTENERS);
- }
- }
-
- /** This must be called on the UI thread. */
- @Override
- public void pageRectUpdated() {
- if (mState == PanZoomState.NOTHING) {
- synchronized (mTarget.getLock()) {
- ImmutableViewportMetrics validated = getValidViewportMetrics();
- if (!getMetrics().fuzzyEquals(validated)) {
- // page size changed such that we are now in overscroll. snap to the
- // the nearest valid viewport
- mTarget.setViewportMetrics(validated);
- }
- }
- }
- }
-
- /*
- * Panning/scrolling
- */
-
- private boolean handleTouchStart(MotionEvent event) {
- // user is taking control of movement, so stop
- // any auto-movement we have going
- stopAnimationTask();
-
- switch (mState) {
- case ANIMATED_ZOOM:
- // We just interrupted a double-tap animation, so force a redraw in
- // case this touchstart is just a tap that doesn't end up triggering
- // a redraw
- mTarget.forceRedraw(null);
- // fall through
- case FLING:
- case AUTONAV:
- case BOUNCE:
- case NOTHING:
- case WAITING_LISTENERS:
- startTouch(event.getX(0), event.getY(0), event.getEventTime());
- return false;
- case TOUCHING:
- case PANNING:
- case PANNING_LOCKED_X:
- case PANNING_LOCKED_Y:
- case PANNING_HOLD:
- case PANNING_HOLD_LOCKED_X:
- case PANNING_HOLD_LOCKED_Y:
- case PINCHING:
- Log.e(LOGTAG, "Received impossible touch down while in " + mState);
- return false;
- }
- Log.e(LOGTAG, "Unhandled case " + mState + " in handleTouchStart");
- return false;
- }
-
- private boolean handleTouchMove(MotionEvent event) {
-
- switch (mState) {
- case FLING:
- case AUTONAV:
- case BOUNCE:
- case WAITING_LISTENERS:
- // should never happen
- Log.e(LOGTAG, "Received impossible touch move while in " + mState);
- // fall through
- case ANIMATED_ZOOM:
- case NOTHING:
- // may happen if user double-taps and drags without lifting after the
- // second tap. ignore the move if this happens.
- return false;
-
- case TOUCHING:
- // Don't allow panning if there is an element in full-screen mode. See bug 775511.
- if ((mTarget.isFullScreen() && !mSubscroller.scrolling()) || panDistance(event) < PAN_THRESHOLD) {
- return false;
- }
- cancelTouch();
- startPanning(event.getX(0), event.getY(0), event.getEventTime());
- track(event);
- return true;
-
- case PANNING_HOLD_LOCKED_X:
- setState(PanZoomState.PANNING_LOCKED_X);
- track(event);
- return true;
- case PANNING_HOLD_LOCKED_Y:
- setState(PanZoomState.PANNING_LOCKED_Y);
- // fall through
- case PANNING_LOCKED_X:
- case PANNING_LOCKED_Y:
- track(event);
- return true;
-
- case PANNING_HOLD:
- setState(PanZoomState.PANNING);
- // fall through
- case PANNING:
- track(event);
- return true;
-
- case PINCHING:
- // scale gesture listener will handle this
- return false;
- }
- Log.e(LOGTAG, "Unhandled case " + mState + " in handleTouchMove");
- return false;
- }
-
- private boolean handleTouchEnd(MotionEvent event) {
-
- switch (mState) {
- case FLING:
- case AUTONAV:
- case BOUNCE:
- case ANIMATED_ZOOM:
- case NOTHING:
- // may happen if user double-taps and drags without lifting after the
- // second tap. ignore if this happens.
- return false;
-
- case WAITING_LISTENERS:
- if (!mDefaultPrevented) {
- // should never happen
- Log.e(LOGTAG, "Received impossible touch end while in " + mState);
- }
- // fall through
- case TOUCHING:
- // the switch into TOUCHING might have happened while the page was
- // snapping back after overscroll. we need to finish the snap if that
- // was the case
- bounce();
- return false;
-
- case PANNING:
- case PANNING_LOCKED_X:
- case PANNING_LOCKED_Y:
- case PANNING_HOLD:
- case PANNING_HOLD_LOCKED_X:
- case PANNING_HOLD_LOCKED_Y:
- setState(PanZoomState.FLING);
- fling();
- return true;
-
- case PINCHING:
- setState(PanZoomState.NOTHING);
- return true;
- }
- Log.e(LOGTAG, "Unhandled case " + mState + " in handleTouchEnd");
- return false;
- }
-
- private boolean handleTouchCancel(MotionEvent event) {
- cancelTouch();
-
- // ensure we snap back if we're overscrolled
- bounce();
- return false;
- }
-
- private boolean handlePointerScroll(MotionEvent event) {
- if (mState == PanZoomState.NOTHING || mState == PanZoomState.FLING) {
- float scrollX = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
- float scrollY = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
- if (mNegateWheelScrollY) {
- scrollY *= -1.0;
- }
- scrollBy(scrollX * MAX_SCROLL, scrollY * MAX_SCROLL);
- bounce();
- return true;
- }
- return false;
- }
-
- private float filterDeadZone(MotionEvent event, int axis) {
- return 0; //(GamepadUtils.isValueInDeadZone(event, axis) ? 0 : event.getAxisValue(axis));
- }
-
- private float normalizeJoystickScroll(MotionEvent event, int axis) {
- return filterDeadZone(event, axis) * MAX_SCROLL;
- }
-
- private float normalizeJoystickZoom(MotionEvent event, int axis) {
- // negate MAX_ZOOM_DELTA so that pushing up on the stick zooms in
- return filterDeadZone(event, axis) * -MAX_ZOOM_DELTA;
- }
-
- // Since this event is a position-based event rather than a motion-based event, we need to
- // set up an AUTONAV animation to keep scrolling even while we don't get events.
- private boolean handleJoystickNav(MotionEvent event) {
- float velocityX = normalizeJoystickScroll(event, MotionEvent.AXIS_X);
- float velocityY = normalizeJoystickScroll(event, MotionEvent.AXIS_Y);
- float zoomDelta = normalizeJoystickZoom(event, MotionEvent.AXIS_RZ);
-
- if (velocityX == 0 && velocityY == 0 && zoomDelta == 0) {
- if (mState == PanZoomState.AUTONAV) {
- bounce(); // if not needed, this will automatically go to state NOTHING
- return true;
- }
- return false;
- }
-
- if (mState == PanZoomState.NOTHING) {
- setState(PanZoomState.AUTONAV);
- startAnimationRenderTask(new AutonavRenderTask());
- }
- if (mState == PanZoomState.AUTONAV) {
- mX.setAutoscrollVelocity(velocityX);
- mY.setAutoscrollVelocity(velocityY);
- mAutonavZoomDelta = zoomDelta;
- return true;
- }
- return false;
- }
-
- private void startTouch(float x, float y, long time) {
- mX.startTouch(x);
- mY.startTouch(y);
- setState(PanZoomState.TOUCHING);
- mLastEventTime = time;
- }
-
- private void startPanning(float x, float y, long time) {
- float dx = mX.panDistance(x);
- float dy = mY.panDistance(y);
- double angle = Math.atan2(dy, dx); // range [-pi, pi]
- angle = Math.abs(angle); // range [0, pi]
-
- // When the touch move breaks through the pan threshold, reposition the touch down origin
- // so the page won't jump when we start panning.
- mX.startTouch(x);
- mY.startTouch(y);
- mLastEventTime = time;
-
- if (mMode == AxisLockMode.STANDARD || mMode == AxisLockMode.STICKY) {
- if (!mX.scrollable() || !mY.scrollable()) {
- setState(PanZoomState.PANNING);
- } else if (angle < AXIS_LOCK_ANGLE || angle > (Math.PI - AXIS_LOCK_ANGLE)) {
- mY.setScrollingDisabled(true);
- setState(PanZoomState.PANNING_LOCKED_X);
- } else if (Math.abs(angle - (Math.PI / 2)) < AXIS_LOCK_ANGLE) {
- mX.setScrollingDisabled(true);
- setState(PanZoomState.PANNING_LOCKED_Y);
- } else {
- setState(PanZoomState.PANNING);
- }
- } else if (mMode == AxisLockMode.FREE) {
- setState(PanZoomState.PANNING);
- }
- }
-
- private float panDistance(MotionEvent move) {
- float dx = mX.panDistance(move.getX(0));
- float dy = mY.panDistance(move.getY(0));
- return FloatMath.sqrt(dx * dx + dy * dy);
- }
-
- private void track(float x, float y, long time) {
- float timeDelta = (float)(time - mLastEventTime);
- if (FloatUtils.fuzzyEquals(timeDelta, 0)) {
- // probably a duplicate event, ignore it. using a zero timeDelta will mess
- // up our velocity
- return;
- }
- mLastEventTime = time;
-
-
- // if we're axis-locked check if the user is trying to scroll away from the lock
- if (mMode == AxisLockMode.STICKY) {
- float dx = mX.panDistance(x);
- float dy = mY.panDistance(y);
- double angle = Math.atan2(dy, dx); // range [-pi, pi]
- angle = Math.abs(angle); // range [0, pi]
-
- if (Math.abs(dx) > AXIS_BREAKOUT_THRESHOLD || Math.abs(dy) > AXIS_BREAKOUT_THRESHOLD) {
- if (mState == PanZoomState.PANNING_LOCKED_X) {
- if (angle > AXIS_BREAKOUT_ANGLE && angle < (Math.PI - AXIS_BREAKOUT_ANGLE)) {
- mY.setScrollingDisabled(false);
- setState(PanZoomState.PANNING);
- }
- } else if (mState == PanZoomState.PANNING_LOCKED_Y) {
- if (Math.abs(angle - (Math.PI / 2)) > AXIS_BREAKOUT_ANGLE) {
- mX.setScrollingDisabled(false);
- setState(PanZoomState.PANNING);
- }
- }
- }
- }
-
- mX.updateWithTouchAt(x, timeDelta);
- mY.updateWithTouchAt(y, timeDelta);
- }
-
- private void track(MotionEvent event) {
- mX.saveTouchPos();
- mY.saveTouchPos();
-
- for (int i = 0; i < event.getHistorySize(); i++) {
- track(event.getHistoricalX(0, i),
- event.getHistoricalY(0, i),
- event.getHistoricalEventTime(i));
- }
- track(event.getX(0), event.getY(0), event.getEventTime());
-
- if (stopped()) {
- if (mState == PanZoomState.PANNING) {
- setState(PanZoomState.PANNING_HOLD);
- } else if (mState == PanZoomState.PANNING_LOCKED_X) {
- setState(PanZoomState.PANNING_HOLD_LOCKED_X);
- } else if (mState == PanZoomState.PANNING_LOCKED_Y) {
- setState(PanZoomState.PANNING_HOLD_LOCKED_Y);
- } else {
- // should never happen, but handle anyway for robustness
- Log.e(LOGTAG, "Impossible case " + mState + " when stopped in track");
- setState(PanZoomState.PANNING_HOLD);
- }
- }
-
- mX.startPan();
- mY.startPan();
- updatePosition();
- }
-
- private void scrollBy(float dx, float dy) {
- mTarget.scrollBy(dx, dy);
- }
-
- private void fling() {
- updatePosition();
-
- stopAnimationTask();
-
- boolean stopped = stopped();
- mX.startFling(stopped);
- mY.startFling(stopped);
-
- startAnimationRenderTask(new FlingRenderTask());
- }
-
- /* Performs a bounce-back animation to the given viewport metrics. */
- private void bounce(ImmutableViewportMetrics metrics, PanZoomState state) {
- stopAnimationTask();
-
- ImmutableViewportMetrics bounceStartMetrics = getMetrics();
- if (bounceStartMetrics.fuzzyEquals(metrics)) {
- setState(PanZoomState.NOTHING);
- return;
- }
-
- setState(state);
-
- // At this point we have already set mState to BOUNCE or ANIMATED_ZOOM, so
- // getRedrawHint() is returning false. This means we can safely call
- // setAnimationTarget to set the new final display port and not have it get
- // clobbered by display ports from intermediate animation frames.
- mTarget.setAnimationTarget(metrics);
- startAnimationRenderTask(new BounceRenderTask(bounceStartMetrics, metrics));
- }
-
- /* Performs a bounce-back animation to the nearest valid viewport metrics. */
- private void bounce() {
- bounce(getValidViewportMetrics(), PanZoomState.BOUNCE);
- }
-
- /* Starts the fling or bounce animation. */
- private void startAnimationRenderTask(final PanZoomRenderTask task) {
- if (mAnimationRenderTask != null) {
- Log.e(LOGTAG, "Attempted to start a new task without canceling the old one!");
- stopAnimationTask();
- }
-
- mAnimationRenderTask = task;
- mTarget.postRenderTask(mAnimationRenderTask);
- }
-
- /* Stops the fling or bounce animation. */
- private void stopAnimationTask() {
- if (mAnimationRenderTask != null) {
- mAnimationRenderTask.terminate();
- mTarget.removeRenderTask(mAnimationRenderTask);
- mAnimationRenderTask = null;
- }
- }
-
- private float getVelocity() {
- float xvel = mX.getRealVelocity();
- float yvel = mY.getRealVelocity();
- return FloatMath.sqrt(xvel * xvel + yvel * yvel);
- }
-
- @Override
- public PointF getVelocityVector() {
- return new PointF(mX.getRealVelocity(), mY.getRealVelocity());
- }
-
- private boolean stopped() {
- return getVelocity() < STOPPED_THRESHOLD;
- }
-
- PointF resetDisplacement() {
- return new PointF(mX.resetDisplacement(), mY.resetDisplacement());
- }
-
- private void updatePosition() {
- mX.displace();
- mY.displace();
- PointF displacement = resetDisplacement();
- if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
- return;
- }
- if (mDefaultPrevented || mSubscroller.scrollBy(displacement)) {
- synchronized (mTarget.getLock()) {
- mTarget.scrollMarginsBy(displacement.x, displacement.y);
- }
- } else {
- synchronized (mTarget.getLock()) {
- scrollBy(displacement.x, displacement.y);
- }
- }
- }
-
- /**
- * This class is an implementation of RenderTask which enforces its implementor to run in the UI thread.
- *
- */
- private abstract class PanZoomRenderTask extends RenderTask {
-
- /**
- * the time when the current frame was started in ns.
- */
- protected long mCurrentFrameStartTime;
- /**
- * The current frame duration in ns.
- */
- protected long mLastFrameTimeDelta;
-
- private final Runnable mRunnable = new Runnable() {
- @Override
- public final void run() {
- if (mContinueAnimation) {
- animateFrame();
- }
- }
- };
-
- private boolean mContinueAnimation = true;
-
- public PanZoomRenderTask() {
- super(false);
- }
-
- @Override
- protected final boolean internalRun(long timeDelta, long currentFrameStartTime) {
-
- mCurrentFrameStartTime = currentFrameStartTime;
- mLastFrameTimeDelta = timeDelta;
-
- mTarget.post(mRunnable);
- return mContinueAnimation;
- }
-
- /**
- * The method subclasses must override. This method is run on the UI thread thanks to internalRun
- */
- protected abstract void animateFrame();
-
- /**
- * Terminate the animation.
- */
- public void terminate() {
- mContinueAnimation = false;
- }
- }
-
- private class AutonavRenderTask extends PanZoomRenderTask {
- public AutonavRenderTask() {
- super();
- }
-
- @Override
- protected void animateFrame() {
- if (mState != PanZoomState.AUTONAV) {
- finishAnimation();
- return;
- }
-
- updatePosition();
- synchronized (mTarget.getLock()) {
- mTarget.setViewportMetrics(applyZoomDelta(getMetrics(), mAutonavZoomDelta));
- }
- }
- }
-
- /* The task that performs the bounce animation. */
- private class BounceRenderTask extends PanZoomRenderTask {
-
- /*
- * The viewport metrics that represent the start and end of the bounce-back animation,
- * respectively.
- */
- private ImmutableViewportMetrics mBounceStartMetrics;
- private ImmutableViewportMetrics mBounceEndMetrics;
- // How long ago this bounce was started in ns.
- private long mBounceDuration;
-
- BounceRenderTask(ImmutableViewportMetrics startMetrics, ImmutableViewportMetrics endMetrics) {
- super();
- mBounceStartMetrics = startMetrics;
- mBounceEndMetrics = endMetrics;
- }
-
- @Override
- protected void animateFrame() {
- /*
- * The pan/zoom controller might have signaled to us that it wants to abort the
- * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
- * out.
- */
- if (!(mState == PanZoomState.BOUNCE || mState == PanZoomState.ANIMATED_ZOOM)) {
- finishAnimation();
- return;
- }
-
- /* Perform the next frame of the bounce-back animation. */
- mBounceDuration = mCurrentFrameStartTime - getStartTime();
- if (mBounceDuration < BOUNCE_ANIMATION_DURATION) {
- advanceBounce();
- return;
- }
-
- /* Finally, if there's nothing else to do, complete the animation and go to sleep. */
- finishBounce();
- finishAnimation();
- setState(PanZoomState.NOTHING);
- }
-
- /* Performs one frame of a bounce animation. */
- private void advanceBounce() {
- synchronized (mTarget.getLock()) {
- float t = easeOut((float)mBounceDuration / BOUNCE_ANIMATION_DURATION);
- ImmutableViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
- mTarget.setViewportMetrics(newMetrics);
- }
- }
-
- /* Concludes a bounce animation and snaps the viewport into place. */
- private void finishBounce() {
- synchronized (mTarget.getLock()) {
- mTarget.setViewportMetrics(mBounceEndMetrics);
- }
- }
- }
-
- // The callback that performs the fling animation.
- private class FlingRenderTask extends PanZoomRenderTask {
-
- public FlingRenderTask() {
- super();
- }
-
- @Override
- protected void animateFrame() {
- /*
- * The pan/zoom controller might have signaled to us that it wants to abort the
- * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
- * out.
- */
- if (mState != PanZoomState.FLING) {
- finishAnimation();
- return;
- }
-
- /* Advance flings, if necessary. */
- boolean flingingX = mX.advanceFling(mLastFrameTimeDelta);
- boolean flingingY = mY.advanceFling(mLastFrameTimeDelta);
-
- boolean overscrolled = (mX.overscrolled() || mY.overscrolled());
-
- /* If we're still flinging in any direction, update the origin. */
- if (flingingX || flingingY) {
- updatePosition();
-
- /*
- * Check to see if we're still flinging with an appreciable velocity. The threshold is
- * higher in the case of overscroll, so we bounce back eagerly when overscrolling but
- * coast smoothly to a stop when not. In other words, require a greater velocity to
- * maintain the fling once we enter overscroll.
- */
- float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD);
- if (getVelocity() >= threshold) {
- // we're still flinging
- return;
- }
-
- mX.stopFling();
- mY.stopFling();
- }
-
- /* Perform a bounce-back animation if overscrolled. */
- if (overscrolled) {
- bounce();
- } else {
- finishAnimation();
- setState(PanZoomState.NOTHING);
- }
- }
- }
-
- private void finishAnimation() {
- checkMainThread();
-
- stopAnimationTask();
-
- // Force a viewport synchronisation
- mTarget.forceRedraw(null);
- }
-
- /* Returns the nearest viewport metrics with no overscroll visible. */
- private ImmutableViewportMetrics getValidViewportMetrics() {
- return getValidViewportMetrics(getMetrics());
- }
-
- private ImmutableViewportMetrics getValidViewportMetrics(ImmutableViewportMetrics viewportMetrics) {
- /* First, we adjust the zoom factor so that we can make no overscrolled area visible. */
- float zoomFactor = viewportMetrics.zoomFactor;
- RectF pageRect = viewportMetrics.getPageRect();
- RectF viewport = viewportMetrics.getViewport();
-
- float focusX = viewport.width() / 2.0f;
- float focusY = viewport.height() / 2.0f;
-
- float minZoomFactor = 0.0f;
- float maxZoomFactor = MAX_ZOOM;
-
- ZoomConstraints constraints = mTarget.getZoomConstraints();
-
- if (constraints.getMinZoom() > 0)
- minZoomFactor = constraints.getMinZoom();
- if (constraints.getMaxZoom() > 0)
- maxZoomFactor = constraints.getMaxZoom();
-
- if (!constraints.getAllowZoom()) {
- // If allowZoom is false, clamp to the default zoom level.
- maxZoomFactor = minZoomFactor = constraints.getDefaultZoom();
- }
-
- // Ensure minZoomFactor keeps the page at least as big as the viewport.
- if (pageRect.width() > 0) {
- float pageWidth = pageRect.width() +
- viewportMetrics.marginLeft +
- viewportMetrics.marginRight;
- float scaleFactor = viewport.width() / pageWidth;
- minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
- if (viewport.width() > pageWidth)
- focusX = 0.0f;
- }
- if (pageRect.height() > 0) {
- float pageHeight = pageRect.height() +
- viewportMetrics.marginTop +
- viewportMetrics.marginBottom;
- float scaleFactor = viewport.height() / pageHeight;
- minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
- if (viewport.height() > pageHeight)
- focusY = 0.0f;
- }
-
- maxZoomFactor = Math.max(maxZoomFactor, minZoomFactor);
-
- if (zoomFactor < minZoomFactor) {
- // if one (or both) of the page dimensions is smaller than the viewport,
- // zoom using the top/left as the focus on that axis. this prevents the
- // scenario where, if both dimensions are smaller than the viewport, but
- // by different scale factors, we end up scrolled to the end on one axis
- // after applying the scale
- PointF center = new PointF(focusX, focusY);
- viewportMetrics = viewportMetrics.scaleTo(minZoomFactor, center);
- } else if (zoomFactor > maxZoomFactor) {
- PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f);
- viewportMetrics = viewportMetrics.scaleTo(maxZoomFactor, center);
- }
-
- /* Now we pan to the right origin. */
- viewportMetrics = viewportMetrics.clampWithMargins();
-
- return viewportMetrics;
- }
-
- private class AxisX extends Axis {
- AxisX(SubdocumentScrollHelper subscroller) { super(subscroller); }
- @Override
- public float getOrigin() { return getMetrics().viewportRectLeft; }
- @Override
- protected float getViewportLength() { return getMetrics().getWidth(); }
- @Override
- protected float getPageStart() { return getMetrics().pageRectLeft; }
- @Override
- protected float getMarginStart() { return mTarget.getMaxMargins().left - getMetrics().marginLeft; }
- @Override
- protected float getMarginEnd() { return mTarget.getMaxMargins().right - getMetrics().marginRight; }
- @Override
- protected float getPageLength() { return getMetrics().getPageWidthWithMargins(); }
- @Override
- protected boolean marginsHidden() {
- ImmutableViewportMetrics metrics = getMetrics();
- RectF maxMargins = mTarget.getMaxMargins();
- return (metrics.marginLeft < maxMargins.left || metrics.marginRight < maxMargins.right);
- }
- @Override
- protected void overscrollFling(final float velocity) {
- if (mOverscroll != null) {
- mOverscroll.setVelocity(velocity, Overscroll.Axis.X);
- }
- }
- @Override
- protected void overscrollPan(final float distance) {
- if (mOverscroll != null) {
- mOverscroll.setDistance(distance, Overscroll.Axis.X);
- }
- }
- }
-
- private class AxisY extends Axis {
- AxisY(SubdocumentScrollHelper subscroller) { super(subscroller); }
- @Override
- public float getOrigin() { return getMetrics().viewportRectTop; }
- @Override
- protected float getViewportLength() { return getMetrics().getHeight(); }
- @Override
- protected float getPageStart() { return getMetrics().pageRectTop; }
- @Override
- protected float getPageLength() { return getMetrics().getPageHeightWithMargins(); }
- @Override
- protected float getMarginStart() { return mTarget.getMaxMargins().top - getMetrics().marginTop; }
- @Override
- protected float getMarginEnd() { return mTarget.getMaxMargins().bottom - getMetrics().marginBottom; }
- @Override
- protected boolean marginsHidden() {
- ImmutableViewportMetrics metrics = getMetrics();
- RectF maxMargins = mTarget.getMaxMargins();
- return (metrics.marginTop < maxMargins.top || metrics.marginBottom < maxMargins.bottom);
- }
- @Override
- protected void overscrollFling(final float velocity) {
- if (mOverscroll != null) {
- mOverscroll.setVelocity(velocity, Overscroll.Axis.Y);
- }
- }
- @Override
- protected void overscrollPan(final float distance) {
- if (mOverscroll != null) {
- mOverscroll.setDistance(distance, Overscroll.Axis.Y);
- }
- }
- }
-
- /*
- * Zooming
- */
- @Override
- public boolean onScaleBegin(SimpleScaleGestureDetector detector) {
- if (mState == PanZoomState.ANIMATED_ZOOM)
- return false;
-
- if (!mTarget.getZoomConstraints().getAllowZoom())
- return false;
-
- setState(PanZoomState.PINCHING);
- mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
- cancelTouch();
-
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_START, mLastZoomFocus, getMetrics().zoomFactor));
-
- return true;
- }
-
- @Override
- public boolean onScale(SimpleScaleGestureDetector detector) {
- if (mTarget.isFullScreen())
- return false;
-
- if (mState != PanZoomState.PINCHING)
- return false;
-
- float prevSpan = detector.getPreviousSpan();
- if (FloatUtils.fuzzyEquals(prevSpan, 0.0f)) {
- // let's eat this one to avoid setting the new zoom to infinity (bug 711453)
- return true;
- }
-
- synchronized (mTarget.getLock()) {
- float zoomFactor = getAdjustedZoomFactor(detector.getCurrentSpan() / prevSpan);
- scrollBy(mLastZoomFocus.x - detector.getFocusX(),
- mLastZoomFocus.y - detector.getFocusY());
- mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY());
- ImmutableViewportMetrics target = getMetrics().scaleTo(zoomFactor, mLastZoomFocus);
-
- // If overscroll is diabled, prevent zooming outside the normal document pans.
- if (mX.getOverScrollMode() == View.OVER_SCROLL_NEVER || mY.getOverScrollMode() == View.OVER_SCROLL_NEVER) {
- target = getValidViewportMetrics(target);
- }
- mTarget.setViewportMetrics(target);
- }
-
- //GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY, mLastZoomFocus, getMetrics().zoomFactor);
- //GeckoAppShell.sendEventToGecko(event);
-
- return true;
- }
-
- private ImmutableViewportMetrics applyZoomDelta(ImmutableViewportMetrics metrics, float zoomDelta) {
- float oldZoom = metrics.zoomFactor;
- float newZoom = oldZoom + zoomDelta;
- float adjustedZoom = getAdjustedZoomFactor(newZoom / oldZoom);
- // since we don't have a particular focus to zoom to, just use the center
- PointF center = new PointF(metrics.getWidth() / 2.0f, metrics.getHeight() / 2.0f);
- metrics = metrics.scaleTo(adjustedZoom, center);
- return metrics;
- }
-
- private boolean animatedScale(float zoomDelta) {
- if (mState != PanZoomState.NOTHING && mState != PanZoomState.BOUNCE) {
- return false;
- }
- synchronized (mTarget.getLock()) {
- ImmutableViewportMetrics metrics = applyZoomDelta(getMetrics(), zoomDelta);
- bounce(getValidViewportMetrics(metrics), PanZoomState.BOUNCE);
- }
- return true;
- }
-
- private float getAdjustedZoomFactor(float zoomRatio) {
- /*
- * Apply edge resistance if we're zoomed out smaller than the page size by scaling the zoom
- * factor toward 1.0.
- */
- float resistance = Math.min(mX.getEdgeResistance(true), mY.getEdgeResistance(true));
- if (zoomRatio > 1.0f)
- zoomRatio = 1.0f + (zoomRatio - 1.0f) * resistance;
- else
- zoomRatio = 1.0f - (1.0f - zoomRatio) * resistance;
-
- float newZoomFactor = getMetrics().zoomFactor * zoomRatio;
- float minZoomFactor = 0.0f;
- float maxZoomFactor = MAX_ZOOM;
-
- ZoomConstraints constraints = mTarget.getZoomConstraints();
-
- if (constraints.getMinZoom() > 0)
- minZoomFactor = constraints.getMinZoom();
- if (constraints.getMaxZoom() > 0)
- maxZoomFactor = constraints.getMaxZoom();
-
- if (newZoomFactor < minZoomFactor) {
- // apply resistance when zooming past minZoomFactor,
- // such that it asymptotically reaches minZoomFactor / 2.0
- // but never exceeds that
- final float rate = 0.5f; // controls how quickly we approach the limit
- float excessZoom = minZoomFactor - newZoomFactor;
- excessZoom = 1.0f - (float)Math.exp(-excessZoom * rate);
- newZoomFactor = minZoomFactor * (1.0f - excessZoom / 2.0f);
- }
-
- if (newZoomFactor > maxZoomFactor) {
- // apply resistance when zooming past maxZoomFactor,
- // such that it asymptotically reaches maxZoomFactor + 1.0
- // but never exceeds that
- float excessZoom = newZoomFactor - maxZoomFactor;
- excessZoom = 1.0f - (float)Math.exp(-excessZoom);
- newZoomFactor = maxZoomFactor + excessZoom;
- }
-
- return newZoomFactor;
- }
-
- @Override
- public void onScaleEnd(SimpleScaleGestureDetector detector) {
- if (mState == PanZoomState.ANIMATED_ZOOM)
- return;
-
- // switch back to the touching state
- startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime());
-
- // Force a viewport synchronisation
- mTarget.forceRedraw(null);
-
- PointF point = new PointF(detector.getFocusX(), detector.getFocusY());
- //GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_END, point, getMetrics().zoomFactor);
-
- //if (event == null) {
- // return;
- //}
-
- //GeckoAppShell.sendEventToGecko(event);
- }
-
- @Override
- public boolean getRedrawHint() {
- switch (mState) {
- case PINCHING:
- case ANIMATED_ZOOM:
- case BOUNCE:
- // don't redraw during these because the zoom is (or might be, in the case
- // of BOUNCE) be changing rapidly and gecko will have to redraw the entire
- // display port area. we trigger a force-redraw upon exiting these states.
- return false;
- default:
- // allow redrawing in other states
- return true;
- }
- }
-
- private void sendPointToGecko(String event, MotionEvent motionEvent) {
- String json;
- try {
- PointF point = new PointF(motionEvent.getX(), motionEvent.getY());
- point = mTarget.convertViewPointToLayerPoint(point);
- if (point == null) {
- return;
- }
- json = PointUtils.toJSON(point).toString();
- } catch (Exception e) {
- Log.e(LOGTAG, "Unable to convert point to JSON for " + event, e);
- return;
- }
-
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(event, json));
- }
-
- @Override
- public boolean onDown(MotionEvent motionEvent) {
- mMediumPress = false;
- return false;
- }
-
- @Override
- public void onShowPress(MotionEvent motionEvent) {
- // If we get this, it will be followed either by a call to
- // onSingleTapUp (if the user lifts their finger before the
- // long-press timeout) or a call to onLongPress (if the user
- // does not). In the former case, we want to make sure it is
- // treated as a click. (Note that if this is called, we will
- // not get a call to onDoubleTap).
- mMediumPress = true;
- }
-
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- sendPointToGecko("Gesture:LongPress", motionEvent);
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent motionEvent) {
- // When zooming is enabled, we wait to see if there's a double-tap.
- // However, if mMediumPress is true then we know there will be no
- // double-tap so we treat this as a click.
- if (mMediumPress || !mTarget.getZoomConstraints().getAllowZoom()) {
- sendPointToGecko("Gesture:SingleTap", motionEvent);
- }
- // return false because we still want to get the ACTION_UP event that triggers this
- return false;
- }
-
- @Override
- public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
- // When zooming is disabled, we handle this in onSingleTapUp.
- if (mTarget.getZoomConstraints().getAllowZoom()) {
- sendPointToGecko("Gesture:SingleTap", motionEvent);
- }
- return true;
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent motionEvent) {
- if (mTarget.getZoomConstraints().getAllowZoom()) {
- sendPointToGecko("Gesture:DoubleTap", motionEvent);
- }
- return true;
- }
-
- private void cancelTouch() {
- //GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", "");
- //GeckoAppShell.sendEventToGecko(e);
- }
-
- /**
- * Zoom to a specified rect IN CSS PIXELS.
- *
- * While we usually use device pixels, @zoomToRect must be specified in CSS
- * pixels.
- */
- private ImmutableViewportMetrics getMetricsToZoomTo(RectF zoomToRect) {
- final float startZoom = getMetrics().zoomFactor;
-
- RectF viewport = getMetrics().getViewport();
- // 1. adjust the aspect ratio of zoomToRect to match that of the current viewport,
- // enlarging as necessary (if it gets too big, it will get shrunk in the next step).
- // while enlarging make sure we enlarge equally on both sides to keep the target rect
- // centered.
- float targetRatio = viewport.width() / viewport.height();
- float rectRatio = zoomToRect.width() / zoomToRect.height();
- if (FloatUtils.fuzzyEquals(targetRatio, rectRatio)) {
- // all good, do nothing
- } else if (targetRatio < rectRatio) {
- // need to increase zoomToRect height
- float newHeight = zoomToRect.width() / targetRatio;
- zoomToRect.top -= (newHeight - zoomToRect.height()) / 2;
- zoomToRect.bottom = zoomToRect.top + newHeight;
- } else { // targetRatio > rectRatio) {
- // need to increase zoomToRect width
- float newWidth = targetRatio * zoomToRect.height();
- zoomToRect.left -= (newWidth - zoomToRect.width()) / 2;
- zoomToRect.right = zoomToRect.left + newWidth;
- }
-
- float finalZoom = viewport.width() / zoomToRect.width();
-
- ImmutableViewportMetrics finalMetrics = getMetrics();
- finalMetrics = finalMetrics.setViewportOrigin(
- zoomToRect.left * finalMetrics.zoomFactor,
- zoomToRect.top * finalMetrics.zoomFactor);
- finalMetrics = finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f));
-
- // 2. now run getValidViewportMetrics on it, so that the target viewport is
- // clamped down to prevent overscroll, over-zoom, and other bad conditions.
- finalMetrics = getValidViewportMetrics(finalMetrics);
- return finalMetrics;
- }
-
- private boolean animatedZoomTo(RectF zoomToRect) {
- bounce(getMetricsToZoomTo(zoomToRect), PanZoomState.ANIMATED_ZOOM);
- return true;
- }
-
- /** This function must be called from the UI thread. */
- @Override
- public void abortPanning() {
- checkMainThread();
- bounce();
- }
-
- @Override
- public void setOverScrollMode(int overscrollMode) {
- mX.setOverScrollMode(overscrollMode);
- mY.setOverScrollMode(overscrollMode);
- }
-
- @Override
- public int getOverScrollMode() {
- return mX.getOverScrollMode();
- }
-
- @Override
- public void setOverscrollHandler(final Overscroll handler) {
- mOverscroll = handler;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java
deleted file mode 100644
index cae7377d7a29..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.util.FloatUtils;
-
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-import java.nio.FloatBuffer;
-import java.util.concurrent.locks.ReentrantLock;
-
-public abstract class Layer {
- private final ReentrantLock mTransactionLock;
- private boolean mInTransaction;
- private Rect mNewPosition;
- private float mNewResolution;
-
- protected Rect mPosition;
- protected float mResolution;
-
- public Layer() {
- this(null);
- }
-
- public Layer(IntSize size) {
- mTransactionLock = new ReentrantLock();
- if (size == null) {
- mPosition = new Rect();
- } else {
- mPosition = new Rect(0, 0, size.width, size.height);
- }
- mResolution = 1.0f;
- }
-
- /**
- * Updates the layer. This returns false if there is still work to be done
- * after this update.
- */
- public final boolean update(RenderContext context) {
- if (mTransactionLock.isHeldByCurrentThread()) {
- throw new RuntimeException("draw() called while transaction lock held by this " +
- "thread?!");
- }
-
- if (mTransactionLock.tryLock()) {
- try {
- performUpdates(context);
- return true;
- } finally {
- mTransactionLock.unlock();
- }
- }
-
- return false;
- }
-
- /** Subclasses override this function to draw the layer. */
- public abstract void draw(RenderContext context);
-
- /** Given the intrinsic size of the layer, returns the pixel boundaries of the layer rect. */
- protected RectF getBounds(RenderContext context) {
- return RectUtils.scale(new RectF(mPosition), context.zoomFactor / mResolution);
- }
-
- /**
- * Call this before modifying the layer. Note that, for TileLayers, "modifying the layer"
- * includes altering the underlying CairoImage in any way. Thus you must call this function
- * before modifying the byte buffer associated with this layer.
- *
- * This function may block, so you should never call this on the main UI thread.
- */
- public void beginTransaction() {
- if (mTransactionLock.isHeldByCurrentThread())
- throw new RuntimeException("Nested transactions are not supported");
- mTransactionLock.lock();
- mInTransaction = true;
- mNewResolution = mResolution;
- }
-
- /** Call this when you're done modifying the layer. */
- public void endTransaction() {
- if (!mInTransaction)
- throw new RuntimeException("endTransaction() called outside a transaction");
- mInTransaction = false;
- mTransactionLock.unlock();
- }
-
- /** Returns true if the layer is currently in a transaction and false otherwise. */
- protected boolean inTransaction() {
- return mInTransaction;
- }
-
- /** Returns the current layer position. */
- public Rect getPosition() {
- return mPosition;
- }
-
- /** Sets the position. Only valid inside a transaction. */
- public void setPosition(Rect newPosition) {
- if (!mInTransaction)
- throw new RuntimeException("setPosition() is only valid inside a transaction");
- mNewPosition = newPosition;
- }
-
- /** Returns the current layer's resolution. */
- public float getResolution() {
- return mResolution;
- }
-
- /**
- * Sets the layer resolution. This value is used to determine how many pixels per
- * device pixel this layer was rendered at. This will be reflected by scaling by
- * the reciprocal of the resolution in the layer's transform() function.
- * Only valid inside a transaction. */
- public void setResolution(float newResolution) {
- if (!mInTransaction)
- throw new RuntimeException("setResolution() is only valid inside a transaction");
- mNewResolution = newResolution;
- }
-
- /**
- * Subclasses may override this method to perform custom layer updates. This will be called
- * with the transaction lock held. Subclass implementations of this method must call the
- * superclass implementation. Returns false if there is still work to be done after this
- * update is complete.
- */
- protected void performUpdates(RenderContext context) {
- if (mNewPosition != null) {
- mPosition = mNewPosition;
- mNewPosition = null;
- }
- if (mNewResolution != 0.0f) {
- mResolution = mNewResolution;
- mNewResolution = 0.0f;
- }
- }
-
- /**
- * This function fills in the provided <tt>dest</tt> array with values to render a texture.
- * The array is filled with 4 sets of {x, y, z, texture_x, texture_y} values (so 20 values
- * in total) corresponding to the corners of the rect.
- */
- protected final void fillRectCoordBuffer(float[] dest, RectF rect, float viewWidth, float viewHeight,
- Rect cropRect, float texWidth, float texHeight) {
- //x, y, z, texture_x, texture_y
- dest[0] = rect.left / viewWidth;
- dest[1] = rect.bottom / viewHeight;
- dest[2] = 0;
- dest[3] = cropRect.left / texWidth;
- dest[4] = cropRect.top / texHeight;
-
- dest[5] = rect.left / viewWidth;
- dest[6] = rect.top / viewHeight;
- dest[7] = 0;
- dest[8] = cropRect.left / texWidth;
- dest[9] = cropRect.bottom / texHeight;
-
- dest[10] = rect.right / viewWidth;
- dest[11] = rect.bottom / viewHeight;
- dest[12] = 0;
- dest[13] = cropRect.right / texWidth;
- dest[14] = cropRect.top / texHeight;
-
- dest[15] = rect.right / viewWidth;
- dest[16] = rect.top / viewHeight;
- dest[17] = 0;
- dest[18] = cropRect.right / texWidth;
- dest[19] = cropRect.bottom / texHeight;
- }
-
- public static class RenderContext {
- public final RectF viewport;
- public final RectF pageRect;
- public final float zoomFactor;
- public final PointF offset;
- public final int positionHandle;
- public final int textureHandle;
- public final FloatBuffer coordBuffer;
-
- public RenderContext(RectF aViewport, RectF aPageRect, float aZoomFactor, PointF aOffset,
- int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) {
- viewport = aViewport;
- pageRect = aPageRect;
- zoomFactor = aZoomFactor;
- offset = aOffset;
- positionHandle = aPositionHandle;
- textureHandle = aTextureHandle;
- coordBuffer = aCoordBuffer;
- }
-
- public boolean fuzzyEquals(RenderContext other) {
- if (other == null) {
- return false;
- }
- return RectUtils.fuzzyEquals(viewport, other.viewport)
- && RectUtils.fuzzyEquals(pageRect, other.pageRect)
- && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor)
- && FloatUtils.fuzzyEquals(offset, other.offset);
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java
deleted file mode 100644
index c2b719b914dc..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-//import org.mozilla.gecko.PrefsHelper;
-import org.mozilla.gecko.TouchEventInterceptor;
-import org.mozilla.gecko.util.FloatUtils;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.animation.DecelerateInterpolator;
-import android.view.MotionEvent;
-import android.view.View;
-
-public class LayerMarginsAnimator implements TouchEventInterceptor {
- private static final String LOGTAG = "GeckoLayerMarginsAnimator";
- // The duration of the animation in ns
- private static final long MARGIN_ANIMATION_DURATION = 250000000;
- private static final String PREF_SHOW_MARGINS_THRESHOLD = "browser.ui.show-margins-threshold";
-
- /* This is the proportion of the viewport rect, minus maximum margins,
- * that needs to be travelled before margins will be exposed.
- */
- private float SHOW_MARGINS_THRESHOLD = 0.20f;
-
- /* This rect stores the maximum value margins can grow to when scrolling. When writing
- * to this member variable, or when reading from this member variable on a non-UI thread,
- * you must synchronize on the LayerMarginsAnimator instance. */
- private final RectF mMaxMargins;
- /* If this boolean is true, scroll changes will not affect margins */
- private boolean mMarginsPinned;
- /* The task that handles showing/hiding margins */
- private LayerMarginsAnimationTask mAnimationTask;
- /* This interpolator is used for the above mentioned animation */
- private final DecelerateInterpolator mInterpolator;
- /* The GeckoLayerClient whose margins will be animated */
- private final GeckoLayerClient mTarget;
- /* The distance that has been scrolled since either the first touch event,
- * or since the margins were last fully hidden */
- private final PointF mTouchTravelDistance;
- /* The ID of the prefs listener for the show-marginss threshold */
- private Integer mPrefObserverId;
-
- public LayerMarginsAnimator(GeckoLayerClient aTarget, LayerView aView) {
- // Assign member variables from parameters
- mTarget = aTarget;
-
- // Create other member variables
- mMaxMargins = new RectF();
- mInterpolator = new DecelerateInterpolator();
- mTouchTravelDistance = new PointF();
-
- // Listen to the dynamic toolbar pref
- /*mPrefObserverId = PrefsHelper.getPref(PREF_SHOW_MARGINS_THRESHOLD, new PrefsHelper.PrefHandlerBase() {
- @Override
- public void prefValue(String pref, int value) {
- SHOW_MARGINS_THRESHOLD = (float)value / 100.0f;
- }
-
- @Override
- public boolean isObserver() {
- return true;
- }
- });*/
-
- // Listen to touch events, for auto-pinning
- aView.addTouchInterceptor(this);
- }
-
- public void destroy() {
- if (mPrefObserverId != null) {
- //PrefsHelper.removeObserver(mPrefObserverId);
- mPrefObserverId = null;
- }
- }
-
- /**
- * Sets the maximum values for margins to grow to, in pixels.
- */
- public synchronized void setMaxMargins(float left, float top, float right, float bottom) {
- ThreadUtils.assertOnUiThread();
-
- mMaxMargins.set(left, top, right, bottom);
-
- // Update the Gecko-side global for fixed viewport margins.
- /*GeckoAppShell.sendEventToGecko(
- GeckoEvent.createBroadcastEvent("Viewport:FixedMarginsChanged",
- "{ \"top\" : " + top + ", \"right\" : " + right
- + ", \"bottom\" : " + bottom + ", \"left\" : " + left + " }"));*/
- }
-
- RectF getMaxMargins() {
- return mMaxMargins;
- }
-
- private void animateMargins(final float left, final float top, final float right, final float bottom, boolean immediately) {
- if (mAnimationTask != null) {
- mTarget.getView().removeRenderTask(mAnimationTask);
- mAnimationTask = null;
- }
-
- if (immediately) {
- ImmutableViewportMetrics newMetrics = mTarget.getViewportMetrics().setMargins(left, top, right, bottom);
- mTarget.forceViewportMetrics(newMetrics, true, true);
- return;
- }
-
- ImmutableViewportMetrics metrics = mTarget.getViewportMetrics();
-
- mAnimationTask = new LayerMarginsAnimationTask(false, metrics, left, top, right, bottom);
- mTarget.getView().postRenderTask(mAnimationTask);
- }
-
- /**
- * Exposes the margin area by growing the margin components of the current
- * metrics to the values set in setMaxMargins.
- */
- public synchronized void showMargins(boolean immediately) {
- animateMargins(mMaxMargins.left, mMaxMargins.top, mMaxMargins.right, mMaxMargins.bottom, immediately);
- }
-
- public synchronized void hideMargins(boolean immediately) {
- animateMargins(0, 0, 0, 0, immediately);
- }
-
- public void setMarginsPinned(boolean pin) {
- if (pin == mMarginsPinned) {
- return;
- }
-
- mMarginsPinned = pin;
- }
-
- public boolean areMarginsShown() {
- final ImmutableViewportMetrics metrics = mTarget.getViewportMetrics();
- return metrics.marginLeft != 0 ||
- metrics.marginRight != 0 ||
- metrics.marginTop != 0 ||
- metrics.marginBottom != 0;
- }
-
- /**
- * This function will scroll a margin down to zero, or up to the maximum
- * specified margin size and return the left-over delta.
- * aMargins are in/out parameters. In specifies the current margin size,
- * and out specifies the modified margin size. They are specified in the
- * order of start-margin, then end-margin.
- * This function will also take into account how far the touch point has
- * moved and react accordingly. If a touch point hasn't moved beyond a
- * certain threshold, margins can only be hidden and not shown.
- * aNegativeOffset can be used if the remaining delta should be determined
- * by the end-margin instead of the start-margin (for example, in rtl
- * pages).
- */
- private float scrollMargin(float[] aMargins, float aDelta,
- float aOverscrollStart, float aOverscrollEnd,
- float aTouchTravelDistance,
- float aViewportStart, float aViewportEnd,
- float aPageStart, float aPageEnd,
- float aMaxMarginStart, float aMaxMarginEnd,
- boolean aNegativeOffset) {
- float marginStart = aMargins[0];
- float marginEnd = aMargins[1];
- float viewportSize = aViewportEnd - aViewportStart;
- float exposeThreshold = viewportSize * SHOW_MARGINS_THRESHOLD;
-
- if (aDelta >= 0) {
- float marginDelta = Math.max(0, aDelta - aOverscrollStart);
- aMargins[0] = marginStart - Math.min(marginDelta, marginStart);
- if (aTouchTravelDistance < exposeThreshold && marginEnd == 0) {
- // We only want the margin to be newly exposed after the touch
- // has moved a certain distance.
- marginDelta = Math.max(0, marginDelta - (aPageEnd - aViewportEnd));
- }
- aMargins[1] = marginEnd + Math.min(marginDelta, aMaxMarginEnd - marginEnd);
- } else {
- float marginDelta = Math.max(0, -aDelta - aOverscrollEnd);
- aMargins[1] = marginEnd - Math.min(marginDelta, marginEnd);
- if (-aTouchTravelDistance < exposeThreshold && marginStart == 0) {
- marginDelta = Math.max(0, marginDelta - (aViewportStart - aPageStart));
- }
- aMargins[0] = marginStart + Math.min(marginDelta, aMaxMarginStart - marginStart);
- }
-
- if (aNegativeOffset) {
- return aDelta - (marginEnd - aMargins[1]);
- }
- return aDelta - (marginStart - aMargins[0]);
- }
-
- /*
- * Taking maximum margins into account, offsets the margins and then the
- * viewport origin and returns the modified metrics.
- */
- ImmutableViewportMetrics scrollBy(ImmutableViewportMetrics aMetrics, float aDx, float aDy) {
- float[] newMarginsX = { aMetrics.marginLeft, aMetrics.marginRight };
- float[] newMarginsY = { aMetrics.marginTop, aMetrics.marginBottom };
-
- // Only alter margins if the toolbar isn't pinned
- if (!mMarginsPinned) {
- // Make sure to cancel any margin animations when margin-scrolling begins
- if (mAnimationTask != null) {
- mTarget.getView().removeRenderTask(mAnimationTask);
- mAnimationTask = null;
- }
-
- // Reset the touch travel when changing direction
- if ((aDx >= 0) != (mTouchTravelDistance.x >= 0)) {
- mTouchTravelDistance.x = 0;
- }
- if ((aDy >= 0) != (mTouchTravelDistance.y >= 0)) {
- mTouchTravelDistance.y = 0;
- }
-
- mTouchTravelDistance.offset(aDx, aDy);
- RectF overscroll = aMetrics.getOverscroll();
-
- // Only allow margins to scroll if the page can fill the viewport.
- if (aMetrics.getPageWidth() >= aMetrics.getWidth()) {
- aDx = scrollMargin(newMarginsX, aDx,
- overscroll.left, overscroll.right,
- mTouchTravelDistance.x,
- aMetrics.viewportRectLeft, aMetrics.viewportRectRight,
- aMetrics.pageRectLeft, aMetrics.pageRectRight,
- mMaxMargins.left, mMaxMargins.right,
- aMetrics.isRTL);
- }
- if (aMetrics.getPageHeight() >= aMetrics.getHeight()) {
- aDy = scrollMargin(newMarginsY, aDy,
- overscroll.top, overscroll.bottom,
- mTouchTravelDistance.y,
- aMetrics.viewportRectTop, aMetrics.viewportRectBottom,
- aMetrics.pageRectTop, aMetrics.pageRectBottom,
- mMaxMargins.top, mMaxMargins.bottom,
- false);
- }
- }
-
- return aMetrics.setMargins(newMarginsX[0], newMarginsY[0], newMarginsX[1], newMarginsY[1]).offsetViewportBy(aDx, aDy);
- }
-
- /** Implementation of TouchEventInterceptor */
- @Override
- public boolean onTouch(View view, MotionEvent event) {
- return false;
- }
-
- /** Implementation of TouchEventInterceptor */
- @Override
- public boolean onInterceptTouchEvent(View view, MotionEvent event) {
- int action = event.getActionMasked();
- if (action == MotionEvent.ACTION_DOWN && event.getPointerCount() == 1) {
- mTouchTravelDistance.set(0.0f, 0.0f);
- }
-
- return false;
- }
-
- class LayerMarginsAnimationTask extends RenderTask {
- private float mStartLeft, mStartTop, mStartRight, mStartBottom;
- private float mTop, mBottom, mLeft, mRight;
- private boolean mContinueAnimation;
-
- public LayerMarginsAnimationTask(boolean runAfter, ImmutableViewportMetrics metrics,
- float left, float top, float right, float bottom) {
- super(runAfter);
- mContinueAnimation = true;
- this.mStartLeft = metrics.marginLeft;
- this.mStartTop = metrics.marginTop;
- this.mStartRight = metrics.marginRight;
- this.mStartBottom = metrics.marginBottom;
- this.mLeft = left;
- this.mRight = right;
- this.mTop = top;
- this.mBottom = bottom;
- }
-
- @Override
- public boolean internalRun(long timeDelta, long currentFrameStartTime) {
- if (!mContinueAnimation) {
- return false;
- }
-
- // Calculate the progress (between 0 and 1)
- float progress = mInterpolator.getInterpolation(
- Math.min(1.0f, (System.nanoTime() - getStartTime())
- / (float)MARGIN_ANIMATION_DURATION));
-
- // Calculate the new metrics accordingly
- synchronized (mTarget.getLock()) {
- ImmutableViewportMetrics oldMetrics = mTarget.getViewportMetrics();
- ImmutableViewportMetrics newMetrics = oldMetrics.setMargins(
- FloatUtils.interpolate(mStartLeft, mLeft, progress),
- FloatUtils.interpolate(mStartTop, mTop, progress),
- FloatUtils.interpolate(mStartRight, mRight, progress),
- FloatUtils.interpolate(mStartBottom, mBottom, progress));
- PointF oldOffset = oldMetrics.getMarginOffset();
- PointF newOffset = newMetrics.getMarginOffset();
- newMetrics =
- newMetrics.offsetViewportByAndClamp(newOffset.x - oldOffset.x,
- newOffset.y - oldOffset.y);
-
- if (progress >= 1.0f) {
- mContinueAnimation = false;
-
- // Force a redraw and update Gecko
- mTarget.forceViewportMetrics(newMetrics, true, true);
- } else {
- mTarget.forceViewportMetrics(newMetrics, false, false);
- }
- }
- return mContinueAnimation;
- }
- }
-
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java
deleted file mode 100644
index e8759fd3e462..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java
+++ /dev/null
@@ -1,722 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.libreoffice.LOKitShell;
-import org.libreoffice.R;
-
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.R;
-//import org.mozilla.gecko.Tab;
-//import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.gfx.Layer.RenderContext;
-import org.mozilla.gecko.gfx.RenderTask;
-import org.mozilla.gecko.mozglue.DirectBufferAllocator;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.opengl.GLES20;
-import android.os.SystemClock;
-import android.util.Log;
-//import org.mozilla.gecko.mozglue.JNITarget;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.microedition.khronos.egl.EGLConfig;
-
-/**
- * The layer renderer implements the rendering logic for a layer view.
- */
-public class LayerRenderer /*implements Tabs.OnTabsChangedListener*/ {
- private static final String LOGTAG = "GeckoLayerRenderer";
- private static final String PROFTAG = "GeckoLayerRendererProf";
-
- /*
- * The amount of time a frame is allowed to take to render before we declare it a dropped
- * frame.
- */
- private static final int MAX_FRAME_TIME = 16; /* 1000 ms / 60 FPS */
-
- private static final int FRAME_RATE_METER_WIDTH = 128;
- private static final int FRAME_RATE_METER_HEIGHT = 32;
-
- private static final long NANOS_PER_MS = 1000000;
- private static final int NANOS_PER_SECOND = 1000000000;
-
- private final LayerView mView;
- private TextLayer mFrameRateLayer;
- private final ScrollbarLayer mHorizScrollLayer;
- private final ScrollbarLayer mVertScrollLayer;
- private final FadeRunnable mFadeRunnable;
- private ByteBuffer mCoordByteBuffer;
- private FloatBuffer mCoordBuffer;
- private RenderContext mLastPageContext;
- private int mMaxTextureSize;
- private int mBackgroundColor;
- private int mOverscrollColor;
-
- private long mLastFrameTime;
- private final CopyOnWriteArrayList<RenderTask> mTasks;
-
- private CopyOnWriteArrayList<Layer> mExtraLayers = new CopyOnWriteArrayList<Layer>();
-
- // Dropped frames display
- private int[] mFrameTimings;
- private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames;
-
- // Render profiling output
- private int mFramesRendered;
- private float mCompleteFramesRendered;
- private boolean mProfileRender;
- private long mProfileOutputTime;
-
- private IntBuffer mPixelBuffer;
-
- // Used by GLES 2.0
- private int mProgram;
- private int mPositionHandle;
- private int mTextureHandle;
- private int mSampleHandle;
- private int mTMatrixHandle;
-
- // column-major matrix applied to each vertex to shift the viewport from
- // one ranging from (-1, -1),(1,1) to (0,0),(1,1) and to scale all sizes by
- // a factor of 2 to fill up the screen
- public static final float[] DEFAULT_TEXTURE_MATRIX = {
- 2.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 2.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 2.0f, 0.0f,
- -1.0f, -1.0f, 0.0f, 1.0f
- };
-
- private static final int COORD_BUFFER_SIZE = 20;
-
- // The shaders run on the GPU directly, the vertex shader is only applying the
- // matrix transform detailed above
-
- // Note we flip the y-coordinate in the vertex shader from a
- // coordinate system with (0,0) in the top left to one with (0,0) in
- // the bottom left.
-
- public static final String DEFAULT_VERTEX_SHADER =
- "uniform mat4 uTMatrix;\n" +
- "attribute vec4 vPosition;\n" +
- "attribute vec2 aTexCoord;\n" +
- "varying vec2 vTexCoord;\n" +
- "void main() {\n" +
- " gl_Position = uTMatrix * vPosition;\n" +
- " vTexCoord.x = aTexCoord.x;\n" +
- " vTexCoord.y = 1.0 - aTexCoord.y;\n" +
- "}\n";
-
- // We use highp because the screenshot textures
- // we use are large and we stretch them a lot
- // so we need all the precision we can get.
- // Unfortunately, highp is not required by ES 2.0
- // so on GPU's like Mali we end up getting mediump
- public static final String DEFAULT_FRAGMENT_SHADER =
- "precision highp float;\n" +
- "varying vec2 vTexCoord;\n" +
- "uniform sampler2D sTexture;\n" +
- "void main() {\n" +
- " gl_FragColor = texture2D(sTexture, vTexCoord);\n" +
- "}\n";
-
- public LayerRenderer(LayerView view) {
- mView = view;
- mOverscrollColor = view.getContext().getResources().getColor(R.color.background_normal);
-
- Bitmap scrollbarImage = view.getScrollbarImage();
- IntSize size = new IntSize(scrollbarImage.getWidth(), scrollbarImage.getHeight());
- scrollbarImage = expandCanvasToPowerOfTwo(scrollbarImage, size);
-
- mTasks = new CopyOnWriteArrayList<RenderTask>();
- mLastFrameTime = System.nanoTime();
-
- mVertScrollLayer = new ScrollbarLayer(this, scrollbarImage, size, true);
- mHorizScrollLayer = new ScrollbarLayer(this, diagonalFlip(scrollbarImage), new IntSize(size.height, size.width), false);
- mFadeRunnable = new FadeRunnable();
-
- mFrameTimings = new int[60];
- mCurrentFrame = mFrameTimingsSum = mDroppedFrames = 0;
-
- // Initialize the FloatBuffer that will be used to store all vertices and texture
- // coordinates in draw() commands.
- mCoordByteBuffer = DirectBufferAllocator.allocate(COORD_BUFFER_SIZE * 4);
- mCoordByteBuffer.order(ByteOrder.nativeOrder());
- mCoordBuffer = mCoordByteBuffer.asFloatBuffer();
-
- //Tabs.registerOnTabsChangedListener(this);
- }
-
- private Bitmap expandCanvasToPowerOfTwo(Bitmap image, IntSize size) {
- IntSize potSize = size.nextPowerOfTwo();
- if (size.equals(potSize)) {
- return image;
- }
- // make the bitmap size a power-of-two in both dimensions if it's not already.
- Bitmap potImage = Bitmap.createBitmap(potSize.width, potSize.height, image.getConfig());
- new Canvas(potImage).drawBitmap(image, new Matrix(), null);
- return potImage;
- }
-
- private Bitmap diagonalFlip(Bitmap image) {
- Matrix rotation = new Matrix();
- rotation.setValues(new float[] { 0, 1, 0, 1, 0, 0, 0, 0, 1 }); // transform (x,y) into (y,x)
- Bitmap rotated = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), rotation, true);
- return rotated;
- }
-
- public void destroy() {
- DirectBufferAllocator.free(mCoordByteBuffer);
- mCoordByteBuffer = null;
- mCoordBuffer = null;
- mHorizScrollLayer.destroy();
- mVertScrollLayer.destroy();
- if (mFrameRateLayer != null) {
- mFrameRateLayer.destroy();
- }
- //Tabs.unregisterOnTabsChangedListener(this);
- }
-
- void onSurfaceCreated(EGLConfig config) {
- checkMonitoringEnabled();
- createDefaultProgram();
- activateDefaultProgram();
- }
-
- public void createDefaultProgram() {
- int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, DEFAULT_VERTEX_SHADER);
- int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, DEFAULT_FRAGMENT_SHADER);
-
- mProgram = GLES20.glCreateProgram();
- GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
- GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
- GLES20.glLinkProgram(mProgram); // creates OpenGL program executables
-
- // Get handles to the vertex shader's vPosition, aTexCoord, sTexture, and uTMatrix members.
- mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
- mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord");
- mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
- mTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uTMatrix");
-
- int maxTextureSizeResult[] = new int[1];
- GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0);
- mMaxTextureSize = maxTextureSizeResult[0];
- }
-
- // Activates the shader program.
- public void activateDefaultProgram() {
- // Add the program to the OpenGL environment
- GLES20.glUseProgram(mProgram);
-
- // Set the transformation matrix
- GLES20.glUniformMatrix4fv(mTMatrixHandle, 1, false, DEFAULT_TEXTURE_MATRIX, 0);
-
- // Enable the arrays from which we get the vertex and texture coordinates
- GLES20.glEnableVertexAttribArray(mPositionHandle);
- GLES20.glEnableVertexAttribArray(mTextureHandle);
-
- GLES20.glUniform1i(mSampleHandle, 0);
-
- // TODO: Move these calls into a separate deactivate() call that is called after the
- // underlay and overlay are rendered.
- }
-
- // Deactivates the shader program. This must be done to avoid crashes after returning to the
- // Gecko C++ compositor from Java.
- public void deactivateDefaultProgram() {
- GLES20.glDisableVertexAttribArray(mTextureHandle);
- GLES20.glDisableVertexAttribArray(mPositionHandle);
- GLES20.glUseProgram(0);
- }
-
- public int getMaxTextureSize() {
- return mMaxTextureSize;
- }
-
- public void postRenderTask(RenderTask aTask) {
- mTasks.add(aTask);
- mView.requestRender();
- }
-
- public void removeRenderTask(RenderTask aTask) {
- mTasks.remove(aTask);
- }
-
- private void runRenderTasks(CopyOnWriteArrayList<RenderTask> tasks, boolean after, long frameStartTime) {
- for (RenderTask task : tasks) {
- if (task.runAfter != after) {
- continue;
- }
-
- boolean stillRunning = task.run(frameStartTime - mLastFrameTime, frameStartTime);
-
- // Remove the task from the list if its finished
- if (!stillRunning) {
- tasks.remove(task);
- }
- }
- }
-
- public void addLayer(Layer layer) {
- synchronized (mExtraLayers) {
- if (mExtraLayers.contains(layer)) {
- mExtraLayers.remove(layer);
- }
-
- mExtraLayers.add(layer);
- }
- }
-
- public void removeLayer(Layer layer) {
- synchronized (mExtraLayers) {
- mExtraLayers.remove(layer);
- }
- }
-
- private void printCheckerboardStats() {
- Log.d(PROFTAG, "Frames rendered over last 1000ms: " + mCompleteFramesRendered + "/" + mFramesRendered);
- mFramesRendered = 0;
- mCompleteFramesRendered = 0;
- }
-
- /** Used by robocop for testing purposes. Not for production use! */
- IntBuffer getPixels() {
- IntBuffer pixelBuffer = IntBuffer.allocate(mView.getWidth() * mView.getHeight());
- synchronized (pixelBuffer) {
- mPixelBuffer = pixelBuffer;
- mView.requestRender();
- try {
- pixelBuffer.wait();
- } catch (InterruptedException ie) {
- }
- mPixelBuffer = null;
- }
- return pixelBuffer;
- }
-
- private RenderContext createScreenContext(ImmutableViewportMetrics metrics, PointF offset) {
- RectF viewport = new RectF(0.0f, 0.0f, metrics.getWidth(), metrics.getHeight());
- RectF pageRect = metrics.getPageRect();
-
- return createContext(viewport, pageRect, 1.0f, offset);
- }
-
- private RenderContext createPageContext(ImmutableViewportMetrics metrics, PointF offset) {
- RectF viewport = metrics.getViewport();
- RectF pageRect = metrics.getPageRect();
- float zoomFactor = metrics.zoomFactor;
-
- return createContext(new RectF(RectUtils.round(viewport)), pageRect, zoomFactor, offset);
- }
-
- private RenderContext createContext(RectF viewport, RectF pageRect, float zoomFactor, PointF offset) {
- return new RenderContext(viewport, pageRect, zoomFactor, offset, mPositionHandle, mTextureHandle,
- mCoordBuffer);
- }
-
- private void updateDroppedFrames(long frameStartTime) {
- int frameElapsedTime = (int)((System.nanoTime() - frameStartTime) / NANOS_PER_MS);
-
- /* Update the running statistics. */
- mFrameTimingsSum -= mFrameTimings[mCurrentFrame];
- mFrameTimingsSum += frameElapsedTime;
- mDroppedFrames -= (mFrameTimings[mCurrentFrame] + 1) / MAX_FRAME_TIME;
- mDroppedFrames += (frameElapsedTime + 1) / MAX_FRAME_TIME;
-
- mFrameTimings[mCurrentFrame] = frameElapsedTime;
- mCurrentFrame = (mCurrentFrame + 1) % mFrameTimings.length;
-
- int averageTime = mFrameTimingsSum / mFrameTimings.length;
- mFrameRateLayer.beginTransaction(); // called on compositor thread
- try {
- mFrameRateLayer.setText(averageTime + " ms/" + mDroppedFrames);
- } finally {
- mFrameRateLayer.endTransaction();
- }
- }
-
- /* Given the new dimensions for the surface, moves the frame rate layer appropriately. */
- private void moveFrameRateLayer(int width, int height) {
- mFrameRateLayer.beginTransaction(); // called on compositor thread
- try {
- Rect position = new Rect(width - FRAME_RATE_METER_WIDTH - 8,
- height - FRAME_RATE_METER_HEIGHT + 8,
- width - 8,
- height + 8);
- mFrameRateLayer.setPosition(position);
- } finally {
- mFrameRateLayer.endTransaction();
- }
- }
-
- void checkMonitoringEnabled() {
- /* Do this I/O off the main thread to minimize its impact on startup time. */
- new Thread(new Runnable() {
- @Override
- public void run() {
- Context context = mView.getContext();
- SharedPreferences preferences = context.getSharedPreferences("GeckoApp", 0);
- if (preferences.getBoolean("showFrameRate", false)) {
- IntSize frameRateLayerSize = new IntSize(FRAME_RATE_METER_WIDTH, FRAME_RATE_METER_HEIGHT);
- mFrameRateLayer = TextLayer.create(frameRateLayerSize, "-- ms/--");
- moveFrameRateLayer(mView.getWidth(), mView.getHeight());
- }
- mProfileRender = Log.isLoggable(PROFTAG, Log.DEBUG);
- }
- }).start();
- }
-
- /*
- * create a vertex shader type (GLES20.GL_VERTEX_SHADER)
- * or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
- */
- public static int loadShader(int type, String shaderCode) {
- int shader = GLES20.glCreateShader(type);
- GLES20.glShaderSource(shader, shaderCode);
- GLES20.glCompileShader(shader);
- return shader;
- }
-
- public Frame createFrame(ImmutableViewportMetrics metrics) {
- return new Frame(metrics);
- }
-
- class FadeRunnable implements Runnable {
- private boolean mStarted;
- private long mRunAt;
-
- void scheduleStartFade(long delay) {
- mRunAt = SystemClock.elapsedRealtime() + delay;
- if (!mStarted) {
- mView.postDelayed(this, delay);
- mStarted = true;
- }
- }
-
- void scheduleNextFadeFrame() {
- if (mStarted) {
- Log.e(LOGTAG, "scheduleNextFadeFrame() called while scheduled for starting fade");
- }
- mView.postDelayed(this, 1000L / 60L); // request another frame at 60fps
- }
-
- boolean timeToFade() {
- return !mStarted;
- }
-
- @Override
- public void run() {
- long timeDelta = mRunAt - SystemClock.elapsedRealtime();
- if (timeDelta > 0) {
- // the run-at time was pushed back, so reschedule
- mView.postDelayed(this, timeDelta);
- } else {
- // reached the run-at time, execute
- mStarted = false;
- mView.requestRender();
- }
- }
- }
-
- public class Frame {
- // The timestamp recording the start of this frame.
- private long mFrameStartTime;
- // A fixed snapshot of the viewport metrics that this frame is using to render content.
- private ImmutableViewportMetrics mFrameMetrics;
- // A rendering context for page-positioned layers, and one for screen-positioned layers.
- private RenderContext mPageContext, mScreenContext;
- // Whether a layer was updated.
- private boolean mUpdated;
- private final Rect mPageRect;
- private final Rect mAbsolutePageRect;
- private final PointF mRenderOffset;
-
- public Frame(ImmutableViewportMetrics metrics) {
- mFrameMetrics = metrics;
-
- // Work out the offset due to margins
- Layer rootLayer = mView.getLayerClient().getRoot();
- mRenderOffset = mFrameMetrics.getMarginOffset();
- mPageContext = createPageContext(metrics, mRenderOffset);
- mScreenContext = createScreenContext(metrics, mRenderOffset);
-
- RectF pageRect = mFrameMetrics.getPageRect();
- mAbsolutePageRect = RectUtils.round(pageRect);
-
- PointF origin = mFrameMetrics.getOrigin();
- pageRect.offset(-origin.x, -origin.y);
- mPageRect = RectUtils.round(pageRect);
- }
-
- private void setScissorRect() {
- Rect scissorRect = transformToScissorRect(mPageRect);
- GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
- GLES20.glScissor(scissorRect.left, scissorRect.top,
- scissorRect.width(), scissorRect.height());
- }
-
- private Rect transformToScissorRect(Rect rect) {
- IntSize screenSize = new IntSize(mFrameMetrics.getSize());
-
- int left = Math.max(0, rect.left);
- int top = Math.max(0, rect.top);
- int right = Math.min(screenSize.width, rect.right);
- int bottom = Math.min(screenSize.height, rect.bottom);
-
- Rect scissorRect = new Rect(left, screenSize.height - bottom, right,
- (screenSize.height - bottom) + (bottom - top));
- scissorRect.offset(Math.round(-mRenderOffset.x), Math.round(-mRenderOffset.y));
-
- return scissorRect;
- }
-
- /** This function is invoked via JNI; be careful when modifying signature. */
- //@JNITarget
- public void beginDrawing() {
- mFrameStartTime = System.nanoTime();
-
- TextureReaper.get().reap();
- TextureGenerator.get().fill();
-
- mUpdated = true;
-
- Layer rootLayer = mView.getLayerClient().getRoot();
-
- // Run through pre-render tasks
- runRenderTasks(mTasks, false, mFrameStartTime);
-
- if (!mPageContext.fuzzyEquals(mLastPageContext) && !mView.isFullScreen()) {
- // The viewport or page changed, so show the scrollbars again
- // as per UX decision. Don't do this if we're in full-screen mode though.
- mVertScrollLayer.unfade();
- mHorizScrollLayer.unfade();
- mFadeRunnable.scheduleStartFade(ScrollbarLayer.FADE_DELAY);
- } else if (mFadeRunnable.timeToFade()) {
- boolean stillFading = mVertScrollLayer.fade() | mHorizScrollLayer.fade();
- if (stillFading) {
- mFadeRunnable.scheduleNextFadeFrame();
- }
- }
- mLastPageContext = mPageContext;
-
- /* Update layers. */
- if (rootLayer != null) {
- // Called on compositor thread.
- mUpdated &= rootLayer.update(mPageContext);
- }
-
- if (mFrameRateLayer != null) {
- // Called on compositor thread.
- mUpdated &= mFrameRateLayer.update(mScreenContext);
- }
-
- mUpdated &= mVertScrollLayer.update(mPageContext); // called on compositor thread
- mUpdated &= mHorizScrollLayer.update(mPageContext); // called on compositor thread
-
- for (Layer layer : mExtraLayers) {
- mUpdated &= layer.update(mPageContext); // called on compositor thread
- }
- }
-
- /** Retrieves the bounds for the layer, rounded in such a way that it
- * can be used as a mask for something that will render underneath it.
- * This will round the bounds inwards, but stretch the mask towards any
- * near page edge, where near is considered to be 'within 2 pixels'.
- * Returns null if the given layer is null.
- */
- private Rect getMaskForLayer(Layer layer) {
- if (layer == null) {
- return null;
- }
-
- RectF bounds = RectUtils.contract(layer.getBounds(mPageContext), 1.0f, 1.0f);
- Rect mask = RectUtils.roundIn(bounds);
-
- // If the mask is within two pixels of any page edge, stretch it over
- // that edge. This is to avoid drawing thin slivers when masking
- // layers.
- if (mask.top <= 2) {
- mask.top = -1;
- }
- if (mask.left <= 2) {
- mask.left = -1;
- }
-
- // Because we're drawing relative to the page-rect, we only need to
- // take into account its width and height (and not its origin)
- int pageRight = mPageRect.width();
- int pageBottom = mPageRect.height();
-
- if (mask.right >= pageRight - 2) {
- mask.right = pageRight + 1;
- }
- if (mask.bottom >= pageBottom - 2) {
- mask.bottom = pageBottom + 1;
- }
-
- return mask;
- }
-
- private void clear(int color) {
- GLES20.glClearColor(((color >> 16) & 0xFF) / 255.0f,
- ((color >> 8) & 0xFF) / 255.0f,
- (color & 0xFF) / 255.0f,
- 0.0f);
- // The bits set here need to match up with those used
- // in gfx/layers/opengl/LayerManagerOGL.cpp.
- GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT |
- GLES20.GL_DEPTH_BUFFER_BIT);
- }
-
- /** This function is invoked via JNI; be careful when modifying signature. */
- //@JNITarget
- public void drawBackground() {
- // Any GL state which is changed here must be restored in
- // CompositorOGL::RestoreState
-
- GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
-
- // Draw the overscroll background area as a solid color
- clear(mOverscrollColor);
-
- // Update background color.
- mBackgroundColor = mView.getBackgroundColor();
-
- // Clear the page area to the page background colour.
- setScissorRect();
- clear(mBackgroundColor);
- GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
- }
-
- // Draws the layer the client added to us.
- void drawRootLayer() {
- Layer rootLayer = mView.getLayerClient().getRoot();
- if (rootLayer == null) {
- return;
- }
-
- rootLayer.draw(mPageContext);
- }
-
- //@JNITarget
- public void drawForeground() {
- // Any GL state which is changed here must be restored in
- // CompositorOGL::RestoreState
-
- /* Draw any extra layers that were added (likely plugins) */
- if (mExtraLayers.size() > 0) {
- for (Layer layer : mExtraLayers) {
- layer.draw(mPageContext);
- }
- }
-
- /* Draw the vertical scrollbar. */
- if (mPageRect.height() > mFrameMetrics.getHeight())
- mVertScrollLayer.draw(mPageContext);
-
- /* Draw the horizontal scrollbar. */
- if (mPageRect.width() > mFrameMetrics.getWidth())
- mHorizScrollLayer.draw(mPageContext);
-
- /* Measure how much of the screen is checkerboarding */
- Layer rootLayer = mView.getLayerClient().getRoot();
- if ((rootLayer != null) &&
- (mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) {
- // Calculate the incompletely rendered area of the page
- float checkerboard = 1.0f - /*GeckoAppShell*/LOKitShell.computeRenderIntegrity();
-
- PanningPerfAPI.recordCheckerboard(checkerboard);
- if (checkerboard < 0.0f || checkerboard > 1.0f) {
- Log.e(LOGTAG, "Checkerboard value out of bounds: " + checkerboard);
- }
-
- mCompleteFramesRendered += 1.0f - checkerboard;
- mFramesRendered ++;
-
- if (mFrameStartTime - mProfileOutputTime > NANOS_PER_SECOND) {
- mProfileOutputTime = mFrameStartTime;
- printCheckerboardStats();
- }
- }
-
- runRenderTasks(mTasks, true, mFrameStartTime);
-
- /* Draw the FPS. */
- if (mFrameRateLayer != null) {
- updateDroppedFrames(mFrameStartTime);
-
- GLES20.glEnable(GLES20.GL_BLEND);
- GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
- mFrameRateLayer.draw(mScreenContext);
- }
- }
-
- /** This function is invoked via JNI; be careful when modifying signature. */
- //@JNITarget
- public void endDrawing() {
- // If a layer update requires further work, schedule another redraw
- if (!mUpdated)
- mView.requestRender();
-
- PanningPerfAPI.recordFrameTime();
-
- /* Used by robocop for testing purposes */
- IntBuffer pixelBuffer = mPixelBuffer;
- if (mUpdated && pixelBuffer != null) {
- synchronized (pixelBuffer) {
- pixelBuffer.position(0);
- GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(),
- (int)mScreenContext.viewport.height(), GLES20.GL_RGBA,
- GLES20.GL_UNSIGNED_BYTE, pixelBuffer);
- pixelBuffer.notify();
- }
- }
-
- // Remove background color once we've painted. GeckoLayerClient is
- // responsible for setting this flag before current document is
- // composited.
- if (mView.getPaintState() == LayerView.PAINT_BEFORE_FIRST) {
- mView.post(new Runnable() {
- @Override
- public void run() {
- mView.getChildAt(0).setBackgroundColor(Color.TRANSPARENT);
- }
- });
- mView.setPaintState(LayerView.PAINT_AFTER_FIRST);
- }
- mLastFrameTime = mFrameStartTime;
- }
- }
-
- /*@Override
- public void onTabChanged(final Tab tab, Tabs.TabEvents msg, Object data) {
- // Sets the background of the newly selected tab. This background color
- // gets cleared in endDrawing(). This function runs on the UI thread,
- // but other code that touches the paint state is run on the compositor
- // thread, so this may need to be changed if any problems appear.
- if (msg == Tabs.TabEvents.SELECTED) {
- if (mView != null) {
- if (mView.getChildAt(0) != null) {
- mView.getChildAt(0).setBackgroundColor(tab.getBackgroundColor());
- }
- mView.setPaintState(LayerView.PAINT_START);
- }
- }
- }*/
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java
deleted file mode 100644
index c489e7f044bc..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java
+++ /dev/null
@@ -1,692 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAccessibility;
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-//import org.mozilla.gecko.PrefsHelper;
-//import org.mozilla.gecko.R;
-//import org.mozilla.gecko.Tab;
-//import org.mozilla.gecko.Tabs;
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.TouchEventInterceptor;
-import org.mozilla.gecko.ZoomConstraints;
-//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
-//import org.mozilla.gecko.mozglue.RobocopTarget;
-import org.mozilla.gecko.util.EventDispatcher;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-import android.os.Build;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.TextureView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.FrameLayout;
-
-import java.nio.IntBuffer;
-import java.util.ArrayList;
-
-/**
- * A view rendered by the layer compositor.
- *
- * Note that LayerView is accessed by Robocop via reflection.
- */
-public class LayerView extends FrameLayout /*implements Tabs.OnTabsChangedListener */ {
- private static String LOGTAG = "GeckoLayerView";
-
- private GeckoLayerClient mLayerClient;
- private PanZoomController mPanZoomController;
- private LayerMarginsAnimator mMarginsAnimator;
- private GLController mGLController;
- private InputConnectionHandler mInputConnectionHandler;
- private LayerRenderer mRenderer;
- /* Must be a PAINT_xxx constant */
- private int mPaintState;
- private int mBackgroundColor;
- private boolean mFullScreen;
-
- private SurfaceView mSurfaceView;
- private TextureView mTextureView;
-
- private Listener mListener;
-
- /* This should only be modified on the Java UI thread. */
- private final ArrayList<TouchEventInterceptor> mTouchInterceptors;
- private final Overscroll mOverscroll;
-
- /* Flags used to determine when to show the painted surface. */
- public static final int PAINT_START = 0;
- public static final int PAINT_BEFORE_FIRST = 1;
- public static final int PAINT_AFTER_FIRST = 2;
-
- public boolean shouldUseTextureView() {
- // Disable TextureView support for now as it causes panning/zooming
- // performance regressions (see bug 792259). Uncomment the code below
- // once this bug is fixed.
- return false;
-
- /*
- // we can only use TextureView on ICS or higher
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- Log.i(LOGTAG, "Not using TextureView: not on ICS+");
- return false;
- }
-
- try {
- // and then we can only use it if we have a hardware accelerated window
- Method m = View.class.getMethod("isHardwareAccelerated", (Class[]) null);
- return (Boolean) m.invoke(this);
- } catch (Exception e) {
- Log.i(LOGTAG, "Not using TextureView: caught exception checking for hw accel: " + e.toString());
- return false;
- } */
- }
-
- public LayerView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mGLController = GLController.getInstance(this);
- mPaintState = PAINT_START;
- mBackgroundColor = Color.WHITE;
-
- mTouchInterceptors = new ArrayList<TouchEventInterceptor>();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- mOverscroll = new OverscrollEdgeEffect(this);
- } else {
- mOverscroll = null;
- }
- //Tabs.registerOnTabsChangedListener(this);
- }
-
- public LayerView(Context context) {
- this(context, null);
- }
-
- public void initializeView(EventDispatcher eventDispatcher) {
- mLayerClient = new GeckoLayerClient(getContext(), this, eventDispatcher);
- if (mOverscroll != null) {
- mLayerClient.setOverscrollHandler(mOverscroll);
- }
-
- mPanZoomController = mLayerClient.getPanZoomController();
- mMarginsAnimator = mLayerClient.getLayerMarginsAnimator();
-
- mRenderer = new LayerRenderer(this);
- mInputConnectionHandler = null;
-
- setFocusable(true);
- setFocusableInTouchMode(true);
-
- //GeckoAccessibility.setDelegate(this);
- }
-
- private Point getEventRadius(MotionEvent event) {
- if (Build.VERSION.SDK_INT >= 9) {
- return new Point((int)event.getToolMajor()/2,
- (int)event.getToolMinor()/2);
- }
-
- float size = event.getSize();
- DisplayMetrics displaymetrics = getContext().getResources().getDisplayMetrics();
- size = size * Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels);
- return new Point((int)size, (int)size);
- }
-
- public void geckoConnected() {
- // See if we want to force 16-bit colour before doing anything
- /*PrefsHelper.getPref("gfx.android.rgb16.force", new PrefsHelper.PrefHandlerBase() {
- @Override public void prefValue(String pref, boolean force16bit) {
- if (force16bit) {
- GeckoAppShell.setScreenDepthOverride(16);
- }
- }
- });*/
-
- mLayerClient.notifyGeckoReady();
- addTouchInterceptor(new TouchEventInterceptor() {
- private PointF mInitialTouchPoint = null;
-
- @Override
- public boolean onInterceptTouchEvent(View view, MotionEvent event) {
- return false;
- }
-
- @Override
- public boolean onTouch(View view, MotionEvent event) {
- if (event == null) {
- return true;
- }
-
- int action = event.getActionMasked();
- PointF point = new PointF(event.getX(), event.getY());
- if (action == MotionEvent.ACTION_DOWN) {
- mInitialTouchPoint = point;
- }
-
- if (mInitialTouchPoint != null && action == MotionEvent.ACTION_MOVE) {
- Point p = getEventRadius(event);
-
- if (PointUtils.subtract(point, mInitialTouchPoint).length() <
- Math.max(PanZoomController.CLICK_THRESHOLD, Math.min(Math.min(p.x, p.y), PanZoomController.PAN_THRESHOLD))) {
- // Don't send the touchmove event if the users finger hasn't moved far.
- // Necessary for Google Maps to work correctly. See bug 771099.
- return true;
- } else {
- mInitialTouchPoint = null;
- }
- }
-
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createMotionEvent(event, false));
- return true;
- }
- });
- }
-
- public void showSurface() {
- // Fix this if TextureView support is turned back on above
- mSurfaceView.setVisibility(View.VISIBLE);
- }
-
- public void hideSurface() {
- // Fix this if TextureView support is turned back on above
- mSurfaceView.setVisibility(View.INVISIBLE);
- }
-
- public void destroy() {
- if (mLayerClient != null) {
- mLayerClient.destroy();
- }
- if (mRenderer != null) {
- mRenderer.destroy();
- }
- //Tabs.unregisterOnTabsChangedListener(this);
- }
-
- public void addTouchInterceptor(final TouchEventInterceptor aTouchInterceptor) {
- post(new Runnable() {
- @Override
- public void run() {
- mTouchInterceptors.add(aTouchInterceptor);
- }
- });
- }
-
- public void removeTouchInterceptor(final TouchEventInterceptor aTouchInterceptor) {
- post(new Runnable() {
- @Override
- public void run() {
- mTouchInterceptors.remove(aTouchInterceptor);
- }
- });
- }
-
- private boolean runTouchInterceptors(MotionEvent event, boolean aOnTouch) {
- boolean result = false;
- for (TouchEventInterceptor i : mTouchInterceptors) {
- if (aOnTouch) {
- result |= i.onTouch(this, event);
- } else {
- result |= i.onInterceptTouchEvent(this, event);
- }
- }
-
- return result;
- }
-
- @Override
- public void dispatchDraw(final Canvas canvas) {
- super.dispatchDraw(canvas);
-
- // We must have a layer client to get valid viewport metrics
- if (mLayerClient != null && mOverscroll != null) {
- mOverscroll.draw(canvas, getViewportMetrics());
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- requestFocus();
- }
-
- if (runTouchInterceptors(event, false)) {
- return true;
- }
- if (mPanZoomController != null && mPanZoomController.onTouchEvent(event)) {
- return true;
- }
- if (runTouchInterceptors(event, true)) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onHoverEvent(MotionEvent event) {
- if (runTouchInterceptors(event, true)) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onGenericMotionEvent(MotionEvent event) {
- if (mPanZoomController != null && mPanZoomController.onMotionEvent(event)) {
- return true;
- }
- return false;
- }
-
- @Override
- protected void onAttachedToWindow() {
- // This check should not be done before the view is attached to a window
- // as hardware acceleration will not be enabled at that point.
- // We must create and add the SurfaceView instance before the view tree
- // is fully created to avoid flickering (see bug 801477).
- if (shouldUseTextureView()) {
- mTextureView = new TextureView(getContext());
- mTextureView.setSurfaceTextureListener(new SurfaceTextureListener());
-
- // The background is set to this color when the LayerView is
- // created, and it will be shown immediately at startup. Shortly
- // after, the tab's background color will be used before any content
- // is shown.
- mTextureView.setBackgroundColor(Color.WHITE);
- addView(mTextureView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
- } else {
- // This will stop PropertyAnimator from creating a drawing cache (i.e. a bitmap)
- // from a SurfaceView, which is just not possible (the bitmap will be transparent).
- setWillNotCacheDrawing(false);
-
- mSurfaceView = new LayerSurfaceView(getContext(), this);
- mSurfaceView.setBackgroundColor(Color.WHITE);
- addView(mSurfaceView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-
- SurfaceHolder holder = mSurfaceView.getHolder();
- holder.addCallback(new SurfaceListener());
- holder.setFormat(PixelFormat.RGB_565);
- }
- }
-
- //@RobocopTarget
- public GeckoLayerClient getLayerClient() { return mLayerClient; }
- public PanZoomController getPanZoomController() { return mPanZoomController; }
- public LayerMarginsAnimator getLayerMarginsAnimator() { return mMarginsAnimator; }
-
- public ImmutableViewportMetrics getViewportMetrics() {
- return mLayerClient.getViewportMetrics();
- }
-
- public void abortPanning() {
- if (mPanZoomController != null) {
- mPanZoomController.abortPanning();
- }
- }
-
- public PointF convertViewPointToLayerPoint(PointF viewPoint) {
- return mLayerClient.convertViewPointToLayerPoint(viewPoint);
- }
-
- int getBackgroundColor() {
- return mBackgroundColor;
- }
-
- @Override
- public void setBackgroundColor(int newColor) {
- mBackgroundColor = newColor;
- requestRender();
- }
-
- public void setZoomConstraints(ZoomConstraints constraints) {
- mLayerClient.setZoomConstraints(constraints);
- }
-
- public void setIsRTL(boolean aIsRTL) {
- mLayerClient.setIsRTL(aIsRTL);
- }
-
- public void setInputConnectionHandler(InputConnectionHandler inputConnectionHandler) {
- mInputConnectionHandler = inputConnectionHandler;
- mLayerClient.forceRedraw(null);
- }
-
- @Override
- public Handler getHandler() {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.getHandler(super.getHandler());
- return super.getHandler();
- }
-
- @Override
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.onCreateInputConnection(outAttrs);
- return null;
- }
-
- @Override
- public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyPreIme(keyCode, event)) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mPanZoomController != null && mPanZoomController.onKeyEvent(event)) {
- return true;
- }
- if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyDown(keyCode, event)) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onKeyLongPress(int keyCode, KeyEvent event) {
- if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyLongPress(keyCode, event)) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
- if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyMultiple(keyCode, repeatCount, event)) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyUp(keyCode, event)) {
- return true;
- }
- return false;
- }
-
- public boolean isIMEEnabled() {
- if (mInputConnectionHandler != null) {
- return mInputConnectionHandler.isIMEEnabled();
- }
- return false;
- }
-
- public void requestRender() {
- if (mListener != null) {
- mListener.renderRequested();
- }
- }
-
- public void addLayer(Layer layer) {
- mRenderer.addLayer(layer);
- }
-
- public void removeLayer(Layer layer) {
- mRenderer.removeLayer(layer);
- }
-
- public void postRenderTask(RenderTask task) {
- mRenderer.postRenderTask(task);
- }
-
- public void removeRenderTask(RenderTask task) {
- mRenderer.removeRenderTask(task);
- }
-
- public int getMaxTextureSize() {
- return mRenderer.getMaxTextureSize();
- }
-
- /** Used by robocop for testing purposes. Not for production use! */
- //@RobocopTarget
- public IntBuffer getPixels() {
- return mRenderer.getPixels();
- }
-
- /* paintState must be a PAINT_xxx constant. */
- public void setPaintState(int paintState) {
- mPaintState = paintState;
- }
-
- public int getPaintState() {
- return mPaintState;
- }
-
- public LayerRenderer getRenderer() {
- return mRenderer;
- }
-
- public void setListener(Listener listener) {
- mListener = listener;
- }
-
- Listener getListener() {
- return mListener;
- }
-
- public GLController getGLController() {
- return mGLController;
- }
-
- private Bitmap getDrawable(String name) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- Context context = getContext();
- int resId = context.getResources().getIdentifier(name, "drawable", context.getPackageName());
- return BitmapUtils.decodeResource(context, resId, options);
- }
-
- Bitmap getScrollbarImage() {
- return getDrawable("scrollbar");
- }
-
- /* When using a SurfaceView (mSurfaceView != null), resizing happens in two
- * phases. First, the LayerView changes size, then, often some frames later,
- * the SurfaceView changes size. Because of this, we need to split the
- * resize into two phases to avoid jittering.
- *
- * The first phase is the LayerView size change. mListener is notified so
- * that a synchronous draw can be performed (otherwise a blank frame will
- * appear).
- *
- * The second phase is the SurfaceView size change. At this point, the
- * backing GL surface is resized and another synchronous draw is performed.
- * Gecko is also sent the new window size, and this will likely cause an
- * extra draw a few frames later, after it's re-rendered and caught up.
- *
- * In the case that there is no valid GL surface (for example, when
- * resuming, or when coming back from the awesomescreen), or we're using a
- * TextureView instead of a SurfaceView, the first phase is skipped.
- */
- private void onSizeChanged(int width, int height) {
- if (!mGLController.isCompositorCreated()) {
- return;
- }
-
- surfaceChanged(width, height);
-
- if (mSurfaceView == null) {
- return;
- }
-
- if (mListener != null) {
- mListener.sizeChanged(width, height);
- }
-
- if (mOverscroll != null) {
- mOverscroll.setSize(width, height);
- }
- }
-
- private void surfaceChanged(int width, int height) {
- mGLController.serverSurfaceChanged(width, height);
-
- if (mListener != null) {
- mListener.surfaceChanged(width, height);
- }
-
- if (mOverscroll != null) {
- mOverscroll.setSize(width, height);
- }
- }
-
- private void onDestroyed() {
- mGLController.serverSurfaceDestroyed();
- }
-
- public Object getNativeWindow() {
- if (mSurfaceView != null)
- return mSurfaceView.getHolder();
-
- return mTextureView.getSurfaceTexture();
- }
-
- //@WrapElementForJNI(allowMultithread = true, stubName = "RegisterCompositorWrapper")
- public static GLController registerCxxCompositor() {
- try {
- LayerView layerView = /*GeckoAppShell*/LOKitShell.getLayerView();
- GLController controller = layerView.getGLController();
- controller.compositorCreated();
- return controller;
- } catch (Exception e) {
- Log.e(LOGTAG, "Error registering compositor!", e);
- return null;
- }
- }
-
- public interface Listener {
- void renderRequested();
- void sizeChanged(int width, int height);
- void surfaceChanged(int width, int height);
- }
-
- private class SurfaceListener implements SurfaceHolder.Callback {
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- onSizeChanged(width, height);
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- onDestroyed();
- }
- }
-
- /* A subclass of SurfaceView to listen to layout changes, as
- * View.OnLayoutChangeListener requires API level 11.
- */
- private class LayerSurfaceView extends SurfaceView {
- LayerView mParent;
-
- public LayerSurfaceView(Context aContext, LayerView aParent) {
- super(aContext);
- mParent = aParent;
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- if (changed) {
- mParent.surfaceChanged(right - left, bottom - top);
- }
- }
- }
-
- private class SurfaceTextureListener implements TextureView.SurfaceTextureListener {
- @Override
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- // We don't do this for surfaceCreated above because it is always followed by a surfaceChanged,
- // but that is not the case here.
- onSizeChanged(width, height);
- }
-
- @Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- onDestroyed();
- return true; // allow Android to call release() on the SurfaceTexture, we are done drawing to it
- }
-
- @Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
- onSizeChanged(width, height);
- }
-
- @Override
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
-
- }
- }
-
- @Override
- public void setOverScrollMode(int overscrollMode) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
- super.setOverScrollMode(overscrollMode);
- }
- if (mPanZoomController != null) {
- mPanZoomController.setOverScrollMode(overscrollMode);
- }
- }
-
- @Override
- public int getOverScrollMode() {
- if (mPanZoomController != null) {
- return mPanZoomController.getOverScrollMode();
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
- return super.getOverScrollMode();
- }
- return View.OVER_SCROLL_ALWAYS;
- }
-
- @Override
- public void onFocusChanged (boolean gainFocus, int direction, Rect previouslyFocusedRect) {
- super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
- //GeckoAccessibility.onLayerViewFocusChanged(this, gainFocus);
- }
-
- public void setFullScreen(boolean fullScreen) {
- mFullScreen = fullScreen;
- }
-
- public boolean isFullScreen() {
- return mFullScreen;
- }
-
- /*@Override
- public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
- if (msg == Tabs.TabEvents.VIEWPORT_CHANGE && Tabs.getInstance().isSelectedTab(tab) && mLayerClient != null) {
- setZoomConstraints(tab.getZoomConstraints());
- setIsRTL(tab.getIsRTL());
- }
- }*/
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java
deleted file mode 100644
index e442444d5a7b..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Canvas;
-
-public interface Overscroll {
- // The axis to show overscroll on.
- public enum Axis {
- X,
- Y,
- };
-
- public void draw(final Canvas canvas, final ImmutableViewportMetrics metrics);
- public void setSize(final int width, final int height);
- public void setVelocity(final float velocity, final Axis axis);
- public void setDistance(final float distance, final Axis axis);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java
deleted file mode 100644
index 9ab64d5f3e51..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.os.Build;
-import android.widget.EdgeEffect;
-import android.view.View;
-
-
-public class OverscrollEdgeEffect implements Overscroll {
- // Used to index particular edges in the edges array
- private static final int TOP = 0;
- private static final int BOTTOM = 1;
- private static final int LEFT = 2;
- private static final int RIGHT = 3;
-
- // All four edges of the screen
- private final EdgeEffect[] mEdges = new EdgeEffect[4];
-
- // The view we're showing this overscroll on.
- private final View mView;
-
- public OverscrollEdgeEffect(final View v) {
- mView = v;
- Context context = v.getContext();
- for (int i = 0; i < 4; i++) {
- mEdges[i] = new EdgeEffect(context);
- }
- }
-
- public void setSize(final int width, final int height) {
- mEdges[LEFT].setSize(height, width);
- mEdges[RIGHT].setSize(height, width);
- mEdges[TOP].setSize(width, height);
- mEdges[BOTTOM].setSize(width, height);
- }
-
- private EdgeEffect getEdgeForAxisAndSide(final Axis axis, final float side) {
- if (axis == Axis.Y) {
- if (side < 0) {
- return mEdges[TOP];
- } else {
- return mEdges[BOTTOM];
- }
- } else {
- if (side < 0) {
- return mEdges[LEFT];
- } else {
- return mEdges[RIGHT];
- }
- }
- }
-
- private void invalidate() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- mView.postInvalidateOnAnimation();
- } else {
- mView.postInvalidateDelayed(10);
- }
- }
-
- public void setVelocity(final float velocity, final Axis axis) {
- final EdgeEffect edge = getEdgeForAxisAndSide(axis, velocity);
-
- // If we're showing overscroll already, start fading it out.
- if (!edge.isFinished()) {
- edge.onRelease();
- } else {
- // Otherwise, show an absorb effect
- edge.onAbsorb((int)velocity);
- }
-
- invalidate();
- }
-
- public void setDistance(final float distance, final Axis axis) {
- // The first overscroll event often has zero distance. Throw it out
- if (distance == 0.0f) {
- return;
- }
-
- final EdgeEffect edge = getEdgeForAxisAndSide(axis, (int)distance);
- edge.onPull(distance / (axis == Axis.X ? mView.getWidth() : mView.getHeight()));
- invalidate();
- }
-
- public void draw(final Canvas canvas, final ImmutableViewportMetrics metrics) {
- if (metrics == null) {
- return;
- }
-
- // If we're pulling an edge, or fading it out, draw!
- boolean invalidate = false;
- if (!mEdges[TOP].isFinished()) {
- invalidate |= draw(mEdges[TOP], canvas, metrics.marginLeft, metrics.marginTop, 0);
- }
-
- if (!mEdges[BOTTOM].isFinished()) {
- invalidate |= draw(mEdges[BOTTOM], canvas, mView.getWidth(), mView.getHeight(), 180);
- }
-
- if (!mEdges[LEFT].isFinished()) {
- invalidate |= draw(mEdges[LEFT], canvas, metrics.marginLeft, mView.getHeight(), 270);
- }
-
- if (!mEdges[RIGHT].isFinished()) {
- invalidate |= draw(mEdges[RIGHT], canvas, mView.getWidth(), metrics.marginTop, 90);
- }
-
- // If the edge effect is animating off screen, invalidate.
- if (invalidate) {
- invalidate();
- }
- }
-
- public boolean draw(final EdgeEffect edge, final Canvas canvas, final float translateX, final float translateY, final float rotation) {
- final int state = canvas.save();
- canvas.translate(translateX, translateY);
- canvas.rotate(rotation);
- boolean invalidate = edge.draw(canvas);
- canvas.restoreToCount(state);
-
- return invalidate;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java
deleted file mode 100644
index 5ef25a64628c..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.util.EventDispatcher;
-
-import android.graphics.PointF;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-
-public interface PanZoomController {
- // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans
- // between the touch-down and touch-up of a click). In units of density-independent pixels.
- public static final float PAN_THRESHOLD = 1/16f * /*GeckoAppShell*/LOKitShell.getDpi();
-
- // Threshold for sending touch move events to content
- public static final float CLICK_THRESHOLD = 1/50f * /*GeckoAppShell*/LOKitShell.getDpi();
-
- static class Factory {
- static PanZoomController create(PanZoomTarget target, View view, EventDispatcher dispatcher) {
- return new JavaPanZoomController(target, view, dispatcher);
- }
- }
-
- public void destroy();
-
- public boolean onTouchEvent(MotionEvent event);
- public boolean onMotionEvent(MotionEvent event);
- public boolean onKeyEvent(KeyEvent event);
- public void notifyDefaultActionPrevented(boolean prevented);
-
- public boolean getRedrawHint();
- public PointF getVelocityVector();
-
- public void pageRectUpdated();
- public void abortPanning();
- public void abortAnimation();
-
- public void setOverScrollMode(int overscrollMode);
- public int getOverScrollMode();
-
- public void setOverscrollHandler(final Overscroll controller);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java
deleted file mode 100644
index c32f213937f2..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.ZoomConstraints;
-
-import android.graphics.PointF;
-import android.graphics.RectF;
-
-public interface PanZoomTarget {
- public ImmutableViewportMetrics getViewportMetrics();
- public ZoomConstraints getZoomConstraints();
- public boolean isFullScreen();
- public RectF getMaxMargins();
-
- public void setAnimationTarget(ImmutableViewportMetrics viewport);
- public void setViewportMetrics(ImmutableViewportMetrics viewport);
- public void scrollBy(float dx, float dy);
- public void scrollMarginsBy(float dx, float dy);
- public void panZoomStopped();
- /** This triggers an (asynchronous) viewport update/redraw. */
- public void forceRedraw(DisplayPortMetrics displayPort);
-
- public boolean post(Runnable action);
- public boolean postDelayed(Runnable action, long delayMillis);
- public void postRenderTask(RenderTask task);
- public void removeRenderTask(RenderTask task);
- public Object getLock();
- public PointF convertViewPointToLayerPoint(PointF viewPoint);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java
deleted file mode 100644
index 7c2ca2b9d030..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.mozglue.RobocopTarget;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PanningPerfAPI {
- private static final String LOGTAG = "GeckoPanningPerfAPI";
-
- // make this large enough to avoid having to resize the frame time
- // list, as that may be expensive and impact the thing we're trying
- // to measure.
- private static final int EXPECTED_FRAME_COUNT = 2048;
-
- private static boolean mRecordingFrames = false;
- private static List<Long> mFrameTimes;
- private static long mFrameStartTime;
-
- private static boolean mRecordingCheckerboard = false;
- private static List<Float> mCheckerboardAmounts;
- private static long mCheckerboardStartTime;
-
- private static void initialiseRecordingArrays() {
- if (mFrameTimes == null) {
- mFrameTimes = new ArrayList<Long>(EXPECTED_FRAME_COUNT);
- } else {
- mFrameTimes.clear();
- }
- if (mCheckerboardAmounts == null) {
- mCheckerboardAmounts = new ArrayList<Float>(EXPECTED_FRAME_COUNT);
- } else {
- mCheckerboardAmounts.clear();
- }
- }
-
- //@RobocopTarget
- public static void startFrameTimeRecording() {
- if (mRecordingFrames || mRecordingCheckerboard) {
- Log.e(LOGTAG, "Error: startFrameTimeRecording() called while already recording!");
- return;
- }
- mRecordingFrames = true;
- initialiseRecordingArrays();
- mFrameStartTime = SystemClock.uptimeMillis();
- }
-
- //@RobocopTarget
- public static List<Long> stopFrameTimeRecording() {
- if (!mRecordingFrames) {
- Log.e(LOGTAG, "Error: stopFrameTimeRecording() called when not recording!");
- return null;
- }
- mRecordingFrames = false;
- return mFrameTimes;
- }
-
- public static void recordFrameTime() {
- // this will be called often, so try to make it as quick as possible
- if (mRecordingFrames) {
- mFrameTimes.add(SystemClock.uptimeMillis() - mFrameStartTime);
- }
- }
-
- public static boolean isRecordingCheckerboard() {
- return mRecordingCheckerboard;
- }
-
- //@RobocopTarget
- public static void startCheckerboardRecording() {
- if (mRecordingCheckerboard || mRecordingFrames) {
- Log.e(LOGTAG, "Error: startCheckerboardRecording() called while already recording!");
- return;
- }
- mRecordingCheckerboard = true;
- initialiseRecordingArrays();
- mCheckerboardStartTime = SystemClock.uptimeMillis();
- }
-
- //@RobocopTarget
- public static List<Float> stopCheckerboardRecording() {
- if (!mRecordingCheckerboard) {
- Log.e(LOGTAG, "Error: stopCheckerboardRecording() called when not recording!");
- return null;
- }
- mRecordingCheckerboard = false;
-
- // We take the number of values in mCheckerboardAmounts here, as there's
- // the possibility that this function is called while recordCheckerboard
- // is still executing. As values are added to this list last, we use
- // this number as the canonical number of recordings.
- int values = mCheckerboardAmounts.size();
-
- // The score will be the sum of all the values in mCheckerboardAmounts,
- // so weight the checkerboard values by time so that frame-rate and
- // run-length don't affect score.
- long lastTime = 0;
- float totalTime = mFrameTimes.get(values - 1);
- for (int i = 0; i < values; i++) {
- long elapsedTime = mFrameTimes.get(i) - lastTime;
- mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime);
- lastTime += elapsedTime;
- }
-
- return mCheckerboardAmounts;
- }
-
- public static void recordCheckerboard(float amount) {
- // this will be called often, so try to make it as quick as possible
- if (mRecordingCheckerboard) {
- mFrameTimes.add(SystemClock.uptimeMillis() - mCheckerboardStartTime);
- mCheckerboardAmounts.add(amount);
- }
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java
deleted file mode 100644
index 8db329c9fe8d..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.graphics.Point;
-import android.graphics.PointF;
-
-public final class PointUtils {
- public static PointF add(PointF one, PointF two) {
- return new PointF(one.x + two.x, one.y + two.y);
- }
-
- public static PointF subtract(PointF one, PointF two) {
- return new PointF(one.x - two.x, one.y - two.y);
- }
-
- public static PointF scale(PointF point, float factor) {
- return new PointF(point.x * factor, point.y * factor);
- }
-
- public static Point round(PointF point) {
- return new Point(Math.round(point.x), Math.round(point.y));
- }
-
- /* Computes the magnitude of the given vector. */
- public static float distance(PointF point) {
- return (float)Math.sqrt(point.x * point.x + point.y * point.y);
- }
-
- /** Computes the scalar distance between two points. */
- public static float distance(PointF one, PointF two) {
- return PointF.length(one.x - two.x, one.y - two.y);
- }
-
- public static JSONObject toJSON(PointF point) throws JSONException {
- // Ensure we put ints, not longs, because Gecko message handlers call getInt().
- int x = Math.round(point.x);
- int y = Math.round(point.y);
- JSONObject json = new JSONObject();
- json.put("x", x);
- json.put("y", y);
- return json;
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java
deleted file mode 100644
index b7c381c688b0..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI;
-
-/**
- * This is the data structure that's returned by the progressive tile update
- * callback function. It encompasses the current viewport and a boolean value
- * representing whether the front-end is interested in the current progressive
- * update continuing.
- */
-//@WrapEntireClassForJNI
-public class ProgressiveUpdateData {
- public float x;
- public float y;
- public float width;
- public float height;
- public float scale;
- public boolean abort;
-
- public void setViewport(ImmutableViewportMetrics viewport) {
- this.x = viewport.viewportRectLeft;
- this.y = viewport.viewportRectTop;
- this.width = viewport.viewportRectRight - this.x;
- this.height = viewport.viewportRectBottom - this.y;
- this.scale = viewport.zoomFactor;
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java
deleted file mode 100644
index 22151db76921..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.util.FloatUtils;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-public final class RectUtils {
- private RectUtils() {}
-
- public static Rect create(JSONObject json) {
- try {
- int x = json.getInt("x");
- int y = json.getInt("y");
- int width = json.getInt("width");
- int height = json.getInt("height");
- return new Rect(x, y, x + width, y + height);
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static String toJSON(RectF rect) {
- StringBuilder sb = new StringBuilder(256);
- sb.append("{ \"left\": ").append(rect.left)
- .append(", \"top\": ").append(rect.top)
- .append(", \"right\": ").append(rect.right)
- .append(", \"bottom\": ").append(rect.bottom)
- .append('}');
- return sb.toString();
- }
-
- public static RectF expand(RectF rect, float moreWidth, float moreHeight) {
- float halfMoreWidth = moreWidth / 2;
- float halfMoreHeight = moreHeight / 2;
- return new RectF(rect.left - halfMoreWidth,
- rect.top - halfMoreHeight,
- rect.right + halfMoreWidth,
- rect.bottom + halfMoreHeight);
- }
-
- public static RectF contract(RectF rect, float lessWidth, float lessHeight) {
- float halfLessWidth = lessWidth / 2.0f;
- float halfLessHeight = lessHeight / 2.0f;
- return new RectF(rect.left + halfLessWidth,
- rect.top + halfLessHeight,
- rect.right - halfLessWidth,
- rect.bottom - halfLessHeight);
- }
-
- public static RectF intersect(RectF one, RectF two) {
- float left = Math.max(one.left, two.left);
- float top = Math.max(one.top, two.top);
- float right = Math.min(one.right, two.right);
- float bottom = Math.min(one.bottom, two.bottom);
- return new RectF(left, top, Math.max(right, left), Math.max(bottom, top));
- }
-
- public static RectF scale(RectF rect, float scale) {
- float x = rect.left * scale;
- float y = rect.top * scale;
- return new RectF(x, y,
- x + (rect.width() * scale),
- y + (rect.height() * scale));
- }
-
- public static RectF scaleAndRound(RectF rect, float scale) {
- float left = rect.left * scale;
- float top = rect.top * scale;
- return new RectF(Math.round(left),
- Math.round(top),
- Math.round(left + (rect.width() * scale)),
- Math.round(top + (rect.height() * scale)));
- }
-
- /** Returns the nearest integer rect of the given rect. */
- public static Rect round(RectF rect) {
- Rect r = new Rect();
- round(rect, r);
- return r;
- }
-
- public static void round(RectF rect, Rect dest) {
- dest.set(Math.round(rect.left), Math.round(rect.top),
- Math.round(rect.right), Math.round(rect.bottom));
- }
-
- public static Rect roundIn(RectF rect) {
- return new Rect((int)Math.ceil(rect.left), (int)Math.ceil(rect.top),
- (int)Math.floor(rect.right), (int)Math.floor(rect.bottom));
- }
-
- public static IntSize getSize(Rect rect) {
- return new IntSize(rect.width(), rect.height());
- }
-
- public static Point getOrigin(Rect rect) {
- return new Point(rect.left, rect.top);
- }
-
- public static PointF getOrigin(RectF rect) {
- return new PointF(rect.left, rect.top);
- }
-
- public static boolean fuzzyEquals(RectF a, RectF b) {
- if (a == null && b == null)
- return true;
- else if ((a == null && b != null) || (a != null && b == null))
- return false;
- else
- return FloatUtils.fuzzyEquals(a.top, b.top)
- && FloatUtils.fuzzyEquals(a.left, b.left)
- && FloatUtils.fuzzyEquals(a.right, b.right)
- && FloatUtils.fuzzyEquals(a.bottom, b.bottom);
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java
deleted file mode 100644
index 39c6eacb59f8..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-/**
- * A class used to schedule a callback to occur when the next frame is drawn.
- * Subclasses must redefine the internalRun method, not the run method.
- */
-public abstract class RenderTask {
- /**
- * Whether to run the task after the render, or before.
- */
- public final boolean runAfter;
-
- /**
- * Time when this task has first run, in ns. Useful for tasks which run for a specific duration.
- */
- private long mStartTime;
-
- /**
- * Whether we should initialise mStartTime on the next frame run.
- */
- private boolean mResetStartTime = true;
-
- /**
- * The callback to run on each frame. timeDelta is the time elapsed since
- * the last call, in nanoseconds. Returns true if it should continue
- * running, or false if it should be removed from the task queue. Returning
- * true implicitly schedules a redraw.
- *
- * This method first initializes the start time if resetStartTime has been invoked,
- * then calls internalRun.
- *
- * Note : subclasses should override internalRun.
- *
- * @param timeDelta the time between the beginning of last frame and the beginning of this frame, in ns.
- * @param currentFrameStartTime the startTime of the current frame, in ns.
- * @return true if animation should be run at the next frame, false otherwise
- * @see org.mozilla.gecko.gfx.RenderTask#internalRun(long, long)
- */
- public final boolean run(long timeDelta, long currentFrameStartTime) {
- if (mResetStartTime) {
- mStartTime = currentFrameStartTime;
- mResetStartTime = false;
- }
- return internalRun(timeDelta, currentFrameStartTime);
- }
-
- /**
- * Abstract method to be overridden by subclasses.
- * @param timeDelta the time between the beginning of last frame and the beginning of this frame, in ns
- * @param currentFrameStartTime the startTime of the current frame, in ns.
- * @return true if animation should be run at the next frame, false otherwise
- */
- protected abstract boolean internalRun(long timeDelta, long currentFrameStartTime);
-
- public RenderTask(boolean aRunAfter) {
- runAfter = aRunAfter;
- }
-
- /**
- * Get the start time of this task.
- * It is the start time of the first frame this task was run on.
- * @return the start time in ns
- */
- public long getStartTime() {
- return mStartTime;
- }
-
- /**
- * Schedule a reset of the recorded start time next time {@link org.mozilla.gecko.gfx.RenderTask#run(long, long)} is run.
- * @see org.mozilla.gecko.gfx.RenderTask#getStartTime()
- */
- public void resetStartTime() {
- mResetStartTime = true;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java
deleted file mode 100644
index 043c82775467..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.util.FloatUtils;
-
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.opengl.GLES20;
-
-import java.nio.FloatBuffer;
-
-public class ScrollbarLayer extends TileLayer {
- public static final long FADE_DELAY = 500; // milliseconds before fade-out starts
- private static final float FADE_AMOUNT = 0.03f; // how much (as a percent) the scrollbar should fade per frame
-
- private final boolean mVertical;
- private float mOpacity;
-
- // To avoid excessive GC, declare some objects here that would otherwise
- // be created and destroyed frequently during draw().
- private final RectF mBarRectF;
- private final Rect mBarRect;
- private final float[] mCoords;
- private final RectF mCapRectF;
-
- private LayerRenderer mRenderer;
- private int mProgram;
- private int mPositionHandle;
- private int mTextureHandle;
- private int mSampleHandle;
- private int mTMatrixHandle;
- private int mOpacityHandle;
-
- // Fragment shader used to draw the scroll-bar with opacity
- private static final String FRAGMENT_SHADER =
- "precision mediump float;\n" +
- "varying vec2 vTexCoord;\n" +
- "uniform sampler2D sTexture;\n" +
- "uniform float uOpacity;\n" +
- "void main() {\n" +
- " gl_FragColor = texture2D(sTexture, vTexCoord);\n" +
- " gl_FragColor.a *= uOpacity;\n" +
- "}\n";
-
- // Dimensions of the texture bitmap (will always be power-of-two)
- private final int mTexWidth;
- private final int mTexHeight;
- // Some useful dimensions of the actual content in the bitmap
- private final int mBarWidth;
- private final int mCapLength;
-
- private final Rect mStartCapTexCoords; // top/left endcap coordinates
- private final Rect mBodyTexCoords; // 1-pixel slice of the texture to be stretched
- private final Rect mEndCapTexCoords; // bottom/right endcap coordinates
-
- ScrollbarLayer(LayerRenderer renderer, Bitmap scrollbarImage, IntSize imageSize, boolean vertical) {
- super(new BufferedCairoImage(scrollbarImage), TileLayer.PaintMode.NORMAL);
- mRenderer = renderer;
- mVertical = vertical;
-
- mBarRectF = new RectF();
- mBarRect = new Rect();
- mCoords = new float[20];
- mCapRectF = new RectF();
-
- mTexHeight = scrollbarImage.getHeight();
- mTexWidth = scrollbarImage.getWidth();
-
- if (mVertical) {
- mBarWidth = imageSize.width;
- mCapLength = imageSize.height / 2;
- mStartCapTexCoords = new Rect(0, mTexHeight - mCapLength, imageSize.width, mTexHeight);
- mBodyTexCoords = new Rect(0, mTexHeight - (mCapLength + 1), imageSize.width, mTexHeight - mCapLength);
- mEndCapTexCoords = new Rect(0, mTexHeight - imageSize.height, imageSize.width, mTexHeight - (mCapLength + 1));
- } else {
- mBarWidth = imageSize.height;
- mCapLength = imageSize.width / 2;
- mStartCapTexCoords = new Rect(0, mTexHeight - imageSize.height, mCapLength, mTexHeight);
- mBodyTexCoords = new Rect(mCapLength, mTexHeight - imageSize.height, mCapLength + 1, mTexHeight);
- mEndCapTexCoords = new Rect(mCapLength + 1, mTexHeight - imageSize.height, imageSize.width, mTexHeight);
- }
- }
-
- private void createProgram() {
- int vertexShader = LayerRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
- LayerRenderer.DEFAULT_VERTEX_SHADER);
- int fragmentShader = LayerRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
- FRAGMENT_SHADER);
-
- mProgram = GLES20.glCreateProgram();
- GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
- GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
- GLES20.glLinkProgram(mProgram); // creates OpenGL program executables
-
- // Get handles to the shaders' vPosition, aTexCoord, sTexture, and uTMatrix members.
- mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
- mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord");
- mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
- mTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uTMatrix");
- mOpacityHandle = GLES20.glGetUniformLocation(mProgram, "uOpacity");
- }
-
- private void activateProgram() {
- // Add the program to the OpenGL environment
- GLES20.glUseProgram(mProgram);
-
- // Set the transformation matrix
- GLES20.glUniformMatrix4fv(mTMatrixHandle, 1, false,
- LayerRenderer.DEFAULT_TEXTURE_MATRIX, 0);
-
- // Enable the arrays from which we get the vertex and texture coordinates
- GLES20.glEnableVertexAttribArray(mPositionHandle);
- GLES20.glEnableVertexAttribArray(mTextureHandle);
-
- GLES20.glUniform1i(mSampleHandle, 0);
- GLES20.glUniform1f(mOpacityHandle, mOpacity);
- }
-
- private void deactivateProgram() {
- GLES20.glDisableVertexAttribArray(mTextureHandle);
- GLES20.glDisableVertexAttribArray(mPositionHandle);
- GLES20.glUseProgram(0);
- }
-
- /**
- * Decrease the opacity of the scrollbar by one frame's worth.
- * Return true if the opacity was decreased, or false if the scrollbars
- * are already fully faded out.
- */
- public boolean fade() {
- if (FloatUtils.fuzzyEquals(mOpacity, 0.0f)) {
- return false;
- }
- beginTransaction(); // called on compositor thread
- mOpacity = Math.max(mOpacity - FADE_AMOUNT, 0.0f);
- endTransaction();
- return true;
- }
-
- /**
- * Restore the opacity of the scrollbar to fully opaque.
- * Return true if the opacity was changed, or false if the scrollbars
- * are already fully opaque.
- */
- public boolean unfade() {
- if (FloatUtils.fuzzyEquals(mOpacity, 1.0f)) {
- return false;
- }
- beginTransaction(); // called on compositor thread
- mOpacity = 1.0f;
- endTransaction();
- return true;
- }
-
- @Override
- public void draw(RenderContext context) {
- if (!initialized())
- return;
-
- // Create the shader program, if necessary
- if (mProgram == 0) {
- createProgram();
- }
-
- // Enable the shader program
- mRenderer.deactivateDefaultProgram();
- activateProgram();
-
- GLES20.glEnable(GLES20.GL_BLEND);
- GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
-
- if (mVertical) {
- getVerticalRect(context, mBarRectF);
- } else {
- getHorizontalRect(context, mBarRectF);
- }
- RectUtils.round(mBarRectF, mBarRect);
-
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
-
- float viewWidth = context.viewport.width();
- float viewHeight = context.viewport.height();
-
- mBarRectF.set(mBarRect.left, viewHeight - mBarRect.top, mBarRect.right, viewHeight - mBarRect.bottom);
- mBarRectF.offset(context.offset.x, -context.offset.y);
-
- // We take a 1-pixel slice from the center of the image and scale it to become the bar
- fillRectCoordBuffer(mCoords, mBarRectF, viewWidth, viewHeight, mBodyTexCoords, mTexWidth, mTexHeight);
-
- // Get the buffer and handles from the context
- FloatBuffer coordBuffer = context.coordBuffer;
- int positionHandle = mPositionHandle;
- int textureHandle = mTextureHandle;
-
- // Make sure we are at position zero in the buffer in case other draw methods did not
- // clean up after themselves
- coordBuffer.position(0);
- coordBuffer.put(mCoords);
-
- // Unbind any the current array buffer so we can use client side buffers
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- // Reset the position in the buffer for the next set of vertex and texture coordinates.
- coordBuffer.position(0);
- if (mVertical) {
- // top endcap
- mCapRectF.set(mBarRectF.left, mBarRectF.top + mCapLength, mBarRectF.right, mBarRectF.top);
- } else {
- // left endcap
- mCapRectF.set(mBarRectF.left - mCapLength, mBarRectF.bottom + mBarWidth, mBarRectF.left, mBarRectF.bottom);
- }
-
- fillRectCoordBuffer(mCoords, mCapRectF, viewWidth, viewHeight, mStartCapTexCoords, mTexWidth, mTexHeight);
- coordBuffer.put(mCoords);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- // Reset the position in the buffer for the next set of vertex and texture coordinates.
- coordBuffer.position(0);
- if (mVertical) {
- // bottom endcap
- mCapRectF.set(mBarRectF.left, mBarRectF.bottom, mBarRectF.right, mBarRectF.bottom - mCapLength);
- } else {
- // right endcap
- mCapRectF.set(mBarRectF.right, mBarRectF.bottom + mBarWidth, mBarRectF.right + mCapLength, mBarRectF.bottom);
- }
- fillRectCoordBuffer(mCoords, mCapRectF, viewWidth, viewHeight, mEndCapTexCoords, mTexWidth, mTexHeight);
- coordBuffer.put(mCoords);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- // Reset the position in the buffer for the next set of vertex and texture coordinates.
- coordBuffer.position(0);
-
- // Enable the default shader program again
- deactivateProgram();
- mRenderer.activateDefaultProgram();
- }
-
- private void getVerticalRect(RenderContext context, RectF dest) {
- RectF viewport = context.viewport;
- RectF pageRect = context.pageRect;
- float viewportHeight = viewport.height() - context.offset.y;
- float barStart = ((viewport.top - context.offset.y - pageRect.top) * (viewportHeight / pageRect.height())) + mCapLength;
- float barEnd = ((viewport.bottom - context.offset.y - pageRect.top) * (viewportHeight / pageRect.height())) - mCapLength;
- if (barStart > barEnd) {
- float middle = (barStart + barEnd) / 2.0f;
- barStart = barEnd = middle;
- }
- dest.set(viewport.width() - mBarWidth, barStart, viewport.width(), barEnd);
- }
-
- private void getHorizontalRect(RenderContext context, RectF dest) {
- RectF viewport = context.viewport;
- RectF pageRect = context.pageRect;
- float viewportWidth = viewport.width() - context.offset.x;
- float barStart = ((viewport.left - context.offset.x - pageRect.left) * (viewport.width() / pageRect.width())) + mCapLength;
- float barEnd = ((viewport.right - context.offset.x - pageRect.left) * (viewport.width() / pageRect.width())) - mCapLength;
- if (barStart > barEnd) {
- float middle = (barStart + barEnd) / 2.0f;
- barStart = barEnd = middle;
- }
- dest.set(barStart, viewport.height() - mBarWidth, barEnd, viewport.height());
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java
deleted file mode 100644
index b3f6fcbc55e9..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.json.JSONException;
-
-import android.graphics.PointF;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Stack;
-
-/**
- * A less buggy, and smoother, replacement for the built-in Android ScaleGestureDetector.
- *
- * This gesture detector is more reliable than the built-in ScaleGestureDetector because:
- *
- * - It doesn't assume that pointer IDs are numbered 0 and 1.
- *
- * - It doesn't attempt to correct for "slop" when resting one's hand on the device. On some
- * devices (e.g. the Droid X) this can cause the ScaleGestureDetector to lose track of how many
- * pointers are down, with disastrous results (bug 706684).
- *
- * - Cancelling a zoom into a pan is handled correctly.
- *
- * - Starting with three or more fingers down, releasing fingers so that only two are down, and
- * then performing a scale gesture is handled correctly.
- *
- * - It doesn't take pressure into account, which results in smoother scaling.
- */
-class SimpleScaleGestureDetector {
- private static final String LOGTAG = "GeckoSimpleScaleGestureDetector";
-
- private SimpleScaleGestureListener mListener;
- private long mLastEventTime;
- private boolean mScaleResult;
-
- /* Information about all pointers that are down. */
- private LinkedList<PointerInfo> mPointerInfo;
-
- /** Creates a new gesture detector with the given listener. */
- SimpleScaleGestureDetector(SimpleScaleGestureListener listener) {
- mListener = listener;
- mPointerInfo = new LinkedList<PointerInfo>();
- }
-
- /** Forward touch events to this function. */
- public void onTouchEvent(MotionEvent event) {
- switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN:
- // If we get ACTION_DOWN while still tracking any pointers,
- // something is wrong. Cancel the current gesture and start over.
- if (getPointersDown() > 0)
- onTouchEnd(event);
- onTouchStart(event);
- break;
- case MotionEvent.ACTION_POINTER_DOWN:
- onTouchStart(event);
- break;
- case MotionEvent.ACTION_MOVE:
- onTouchMove(event);
- break;
- case MotionEvent.ACTION_POINTER_UP:
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- onTouchEnd(event);
- break;
- }
- }
-
- private int getPointersDown() {
- return mPointerInfo.size();
- }
-
- private int getActionIndex(MotionEvent event) {
- return (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
- >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- }
-
- private void onTouchStart(MotionEvent event) {
- mLastEventTime = event.getEventTime();
- mPointerInfo.addFirst(PointerInfo.create(event, getActionIndex(event)));
- if (getPointersDown() == 2) {
- sendScaleGesture(EventType.BEGIN);
- }
- }
-
- private void onTouchMove(MotionEvent event) {
- mLastEventTime = event.getEventTime();
- for (int i = 0; i < event.getPointerCount(); i++) {
- PointerInfo pointerInfo = pointerInfoForEventIndex(event, i);
- if (pointerInfo != null) {
- pointerInfo.populate(event, i);
- }
- }
-
- if (getPointersDown() == 2) {
- sendScaleGesture(EventType.CONTINUE);
- }
- }
-
- private void onTouchEnd(MotionEvent event) {
- mLastEventTime = event.getEventTime();
-
- int action = event.getAction() & MotionEvent.ACTION_MASK;
- boolean isCancel = (action == MotionEvent.ACTION_CANCEL ||
- action == MotionEvent.ACTION_DOWN);
-
- int id = event.getPointerId(getActionIndex(event));
- ListIterator<PointerInfo> iterator = mPointerInfo.listIterator();
- while (iterator.hasNext()) {
- PointerInfo pointerInfo = iterator.next();
- if (!(isCancel || pointerInfo.getId() == id)) {
- continue;
- }
-
- // One of the pointers we were tracking was lifted. Remove its info object from the
- // list, recycle it to avoid GC pauses, and send an onScaleEnd() notification if this
- // ended the gesture.
- iterator.remove();
- pointerInfo.recycle();
- if (getPointersDown() == 1) {
- sendScaleGesture(EventType.END);
- }
- }
- }
-
- /**
- * Returns the X coordinate of the focus location (the midpoint of the two fingers). If only
- * one finger is down, returns the location of that finger.
- */
- public float getFocusX() {
- switch (getPointersDown()) {
- case 1:
- return mPointerInfo.getFirst().getCurrent().x;
- case 2:
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- return (pointerA.getCurrent().x + pointerB.getCurrent().x) / 2.0f;
- }
-
- Log.e(LOGTAG, "No gesture taking place in getFocusX()!");
- return 0.0f;
- }
-
- /**
- * Returns the Y coordinate of the focus location (the midpoint of the two fingers). If only
- * one finger is down, returns the location of that finger.
- */
- public float getFocusY() {
- switch (getPointersDown()) {
- case 1:
- return mPointerInfo.getFirst().getCurrent().y;
- case 2:
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- return (pointerA.getCurrent().y + pointerB.getCurrent().y) / 2.0f;
- }
-
- Log.e(LOGTAG, "No gesture taking place in getFocusY()!");
- return 0.0f;
- }
-
- /** Returns the most recent distance between the two pointers. */
- public float getCurrentSpan() {
- if (getPointersDown() != 2) {
- Log.e(LOGTAG, "No gesture taking place in getCurrentSpan()!");
- return 0.0f;
- }
-
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- return PointUtils.distance(pointerA.getCurrent(), pointerB.getCurrent());
- }
-
- /** Returns the second most recent distance between the two pointers. */
- public float getPreviousSpan() {
- if (getPointersDown() != 2) {
- Log.e(LOGTAG, "No gesture taking place in getPreviousSpan()!");
- return 0.0f;
- }
-
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- PointF a = pointerA.getPrevious(), b = pointerB.getPrevious();
- if (a == null || b == null) {
- a = pointerA.getCurrent();
- b = pointerB.getCurrent();
- }
-
- return PointUtils.distance(a, b);
- }
-
- /** Returns the time of the last event related to the gesture. */
- public long getEventTime() {
- return mLastEventTime;
- }
-
- /** Returns true if the scale gesture is in progress and false otherwise. */
- public boolean isInProgress() {
- return getPointersDown() == 2;
- }
-
- /* Sends the requested scale gesture notification to the listener. */
- private void sendScaleGesture(EventType eventType) {
- switch (eventType) {
- case BEGIN:
- mScaleResult = mListener.onScaleBegin(this);
- break;
- case CONTINUE:
- if (mScaleResult) {
- mListener.onScale(this);
- }
- break;
- case END:
- if (mScaleResult) {
- mListener.onScaleEnd(this);
- }
- break;
- }
- }
-
- /*
- * Returns the pointer info corresponding to the given pointer index, or null if the pointer
- * isn't one that's being tracked.
- */
- private PointerInfo pointerInfoForEventIndex(MotionEvent event, int index) {
- int id = event.getPointerId(index);
- for (PointerInfo pointerInfo : mPointerInfo) {
- if (pointerInfo.getId() == id) {
- return pointerInfo;
- }
- }
- return null;
- }
-
- private enum EventType {
- BEGIN,
- CONTINUE,
- END,
- }
-
- /* Encapsulates information about one of the two fingers involved in the gesture. */
- private static class PointerInfo {
- /* A free list that recycles pointer info objects, to reduce GC pauses. */
- private static Stack<PointerInfo> sPointerInfoFreeList;
-
- private int mId;
- private PointF mCurrent, mPrevious;
-
- private PointerInfo() {
- // External users should use create() instead.
- }
-
- /* Creates or recycles a new PointerInfo instance from an event and a pointer index. */
- public static PointerInfo create(MotionEvent event, int index) {
- if (sPointerInfoFreeList == null) {
- sPointerInfoFreeList = new Stack<PointerInfo>();
- }
-
- PointerInfo pointerInfo;
- if (sPointerInfoFreeList.empty()) {
- pointerInfo = new PointerInfo();
- } else {
- pointerInfo = sPointerInfoFreeList.pop();
- }
-
- pointerInfo.populate(event, index);
- return pointerInfo;
- }
-
- /*
- * Fills in the fields of this instance from the given motion event and pointer index
- * within that event.
- */
- public void populate(MotionEvent event, int index) {
- mId = event.getPointerId(index);
- mPrevious = mCurrent;
- mCurrent = new PointF(event.getX(index), event.getY(index));
- }
-
- public void recycle() {
- mId = -1;
- mPrevious = mCurrent = null;
- sPointerInfoFreeList.push(this);
- }
-
- public int getId() { return mId; }
- public PointF getCurrent() { return mCurrent; }
- public PointF getPrevious() { return mPrevious; }
-
- @Override
- public String toString() {
- if (mId == -1) {
- return "(up)";
- }
-
- try {
- String prevString;
- if (mPrevious == null) {
- prevString = "n/a";
- } else {
- prevString = PointUtils.toJSON(mPrevious).toString();
- }
-
- // The current position should always be non-null.
- String currentString = PointUtils.toJSON(mCurrent).toString();
- return "id=" + mId + " cur=" + currentString + " prev=" + prevString;
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public static interface SimpleScaleGestureListener {
- public boolean onScale(SimpleScaleGestureDetector detector);
- public boolean onScaleBegin(SimpleScaleGestureDetector detector);
- public void onScaleEnd(SimpleScaleGestureDetector detector);
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java
deleted file mode 100644
index 4b29c515271a..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.RegionIterator;
-import android.opengl.GLES20;
-
-import java.nio.FloatBuffer;
-
-/**
- * Encapsulates the logic needed to draw a single textured tile.
- *
- * TODO: Repeating textures really should be their own type of layer.
- */
-public class SingleTileLayer extends TileLayer {
- private static final String LOGTAG = "GeckoSingleTileLayer";
-
- private Rect mMask;
-
- // To avoid excessive GC, declare some objects here that would otherwise
- // be created and destroyed frequently during draw().
- private final RectF mBounds;
- private final RectF mTextureBounds;
- private final RectF mViewport;
- private final Rect mIntBounds;
- private final Rect mSubRect;
- private final RectF mSubRectF;
- private final Region mMaskedBounds;
- private final Rect mCropRect;
- private final RectF mObjRectF;
- private final float[] mCoords;
-
- public SingleTileLayer(CairoImage image) {
- this(false, image);
- }
-
- public SingleTileLayer(boolean repeat, CairoImage image) {
- this(image, repeat ? PaintMode.REPEAT : PaintMode.NORMAL);
- }
-
- public SingleTileLayer(CairoImage image, PaintMode paintMode) {
- super(image, paintMode);
-
- mBounds = new RectF();
- mTextureBounds = new RectF();
- mViewport = new RectF();
- mIntBounds = new Rect();
- mSubRect = new Rect();
- mSubRectF = new RectF();
- mMaskedBounds = new Region();
- mCropRect = new Rect();
- mObjRectF = new RectF();
- mCoords = new float[20];
- }
-
- /**
- * Set an area to mask out when rendering.
- */
- public void setMask(Rect aMaskRect) {
- mMask = aMaskRect;
- }
-
- @Override
- public void draw(RenderContext context) {
- // mTextureIDs may be null here during startup if Layer.java's draw method
- // failed to acquire the transaction lock and call performUpdates.
- if (!initialized())
- return;
-
- mViewport.set(context.viewport);
-
- if (repeats()) {
- // If we're repeating, we want to adjust the texture bounds so that
- // the texture repeats the correct number of times when drawn at
- // the size of the viewport.
- mBounds.set(getBounds(context));
- mTextureBounds.set(0.0f, 0.0f, mBounds.width(), mBounds.height());
- mBounds.set(0.0f, 0.0f, mViewport.width(), mViewport.height());
- } else if (stretches()) {
- // If we're stretching, we just want the bounds and texture bounds
- // to fit to the page.
- mBounds.set(context.pageRect);
- mTextureBounds.set(mBounds);
- } else {
- mBounds.set(getBounds(context));
- mTextureBounds.set(mBounds);
- }
-
- mBounds.roundOut(mIntBounds);
- mMaskedBounds.set(mIntBounds);
- if (mMask != null) {
- mMaskedBounds.op(mMask, Region.Op.DIFFERENCE);
- if (mMaskedBounds.isEmpty())
- return;
- }
-
- // XXX Possible optimisation here, form this array so we can draw it in
- // a single call.
- RegionIterator i = new RegionIterator(mMaskedBounds);
- while (i.next(mSubRect)) {
- // Compensate for rounding errors at the edge of the tile caused by
- // the roundOut above
- mSubRectF.set(Math.max(mBounds.left, (float)mSubRect.left),
- Math.max(mBounds.top, (float)mSubRect.top),
- Math.min(mBounds.right, (float)mSubRect.right),
- Math.min(mBounds.bottom, (float)mSubRect.bottom));
-
- // This is the left/top/right/bottom of the rect, relative to the
- // bottom-left of the layer, to use for texture coordinates.
- mCropRect.set(Math.round(mSubRectF.left - mBounds.left),
- Math.round(mBounds.bottom - mSubRectF.top),
- Math.round(mSubRectF.right - mBounds.left),
- Math.round(mBounds.bottom - mSubRectF.bottom));
-
- mObjRectF.set(mSubRectF.left - mViewport.left,
- mViewport.bottom - mSubRectF.bottom,
- mSubRectF.right - mViewport.left,
- mViewport.bottom - mSubRectF.top);
-
- fillRectCoordBuffer(mCoords, mObjRectF, mViewport.width(), mViewport.height(),
- mCropRect, mTextureBounds.width(), mTextureBounds.height());
-
- FloatBuffer coordBuffer = context.coordBuffer;
- int positionHandle = context.positionHandle;
- int textureHandle = context.textureHandle;
-
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
-
- // Make sure we are at position zero in the buffer
- coordBuffer.position(0);
- coordBuffer.put(mCoords);
-
- // Unbind any the current array buffer so we can use client side buffers
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
- }
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java
deleted file mode 100644
index b581d3147ec1..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-import org.mozilla.gecko.util.EventDispatcher;
-import org.mozilla.gecko.util.GeckoEventListener;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.graphics.PointF;
-import android.os.Handler;
-import android.util.Log;
-
-class SubdocumentScrollHelper implements GeckoEventListener {
- private static final String LOGTAG = "GeckoSubdocScroll";
-
- private static String MESSAGE_PANNING_OVERRIDE = "Panning:Override";
- private static String MESSAGE_CANCEL_OVERRIDE = "Panning:CancelOverride";
- private static String MESSAGE_SCROLL = "Gesture:Scroll";
- private static String MESSAGE_SCROLL_ACK = "Gesture:ScrollAck";
-
- private final Handler mUiHandler;
- private final EventDispatcher mEventDispatcher;
-
- /* This is the amount of displacement we have accepted but not yet sent to JS; this is
- * only valid when mOverrideScrollPending is true. */
- private final PointF mPendingDisplacement;
-
- /* When this is true, we're sending scroll events to JS to scroll the active subdocument. */
- private boolean mOverridePanning;
-
- /* When this is true, we have received an ack for the last scroll event we sent to JS, and
- * are ready to send the next scroll event. Note we only ever have one scroll event inflight
- * at a time. */
- private boolean mOverrideScrollAck;
-
- /* When this is true, we have a pending scroll that we need to send to JS; we were unable
- * to send it when it was initially requested because mOverrideScrollAck was not true. */
- private boolean mOverrideScrollPending;
-
- /* When this is true, the last scroll event we sent actually did some amount of scrolling on
- * the subdocument; we use this to decide when we have reached the end of the subdocument. */
- private boolean mScrollSucceeded;
-
- SubdocumentScrollHelper(EventDispatcher eventDispatcher) {
- // mUiHandler will be bound to the UI thread since that's where this constructor runs
- mUiHandler = new Handler();
- mPendingDisplacement = new PointF();
-
- mEventDispatcher = eventDispatcher;
- registerEventListener(MESSAGE_PANNING_OVERRIDE);
- registerEventListener(MESSAGE_CANCEL_OVERRIDE);
- registerEventListener(MESSAGE_SCROLL_ACK);
- }
-
- void destroy() {
- unregisterEventListener(MESSAGE_PANNING_OVERRIDE);
- unregisterEventListener(MESSAGE_CANCEL_OVERRIDE);
- unregisterEventListener(MESSAGE_SCROLL_ACK);
- }
-
- private void registerEventListener(String event) {
- mEventDispatcher.registerEventListener(event, this);
- }
-
- private void unregisterEventListener(String event) {
- mEventDispatcher.unregisterEventListener(event, this);
- }
-
- boolean scrollBy(PointF displacement) {
- if (! mOverridePanning) {
- return false;
- }
-
- if (! mOverrideScrollAck) {
- mOverrideScrollPending = true;
- mPendingDisplacement.x += displacement.x;
- mPendingDisplacement.y += displacement.y;
- return true;
- }
-
- JSONObject json = new JSONObject();
- try {
- json.put("x", displacement.x);
- json.put("y", displacement.y);
- } catch (JSONException e) {
- Log.e(LOGTAG, "Error forming subwindow scroll message: ", e);
- }
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(MESSAGE_SCROLL, json.toString()));
-
- mOverrideScrollAck = false;
- mOverrideScrollPending = false;
- // clear the |mPendingDisplacement| after serializing |displacement| to
- // JSON because they might be the same object
- mPendingDisplacement.x = 0;
- mPendingDisplacement.y = 0;
-
- return true;
- }
-
- void cancel() {
- mOverridePanning = false;
- }
-
- boolean scrolling() {
- return mOverridePanning;
- }
-
- boolean lastScrollSucceeded() {
- return mScrollSucceeded;
- }
-
- // GeckoEventListener implementation
-
- @Override
- public void handleMessage(final String event, final JSONObject message) {
- // This comes in on the Gecko thread; hand off the handling to the UI thread.
- mUiHandler.post(new Runnable() {
- @Override
- public void run() {
- try {
- if (MESSAGE_PANNING_OVERRIDE.equals(event)) {
- mOverridePanning = true;
- mOverrideScrollAck = true;
- mOverrideScrollPending = false;
- mScrollSucceeded = true;
- } else if (MESSAGE_CANCEL_OVERRIDE.equals(event)) {
- mOverridePanning = false;
- } else if (MESSAGE_SCROLL_ACK.equals(event)) {
- mOverrideScrollAck = true;
- mScrollSucceeded = message.getBoolean("scrolled");
- if (mOverridePanning && mOverrideScrollPending) {
- scrollBy(mPendingDisplacement);
- }
- }
- } catch (Exception e) {
- Log.e(LOGTAG, "Exception handling message", e);
- }
- }
- });
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java
deleted file mode 100644
index c8eb99cb4a88..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.mozglue.DirectBufferAllocator;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-
-import java.nio.ByteBuffer;
-
-/**
- * Draws text on a layer. This is used for the frame rate meter.
- */
-public class TextLayer extends SingleTileLayer {
- private final ByteBuffer mBuffer; // this buffer is owned by the BufferedCairoImage
- private final IntSize mSize;
-
- /*
- * This awkward pattern is necessary due to Java's restrictions on when one can call superclass
- * constructors.
- */
- private TextLayer(ByteBuffer buffer, BufferedCairoImage image, IntSize size, String text) {
- super(false, image);
- mBuffer = buffer;
- mSize = size;
- renderText(text);
- }
-
- public static TextLayer create(IntSize size, String text) {
- ByteBuffer buffer = DirectBufferAllocator.allocate(size.width * size.height * 4);
- BufferedCairoImage image = new BufferedCairoImage(buffer, size.width, size.height,
- CairoImage.FORMAT_ARGB32);
- return new TextLayer(buffer, image, size, text);
- }
-
- public void setText(String text) {
- renderText(text);
- invalidate();
- }
-
- private void renderText(String text) {
- Bitmap bitmap = Bitmap.createBitmap(mSize.width, mSize.height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
-
- Paint textPaint = new Paint();
- textPaint.setAntiAlias(true);
- textPaint.setColor(Color.WHITE);
- textPaint.setFakeBoldText(true);
- textPaint.setTextSize(18.0f);
- textPaint.setTypeface(Typeface.DEFAULT_BOLD);
- float width = textPaint.measureText(text) + 18.0f;
-
- Paint backgroundPaint = new Paint();
- backgroundPaint.setColor(Color.argb(127, 0, 0, 0));
- canvas.drawRect(0.0f, 0.0f, width, 18.0f + 6.0f, backgroundPaint);
-
- canvas.drawText(text, 6.0f, 18.0f, textPaint);
-
- bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java
deleted file mode 100644
index 239ba7bf7694..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.opengl.GLES20;
-import android.util.Log;
-
-import java.util.concurrent.ArrayBlockingQueue;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLContext;
-
-public class TextureGenerator {
- private static final String LOGTAG = "TextureGenerator";
- private static final int POOL_SIZE = 5;
-
- private static TextureGenerator sSharedInstance;
-
- private ArrayBlockingQueue<Integer> mTextureIds;
- private EGLContext mContext;
-
- private TextureGenerator() { mTextureIds = new ArrayBlockingQueue<Integer>(POOL_SIZE); }
-
- public static TextureGenerator get() {
- if (sSharedInstance == null)
- sSharedInstance = new TextureGenerator();
- return sSharedInstance;
- }
-
- public synchronized int take() {
- try {
- // Will block until one becomes available
- return (int)mTextureIds.take();
- } catch (InterruptedException e) {
- return 0;
- }
- }
-
- public synchronized void fill() {
- EGL10 egl = (EGL10)EGLContext.getEGL();
- EGLContext context = egl.eglGetCurrentContext();
-
- if (mContext != null && mContext != context) {
- mTextureIds.clear();
- }
-
- mContext = context;
-
- int numNeeded = mTextureIds.remainingCapacity();
- if (numNeeded == 0)
- return;
-
- // Clear existing GL errors
- int error;
- while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
- Log.w(LOGTAG, String.format("Clearing GL error: %#x", error));
- }
-
- int[] textures = new int[numNeeded];
- GLES20.glGenTextures(numNeeded, textures, 0);
-
- error = GLES20.glGetError();
- if (error != GLES20.GL_NO_ERROR) {
- Log.e(LOGTAG, String.format("Failed to generate textures: %#x", error), new Exception());
- return;
- }
-
- for (int i = 0; i < numNeeded; i++) {
- mTextureIds.offer(textures[i]);
- }
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java
deleted file mode 100644
index 71b4690eb9f1..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.opengl.GLES20;
-
-import java.util.ArrayList;
-
-/** Manages a list of dead tiles, so we don't leak resources. */
-public class TextureReaper {
- private static TextureReaper sSharedInstance;
- private ArrayList<Integer> mDeadTextureIDs;
-
- private TextureReaper() { mDeadTextureIDs = new ArrayList<Integer>(); }
-
- public static TextureReaper get() {
- if (sSharedInstance == null)
- sSharedInstance = new TextureReaper();
- return sSharedInstance;
- }
-
- public void add(int[] textureIDs) {
- for (int textureID : textureIDs)
- add(textureID);
- }
-
- public void add(int textureID) {
- mDeadTextureIDs.add(textureID);
- }
-
- public void reap() {
- int numTextures = mDeadTextureIDs.size();
- // Adreno 200 will generate INVALID_VALUE if len == 0 is passed to glDeleteTextures,
- // even though it's not supposed to.
- if (numTextures == 0)
- return;
-
- int[] deadTextureIDs = new int[numTextures];
- for (int i = 0; i < numTextures; i++) {
- deadTextureIDs[i] = mDeadTextureIDs.get(i);
- }
- mDeadTextureIDs.clear();
-
- GLES20.glDeleteTextures(deadTextureIDs.length, deadTextureIDs, 0);
- }
-}
-
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java
deleted file mode 100644
index 3c3bc2887109..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Rect;
-import android.opengl.GLES20;
-import android.util.Log;
-
-import java.nio.ByteBuffer;
-
-/**
- * Base class for tile layers, which encapsulate the logic needed to draw textured tiles in OpenGL
- * ES.
- */
-public abstract class TileLayer extends Layer {
- private static final String LOGTAG = "GeckoTileLayer";
-
- private final Rect mDirtyRect;
- private IntSize mSize;
- private int[] mTextureIDs;
-
- protected final CairoImage mImage;
-
- public enum PaintMode { NORMAL, REPEAT, STRETCH };
- private PaintMode mPaintMode;
-
- public TileLayer(CairoImage image, PaintMode paintMode) {
- super(image.getSize());
-
- mPaintMode = paintMode;
- mImage = image;
- mSize = new IntSize(0, 0);
- mDirtyRect = new Rect();
- }
-
- protected boolean repeats() { return mPaintMode == PaintMode.REPEAT; }
- protected boolean stretches() { return mPaintMode == PaintMode.STRETCH; }
- protected int getTextureID() { return mTextureIDs[0]; }
- protected boolean initialized() { return mImage != null && mTextureIDs != null; }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mTextureIDs != null)
- TextureReaper.get().add(mTextureIDs);
- } finally {
- super.finalize();
- }
- }
-
- public void destroy() {
- try {
- if (mImage != null) {
- mImage.destroy();
- }
- } catch (Exception ex) {
- Log.e(LOGTAG, "error clearing buffers: ", ex);
- }
- }
-
- public void setPaintMode(PaintMode mode) {
- mPaintMode = mode;
- }
-
- /**
- * Invalidates the entire buffer so that it will be uploaded again. Only valid inside a
- * transaction.
- */
-
- public void invalidate() {
- if (!inTransaction())
- throw new RuntimeException("invalidate() is only valid inside a transaction");
- IntSize bufferSize = mImage.getSize();
- mDirtyRect.set(0, 0, bufferSize.width, bufferSize.height);
- }
-
- private void validateTexture() {
- /* Calculate the ideal texture size. This must be a power of two if
- * the texture is repeated or OpenGL ES 2.0 isn't supported, as
- * OpenGL ES 2.0 is required for NPOT texture support (without
- * extensions), but doesn't support repeating NPOT textures.
- *
- * XXX Currently, we don't pick a GLES 2.0 context, so always round.
- */
- IntSize textureSize = mImage.getSize().nextPowerOfTwo();
-
- if (!textureSize.equals(mSize)) {
- mSize = textureSize;
-
- // Delete the old texture
- if (mTextureIDs != null) {
- TextureReaper.get().add(mTextureIDs);
- mTextureIDs = null;
-
- // Free the texture immediately, so we don't incur a
- // temporarily increased memory usage.
- TextureReaper.get().reap();
- }
- }
- }
-
- @Override
- protected void performUpdates(RenderContext context) {
- super.performUpdates(context);
-
- // Reallocate the texture if the size has changed
- validateTexture();
-
- // Don't do any work if the image has an invalid size.
- if (!mImage.getSize().isPositive())
- return;
-
- // If we haven't allocated a texture, assume the whole region is dirty
- if (mTextureIDs == null) {
- uploadFullTexture();
- } else {
- uploadDirtyRect(mDirtyRect);
- }
-
- mDirtyRect.setEmpty();
- }
-
- private void uploadFullTexture() {
- IntSize bufferSize = mImage.getSize();
- uploadDirtyRect(new Rect(0, 0, bufferSize.width, bufferSize.height));
- }
-
- private void uploadDirtyRect(Rect dirtyRect) {
- // If we have nothing to upload, just return for now
- if (dirtyRect.isEmpty())
- return;
-
- // It's possible that the buffer will be null, check for that and return
- ByteBuffer imageBuffer = mImage.getBuffer();
- if (imageBuffer == null)
- return;
-
- if (mTextureIDs == null) {
- mTextureIDs = new int[1];
- GLES20.glGenTextures(mTextureIDs.length, mTextureIDs, 0);
- }
-
- int cairoFormat = mImage.getFormat();
- CairoGLInfo glInfo = new CairoGLInfo(cairoFormat);
-
- bindAndSetGLParameters();
-
- // XXX TexSubImage2D is too broken to rely on Adreno, and very slow
- // on other chipsets, so we always upload the entire buffer.
- IntSize bufferSize = mImage.getSize();
- if (mSize.equals(bufferSize)) {
- GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width,
- mSize.height, 0, glInfo.format, glInfo.type, imageBuffer);
- } else {
- // Our texture has been expanded to the next power of two.
- // XXX We probably never want to take this path, so throw an exception.
- throw new RuntimeException("Buffer/image size mismatch in TileLayer!");
- }
- }
-
- private void bindAndSetGLParameters() {
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
- GLES20.GL_LINEAR);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
- GLES20.GL_LINEAR);
-
- int repeatMode = repeats() ? GLES20.GL_REPEAT : GLES20.GL_CLAMP_TO_EDGE;
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, repeatMode);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, repeatMode);
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java
deleted file mode 100644
index 9710bd41df5f..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.Tab;
-//import org.mozilla.gecko.Tabs;
-
-import android.content.Context;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View;
-
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * This class handles incoming touch events from the user and sends them to
- * listeners in Gecko and/or performs the "default action" (asynchronous pan/zoom
- * behaviour. EVERYTHING IN THIS CLASS MUST RUN ON THE UI THREAD.
- *
- * In the following code/comments, a "block" of events refers to a contiguous
- * sequence of events that starts with a DOWN or POINTER_DOWN and goes up to
- * but not including the next DOWN or POINTER_DOWN event.
- *
- * "Dispatching" an event refers to performing the default actions for the event,
- * which at our level of abstraction just means sending it off to the gesture
- * detectors and the pan/zoom controller.
- *
- * If an event is "default-prevented" that means one or more listeners in Gecko
- * has called preventDefault() on the event, which means that the default action
- * for that event should not occur. Usually we care about a "block" of events being
- * default-prevented, which means that the DOWN/POINTER_DOWN event that started
- * the block, or the first MOVE event following that, were prevent-defaulted.
- *
- * A "default-prevented notification" is when we here in Java-land receive a notification
- * from gecko as to whether or not a block of events was default-prevented. This happens
- * at some point after the first or second event in the block is processed in Gecko.
- * This code assumes we get EXACTLY ONE default-prevented notification for each block
- * of events.
- *
- * Note that even if all events are default-prevented, we still send specific types
- * of notifications to the pan/zoom controller. The notifications are needed
- * to respond to user actions a timely manner regardless of default-prevention,
- * and fix issues like bug 749384.
- */
-final class TouchEventHandler /*implements Tabs.OnTabsChangedListener*/ {
- private static final String LOGTAG = "GeckoTouchEventHandler";
-
- // The time limit for listeners to respond with preventDefault on touchevents
- // before we begin panning the page
- private final int EVENT_LISTENER_TIMEOUT = 200;
-
- private final View mView;
- private final GestureDetector mGestureDetector;
- private final SimpleScaleGestureDetector mScaleGestureDetector;
- private final JavaPanZoomController mPanZoomController;
-
- // the queue of events that we are holding on to while waiting for a preventDefault
- // notification
- private final Queue<MotionEvent> mEventQueue;
- private final ListenerTimeoutProcessor mListenerTimeoutProcessor;
-
- // whether or not we should wait for touch listeners to respond (this state is
- // per-tab and is updated when we switch tabs).
- private boolean mWaitForTouchListeners;
-
- // true if we should hold incoming events in our queue. this is re-set for every
- // block of events, this is cleared once we find out if the block has been
- // default-prevented or not (or we time out waiting for that).
- private boolean mHoldInQueue;
-
- // false if the current event block has been default-prevented. In this case,
- // we still pass the event to both Gecko and the pan/zoom controller, but the
- // latter will not use it to scroll content. It may still use the events for
- // other things, such as making the dynamic toolbar visible.
- private boolean mAllowDefaultAction;
-
- // this next variable requires some explanation. strap yourself in.
- //
- // for each block of events, we do two things: (1) send the events to gecko and expect
- // exactly one default-prevented notification in return, and (2) kick off a delayed
- // ListenerTimeoutProcessor that triggers in case we don't hear from the listener in
- // a timely fashion.
- // since events are constantly coming in, we need to be able to handle more than one
- // block of events in the queue.
- //
- // this means that there are ordering restrictions on these that we can take advantage of,
- // and need to abide by. blocks of events in the queue will always be in the order that
- // the user generated them. default-prevented notifications we get from gecko will be in
- // the same order as the blocks of events in the queue. the ListenerTimeoutProcessors that
- // have been posted will also fire in the same order as the blocks of events in the queue.
- // HOWEVER, we may get multiple default-prevented notifications interleaved with multiple
- // ListenerTimeoutProcessor firings, and that interleaving is not predictable.
- //
- // therefore, we need to make sure that for each block of events, we process the queued
- // events exactly once, either when we get the default-prevented notification, or when the
- // timeout expires (whichever happens first). there is no way to associate the
- // default-prevented notification with a particular block of events other than via ordering,
- //
- // so what we do to accomplish this is to track a "processing balance", which is the number
- // of default-prevented notifications that we have received, minus the number of ListenerTimeoutProcessors
- // that have fired. (think "balance" as in teeter-totter balance). this value is:
- // - zero when we are in a state where the next default-prevented notification we expect
- // to receive and the next ListenerTimeoutProcessor we expect to fire both correspond to
- // the next block of events in the queue.
- // - positive when we are in a state where we have received more default-prevented notifications
- // than ListenerTimeoutProcessors. This means that the next default-prevented notification
- // does correspond to the block at the head of the queue, but the next n ListenerTimeoutProcessors
- // need to be ignored as they are for blocks we have already processed. (n is the absolute value
- // of the balance.)
- // - negative when we are in a state where we have received more ListenerTimeoutProcessors than
- // default-prevented notifications. This means that the next ListenerTimeoutProcessor that
- // we receive does correspond to the block at the head of the queue, but the next n
- // default-prevented notifications need to be ignored as they are for blocks we have already
- // processed. (n is the absolute value of the balance.)
- private int mProcessingBalance;
-
- TouchEventHandler(Context context, View view, JavaPanZoomController panZoomController) {
- mView = view;
-
- mEventQueue = new LinkedList<MotionEvent>();
- mPanZoomController = panZoomController;
- mGestureDetector = new GestureDetector(context, mPanZoomController);
- mScaleGestureDetector = new SimpleScaleGestureDetector(mPanZoomController);
- mListenerTimeoutProcessor = new ListenerTimeoutProcessor();
- mAllowDefaultAction = true;
-
- mGestureDetector.setOnDoubleTapListener(mPanZoomController);
-
- //Tabs.registerOnTabsChangedListener(this);
- }
-
- public void destroy() {
- //Tabs.unregisterOnTabsChangedListener(this);
- }
-
- /* This function MUST be called on the UI thread */
- public boolean handleEvent(MotionEvent event) {
- if (isDownEvent(event)) {
- // this is the start of a new block of events! whee!
- mHoldInQueue = mWaitForTouchListeners;
-
- // Set mAllowDefaultAction to true so that in the event we dispatch events, the
- // PanZoomController doesn't treat them as if they've been prevent-defaulted
- // when they haven't.
- mAllowDefaultAction = true;
- if (mHoldInQueue) {
- // if the new block we are starting is the current block (i.e. there are no
- // other blocks waiting in the queue, then we should let the pan/zoom controller
- // know we are waiting for the touch listeners to run
- if (mEventQueue.isEmpty()) {
- mPanZoomController.startingNewEventBlock(event, true);
- }
- } else {
- // we're not going to be holding this block of events in the queue, but we need
- // a marker of some sort so that the processEventBlock loop deals with the blocks
- // in the right order as notifications come in. we use a single null event in
- // the queue as a placeholder for a block of events that has already been dispatched.
- mEventQueue.add(null);
- mPanZoomController.startingNewEventBlock(event, false);
- }
-
- // set the timeout so that we dispatch these events and update mProcessingBalance
- // if we don't get a default-prevented notification
- mView.postDelayed(mListenerTimeoutProcessor, EVENT_LISTENER_TIMEOUT);
- }
-
- // if we need to hold the events, add it to the queue, otherwise dispatch
- // it directly.
- if (mHoldInQueue) {
- mEventQueue.add(MotionEvent.obtain(event));
- } else {
- dispatchEvent(event, mAllowDefaultAction);
- }
-
- return false;
- }
-
- /**
- * This function is how gecko sends us a default-prevented notification. It is called
- * once gecko knows definitively whether the block of events has had preventDefault
- * called on it (either on the initial down event that starts the block, or on
- * the first event following that down event).
- *
- * This function MUST be called on the UI thread.
- */
- public void handleEventListenerAction(boolean allowDefaultAction) {
- if (mProcessingBalance > 0) {
- // this event listener that triggered this took too long, and the corresponding
- // ListenerTimeoutProcessor runnable already ran for the event in question. the
- // block of events this is for has already been processed, so we don't need to
- // do anything here.
- } else {
- processEventBlock(allowDefaultAction);
- }
- mProcessingBalance--;
- }
-
- /* This function MUST be called on the UI thread. */
- public void setWaitForTouchListeners(boolean aValue) {
- mWaitForTouchListeners = aValue;
- }
-
- private boolean isDownEvent(MotionEvent event) {
- int action = (event.getAction() & MotionEvent.ACTION_MASK);
- return (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN);
- }
-
- private boolean touchFinished(MotionEvent event) {
- int action = (event.getAction() & MotionEvent.ACTION_MASK);
- return (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL);
- }
-
- /**
- * Dispatch the event to the gesture detectors and the pan/zoom controller.
- */
- private void dispatchEvent(MotionEvent event, boolean allowDefaultAction) {
- if (allowDefaultAction) {
- if (mGestureDetector.onTouchEvent(event)) {
- return;
- }
- mScaleGestureDetector.onTouchEvent(event);
- if (mScaleGestureDetector.isInProgress()) {
- return;
- }
- }
- mPanZoomController.handleEvent(event, !allowDefaultAction);
- }
-
- /**
- * Process the block of events at the head of the queue now that we know
- * whether it has been default-prevented or not.
- */
- private void processEventBlock(boolean allowDefaultAction) {
- if (mEventQueue.isEmpty()) {
- Log.e(LOGTAG, "Unexpected empty event queue in processEventBlock!", new Exception());
- return;
- }
-
- // the odd loop condition is because the first event in the queue will
- // always be a DOWN or POINTER_DOWN event, and we want to process all
- // the events in the queue starting at that one, up to but not including
- // the next DOWN or POINTER_DOWN event.
-
- MotionEvent event = mEventQueue.poll();
- while (true) {
- // event being null here is valid and represents a block of events
- // that has already been dispatched.
-
- if (event != null) {
- dispatchEvent(event, allowDefaultAction);
- }
- if (mEventQueue.isEmpty()) {
- // we have processed the backlog of events, and are all caught up.
- // now we can set clear the hold flag and set the dispatch flag so
- // that the handleEvent() function can do the right thing for all
- // remaining events in this block (which is still ongoing) without
- // having to put them in the queue.
- mHoldInQueue = false;
- mAllowDefaultAction = allowDefaultAction;
- break;
- }
- event = mEventQueue.peek();
- if (event == null || isDownEvent(event)) {
- // we have finished processing the block we were interested in.
- // now we wait for the next call to processEventBlock
- if (event != null) {
- mPanZoomController.startingNewEventBlock(event, true);
- }
- break;
- }
- // pop the event we peeked above, as it is still part of the block and
- // we want to keep processing
- mEventQueue.remove();
- }
- }
-
- private class ListenerTimeoutProcessor implements Runnable {
- /* This MUST be run on the UI thread */
- @Override
- public void run() {
- if (mProcessingBalance < 0) {
- // gecko already responded with default-prevented notification, and so
- // the block of events this ListenerTimeoutProcessor corresponds to have
- // already been removed from the queue.
- } else {
- processEventBlock(true);
- }
- mProcessingBalance++;
- }
- }
-
- // Tabs.OnTabsChangedListener implementation
-
- /*@Override
- public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
- if ((Tabs.getInstance().isSelectedTab(tab) && msg == Tabs.TabEvents.STOP) || msg == Tabs.TabEvents.SELECTED) {
- mWaitForTouchListeners = tab.getHasTouchListeners();
- }
- }*/
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java
deleted file mode 100644
index 97ca109f118d..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI;
-
-//@WrapEntireClassForJNI
-public class ViewTransform {
- public float x;
- public float y;
- public float scale;
- public float fixedLayerMarginLeft;
- public float fixedLayerMarginTop;
- public float fixedLayerMarginRight;
- public float fixedLayerMarginBottom;
- public float offsetX;
- public float offsetY;
-
- public ViewTransform(float inX, float inY, float inScale) {
- x = inX;
- y = inY;
- scale = inScale;
- fixedLayerMarginLeft = 0;
- fixedLayerMarginTop = 0;
- fixedLayerMarginRight = 0;
- fixedLayerMarginBottom = 0;
- offsetX = 0;
- offsetY = 0;
- }
-}
-
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java
deleted file mode 100644
index 83d012876176..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.gfx;
-
-public class VirtualLayer extends Layer {
- public VirtualLayer(IntSize size) {
- super(size);
- }
-
- @Override
- public void draw(RenderContext context) {
- // No-op.
- }
-
- void setPositionAndResolution(int left, int top, int right, int bottom, float newResolution) {
- // This is an optimized version of the following code:
- // beginTransaction();
- // try {
- // setPosition(new Rect(left, top, right, bottom));
- // setResolution(newResolution);
- // performUpdates(null);
- // } finally {
- // endTransaction();
- // }
-
- // it is safe to drop the transaction lock in this instance (i.e. for the
- // VirtualLayer that is just a shadow of what gecko is painting) because
- // the position and resolution of this layer are always touched on the compositor
- // thread, and therefore do not require synchronization.
- mPosition.set(left, top, right, bottom);
- mResolution = newResolution;
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java
deleted file mode 100644
index 61444e6cfc47..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.mozglue;
-
-import java.nio.ByteBuffer;
-
-//
-// We must manually allocate direct buffers in JNI to work around a bug where Honeycomb's
-// ByteBuffer.allocateDirect() grossly overallocates the direct buffer size.
-// https://code.google.com/p/android/issues/detail?id=16941
-//
-
-public final class DirectBufferAllocator {
- private DirectBufferAllocator() {}
-
- public static ByteBuffer allocate(int size) {
- if (size <= 0) {
- throw new IllegalArgumentException("Invalid size " + size);
- }
-
- ByteBuffer directBuffer = ByteBuffer.allocateDirect(size);
- //ByteBuffer directBuffer = nativeAllocateDirectBuffer(size);
- if (directBuffer == null) {
- throw new OutOfMemoryError("allocateDirectBuffer() returned null");
- } else if (!directBuffer.isDirect()) {
- throw new AssertionError("allocateDirectBuffer() did not return a direct buffer");
- }
-
- return directBuffer;
- }
-
- public static ByteBuffer free(ByteBuffer buffer) {
- if (buffer == null) {
- return null;
- }
-
- if (!buffer.isDirect()) {
- throw new IllegalArgumentException("buffer must be direct");
- }
-
- //nativeFreeDirectBuffer(buffer);
- return null;
- }
-
- // These JNI methods are implemented in mozglue/android/nsGeckoUtils.cpp.
- //private static native ByteBuffer nativeAllocateDirectBuffer(long size);
- //private static native void nativeFreeDirectBuffer(ByteBuffer buf);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java
deleted file mode 100644
index 5b6d50883b42..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import org.json.JSONObject;
-
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-public final class EventDispatcher {
- private static final String LOGTAG = "GeckoEventDispatcher";
-
- private final Map<String, CopyOnWriteArrayList<GeckoEventListener>> mEventListeners
- = new HashMap<String, CopyOnWriteArrayList<GeckoEventListener>>();
-
- public void registerEventListener(String event, GeckoEventListener listener) {
- synchronized (mEventListeners) {
- CopyOnWriteArrayList<GeckoEventListener> listeners = mEventListeners.get(event);
- if (listeners == null) {
- // create a CopyOnWriteArrayList so that we can modify it
- // concurrently with iterating through it in handleGeckoMessage.
- // Otherwise we could end up throwing a ConcurrentModificationException.
- listeners = new CopyOnWriteArrayList<GeckoEventListener>();
- } else if (listeners.contains(listener)) {
- Log.w(LOGTAG, "EventListener already registered for event '" + event + "'",
- new IllegalArgumentException());
- }
- listeners.add(listener);
- mEventListeners.put(event, listeners);
- }
- }
-
- public void unregisterEventListener(String event, GeckoEventListener listener) {
- synchronized (mEventListeners) {
- CopyOnWriteArrayList<GeckoEventListener> listeners = mEventListeners.get(event);
- if (listeners == null) {
- Log.w(LOGTAG, "unregisterEventListener: event '" + event + "' has no listeners");
- return;
- }
- if (!listeners.remove(listener)) {
- Log.w(LOGTAG, "unregisterEventListener: tried to remove an unregistered listener " +
- "for event '" + event + "'");
- }
- if (listeners.size() == 0) {
- mEventListeners.remove(event);
- }
- }
- }
-
- public String dispatchEvent(String message) {
- try {
- JSONObject json = new JSONObject(message);
- return dispatchEvent(json);
- } catch (Exception e) {
- Log.e(LOGTAG, "dispatchEvent: malformed JSON.", e);
- }
-
- return "";
- }
-
- public String dispatchEvent(JSONObject json) {
- // {
- // "type": "value",
- // "event_specific": "value",
- // ...
- try {
- JSONObject gecko = json.has("gecko") ? json.getJSONObject("gecko") : null;
- if (gecko != null) {
- json = gecko;
- }
-
- String type = json.getString("type");
-
- if (gecko != null) {
- Log.w(LOGTAG, "Message '" + type + "' has deprecated 'gecko' property!");
- }
-
- CopyOnWriteArrayList<GeckoEventListener> listeners;
- synchronized (mEventListeners) {
- listeners = mEventListeners.get(type);
- }
-
- if (listeners == null || listeners.size() == 0) {
- Log.d(LOGTAG, "dispatchEvent: no listeners registered for event '" + type + "'");
- return "";
- }
-
- String response = null;
-
- for (GeckoEventListener listener : listeners) {
- listener.handleMessage(type, json);
- if (listener instanceof GeckoEventResponder) {
- String newResponse = ((GeckoEventResponder)listener).getResponse(json);
- if (response != null && newResponse != null) {
- Log.e(LOGTAG, "Received two responses for message of type " + type);
- }
- response = newResponse;
- }
- }
-
- if (response != null)
- return response;
-
- } catch (Exception e) {
- Log.e(LOGTAG, "handleGeckoMessage throws " + e, e);
- }
-
- return "";
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java
deleted file mode 100644
index fbcd7254f62b..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import android.graphics.PointF;
-
-import java.lang.IllegalArgumentException;
-
-public final class FloatUtils {
- private FloatUtils() {}
-
- public static boolean fuzzyEquals(float a, float b) {
- return (Math.abs(a - b) < 1e-6);
- }
-
- public static boolean fuzzyEquals(PointF a, PointF b) {
- return fuzzyEquals(a.x, b.x) && fuzzyEquals(a.y, b.y);
- }
-
- /*
- * Returns the value that represents a linear transition between `from` and `to` at time `t`,
- * which is on the scale [0, 1). Thus with t = 0.0f, this returns `from`; with t = 1.0f, this
- * returns `to`; with t = 0.5f, this returns the value halfway from `from` to `to`.
- */
- public static float interpolate(float from, float to, float t) {
- return from + (to - from) * t;
- }
-
- /**
- * Returns 'value', clamped so that it isn't any lower than 'low', and it
- * isn't any higher than 'high'.
- */
- public static float clamp(float value, float low, float high) {
- if (high < low) {
- throw new IllegalArgumentException(
- "clamp called with invalid parameters (" + high + " < " + low + ")" );
- }
- return Math.max(low, Math.min(high, value));
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java
deleted file mode 100644
index f7873fe733d3..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import android.os.Handler;
-import android.os.Looper;
-
-import java.util.concurrent.SynchronousQueue;
-
-final class GeckoBackgroundThread extends Thread {
- private static final String LOOPER_NAME = "GeckoBackgroundThread";
-
- // Guarded by 'this'.
- private static Handler sHandler = null;
- private SynchronousQueue<Handler> mHandlerQueue = new SynchronousQueue<Handler>();
-
- // Singleton, so private constructor.
- private GeckoBackgroundThread() {
- super();
- }
-
- @Override
- public void run() {
- setName(LOOPER_NAME);
- Looper.prepare();
- try {
- mHandlerQueue.put(new Handler());
- } catch (InterruptedException ie) {}
-
- Looper.loop();
- }
-
- // Get a Handler for a looper thread, or create one if it doesn't yet exist.
- /*package*/ static synchronized Handler getHandler() {
- if (sHandler == null) {
- GeckoBackgroundThread lt = new GeckoBackgroundThread();
- ThreadUtils.setBackgroundThread(lt);
- lt.start();
- try {
- sHandler = lt.mHandlerQueue.take();
- } catch (InterruptedException ie) {}
- }
- return sHandler;
- }
-
- /*package*/ static void post(Runnable runnable) {
- Handler handler = getHandler();
- if (handler == null) {
- throw new IllegalStateException("No handler! Must have been interrupted. Not posting.");
- }
- handler.post(runnable);
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java
deleted file mode 100644
index 4d0c313b0c6a..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import org.json.JSONObject;
-//import org.mozilla.gecko.mozglue.RobocopTarget;
-
-//@RobocopTarget
-public interface GeckoEventListener {
- void handleMessage(String event, JSONObject message);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java
deleted file mode 100644
index dc4561561c8a..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.util;
-
-import org.json.JSONObject;
-
-public interface GeckoEventResponder extends GeckoEventListener {
- String getResponse(JSONObject response);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java
deleted file mode 100644
index a646f1ae4e9d..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import android.os.Handler;
-import android.os.MessageQueue;
-import android.util.Log;
-
-import java.util.Map;
-
-public final class ThreadUtils {
- private static final String LOGTAG = "ThreadUtils";
-
- private static Thread sUiThread;
- private static Thread sBackgroundThread;
-
- private static Handler sUiHandler;
-
- // Referenced directly from GeckoAppShell in highly performance-sensitive code (The extra
- // function call of the getter was harming performance. (Bug 897123))
- // Once Bug 709230 is resolved we should reconsider this as ProGuard should be able to optimise
- // this out at compile time.
- public static Handler sGeckoHandler;
- public static MessageQueue sGeckoQueue;
- public static Thread sGeckoThread;
-
- // Delayed Runnable that resets the Gecko thread priority.
- private static final Runnable sPriorityResetRunnable = new Runnable() {
- @Override
- public void run() {
- resetGeckoPriority();
- }
- };
-
- private static boolean sIsGeckoPriorityReduced;
-
- @SuppressWarnings("serial")
- public static class UiThreadBlockedException extends RuntimeException {
- public UiThreadBlockedException() {
- super();
- }
-
- public UiThreadBlockedException(String msg) {
- super(msg);
- }
-
- public UiThreadBlockedException(String msg, Throwable e) {
- super(msg, e);
- }
-
- public UiThreadBlockedException(Throwable e) {
- super(e);
- }
- }
-
- public static void dumpAllStackTraces() {
- Log.w(LOGTAG, "Dumping ALL the threads!");
- Map<Thread, StackTraceElement[]> allStacks = Thread.getAllStackTraces();
- for (Thread t : allStacks.keySet()) {
- Log.w(LOGTAG, t.toString());
- for (StackTraceElement ste : allStacks.get(t)) {
- Log.w(LOGTAG, ste.toString());
- }
- Log.w(LOGTAG, "----");
- }
- }
-
- public static void setUiThread(Thread thread, Handler handler) {
- sUiThread = thread;
- sUiHandler = handler;
- }
-
- public static void setBackgroundThread(Thread thread) {
- sBackgroundThread = thread;
- }
-
- public static Thread getUiThread() {
- return sUiThread;
- }
-
- public static Handler getUiHandler() {
- return sUiHandler;
- }
-
- public static void postToUiThread(Runnable runnable) {
- sUiHandler.post(runnable);
- }
-
- public static Thread getBackgroundThread() {
- return sBackgroundThread;
- }
-
- public static Handler getBackgroundHandler() {
- return GeckoBackgroundThread.getHandler();
- }
-
- public static void postToBackgroundThread(Runnable runnable) {
- GeckoBackgroundThread.post(runnable);
- }
-
- public static void assertOnUiThread() {
- assertOnThread(getUiThread());
- }
-
- public static void assertOnGeckoThread() {
- assertOnThread(sGeckoThread);
- }
-
- public static void assertOnBackgroundThread() {
- assertOnThread(getBackgroundThread());
- }
-
- public static void assertOnThread(Thread expectedThread) {
- Thread currentThread = Thread.currentThread();
- long currentThreadId = currentThread.getId();
- long expectedThreadId = expectedThread.getId();
-
- if (currentThreadId != expectedThreadId) {
- throw new IllegalThreadStateException("Expected thread " + expectedThreadId + " (\""
- + expectedThread.getName()
- + "\"), but running on thread " + currentThreadId
- + " (\"" + currentThread.getName() + ")");
- }
- }
-
- public static boolean isOnUiThread() {
- return isOnThread(getUiThread());
- }
-
- public static boolean isOnBackgroundThread() {
- return isOnThread(sBackgroundThread);
- }
-
- public static boolean isOnThread(Thread thread) {
- return (Thread.currentThread().getId() == thread.getId());
- }
-
- /**
- * Reduces the priority of the Gecko thread, allowing other operations
- * (such as those related to the UI and database) to take precedence.
- *
- * Note that there are no guards in place to prevent multiple calls
- * to this method from conflicting with each other.
- *
- * @param timeout Timeout in ms after which the priority will be reset
- */
- public static void reduceGeckoPriority(long timeout) {
- if (!sIsGeckoPriorityReduced) {
- sIsGeckoPriorityReduced = true;
- sGeckoThread.setPriority(Thread.MIN_PRIORITY);
- getUiHandler().postDelayed(sPriorityResetRunnable, timeout);
- }
- }
-
- /**
- * Resets the priority of a thread whose priority has been reduced
- * by reduceGeckoPriority.
- */
- public static void resetGeckoPriority() {
- if (sIsGeckoPriorityReduced) {
- sIsGeckoPriorityReduced = false;
- sGeckoThread.setPriority(Thread.NORM_PRIORITY);
- getUiHandler().removeCallbacks(sPriorityResetRunnable);
- }
- }
-}
diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java
deleted file mode 100644
index aee875c33dc9..000000000000
--- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import android.os.Handler;
-import android.os.Looper;
-
-/**
- * Executes a background task and publishes the result on the UI thread.
- *
- * The standard {@link android.os.AsyncTask} only runs onPostExecute on the
- * thread it is constructed on, so this is a convenience class for creating
- * tasks off the UI thread.
- */
-public abstract class UiAsyncTask<Params, Progress, Result> {
- private volatile boolean mCancelled = false;
- private final Handler mBackgroundThreadHandler;
- private static Handler sHandler;
-
- /**
- * Creates a new asynchronous task.
- *
- * @param backgroundThreadHandler the handler to execute the background task on
- */
- public UiAsyncTask(Handler backgroundThreadHandler) {
- mBackgroundThreadHandler = backgroundThreadHandler;
- }
-
- private static synchronized Handler getUiHandler() {
- if (sHandler == null) {
- sHandler = new Handler(Looper.getMainLooper());
- }
- return sHandler;
- }
-
- private final class BackgroundTaskRunnable implements Runnable {
- private Params[] mParams;
-
- public BackgroundTaskRunnable(Params... params) {
- mParams = params;
- }
-
- @Override
- public void run() {
- final Result result = doInBackground(mParams);
-
- getUiHandler().post(new Runnable() {
- @Override
- public void run() {
- if (mCancelled)
- onCancelled();
- else
- onPostExecute(result);
- }
- });
- }
- }
-
- public final void execute(final Params... params) {
- getUiHandler().post(new Runnable() {
- @Override
- public void run() {
- onPreExecute();
- mBackgroundThreadHandler.post(new BackgroundTaskRunnable(params));
- }
- });
- }
-
- @SuppressWarnings({"UnusedParameters"})
- public final boolean cancel(boolean mayInterruptIfRunning) {
- mCancelled = true;
- return mCancelled;
- }
-
- public final boolean isCancelled() {
- return mCancelled;
- }
-
- protected void onPreExecute() { }
- protected void onPostExecute(Result result) { }
- protected void onCancelled() { }
- protected abstract Result doInBackground(Params... params);
-}
diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 96a442e5b8e9..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.png b/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.png
deleted file mode 100644
index d5f16694f342..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 359047dfa4ed..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.png b/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.png
deleted file mode 100644
index 835fc9290727..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 71c6d760f051..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.png b/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.png
deleted file mode 100644
index c8005425416a..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644
index 4df18946442e..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml b/android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index 600acdd4b40b..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- android:paddingBottom="@dimen/activity_vertical_margin"
- tools:context="org.libreoffice.MainActivity">
-
- <org.libreoffice.MainLayerView android:id="@+id/layer_view"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"/>
-
-</RelativeLayout>
diff --git a/android/experimental/LOAndroid/app/src/main/res/menu/main.xml b/android/experimental/LOAndroid/app/src/main/res/menu/main.xml
deleted file mode 100644
index 6768fd32a890..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/menu/main.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- tools:context="org.libreoffice.MainActivity" >
- <item android:id="@+id/action_settings"
- android:title="@string/action_settings"
- android:orderInCategory="100"
- app:showAsAction="never" />
-</menu>
diff --git a/android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml b/android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml
deleted file mode 100644
index 63fc81644461..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<resources>
- <!-- Example customization of dimensions originally defined in res/values/dimens.xml
- (such as screen margins) for screens with more than 820dp of available width. This
- would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
- <dimen name="activity_horizontal_margin">64dp</dimen>
-</resources>
diff --git a/android/experimental/LOAndroid/app/src/main/res/values/colors.xml b/android/experimental/LOAndroid/app/src/main/res/values/colors.xml
deleted file mode 100644
index f8e207d4e00e..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<resources>
- <color name="background_light">#FFECF0F3</color>
- <color name="background_normal">#FFCED7DE</color>
- <color name="background_private">#FF292C29</color>
- <color name="background_tabs">#FF363B40</color>
- <color name="highlight">#33000000</color>
- <color name="highlight_focused">#1A000000</color>
- <color name="highlight_dark">#33FFFFFF</color>
- <color name="highlight_dark_focused">#1AFFFFFF</color>
-
- <!-- highlight on shaped button: 20% white over background_tabs -->
- <color name="highlight_shaped">#FF696D71</color>
-
- <!-- highlight-focused on shaped button: 10% white over background_tabs -->
- <color name="highlight_shaped_focused">#FF565B60</color>
-
- <!-- highlight on nav button: 20% black over background_normal -->
- <color name="highlight_nav">#FFA5ACB2</color>
-
- <!-- highlight-focused on nav button: 10% black over background_normal -->
- <color name="highlight_nav_focused">#FFB9C1C7</color>
-
- <!-- highlight on private nav button: 20% white over background_private -->
- <color name="highlight_nav_pb">#FF545654</color>
-
- <!-- highlight-focused on private nav button: 10% white over background_private -->
- <color name="highlight_nav_focused_pb">#FF3F423F</color>
-
- <!--
- Application theme colors
- -->
- <!-- Default colors -->
- <color name="text_color_primary">#222222</color>
- <color name="text_color_secondary">#777777</color>
- <color name="text_color_tertiary">#9198A1</color>
-
- <!-- Default inverse colors -->
- <color name="text_color_primary_inverse">#FFFFFF</color>
- <color name="text_color_secondary_inverse">#DDDDDD</color>
- <color name="text_color_tertiary_inverse">#A4A7A9</color>
-
- <!-- Disabled colors -->
- <color name="text_color_primary_disable_only">#999999</color>
-
- <!-- Hint colors -->
- <color name="text_color_hint">#666666</color>
- <color name="text_color_hint_inverse">#7F828A</color>
-
- <!-- Highlight colors -->
- <color name="text_color_highlight">#FF9500</color>
- <color name="text_color_highlight_inverse">#D06BFF</color>
-
- <!-- Link colors -->
- <color name="text_color_link">#22629E</color>
-
- <color name="splash_background">#000000</color>
- <color name="splash_msgfont">#ffffff</color>
- <color name="splash_urlfont">#000000</color>
- <color name="splash_content">#ffffff</color>
-
- <color name="doorhanger_text">#FF222222</color>
- <color name="doorhanger_link">#FF2AA1FE</color>
- <color name="doorhanger_divider_light">#FFD1D5DA</color>
- <color name="doorhanger_divider_dark">#FFB3C2CE</color>
- <color name="doorhanger_background_dark">#FFDDE4EA</color>
-
- <color name="validation_message_text">#ffffff</color>
- <color name="url_bar_text_highlight">#FFFF9500</color>
- <color name="url_bar_text_highlight_pb">#FFD06BFF</color>
- <color name="suggestion_primary">#dddddd</color>
- <color name="suggestion_pressed">#bbbbbb</color>
- <color name="tab_row_pressed">#4D000000</color>
- <color name="dialogtitle_textcolor">#ffffff</color>
-
- <color name="textbox_background">#FFF</color>
- <color name="textbox_background_disabled">#DDD</color>
- <color name="textbox_stroke">#000</color>
- <color name="textbox_stroke_disabled">#666</color>
-
- <color name="url_bar_urltext">#A6A6A6</color>
- <color name="url_bar_domaintext">#000</color>
- <color name="url_bar_domaintext_private">#FFF</color>
- <color name="url_bar_blockedtext">#b14646</color>
- <color name="url_bar_shadow">#12000000</color>
-
- <color name="home_last_tab_bar_bg">#FFF5F7F9</color>
-
- <color name="panel_grid_item_image_background">#D1D9E1</color>
-</resources>
-
diff --git a/android/experimental/LOAndroid/app/src/main/res/values/dimens.xml b/android/experimental/LOAndroid/app/src/main/res/values/dimens.xml
deleted file mode 100644
index 47c82246738c..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<resources>
- <!-- Default screen margins, per the Android Design guidelines. -->
- <dimen name="activity_horizontal_margin">16dp</dimen>
- <dimen name="activity_vertical_margin">16dp</dimen>
-</resources>
diff --git a/android/experimental/LOAndroid/app/src/main/res/values/strings.xml b/android/experimental/LOAndroid/app/src/main/res/values/strings.xml
deleted file mode 100644
index 8864167560f8..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
- <string name="app_name">LOAndroid</string>
- <string name="hello_world">Hello world!</string>
- <string name="action_settings">Settings</string>
-
-</resources>
diff --git a/android/experimental/LOAndroid/app/src/main/res/values/styles.xml b/android/experimental/LOAndroid/app/src/main/res/values/styles.xml
deleted file mode 100644
index ff6c9d2c0fb9..000000000000
--- a/android/experimental/LOAndroid/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
-
- <!-- Base application theme. -->
- <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
- <!-- Customize your theme here. -->
- </style>
-
-</resources>
diff --git a/android/experimental/LOAndroid/build.gradle b/android/experimental/LOAndroid/build.gradle
deleted file mode 100644
index 80eec1a79307..000000000000
--- a/android/experimental/LOAndroid/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:0.9.+'
- }
-}
-
-allprojects {
- repositories {
- mavenCentral()
- }
-}
diff --git a/android/experimental/LOAndroid/gradle.properties b/android/experimental/LOAndroid/gradle.properties
deleted file mode 100644
index 5d08ba75bb97..000000000000
--- a/android/experimental/LOAndroid/gradle.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Settings specified in this file will override any Gradle settings
-# configured through the IDE.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true \ No newline at end of file
diff --git a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jar b/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 8c0fb64a8698..000000000000
--- a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties b/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 5de946b072f1..000000000000
--- a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Wed Apr 10 15:27:10 PDT 2013
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
diff --git a/android/experimental/LOAndroid/gradlew b/android/experimental/LOAndroid/gradlew
deleted file mode 100644
index 91a7e269e19d..000000000000
--- a/android/experimental/LOAndroid/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/android/experimental/LOAndroid/gradlew.bat b/android/experimental/LOAndroid/gradlew.bat
deleted file mode 100644
index aec99730b4e8..000000000000
--- a/android/experimental/LOAndroid/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/android/experimental/LOAndroid/settings.gradle b/android/experimental/LOAndroid/settings.gradle
deleted file mode 100644
index e7b4def49cb5..000000000000
--- a/android/experimental/LOAndroid/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-include ':app'
diff --git a/android/experimental/LOAndroid2/.gitignore b/android/experimental/LOAndroid2/.gitignore
deleted file mode 100644
index d6bfc95b184b..000000000000
--- a/android/experimental/LOAndroid2/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.gradle
-/local.properties
-/.idea/workspace.xml
-.DS_Store
diff --git a/android/experimental/LOAndroid2/.idea/.name b/android/experimental/LOAndroid2/.idea/.name
deleted file mode 100644
index 3300c569c980..000000000000
--- a/android/experimental/LOAndroid2/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-LOAndroid \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/.idea/compiler.xml b/android/experimental/LOAndroid2/.idea/compiler.xml
deleted file mode 100644
index 217af471a9e6..000000000000
--- a/android/experimental/LOAndroid2/.idea/compiler.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="CompilerConfiguration">
- <option name="DEFAULT_COMPILER" value="Javac" />
- <resourceExtensions />
- <wildcardResourcePatterns>
- <entry name="!?*.java" />
- <entry name="!?*.form" />
- <entry name="!?*.class" />
- <entry name="!?*.groovy" />
- <entry name="!?*.scala" />
- <entry name="!?*.flex" />
- <entry name="!?*.kt" />
- <entry name="!?*.clj" />
- </wildcardResourcePatterns>
- <annotationProcessing>
- <profile default="true" name="Default" enabled="false">
- <processorPath useClasspath="true" />
- </profile>
- </annotationProcessing>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml b/android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3377d4..000000000000
--- a/android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<component name="CopyrightManager">
- <settings default="" />
-</component> \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/.idea/encodings.xml b/android/experimental/LOAndroid2/.idea/encodings.xml
deleted file mode 100644
index e206d70d8595..000000000000
--- a/android/experimental/LOAndroid2/.idea/encodings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
-</project>
-
diff --git a/android/experimental/LOAndroid2/.idea/gradle.xml b/android/experimental/LOAndroid2/.idea/gradle.xml
deleted file mode 100644
index 736c7b5cffcc..000000000000
--- a/android/experimental/LOAndroid2/.idea/gradle.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="GradleSettings">
- <option name="linkedExternalProjectsSettings">
- <GradleProjectSettings>
- <option name="distributionType" value="DEFAULT_WRAPPED" />
- <option name="externalProjectPath" value="$PROJECT_DIR$" />
- <option name="modules">
- <set>
- <option value="$PROJECT_DIR$" />
- <option value="$PROJECT_DIR$/app" />
- </set>
- </option>
- </GradleProjectSettings>
- </option>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid2/.idea/misc.xml b/android/experimental/LOAndroid2/.idea/misc.xml
deleted file mode 100644
index 7f0862a388db..000000000000
--- a/android/experimental/LOAndroid2/.idea/misc.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="EntryPointsManager">
- <entry_points version="2.0" />
- </component>
- <component name="ProjectInspectionProfilesVisibleTreeState">
- <entry key="Project Default">
- <profile-state>
- <expanded-state>
- <State>
- <id />
- </State>
- </expanded-state>
- <selected-state>
- <State>
- <id>Abstraction issues</id>
- </State>
- </selected-state>
- </profile-state>
- </entry>
- </component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/build/classes" />
- </component>
- <component name="masterDetails">
- <states>
- <state key="ScopeChooserConfigurable.UI">
- <settings>
- <splitter-proportions>
- <option name="proportions">
- <list>
- <option value="0.2" />
- </list>
- </option>
- </splitter-proportions>
- </settings>
- </state>
- </states>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid2/.idea/modules.xml b/android/experimental/LOAndroid2/.idea/modules.xml
deleted file mode 100644
index d5e166fb414b..000000000000
--- a/android/experimental/LOAndroid2/.idea/modules.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="ProjectModuleManager">
- <modules>
- <module fileurl="file://$PROJECT_DIR$/LOAndroid.iml" filepath="$PROJECT_DIR$/LOAndroid.iml" />
- <module fileurl="file://$PROJECT_DIR$/LOAndroid2.iml" filepath="$PROJECT_DIR$/LOAndroid2.iml" />
- <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
- </modules>
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml b/android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml
deleted file mode 100644
index 922003b8433b..000000000000
--- a/android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<component name="DependencyValidationManager">
- <state>
- <option name="SKIP_IMPORT_STATEMENTS" value="false" />
- </state>
-</component> \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/.idea/vcs.xml b/android/experimental/LOAndroid2/.idea/vcs.xml
deleted file mode 100644
index def6a6a18457..000000000000
--- a/android/experimental/LOAndroid2/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
- <component name="VcsDirectoryMappings">
- <mapping directory="" vcs="" />
- </component>
-</project>
-
diff --git a/android/experimental/LOAndroid2/LOAndroid2.iml b/android/experimental/LOAndroid2/LOAndroid2.iml
deleted file mode 100644
index 0bb6048ae08a..000000000000
--- a/android/experimental/LOAndroid2/LOAndroid2.iml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
- <component name="FacetManager">
- <facet type="java-gradle" name="Java-Gradle">
- <configuration>
- <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
- </configuration>
- </facet>
- </component>
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <excludeFolder url="file://$MODULE_DIR$/.gradle" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module>
-
diff --git a/android/experimental/LOAndroid2/app/.gitignore b/android/experimental/LOAndroid2/app/.gitignore
deleted file mode 100644
index 796b96d1c402..000000000000
--- a/android/experimental/LOAndroid2/app/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/android/experimental/LOAndroid2/app/app.iml b/android/experimental/LOAndroid2/app/app.iml
deleted file mode 100644
index 2fc60e01b0bf..000000000000
--- a/android/experimental/LOAndroid2/app/app.iml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="LOAndroid2" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
- <component name="FacetManager">
- <facet type="android-gradle" name="Android-Gradle">
- <configuration>
- <option name="GRADLE_PROJECT_PATH" value=":app" />
- </configuration>
- </facet>
- <facet type="android" name="Android">
- <configuration>
- <option name="SELECTED_BUILD_VARIANT" value="debug" />
- <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
- <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
- <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
- <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
- <option name="ALLOW_USER_CONFIGURATION" value="false" />
- <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
- <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
- <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
- <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
- </configuration>
- </facet>
- </component>
- <component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
- <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
- <excludeFolder url="file://$MODULE_DIR$/build/intermediates" />
- <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
- </content>
- <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module>
-
diff --git a/android/experimental/LOAndroid2/app/build.gradle b/android/experimental/LOAndroid2/app/build.gradle
deleted file mode 100644
index 6053f9101f39..000000000000
--- a/android/experimental/LOAndroid2/app/build.gradle
+++ /dev/null
@@ -1,23 +0,0 @@
-apply plugin: 'android'
-
-android {
- compileSdkVersion 19
- buildToolsVersion "19.1.0"
-
- defaultConfig {
- minSdkVersion 15
- targetSdkVersion 19
- versionCode 1
- versionName "1.0"
- }
- buildTypes {
- release {
- runProguard false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
- }
- }
-}
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
-}
diff --git a/android/experimental/LOAndroid2/app/proguard-rules.txt b/android/experimental/LOAndroid2/app/proguard-rules.txt
deleted file mode 100644
index 0b0be289afc1..000000000000
--- a/android/experimental/LOAndroid2/app/proguard-rules.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /home/quikee/Programs/android-sdk-linux/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#} \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml b/android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml
deleted file mode 100644
index aef4bb7b591d..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.libreoffice" >
-
- <!-- App requires OpenGL ES 2.0 -->
- <uses-feature android:glEsVersion="0x00020000" android:required="true" />
-
- <application
- android:allowBackup="true"
- android:icon="@drawable/main"
- android:label="@string/app_name"
- android:hardwareAccelerated="true"
- android:theme="@style/AppTheme" >
- <activity
- android:name="org.libreoffice.LibreOfficeMainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java
deleted file mode 100644
index bf4f98b845da..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.libreoffice;
-
-import android.graphics.Rect;
-import android.util.Log;
-
-import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.ViewportMetrics;
-
-public class LOEvent {
-
- public static final int SIZE_CHANGED = 1;
- public static final int TILE_SIZE = 2;
- public static final int VIEWPORT = 3;
- public static final int DRAW = 4;
-
- private ViewportMetrics mViewportMetrics;
-
- public int mType;
- private String mTypeString;
-
- ViewportMetrics viewportMetrics;
-
- public LOEvent(int type, int width, int height, int widthPixels, int heightPixels, int tileWidth, int tileHeight) {
- mType = type;
- mTypeString = "Size Changed";
- }
-
- public LOEvent(int type, IntSize tileSize) {
- mType = type;
- mTypeString = "Tile size";
- }
-
- public LOEvent(int type, ViewportMetrics viewportMetrics) {
- mType = type;
- mTypeString = "Viewport";
- mViewportMetrics = viewportMetrics;
- }
-
- public LOEvent(int type, Rect rect) {
- mType = type;
- mTypeString = "Draw";
- }
-
- public static LOEvent draw(Rect rect) {
- return new LOEvent(DRAW, rect);
- }
-
- public static LOEvent sizeChanged(int width, int height, int widthPixels, int heightPixels, int tileWidth, int tileHeight) {
- return new LOEvent(SIZE_CHANGED, width, height, widthPixels, heightPixels, tileWidth, tileHeight);
- }
-
- public static LOEvent tileSize(IntSize tileSize) {
- return new LOEvent(TILE_SIZE, tileSize);
- }
-
- public static LOEvent viewport(ViewportMetrics viewportMetrics) {
- return new LOEvent(VIEWPORT, viewportMetrics);
- }
-
- public String getTypeString() {
- return mTypeString;
- }
-
- public ViewportMetrics getViewport() {
- return mViewportMetrics;
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java
deleted file mode 100644
index 9dde7906d020..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.libreoffice;
-
-
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-
-import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
-import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.LayerView;
-
-import java.nio.ByteBuffer;
-
-public class LOKitShell {
- private static final String LOGTAG = LOKitShell.class.getSimpleName();
-
- public static int getDpi() {
- return 96;
- }
-
- public static int getScreenDepth() {
- return 24;
- }
-
- public static float computeRenderIntegrity() {
- return 0.0f;
- }
-
- public static ByteBuffer allocateDirectBuffer(int size) {
- if (size <= 0) {
- throw new IllegalArgumentException("Invalid size " + size);
- }
-
- ByteBuffer directBuffer = ByteBuffer.allocateDirect(size);
- //ByteBuffer directBuffer = nativeAllocateDirectBuffer(size);
- if (directBuffer == null) {
- throw new OutOfMemoryError("allocateDirectBuffer() returned null");
- } else if (!directBuffer.isDirect()) {
- throw new AssertionError("allocateDirectBuffer() did not return a direct buffer");
- }
-
- return directBuffer;
- }
-
-
- public static void freeDirectBuffer(ByteBuffer buffer) {
- if (buffer == null) {
- return;
- }
-
- if (!buffer.isDirect()) {
- throw new IllegalArgumentException("buffer must be direct");
- }
- //nativeFreeDirectBuffer(buffer);
- return ;
- }
-
- public static void bindWidgetTexture() {
- }
-
- public static void sendEvent(LOEvent event) {
- Log.i(LOGTAG, "Event: " + event.getTypeString());
- }
-
- public static void runGecko(String apkPath, String args, String url, boolean restoreSession) {
- // run gecko -- it will spawn its own thread
- // GeckoAppShell.nativeInit();
-
- Log.i(LOGTAG, "post native init");
-
- // Tell Gecko where the target byte buffer is for rendering
- //GeckoAppShell.setSoftwareLayerClient(GeckoApp.mAppContext.getSoftwareLayerClient());
-
- Log.i(LOGTAG, "setSoftwareLayerClient called");
-
- // First argument is the .apk path
- String combinedArgs = apkPath + " -greomni " + apkPath;
- if (args != null)
- combinedArgs += " " + args;
- if (url != null)
- combinedArgs += " -remote " + url;
- if (restoreSession)
- combinedArgs += " -restoresession";
-
- DisplayMetrics metrics = new DisplayMetrics();
- LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
- combinedArgs += " -width " + metrics.widthPixels + " -height " + metrics.heightPixels;
-
- LibreOfficeMainActivity.mAppContext.runOnUiThread(new Runnable() {
- public void run() {
- geckoLoaded();
- }
- });
-
- //LOKitShell.nativeRun(combinedArgs);
- }
-
- // Called on the UI thread after Gecko loads.
- private static void geckoLoaded() {
- /*final LayerController layerController = LibreOfficeMainActivity.mAppContext.getLayerController();
- LayerView v = layerController.getView();
- mInputConnection = GeckoInputConnection.create(v);
- v.setInputConnectionHandler(mInputConnection);
-
- layerController.setOnTouchListener(new View.OnTouchListener() {
- public boolean onTouch(View view, MotionEvent event) {
- if (event == null)
- return true;
- GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
- return true;
- }
- });
-
- layerController.notifyLayerClientOfGeometryChange();*/
- }
-
- public static void viewSizeChanged() {
- }
-
- public static void scheduleComposite() {
- }
-
- public static void schedulePauseComposition() {
- }
-
- public static void scheduleResumeComposition() {
-
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
deleted file mode 100644
index f486ad804512..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.libreoffice;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.util.JsonWriter;
-
-import org.mozilla.gecko.gfx.ViewportMetrics;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.nio.ByteBuffer;
-import java.util.Random;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-public class LOKitThread extends Thread {
- private static final String LOGTAG = "GeckoThread";
- private static final int TILE_SIZE = 256;
-
-
- public ConcurrentLinkedQueue<LOEvent> gEvents = new ConcurrentLinkedQueue<LOEvent>();
- private ViewportMetrics mViewportMetrics;
- private Random rand = new Random();
-
- LOKitThread() {
- }
-
- private boolean draw() throws InterruptedException {
- final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext;
-
- Bitmap originalBitmap = application.getLayerClient().getLayerController().getDrawable("dummy_page");
-
- String metadata;
- if (mViewportMetrics == null) {
- metadata = createJson(0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), originalBitmap.getWidth(), originalBitmap.getHeight(), 0, 0, 1.0);
- } else {
- metadata = createJson(mViewportMetrics);
- }
-
- Rect bufferRect = application.getLayerClient().beginDrawing(originalBitmap.getWidth(), originalBitmap.getHeight(), 256, 256, metadata);
- if (bufferRect == null) {
- return false;
- }
- int x = 0;
- int y = 0;
-
- for (Integer i = 1; i <= 9; i++) {
- String imageName = "d" + i;
- Bitmap bitmap = application.getLayerClient().getLayerController().getDrawable(imageName);
- application.getLayerClient().addTile(bitmap, x, y);
- x += TILE_SIZE;
- if (x > originalBitmap.getWidth()) {
- x = 0;
- y += TILE_SIZE;
- }
- }
-
- application.getLayerClient().endDrawing(0, 0, originalBitmap.getWidth(), originalBitmap.getHeight());
-
- application.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- application.getLayerClient().handleMessage("Viewport:UpdateLater", null);
- }
- });
-
- return true;
- }
-
- private String createJson(ViewportMetrics viewportMetrics) {
- return createJson(
- (int) viewportMetrics.getOrigin().x,
- (int) viewportMetrics.getOrigin().y,
- (int) viewportMetrics.getSize().width,
- (int) viewportMetrics.getSize().height,
- (int) viewportMetrics.getPageSize().width,
- (int) viewportMetrics.getPageSize().height,
- (int) viewportMetrics.getViewportOffset().x,
- (int) viewportMetrics.getViewportOffset().y,
- viewportMetrics.getZoomFactor());
- }
-
- private String createJson(int x, int y, int width, int height, int pageWidth, int pageHeight, int offsetX, int offsetY, double zoom) {
- try {
- StringWriter stringWriter = new StringWriter();
- JsonWriter writer = new JsonWriter(stringWriter);
- writer.beginObject();
- writer.name("x").value(x);
- writer.name("y").value(y);
- writer.name("width").value(width);
- writer.name("height").value(height);
- writer.name("pageWidth").value(pageWidth);
- writer.name("pageHeight").value(pageHeight);
- writer.name("offsetX").value(offsetX);
- writer.name("offsetY").value(offsetY);
- writer.name("zoom").value(zoom);
- writer.name("backgroundColor").value("rgb(255,255,255)");
- writer.endObject();
- writer.close();
- return stringWriter.toString();
- } catch (IOException ex) {
- }
- return null;
- }
-
- private short convertTo16Bit(int color) {
- int r = Color.red(color) >> 3, g = Color.green(color) >> 2, b = Color.blue(color) >> 3;
- int c = ((r << 11) | (g << 5) | b);
- // Swap endianness.
- return (short) ((c >> 8) | ((c & 0xff) << 8));
- }
-
- private Bitmap convert(Bitmap bitmap, Bitmap.Config config) {
- Bitmap convertedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), config);
- Canvas canvas = new Canvas(convertedBitmap);
- Paint paint = new Paint();
- paint.setColor(Color.BLACK);
- canvas.drawBitmap(bitmap, 0, 0, paint);
- return convertedBitmap;
- }
-
-
- public void run() {
- try {
- boolean drawn = false;
- while (true) {
-
- if (!gEvents.isEmpty()) {
- processEvent(gEvents.poll());
- } else {
- if (!drawn) {
- drawn = draw();
- }
- Thread.sleep(100L);
- }
- }
- } catch (InterruptedException ex) {
- }
- }
-
- private void processEvent(LOEvent event) throws InterruptedException {
- switch (event.mType) {
- case LOEvent.VIEWPORT:
- mViewportMetrics = event.getViewport();
- break;
- case LOEvent.DRAW:
- draw();
- break;
- case LOEvent.SIZE_CHANGED:
- break;
- }
- }
-
-
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java
deleted file mode 100644
index 934464d2dea6..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.libreoffice;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-
-import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.LayerView;
-
-public class LibreOfficeMainActivity extends Activity {
-
- private static final String LOGTAG = "LibreOfficeMainActivity";
-
- private LinearLayout mMainLayout;
- private RelativeLayout mGeckoLayout;
- private static LayerController mLayerController;
- private static GeckoSoftwareLayerClient mLayerClient;
- private static LOKitThread sLOKitThread;
-
- public static LibreOfficeMainActivity mAppContext;
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- public DisplayMetrics getDisplayMetrics() {
- DisplayMetrics metrics = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(metrics);
- return metrics;
- }
-
- /**
- * Called when the activity is first created.
- */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- mAppContext = this;
-
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
-
- setContentView(R.layout.activity_main);
-
- // setup gecko layout
- mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
- mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
-
-
- if (mLayerController == null) {
- mLayerController = new LayerController(this);
-
- Log.e(LOGTAG, "### Creating GeckoSoftwareLayerClient");
- mLayerClient = new GeckoSoftwareLayerClient(this);
- Log.e(LOGTAG, "### Done creating GeckoSoftwareLayerClient");
-
- mLayerController.setLayerClient(mLayerClient);
- mGeckoLayout.addView(mLayerController.getView(), 0);
- }
-
- mLayerController.notifyLayerClientOfGeometryChange();
-
- sLOKitThread = new LOKitThread();
- sLOKitThread.start();
-
-
- Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - UI almost up");
- }
-
- public static GeckoSoftwareLayerClient getLayerClient() {
- return mLayerClient;
- }
-
- public static LayerController getLayerController() {
- return mLayerController;
- }
-} \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java
deleted file mode 100644
index 670513f2cfb2..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Sriram Ramasubramanian <sriram@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko;
-
-import org.json.JSONObject;
-
-public interface GeckoEventListener {
- public void handleMessage(String event, JSONObject message);
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java
deleted file mode 100644
index 2ffe11329f85..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Bitmap;
-
-import org.libreoffice.LOKitShell;
-
-import java.nio.ByteBuffer;
-
-//import org.mozilla.gecko.GeckoAppShell;
-
-/**
- * A Cairo image that simply saves a buffer of pixel data.
- */
-public class BufferedCairoImage extends CairoImage {
- private ByteBuffer mBuffer;
- private IntSize mSize;
- private int mFormat;
- private boolean mNeedToFreeBuffer = false;
-
- /**
- * Creates a buffered Cairo image from a byte buffer.
- */
- public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) {
- mBuffer = inBuffer;
- mSize = new IntSize(inWidth, inHeight);
- mFormat = inFormat;
- }
-
- /**
- * Creates a buffered Cairo image from an Android bitmap.
- */
- public BufferedCairoImage(Bitmap bitmap) {
- mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig());
- mSize = new IntSize(bitmap.getWidth(), bitmap.getHeight());
- mNeedToFreeBuffer = true;
- // XXX Why is this * 4? Shouldn't it depend on mFormat?
- mBuffer = LOKitShell.allocateDirectBuffer(mSize.getArea() * 4);
-
- bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
- }
-
- protected void finalize() throws Throwable {
- try {
- if (mNeedToFreeBuffer && mBuffer != null)
- LOKitShell.freeDirectBuffer(mBuffer);
- mNeedToFreeBuffer = false;
- mBuffer = null;
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public ByteBuffer getBuffer() {
- return mBuffer;
- }
-
- @Override
- public IntSize getSize() {
- return mSize;
- }
-
- @Override
- public int getFormat() {
- return mFormat;
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java
deleted file mode 100644
index bd4eedcaf951..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * Information needed to render Cairo bitmaps using OpenGL ES.
- */
-public class CairoGLInfo {
- public final int internalFormat;
- public final int format;
- public final int type;
-
- public CairoGLInfo(int cairoFormat) {
- switch (cairoFormat) {
- case CairoImage.FORMAT_ARGB32:
- internalFormat = format = GL10.GL_RGBA;
- type = GL10.GL_UNSIGNED_BYTE;
- break;
- case CairoImage.FORMAT_RGB24:
- internalFormat = format = GL10.GL_RGB;
- type = GL10.GL_UNSIGNED_BYTE;
- break;
- case CairoImage.FORMAT_RGB16_565:
- internalFormat = format = GL10.GL_RGB;
- type = GL10.GL_UNSIGNED_SHORT_5_6_5;
- break;
- case CairoImage.FORMAT_A8:
- case CairoImage.FORMAT_A1:
- throw new RuntimeException("Cairo FORMAT_A1 and FORMAT_A8 unsupported");
- default:
- throw new RuntimeException("Unknown Cairo format");
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java
deleted file mode 100644
index 06c389dd0524..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import java.nio.ByteBuffer;
-
-/*
- * A bitmap with pixel data in one of the formats that Cairo understands.
- */
-public abstract class CairoImage {
- public abstract ByteBuffer getBuffer();
-
- public abstract IntSize getSize();
- public abstract int getFormat();
-
- public static final int FORMAT_INVALID = -1;
- public static final int FORMAT_ARGB32 = 0;
- public static final int FORMAT_RGB24 = 1;
- public static final int FORMAT_A8 = 2;
- public static final int FORMAT_A1 = 3;
- public static final int FORMAT_RGB16_565 = 4;
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java
deleted file mode 100644
index 00bd896e1664..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.gfx.CairoImage;
-import android.graphics.Bitmap;
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * Utility methods useful when displaying Cairo bitmaps using OpenGL ES.
- */
-public class CairoUtils {
- private CairoUtils() { /* Don't call me. */ }
-
- public static int bitsPerPixelForCairoFormat(int cairoFormat) {
- switch (cairoFormat) {
- case CairoImage.FORMAT_A1: return 1;
- case CairoImage.FORMAT_A8: return 8;
- case CairoImage.FORMAT_RGB16_565: return 16;
- case CairoImage.FORMAT_RGB24: return 24;
- case CairoImage.FORMAT_ARGB32: return 32;
- default:
- throw new RuntimeException("Unknown Cairo format");
- }
- }
-
- public static int bitmapConfigToCairoFormat(Bitmap.Config config) {
- if (config == null)
- return CairoImage.FORMAT_ARGB32; /* Droid Pro fix. */
-
- switch (config) {
- case ALPHA_8: return CairoImage.FORMAT_A8;
- case ARGB_4444: throw new RuntimeException("ARGB_444 unsupported");
- case ARGB_8888: return CairoImage.FORMAT_ARGB32;
- case RGB_565: return CairoImage.FORMAT_RGB16_565;
- default: throw new RuntimeException("Unknown Skia bitmap config");
- }
- }
-
- public static Bitmap.Config cairoFormatTobitmapConfig(int format) {
- switch (format) {
- case CairoImage.FORMAT_A8: return Bitmap.Config.ALPHA_8;
- case CairoImage.FORMAT_ARGB32: return Bitmap.Config.ARGB_8888;
- case CairoImage.FORMAT_RGB16_565: return Bitmap.Config.RGB_565;
- default:
- throw new RuntimeException("Unknown CairoImage format");
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java
deleted file mode 100644
index 392d7e8d8463..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.libreoffice.LOKitShell;
-import android.graphics.Color;
-import java.nio.ByteBuffer;
-import java.nio.ShortBuffer;
-import java.util.Arrays;
-
-/** A Cairo image that displays a tinted checkerboard. */
-public class CheckerboardImage extends CairoImage {
- // The width and height of the checkerboard tile.
- private static final int SIZE = 16;
- // The pixel format of the checkerboard tile.
- private static final int FORMAT = CairoImage.FORMAT_RGB16_565;
- // The color to mix in to tint the background color.
- private static final int TINT_COLOR = Color.GRAY;
- // The amount to mix in.
- private static final float TINT_OPACITY = 0.4f;
-
- private ByteBuffer mBuffer;
- private int mMainColor;
- private boolean mShowChecks;
-
- /** Creates a new checkerboard image. */
- public CheckerboardImage() {
- int bpp = CairoUtils.bitsPerPixelForCairoFormat(FORMAT);
- mBuffer = LOKitShell.allocateDirectBuffer(SIZE * SIZE * bpp / 8);
- update(true, Color.WHITE);
- }
-
- /** Returns the current color of the checkerboard. */
- public int getColor() {
- return mMainColor;
- }
-
- /** Returns whether or not we are currently showing checks on the checkerboard. */
- public boolean getShowChecks() {
- return mShowChecks;
- }
-
- /** Updates the checkerboard image. If showChecks is true, then create a
- checkerboard image that is tinted to the color. Otherwise just return a flat
- image of the color. */
- public void update(boolean showChecks, int color) {
- mMainColor = color;
- mShowChecks = showChecks;
-
- short mainColor16 = convertTo16Bit(mMainColor);
-
- mBuffer.rewind();
- ShortBuffer shortBuffer = mBuffer.asShortBuffer();
-
- if (!mShowChecks) {
- short color16 = convertTo16Bit(mMainColor);
- short[] fillBuffer = new short[SIZE];
- Arrays.fill(fillBuffer, color16);
-
- for (int i = 0; i < SIZE; i++) {
- shortBuffer.put(fillBuffer);
- }
-
- return;
- }
-
- short tintColor16 = convertTo16Bit(tint(mMainColor));
-
- short[] mainPattern = new short[SIZE / 2], tintPattern = new short[SIZE / 2];
- Arrays.fill(mainPattern, mainColor16);
- Arrays.fill(tintPattern, tintColor16);
-
- // The checkerboard pattern looks like this:
- //
- // +---+---+
- // | N | T | N = normal
- // +---+---+ T = tinted
- // | T | N |
- // +---+---+
-
- for (int i = 0; i < SIZE / 2; i++) {
- shortBuffer.put(mainPattern);
- shortBuffer.put(tintPattern);
- }
- for (int i = SIZE / 2; i < SIZE; i++) {
- shortBuffer.put(tintPattern);
- shortBuffer.put(mainPattern);
- }
- }
-
- // Tints the given color appropriately and returns the tinted color.
- private int tint(int color) {
- float negTintOpacity = 1.0f - TINT_OPACITY;
- float r = Color.red(color) * negTintOpacity + Color.red(TINT_COLOR) * TINT_OPACITY;
- float g = Color.green(color) * negTintOpacity + Color.green(TINT_COLOR) * TINT_OPACITY;
- float b = Color.blue(color) * negTintOpacity + Color.blue(TINT_COLOR) * TINT_OPACITY;
- return Color.rgb(Math.round(r), Math.round(g), Math.round(b));
- }
-
- // Converts a 32-bit ARGB color to 16-bit R5G6B5, truncating values and discarding the alpha
- // channel.
- private short convertTo16Bit(int color) {
- int r = Color.red(color) >> 3, g = Color.green(color) >> 2, b = Color.blue(color) >> 3;
- int c = ((r << 11) | (g << 5) | b);
- // Swap endianness.
- return (short)((c >> 8) | ((c & 0xff) << 8));
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mBuffer != null) {
- LOKitShell.freeDirectBuffer(mBuffer);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public ByteBuffer getBuffer() {
- return mBuffer;
- }
-
- @Override
- public IntSize getSize() {
- return new IntSize(SIZE, SIZE);
- }
-
- @Override
- public int getFormat() {
- return FORMAT;
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java
deleted file mode 100644
index dc20077b0457..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011-2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoApp;
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.opengl.GLSurfaceView;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import org.libreoffice.LibreOfficeMainActivity;
-
-public class FlexibleGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
- private static final String LOGTAG = "GeckoFlexibleGLSurfaceView";
-
- private GLSurfaceView.Renderer mRenderer;
- private GLThread mGLThread; // Protected by this class's monitor.
- private GLController mController;
- private Listener mListener;
-
- public FlexibleGLSurfaceView(Context context) {
- super(context);
- init();
- }
-
- public FlexibleGLSurfaceView(Context context, AttributeSet attributeSet) {
- super(context, attributeSet);
- init();
- }
-
- public void init() {
- SurfaceHolder holder = getHolder();
- holder.addCallback(this);
- holder.setFormat(PixelFormat.RGB_565);
-
- mController = new GLController(this);
- }
-
- public void setRenderer(GLSurfaceView.Renderer renderer) {
- mRenderer = renderer;
- }
-
- public GLSurfaceView.Renderer getRenderer() {
- return mRenderer;
- }
-
- public void setListener(Listener listener) {
- mListener = listener;
- }
-
- public synchronized void requestRender() {
- if (mGLThread != null) {
- mGLThread.renderFrame();
- }
- if (mListener != null) {
- mListener.renderRequested();
- }
- }
-
- /**
- * Creates a Java GL thread. After this is called, the FlexibleGLSurfaceView may be used just
- * like a GLSurfaceView. It is illegal to access the controller after this has been called.
- */
- public synchronized void createGLThread() {
- if (mGLThread != null) {
- throw new FlexibleGLSurfaceViewException("createGLThread() called with a GL thread " +
- "already in place!");
- }
-
- Log.e(LOGTAG, "### Creating GL thread!");
- mGLThread = new GLThread(mController);
- mGLThread.start();
- notifyAll();
- }
-
- /**
- * Destroys the Java GL thread. Returns a Thread that completes when the Java GL thread is
- * fully shut down.
- */
- public synchronized Thread destroyGLThread() {
- // Wait for the GL thread to be started.
- Log.e(LOGTAG, "### Waiting for GL thread to be created...");
- while (mGLThread == null) {
- try {
- wait();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- Log.e(LOGTAG, "### Destroying GL thread!");
- Thread glThread = mGLThread;
- mGLThread.shutdown();
- mGLThread = null;
- return glThread;
- }
-
- public synchronized void recreateSurface() {
- if (mGLThread == null) {
- throw new FlexibleGLSurfaceViewException("recreateSurface() called with no GL " +
- "thread active!");
- }
-
- mGLThread.recreateSurface();
- }
-
- public synchronized GLController getGLController() {
- if (mGLThread != null) {
- throw new FlexibleGLSurfaceViewException("getGLController() called with a GL thread " +
- "active; shut down the GL thread first!");
- }
-
- return mController;
- }
-
- public synchronized void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- mController.sizeChanged(width, height);
- if (mGLThread != null) {
- mGLThread.surfaceChanged(width, height);
- }
-
- if (mListener != null) {
- mListener.surfaceChanged(width, height);
- }
- }
-
- public synchronized void surfaceCreated(SurfaceHolder holder) {
- mController.surfaceCreated();
- if (mGLThread != null) {
- mGLThread.surfaceCreated();
- }
- }
-
- public synchronized void surfaceDestroyed(SurfaceHolder holder) {
- mController.surfaceDestroyed();
- if (mGLThread != null) {
- mGLThread.surfaceDestroyed();
- }
-
- if (mListener != null) {
- mListener.compositionPauseRequested();
- }
- }
-
- // Called from the compositor thread
- public static GLController registerCxxCompositor() {
- try {
- Log.e(LOGTAG, "### registerCxxCompositor point A");
- System.out.println("register layer comp");
- Log.e(LOGTAG, "### registerCxxCompositor point B");
- FlexibleGLSurfaceView flexView = (FlexibleGLSurfaceView) /*GeckoApp*/LibreOfficeMainActivity.mAppContext.getLayerController().getView();
- Log.e(LOGTAG, "### registerCxxCompositor point C: " + flexView);
- try {
- flexView.destroyGLThread().join();
- } catch (InterruptedException e) {}
- Log.e(LOGTAG, "### registerCxxCompositor point D: " + flexView.getGLController());
- return flexView.getGLController();
- } catch (Exception e) {
- Log.e(LOGTAG, "### Exception! " + e);
- return null;
- }
- }
-
- public interface Listener {
- void renderRequested();
- void compositionPauseRequested();
- void compositionResumeRequested();
- void surfaceChanged(int width, int height);
- }
-
- public static class FlexibleGLSurfaceViewException extends RuntimeException {
- public static final long serialVersionUID = 1L;
-
- FlexibleGLSurfaceViewException(String e) {
- super(e);
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java
deleted file mode 100644
index 5fb73ec18df9..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.mozilla.gecko.util.FloatUtils;
-
-public class FloatSize {
- public final float width, height;
-
- public FloatSize(FloatSize size) {
- width = size.width;
- height = size.height;
- }
-
- public FloatSize(IntSize size) {
- width = size.width;
- height = size.height;
- }
-
- public FloatSize(float aWidth, float aHeight) {
- width = aWidth;
- height = aHeight;
- }
-
- public FloatSize(JSONObject json) {
- try {
- width = (float) json.getDouble("width");
- height = (float) json.getDouble("height");
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String toString() {
- return "(" + width + "," + height + ")";
- }
-
- public boolean isPositive() {
- return (width > 0 && height > 0);
- }
-
- public boolean fuzzyEquals(FloatSize size) {
- return (FloatUtils.fuzzyEquals(size.width, width) &&
- FloatUtils.fuzzyEquals(size.height, height));
- }
-
- public FloatSize scale(float factor) {
- return new FloatSize(width * factor, height * factor);
- }
-
- /*
- * Returns the size that represents a linear transition between this size and `to` at time `t`,
- * which is on the scale [0, 1).
- */
- public FloatSize interpolate(FloatSize to, float t) {
- return new FloatSize(FloatUtils.interpolate(width, to.width, t),
- FloatUtils.interpolate(height, to.height, t));
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java
deleted file mode 100644
index e8f201228666..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011-2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.util.Log;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGL11;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-import javax.microedition.khronos.opengles.GL;
-import javax.microedition.khronos.opengles.GL10;
-
-public class GLController {
- private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
- private static final String LOGTAG = "GeckoGLController";
-
- private FlexibleGLSurfaceView mView;
- private int mGLVersion;
- private boolean mSurfaceValid;
- private int mWidth, mHeight;
-
- private EGL10 mEGL;
- private EGLDisplay mEGLDisplay;
- private EGLConfig mEGLConfig;
- private EGLContext mEGLContext;
- private EGLSurface mEGLSurface;
-
- private GL mGL;
-
- private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4;
-
- private static final int[] CONFIG_SPEC = {
- EGL10.EGL_RED_SIZE, 5,
- EGL10.EGL_GREEN_SIZE, 6,
- EGL10.EGL_BLUE_SIZE, 5,
- EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
- EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
- EGL10.EGL_NONE
- };
-
- public GLController(FlexibleGLSurfaceView view) {
- mView = view;
- mGLVersion = 2;
- mSurfaceValid = false;
- }
-
- public void setGLVersion(int version) {
- mGLVersion = version;
- }
-
- /** You must call this on the same thread you intend to use OpenGL on. */
- public void initGLContext() {
- initEGLContext();
- createEGLSurface();
- }
-
- public void disposeGLContext() {
- if (!mEGL.eglMakeCurrent(mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
- EGL10.EGL_NO_CONTEXT)) {
- throw new GLControllerException("EGL context could not be released!");
- }
-
- if (mEGLSurface != null) {
- if (!mEGL.eglDestroySurface(mEGLDisplay, mEGLSurface)) {
- throw new GLControllerException("EGL surface could not be destroyed!");
- }
-
- mEGLSurface = null;
- }
-
- if (mEGLContext == null) {
- if (!mEGL.eglDestroyContext(mEGLDisplay, mEGLContext)) {
- throw new GLControllerException("EGL context could not be destroyed!");
- }
-
- mGL = null;
- mEGLDisplay = null;
- mEGLConfig = null;
- mEGLContext = null;
- }
- }
-
- public GL getGL() { return mEGLContext.getGL(); }
- public EGLDisplay getEGLDisplay() { return mEGLDisplay; }
- public EGLConfig getEGLConfig() { return mEGLConfig; }
- public EGLContext getEGLContext() { return mEGLContext; }
- public EGLSurface getEGLSurface() { return mEGLSurface; }
- public FlexibleGLSurfaceView getView() { return mView; }
-
- public boolean hasSurface() {
- return mEGLSurface != null;
- }
-
- public boolean swapBuffers() {
- return mEGL.eglSwapBuffers(mEGLDisplay, mEGLSurface);
- }
-
- public boolean checkForLostContext() {
- if (mEGL.eglGetError() != EGL11.EGL_CONTEXT_LOST) {
- return false;
- }
-
- mEGLDisplay = null;
- mEGLConfig = null;
- mEGLContext = null;
- mEGLSurface = null;
- mGL = null;
- return true;
- }
-
- public synchronized void waitForValidSurface() {
- while (!mSurfaceValid) {
- try {
- wait();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public synchronized int getWidth() {
- return mWidth;
- }
-
- public synchronized int getHeight() {
- return mHeight;
- }
-
- synchronized void surfaceCreated() {
- mSurfaceValid = true;
- notifyAll();
- }
-
- synchronized void surfaceDestroyed() {
- mSurfaceValid = false;
- notifyAll();
- }
-
- synchronized void sizeChanged(int newWidth, int newHeight) {
- mWidth = newWidth;
- mHeight = newHeight;
- }
-
- private void initEGL() {
- mEGL = (EGL10)EGLContext.getEGL();
-
- mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
- if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) {
- throw new GLControllerException("eglGetDisplay() failed");
- }
-
- int[] version = new int[2];
- if (!mEGL.eglInitialize(mEGLDisplay, version)) {
- throw new GLControllerException("eglInitialize() failed");
- }
-
- mEGLConfig = chooseConfig();
- }
-
- private void initEGLContext() {
- initEGL();
-
- int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, mGLVersion, EGL10.EGL_NONE };
- mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT,
- attribList);
- if (mEGLContext == null || mEGLContext == EGL10.EGL_NO_CONTEXT) {
- throw new GLControllerException("createContext() failed");
- }
- }
-
- private EGLConfig chooseConfig() {
- int[] numConfigs = new int[1];
- if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, null, 0, numConfigs) ||
- numConfigs[0] <= 0) {
- throw new GLControllerException("No available EGL configurations");
- }
-
- EGLConfig[] configs = new EGLConfig[numConfigs[0]];
- if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, configs, numConfigs[0], numConfigs)) {
- throw new GLControllerException("No EGL configuration for that specification");
- }
-
- // Select the first 565 RGB configuration.
- int[] red = new int[1], green = new int[1], blue = new int[1];
- for (EGLConfig config : configs) {
- mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_RED_SIZE, red);
- mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_GREEN_SIZE, green);
- mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_BLUE_SIZE, blue);
- if (red[0] == 5 && green[0] == 6 && blue[0] == 5) {
- return config;
- }
- }
-
- throw new GLControllerException("No suitable EGL configuration found");
- }
-
- private void createEGLSurface() {
- SurfaceHolder surfaceHolder = mView.getHolder();
- mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null);
- if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) {
- throw new GLControllerException("EGL window surface could not be created!");
- }
-
- if (!mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
- throw new GLControllerException("EGL surface could not be made into the current " +
- "surface!");
- }
-
- mGL = mEGLContext.getGL();
-
- if (mView.getRenderer() != null) {
- mView.getRenderer().onSurfaceCreated((GL10)mGL, mEGLConfig);
- mView.getRenderer().onSurfaceChanged((GL10)mGL, mView.getWidth(), mView.getHeight());
- }
- }
-
- // Provides an EGLSurface without assuming ownership of this surface.
- private EGLSurface provideEGLSurface() {
- if (mEGL == null) {
- initEGL();
- }
-
- SurfaceHolder surfaceHolder = mView.getHolder();
- mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null);
- if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) {
- throw new GLControllerException("EGL window surface could not be created!");
- }
-
- return mEGLSurface;
- }
-
- public static class GLControllerException extends RuntimeException {
- public static final long serialVersionUID = 1L;
-
- GLControllerException(String e) {
- super(e);
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java
deleted file mode 100644
index 4f788f64ebcb..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011-2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.opengl.GLSurfaceView;
-import android.view.SurfaceHolder;
-import javax.microedition.khronos.opengles.GL10;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-
-// A GL thread managed by Java. It is not necessary to use this class to use the
-// FlexibleGLSurfaceView, but it can be helpful, especially if the GL rendering is to be done
-// entirely in Java.
-class GLThread extends Thread {
- private LinkedBlockingQueue<Runnable> mQueue;
- private GLController mController;
- private boolean mRenderQueued;
-
- public GLThread(GLController controller) {
- mQueue = new LinkedBlockingQueue<Runnable>();
- mController = controller;
- }
-
- @Override
- public void run() {
- while (true) {
- Runnable runnable;
- try {
- runnable = mQueue.take();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
-
- runnable.run();
- if (runnable instanceof ShutdownMessage) {
- break;
- }
- }
- }
-
- public void recreateSurface() {
- mQueue.add(new RecreateSurfaceMessage());
- }
-
- public void renderFrame() {
- // Make sure there's only one render event in the queue at a time.
- synchronized (this) {
- if (!mRenderQueued) {
- mQueue.add(new RenderFrameMessage());
- mRenderQueued = true;
- }
- }
- }
-
- public void shutdown() {
- mQueue.add(new ShutdownMessage());
- }
-
- public void surfaceChanged(int width, int height) {
- mQueue.add(new SizeChangedMessage(width, height));
- }
-
- public void surfaceCreated() {
- mQueue.add(new SurfaceCreatedMessage());
- }
-
- public void surfaceDestroyed() {
- mQueue.add(new SurfaceDestroyedMessage());
- }
-
- private void doRecreateSurface() {
- mController.disposeGLContext();
- mController.initGLContext();
- }
-
- private GLSurfaceView.Renderer getRenderer() {
- return mController.getView().getRenderer();
- }
-
- private class RecreateSurfaceMessage implements Runnable {
- public void run() {
- doRecreateSurface();
- }
- }
-
- private class RenderFrameMessage implements Runnable {
- public void run() {
- synchronized (GLThread.this) {
- mRenderQueued = false;
- }
-
- // Bail out if the surface was lost.
- if (mController.getEGLSurface() == null) {
- return;
- }
-
- GLSurfaceView.Renderer renderer = getRenderer();
- if (renderer != null) {
- renderer.onDrawFrame((GL10)mController.getGL());
- }
-
- mController.swapBuffers();
- //if (!mController.swapBuffers() && mController.checkForLostContext()) {
- // doRecreateSurface();
- //}
- }
- }
-
- private class ShutdownMessage implements Runnable {
- public void run() {
- mController.disposeGLContext();
- mController = null;
- }
- }
-
- private class SizeChangedMessage implements Runnable {
- private int mWidth, mHeight;
-
- public SizeChangedMessage(int width, int height) {
- mWidth = width;
- mHeight = height;
- }
-
- public void run() {
- GLSurfaceView.Renderer renderer = getRenderer();
- if (renderer != null) {
- renderer.onSurfaceChanged((GL10)mController.getGL(), mWidth, mHeight);
- }
- }
- }
-
- private class SurfaceCreatedMessage implements Runnable {
- public void run() {
- if (!mController.hasSurface()) {
- mController.initGLContext();
- }
- }
- }
-
- private class SurfaceDestroyedMessage implements Runnable {
- public void run() {
- mController.disposeGLContext();
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
deleted file mode 100644
index 134c40628d0b..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.SystemClock;
-import android.util.DisplayMetrics;
-import android.util.Log;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.libreoffice.LOEvent;
-import org.libreoffice.LOKitShell;
-import org.libreoffice.LibreOfficeMainActivity;
-import org.mozilla.gecko.GeckoEventListener;
-import org.mozilla.gecko.util.FloatUtils;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-//import org.mozilla.gecko.GeckoApp;
-//import org.mozilla.gecko.GeckoAppShell;
-//import org.mozilla.gecko.GeckoEvent;
-
-public abstract class GeckoLayerClient extends LayerClient implements GeckoEventListener {
- public static final int LAYER_CLIENT_TYPE_NONE = 0;
- public static final int LAYER_CLIENT_TYPE_SOFTWARE = 1;
- public static final int LAYER_CLIENT_TYPE_GL = 2;
-
- private static final String LOGTAG = "GeckoLayerClient";
- private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
- private static Pattern sColorPattern;
- protected IntSize mScreenSize;
- protected Layer mTileLayer;
- /* The viewport that Gecko is currently displaying. */
- protected ViewportMetrics mGeckoViewport;
- /* The viewport that Gecko will display when drawing is finished */
- protected ViewportMetrics mNewGeckoViewport;
- private long mLastViewportChangeTime;
- private boolean mPendingViewportAdjust;
- private boolean mViewportSizeChanged;
-
- // mUpdateViewportOnEndDraw is used to indicate that we received a
- // viewport update notification while drawing. therefore, when the
- // draw finishes, we need to update the entire viewport rather than
- // just the page size. this boolean should always be accessed from
- // inside a transaction, so no synchronization is needed.
- private boolean mUpdateViewportOnEndDraw;
- private String mLastCheckerboardColor;
- /* Used by robocop for testing purposes */
- private DrawListener mDrawListener;
-
- public GeckoLayerClient(Context context) {
- mScreenSize = new IntSize(0, 0);
- }
-
- // Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
- // cannot be parsed, returns white.
- private static int parseColorFromGecko(String string) {
- if (sColorPattern == null) {
- sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)");
- }
-
- Matcher matcher = sColorPattern.matcher(string);
- if (!matcher.matches()) {
- return Color.WHITE;
- }
-
- int r = Integer.parseInt(matcher.group(1));
- int g = Integer.parseInt(matcher.group(2));
- int b = Integer.parseInt(matcher.group(3));
- return Color.rgb(r, g, b);
- }
-
- protected abstract boolean setupLayer();
-
- protected abstract boolean shouldDrawProceed(int tileWidth, int tileHeight);
-
- protected abstract void updateLayerAfterDraw(Rect updatedRect);
-
- protected abstract IntSize getBufferSize();
-
- protected abstract IntSize getTileSize();
-
- protected abstract void tileLayerUpdated();
-
- public abstract Bitmap getBitmap();
-
- public abstract int getType();
-
- /**
- * Attaches the root layer to the layer controller so that Gecko appears.
- */
- @Override
- public void setLayerController(LayerController layerController) {
- super.setLayerController(layerController);
-
- layerController.setRoot(mTileLayer);
- if (mGeckoViewport != null) {
- layerController.setViewportMetrics(mGeckoViewport);
- }
-
- sendResizeEventIfNecessary();
- }
-
- public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
-
- Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " + tileHeight);
-
- if (setupLayer()) {
- Log.e(LOGTAG, "### Cancelling due to layer setup");
- return null;
- }
-
- if (!shouldDrawProceed(tileWidth, tileHeight)) {
- Log.e(LOGTAG, "### Cancelling draw due to shouldDrawProceed()");
- return null;
- }
-
- LayerController controller = getLayerController();
-
- try {
- JSONObject viewportObject = new JSONObject(metadata);
- mNewGeckoViewport = new ViewportMetrics(viewportObject);
-
- Log.e(LOGTAG, "### beginDrawing new Gecko viewport " + mNewGeckoViewport);
-
- // Update the background color, if it's present.
- String backgroundColorString = viewportObject.optString("backgroundColor");
- if (backgroundColorString != null && !backgroundColorString.equals(mLastCheckerboardColor)) {
- mLastCheckerboardColor = backgroundColorString;
- controller.setCheckerboardColor(parseColorFromGecko(backgroundColorString));
- }
- } catch (JSONException e) {
- Log.e(LOGTAG, "Aborting draw, bad viewport description: " + metadata);
- return null;
- }
-
- // Make sure we don't spend time painting areas we aren't interested in.
- // Only do this if the Gecko viewport isn't going to override our viewport.
- Rect bufferRect = new Rect(0, 0, width, height);
-
- if (!mUpdateViewportOnEndDraw) {
- // First, find out our ideal displayport. We do this by taking the
- // clamped viewport origin and taking away the optimum viewport offset.
- // This would be what we would send to Gecko if adjustViewport were
- // called now.
- ViewportMetrics currentMetrics = controller.getViewportMetrics();
- PointF currentBestOrigin = RectUtils.getOrigin(currentMetrics.getClampedViewport());
- PointF viewportOffset = currentMetrics.getOptimumViewportOffset(new IntSize(width, height));
- currentBestOrigin.offset(-viewportOffset.x, -viewportOffset.y);
-
- Rect currentRect = RectUtils.round(new RectF(currentBestOrigin.x, currentBestOrigin.y,
- currentBestOrigin.x + width, currentBestOrigin.y + height));
-
- // Second, store Gecko's displayport.
- PointF currentOrigin = mNewGeckoViewport.getDisplayportOrigin();
- bufferRect = RectUtils.round(new RectF(currentOrigin.x, currentOrigin.y,
- currentOrigin.x + width, currentOrigin.y + height));
-
-
- // Take the intersection of the two as the area we're interested in rendering.
-
- if (!bufferRect.intersect(currentRect)) {
- // If there's no intersection, we have no need to render anything,
- // but make sure to update the viewport size.
- beginTransaction(mTileLayer);
- try {
- updateViewport(true);
- } finally {
- endTransaction(mTileLayer);
- }
- return null;
- }
- bufferRect.offset(Math.round(-currentOrigin.x), Math.round(-currentOrigin.y));
- }
-
- beginTransaction(mTileLayer);
- return bufferRect;
- }
-
- /*
- * TODO: Would be cleaner if this took an android.graphics.Rect instead, but that would require
- * a little more JNI magic.
- */
- public void endDrawing(int x, int y, int width, int height) {
- synchronized (getLayerController()) {
- try {
- updateViewport(!mUpdateViewportOnEndDraw);
- mUpdateViewportOnEndDraw = false;
-
- Rect rect = new Rect(x, y, x + width, y + height);
- updateLayerAfterDraw(rect);
- } finally {
- endTransaction(mTileLayer);
- }
- }
- Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - endDrawing");
-
- /* Used by robocop for testing purposes */
- if (mDrawListener != null) {
- mDrawListener.drawFinished(x, y, width, height);
- }
- }
-
- protected void updateViewport(boolean onlyUpdatePageSize) {
- // save and restore the viewport size stored in java; never let the
- // JS-side viewport dimensions override the java-side ones because
- // java is the One True Source of this information, and allowing JS
- // to override can lead to race conditions where this data gets clobbered.
- FloatSize viewportSize = getLayerController().getViewportSize();
- mGeckoViewport = mNewGeckoViewport;
- mGeckoViewport.setSize(viewportSize);
-
- LayerController controller = getLayerController();
- PointF displayportOrigin = mGeckoViewport.getDisplayportOrigin();
- mTileLayer.setOrigin(PointUtils.round(displayportOrigin));
- mTileLayer.setResolution(mGeckoViewport.getZoomFactor());
-
- this.tileLayerUpdated();
- Log.e(LOGTAG, "### updateViewport onlyUpdatePageSize=" + onlyUpdatePageSize + " getTileViewport " + mGeckoViewport);
-
- if (onlyUpdatePageSize) {
- // Don't adjust page size when zooming unless zoom levels are
- // approximately equal.
- if (FloatUtils.fuzzyEquals(controller.getZoomFactor(), mGeckoViewport.getZoomFactor())) {
- controller.setPageSize(mGeckoViewport.getPageSize());
- }
- } else {
- controller.setViewportMetrics(mGeckoViewport);
- controller.abortPanZoomAnimation();
- }
- }
-
- /* Informs Gecko that the screen size has changed. */
- protected void sendResizeEventIfNecessary(boolean force) {
- Log.e(LOGTAG, "### sendResizeEventIfNecessary " + force);
-
- DisplayMetrics metrics = new DisplayMetrics();
- LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
-
- // Return immediately if the screen size hasn't changed or the viewport
- // size is zero (which indicates that the rendering surface hasn't been
- // allocated yet).
- boolean screenSizeChanged = (metrics.widthPixels != mScreenSize.width || metrics.heightPixels != mScreenSize.height);
- boolean viewportSizeValid = (getLayerController() != null && getLayerController().getViewportSize().isPositive());
-
- if (!(force || (screenSizeChanged && viewportSizeValid))) {
- return;
- }
-
- mScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels);
- IntSize bufferSize = getBufferSize(), tileSize = getTileSize();
-
- Log.e(LOGTAG, "### Screen-size changed to " + mScreenSize);
-
- LOEvent event = LOEvent.sizeChanged(bufferSize.width, bufferSize.height,
- metrics.widthPixels, metrics.heightPixels,
- tileSize.width, tileSize.height);
- LOKitShell.sendEvent(event);
- }
-
- @Override
- public void render() {
- adjustViewportWithThrottling();
- }
-
- private void adjustViewportWithThrottling() {
- if (!getLayerController().getRedrawHint())
- return;
-
- if (mPendingViewportAdjust)
- return;
-
- long timeDelta = System.currentTimeMillis() - mLastViewportChangeTime;
- if (timeDelta < MIN_VIEWPORT_CHANGE_DELAY) {
- getLayerController().getView().postDelayed(
- new Runnable() {
- public void run() {
- mPendingViewportAdjust = false;
- adjustViewport();
- }
- }, MIN_VIEWPORT_CHANGE_DELAY - timeDelta
- );
- mPendingViewportAdjust = true;
- return;
- }
-
- adjustViewport();
- }
-
- @Override
- public void viewportSizeChanged() {
- mViewportSizeChanged = true;
- }
-
- private void adjustViewport() {
- ViewportMetrics viewportMetrics = new ViewportMetrics(getLayerController().getViewportMetrics());
-
- PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(getBufferSize());
- viewportMetrics.setViewportOffset(viewportOffset);
- viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
-
- LOKitShell.sendEvent(LOEvent.viewport(viewportMetrics));
- if (mViewportSizeChanged) {
- mViewportSizeChanged = false;
- LOKitShell.viewSizeChanged();
- }
-
- mLastViewportChangeTime = System.currentTimeMillis();
- }
-
- public void handleMessage(String event, JSONObject message) {
- if ("Viewport:UpdateAndDraw".equals(event)) {
- Log.e(LOGTAG, "### Java side Viewport:UpdateAndDraw()!");
- mUpdateViewportOnEndDraw = true;
-
- // Redraw everything.
- IntSize bufferSize = getBufferSize();
- Rect rect = new Rect(0, 0, bufferSize.width, bufferSize.height);
- LOKitShell.sendEvent(LOEvent.draw(rect));
- } else if ("Viewport:UpdateLater".equals(event)) {
- Log.e(LOGTAG, "### Java side Viewport:UpdateLater()!");
- mUpdateViewportOnEndDraw = true;
- }
- }
-
- @Override
- public void geometryChanged() {
- sendResizeEventIfNecessary();
- render();
- }
-
- public ViewportMetrics getGeckoViewportMetrics() {
- if (mGeckoViewport != null)
- return new ViewportMetrics(mGeckoViewport);
- return null;
- }
-
- private void sendResizeEventIfNecessary() {
- sendResizeEventIfNecessary(false);
- }
-
- /**
- * Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop.
- */
- public void setDrawListener(DrawListener listener) {
- mDrawListener = listener;
- }
-
- /**
- * Used by robocop for testing purposes. Not for production use! This is used via reflection by robocop.
- */
- public interface DrawListener {
- public void drawFinished(int x, int y, int width, int height);
- }
-} \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
deleted file mode 100644
index 9269f967f1d2..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.gfx.CairoImage;
-import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.LayerClient;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.LayerRenderer;
-import org.mozilla.gecko.gfx.MultiTileLayer;
-import org.mozilla.gecko.gfx.PointUtils;
-import org.mozilla.gecko.gfx.WidgetTileLayer;
-//import org.mozilla.gecko.GeckoAppShell;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.util.Log;
-import java.nio.ByteBuffer;
-
-/**
- * Transfers a software-rendered Gecko to an ImageLayer so that it can be rendered by our
- * compositor.
- *
- * TODO: Throttle down Gecko's priority when we pan and zoom.
- */
-public class GeckoSoftwareLayerClient extends GeckoLayerClient {
- private static final String LOGTAG = "GeckoSoftwareLayerClient";
-
- private int mFormat;
- private IntSize mViewportSize;
- private IntSize mBufferSize;
- private static final IntSize TILE_SIZE = new IntSize(256, 256);
-
- public GeckoSoftwareLayerClient(Context context) {
- super(context);
- mBufferSize = new IntSize(0,0);
- mFormat = CairoImage.FORMAT_ARGB32;
-
-
- }
-
- /*protected void finalize() throws Throwable {
- try {
- if (mBuffer != null)
- LOKitShell.freeDirectBuffer(mBuffer);
- mBuffer = null;
- } finally {
- super.finalize();
- }
- }*/
-
- public void setLayerController(LayerController layerController) {
- super.setLayerController(layerController);
-
- layerController.setRoot(mTileLayer);
- if (mGeckoViewport != null) {
- layerController.setViewportMetrics(mGeckoViewport);
- }
-
- sendResizeEventIfNecessary(false);
- }
-
- @Override
- protected boolean setupLayer() {
- if (mTileLayer != null)
- return false;
-
- Log.i(LOGTAG, "Creating MultiTileLayer");
- mTileLayer = new MultiTileLayer(TILE_SIZE);
-
- getLayerController().setRoot(mTileLayer);
-
- // Force a resize event to be sent because the results of this
- // are different depending on what tile system we're using
- sendResizeEventIfNecessary(true);
-
- return true;
- }
-
- @Override
- protected boolean shouldDrawProceed(int tileWidth, int tileHeight) {
- // Make sure the tile-size matches. If it doesn't, we could crash trying
- // to access invalid memory.
- if (tileWidth != TILE_SIZE.width || tileHeight != TILE_SIZE.height) {
- Log.e(LOGTAG, "Aborting draw, incorrect tile size of " + tileWidth + "x" + tileHeight);
- return false;
- }
- return true;
- }
-
- @Override
- public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
- Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
-
- if (bufferRect == null) {
- return bufferRect;
- }
-
- // If the window size has changed, reallocate the buffer to match.
- if (mBufferSize.width != width || mBufferSize.height != height) {
- mBufferSize = new IntSize(width, height);
- }
-
- return bufferRect;
- }
-
- @Override
- protected void updateLayerAfterDraw(Rect updatedRect) {
- if (mTileLayer instanceof MultiTileLayer) {
- ((MultiTileLayer)mTileLayer).invalidate(updatedRect);
- }
- }
-
- /*private void copyPixelsFromMultiTileLayer(Bitmap target) {
- Canvas c = new Canvas(target);
- ByteBuffer tileBuffer = mBuffer.slice();
- int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
-
- for (int y = 0; y < mBufferSize.height; y += TILE_SIZE.height) {
- for (int x = 0; x < mBufferSize.width; x += TILE_SIZE.width) {
- // Calculate tile size
- IntSize tileSize = new IntSize(Math.min(mBufferSize.width - x, TILE_SIZE.width),
- Math.min(mBufferSize.height - y, TILE_SIZE.height));
-
- // Create a Bitmap from this tile
- Bitmap tile = Bitmap.createBitmap(tileSize.width, tileSize.height,
- CairoUtils.cairoFormatTobitmapConfig(mFormat));
- tile.copyPixelsFromBuffer(tileBuffer.asIntBuffer());
-
- // Copy the tile to the master Bitmap and recycle it
- c.drawBitmap(tile, x, y, null);
- tile.recycle();
-
- // Progress the buffer to the next tile
- tileBuffer.position(tileSize.getArea() * bpp);
- tileBuffer = tileBuffer.slice();
- }
- }
- }*/
-
- @Override
- protected void tileLayerUpdated() {
- /* No-op. */
- }
-
- @Override
- public Bitmap getBitmap() {
- if (mTileLayer == null)
- return null;
-
- // Begin a tile transaction, otherwise the buffer can be destroyed while
- // we're reading from it.
- /*beginTransaction(mTileLayer);
- try {
- if (mBuffer == null || mBufferSize.width <= 0 || mBufferSize.height <= 0)
- return null;
- try {
- Bitmap b = null;
-
- if (mTileLayer instanceof MultiTileLayer) {
- b = Bitmap.createBitmap(mBufferSize.width, mBufferSize.height,CairoUtils.cairoFormatTobitmapConfig(mFormat));
- copyPixelsFromMultiTileLayer(b);
- } else {
- Log.w(LOGTAG, "getBitmap() called on a layer (" + mTileLayer + ") we don't know how to get a bitmap from");
- }
-
- return b;
- } catch (OutOfMemoryError oom) {
- Log.w(LOGTAG, "Unable to create bitmap", oom);
- return null;
- }
- } finally {
- endTransaction(mTileLayer);
- }*/
-
- return null;
- }
-
- @Override
- public int getType() {
- return LAYER_CLIENT_TYPE_SOFTWARE;
- }
-
- @Override
- protected IntSize getBufferSize() {
- return new IntSize(
- ((mScreenSize.width + LayerController.MIN_BUFFER.width - 1) / TILE_SIZE.width + 1) * TILE_SIZE.width,
- ((mScreenSize.height + LayerController.MIN_BUFFER.height - 1) / TILE_SIZE.height + 1) * TILE_SIZE.height);
- }
-
- @Override
- protected IntSize getTileSize() {
- return TILE_SIZE;
- }
-
- public void addTile(Bitmap bitmap, int x, int y) {
- if (mTileLayer instanceof MultiTileLayer) {
- ((MultiTileLayer)mTileLayer).addTile(bitmap, x, y);
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java
deleted file mode 100644
index 6fef53fb0535..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.mozilla.gecko.gfx;
-
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.view.KeyEvent;
-
-public interface InputConnectionHandler
-{
- InputConnection onCreateInputConnection(EditorInfo outAttrs);
- boolean onKeyPreIme(int keyCode, KeyEvent event);
- boolean onKeyDown(int keyCode, KeyEvent event);
- boolean onKeyLongPress(int keyCode, KeyEvent event);
- boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event);
- boolean onKeyUp(int keyCode, KeyEvent event);
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java
deleted file mode 100644
index ee43b1bf557b..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.gfx.FloatSize;
-import org.json.JSONException;
-import org.json.JSONObject;
-import java.lang.Math;
-
-public class IntSize {
- public final int width, height;
-
- public IntSize(IntSize size) { width = size.width; height = size.height; }
- public IntSize(int inWidth, int inHeight) { width = inWidth; height = inHeight; }
-
- public IntSize(FloatSize size) {
- width = Math.round(size.width);
- height = Math.round(size.height);
- }
-
- public IntSize(JSONObject json) {
- try {
- width = json.getInt("width");
- height = json.getInt("height");
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
-
- public int getArea() {
- return width * height;
- }
-
- public boolean equals(IntSize size) {
- return ((size.width == width) && (size.height == height));
- }
-
- public boolean isPositive() {
- return (width > 0 && height > 0);
- }
-
- @Override
- public String toString() { return "(" + width + "," + height + ")"; }
-
- public IntSize scale(float factor) {
- return new IntSize(Math.round(width * factor),
- Math.round(height * factor));
- }
-
- /* Returns the power of two that is greater than or equal to value */
- public static int nextPowerOfTwo(int value) {
- // code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
- if (0 == value--) {
- return 1;
- }
- value = (value >> 1) | value;
- value = (value >> 2) | value;
- value = (value >> 4) | value;
- value = (value >> 8) | value;
- value = (value >> 16) | value;
- return value + 1;
- }
-
- public IntSize nextPowerOfTwo() {
- return new IntSize(nextPowerOfTwo(width), nextPowerOfTwo(height));
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java
deleted file mode 100644
index 40786532a303..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Point;
-import android.graphics.RectF;
-import android.graphics.Region;
-
-import org.mozilla.gecko.util.FloatUtils;
-
-import java.nio.FloatBuffer;
-import java.util.concurrent.locks.ReentrantLock;
-
-public abstract class Layer {
- private final ReentrantLock mTransactionLock;
- protected Point mOrigin;
- protected float mResolution;
- private boolean mInTransaction;
- private Point mNewOrigin;
- private float mNewResolution;
- private LayerView mView;
-
- public Layer() {
- mTransactionLock = new ReentrantLock();
- mOrigin = new Point(0, 0);
- mResolution = 1.0f;
- }
-
- /**
- * Updates the layer. This returns false if there is still work to be done
- * after this update.
- */
- public final boolean update(RenderContext context) {
- if (mTransactionLock.isHeldByCurrentThread()) {
- throw new RuntimeException("draw() called while transaction lock held by this " +
- "thread?!");
- }
-
- if (mTransactionLock.tryLock()) {
- try {
- return performUpdates(context);
- } finally {
- mTransactionLock.unlock();
- }
- }
-
- return false;
- }
-
- /**
- * Subclasses override this function to draw the layer.
- */
- public abstract void draw(RenderContext context);
-
- /**
- * Subclasses override this function to provide access to the size of the layer.
- */
- public abstract IntSize getSize();
-
- /**
- * Given the intrinsic size of the layer, returns the pixel boundaries of the layer rect.
- */
- protected RectF getBounds(RenderContext context, FloatSize size) {
- float scaleFactor = context.zoomFactor / mResolution;
- float x = mOrigin.x * scaleFactor, y = mOrigin.y * scaleFactor;
- float width = size.width * scaleFactor, height = size.height * scaleFactor;
- return new RectF(x, y, x + width, y + height);
- }
-
- /**
- * Returns the region of the layer that is considered valid. The default
- * implementation of this will return the bounds of the layer, but this
- * may be overridden.
- */
- public Region getValidRegion(RenderContext context) {
- return new Region(RectUtils.round(getBounds(context, new FloatSize(getSize()))));
- }
-
- /**
- * Call this before modifying the layer. Note that, for TileLayers, "modifying the layer"
- * includes altering the underlying CairoImage in any way. Thus you must call this function
- * before modifying the byte buffer associated with this layer.
- * <p/>
- * This function may block, so you should never call this on the main UI thread.
- */
- public void beginTransaction(LayerView aView) {
- //if (mTransactionLock.isHeldByCurrentThread())
- // throw new RuntimeException("Nested transactions are not supported");
- mTransactionLock.lock();
- mView = aView;
- mInTransaction = true;
- mNewResolution = mResolution;
- }
-
- public void beginTransaction() {
- beginTransaction(null);
- }
-
- /**
- * Call this when you're done modifying the layer.
- */
- public void endTransaction() {
- if (!mInTransaction)
- throw new RuntimeException("endTransaction() called outside a transaction");
- mInTransaction = false;
- mTransactionLock.unlock();
-
- if (mView != null)
- mView.requestRender();
- }
-
- /**
- * Returns true if the layer is currently in a transaction and false otherwise.
- */
- protected boolean inTransaction() {
- return mInTransaction;
- }
-
- /**
- * Returns the current layer origin.
- */
- public Point getOrigin() {
- return mOrigin;
- }
-
- /**
- * Sets the origin. Only valid inside a transaction.
- */
- public void setOrigin(Point newOrigin) {
- if (!mInTransaction)
- throw new RuntimeException("setOrigin() is only valid inside a transaction");
- mNewOrigin = newOrigin;
- }
-
- /**
- * Returns the current layer's resolution.
- */
- public float getResolution() {
- return mResolution;
- }
-
- /**
- * Sets the layer resolution. This value is used to determine how many pixels per
- * device pixel this layer was rendered at. This will be reflected by scaling by
- * the reciprocal of the resolution in the layer's transform() function.
- * Only valid inside a transaction.
- */
- public void setResolution(float newResolution) {
- if (!mInTransaction)
- throw new RuntimeException("setResolution() is only valid inside a transaction");
- mNewResolution = newResolution;
- }
-
- /**
- * Subclasses may override this method to perform custom layer updates. This will be called
- * with the transaction lock held. Subclass implementations of this method must call the
- * superclass implementation. Returns false if there is still work to be done after this
- * update is complete.
- */
- protected boolean performUpdates(RenderContext context) {
- if (mNewOrigin != null) {
- mOrigin = mNewOrigin;
- mNewOrigin = null;
- }
- if (mNewResolution != 0.0f) {
- mResolution = mNewResolution;
- mNewResolution = 0.0f;
- }
-
- return true;
- }
-
- protected boolean dimensionChangesPending() {
- return (mNewOrigin != null) || (mNewResolution != 0.0f);
- }
-
- public static class RenderContext {
- public final RectF viewport;
- public final FloatSize pageSize;
- public final float zoomFactor;
- public final int positionHandle;
- public final int textureHandle;
- public final FloatBuffer coordBuffer;
-
- public RenderContext(RectF aViewport, FloatSize aPageSize, float aZoomFactor,
- int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) {
- viewport = aViewport;
- pageSize = aPageSize;
- zoomFactor = aZoomFactor;
- positionHandle = aPositionHandle;
- textureHandle = aTextureHandle;
- coordBuffer = aCoordBuffer;
- }
-
- public boolean fuzzyEquals(RenderContext other) {
- if (other == null) {
- return false;
- }
- return RectUtils.fuzzyEquals(viewport, other.viewport)
- && pageSize.fuzzyEquals(other.pageSize)
- && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor);
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java
deleted file mode 100644
index 4f461088203e..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-/**
- * A layer client provides tiles and manages other information used by the layer controller.
- */
-public abstract class LayerClient {
- private LayerController mLayerController;
-
- public abstract void geometryChanged();
-
- public abstract void viewportSizeChanged();
-
- protected abstract void render();
-
- public LayerController getLayerController() {
- return mLayerController;
- }
-
- public void setLayerController(LayerController layerController) {
- mLayerController = layerController;
- }
-
- /**
- * A utility function for calling Layer.beginTransaction with the
- * appropriate LayerView.
- */
- public void beginTransaction(Layer aLayer) {
- if (mLayerController != null) {
- LayerView view = mLayerController.getView();
- if (view != null) {
- aLayer.beginTransaction(view);
- return;
- }
- }
-
- aLayer.beginTransaction();
- }
-
- // Included for symmetry.
- public void endTransaction(Layer aLayer) {
- aLayer.endTransaction();
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java
deleted file mode 100644
index 250dc84c69fe..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View.OnTouchListener;
-
-import org.mozilla.gecko.ui.PanZoomController;
-import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-/**
- * The layer controller manages a tile that represents the visible page. It does panning and
- * zooming natively by delegating to a panning/zooming controller. Touch events can be dispatched
- * to a higher-level view.
- * <p/>
- * Many methods require that the monitor be held, with a synchronized (controller) { ... } block.
- */
-public class LayerController {
- /* The extra area on the sides of the page that we want to buffer to help with
- * smooth, asynchronous scrolling. Depending on a device's support for NPOT
- * textures, this may be rounded up to the nearest power of two.
- */
- public static final IntSize MIN_BUFFER = new IntSize(512, 1024);
- private static final String LOGTAG = "GeckoLayerController";
- /* If the visible rect is within the danger zone (measured in pixels from each edge of a tile),
- * we start aggressively redrawing to minimize checkerboarding. */
- private static final int DANGER_ZONE_X = 75;
- private static final int DANGER_ZONE_Y = 150;
- /* The time limit for pages to respond with preventDefault on touchevents
- * before we begin panning the page */
- private static final int PREVENT_DEFAULT_TIMEOUT = 200;
- private Layer mRootLayer; /* The root layer. */
- private LayerView mView; /* The main rendering view. */
- /*
- * The panning and zooming controller, which interprets pan and zoom gestures for us and
- * updates our visible rect appropriately.
- */
- private Context mContext; /* The current context. */
- private ViewportMetrics mViewportMetrics; /* The current viewport metrics. */
- private boolean mWaitForTouchListeners;
- private PanZoomController mPanZoomController;
- private OnTouchListener mOnTouchListener; /* The touch listener. */
- private LayerClient mLayerClient; /* The layer client. */
- /* The new color for the checkerboard. */
- private int mCheckerboardColor;
- private boolean mCheckerboardShouldShowChecks;
- private boolean mForceRedraw;
- private boolean allowDefaultActions = true;
- private Timer allowDefaultTimer = null;
- private boolean inTouchSession = false;
- private PointF initialTouchLocation = null;
-
- public LayerController(Context context) {
- mContext = context;
-
- mForceRedraw = true;
- mViewportMetrics = new ViewportMetrics();
- mPanZoomController = new PanZoomController(this);
- mView = new LayerView(context, this);
- }
-
- public void setForceRedraw() {
- mForceRedraw = true;
- }
-
- public LayerClient getLayerClient() {
- return mLayerClient;
- }
-
- public void setLayerClient(LayerClient layerClient) {
- mLayerClient = layerClient;
- layerClient.setLayerController(this);
- }
-
- public Layer getRoot() {
- return mRootLayer;
- }
-
- public void setRoot(Layer layer) {
- mRootLayer = layer;
- }
-
- public LayerView getView() {
- return mView;
- }
-
- public Context getContext() {
- return mContext;
- }
-
- public ViewportMetrics getViewportMetrics() {
- return mViewportMetrics;
- }
-
- /**
- * Sets the entire viewport metrics at once. This function does not notify the layer client or
- * the pan/zoom controller, so you will need to call notifyLayerClientOfGeometryChange() or
- * notifyPanZoomControllerOfGeometryChange() after calling this. You must hold the monitor
- * while calling this.
- */
- public void setViewportMetrics(ViewportMetrics viewport) {
- mViewportMetrics = new ViewportMetrics(viewport);
- Log.d(LOGTAG, "setViewportMetrics: " + mViewportMetrics);
- // this function may or may not be called on the UI thread,
- // but repositionPluginViews must only be called on the UI thread.
- //GeckoApp.mAppContext.runOnUiThread(new Runnable() {
- // public void run() {
- // GeckoApp.mAppContext.repositionPluginViews(false);
- // }
- //});
- mView.requestRender();
- }
-
- public RectF getViewport() {
- return mViewportMetrics.getViewport();
- }
-
- public FloatSize getViewportSize() {
- return mViewportMetrics.getSize();
- }
-
- /**
- * The view calls this function to indicate that the viewport changed size. It must hold the
- * monitor while calling it.
- * <p/>
- * TODO: Refactor this to use an interface. Expose that interface only to the view and not
- * to the layer client. That way, the layer client won't be tempted to call this, which might
- * result in an infinite loop.
- */
- public void setViewportSize(FloatSize size) {
- // Resize the viewport, and modify its zoom factor so that the page retains proportionally
- // zoomed relative to the screen.
- float oldHeight = mViewportMetrics.getSize().height;
- float oldWidth = mViewportMetrics.getSize().width;
- float oldZoomFactor = mViewportMetrics.getZoomFactor();
- mViewportMetrics.setSize(size);
-
- // if the viewport got larger (presumably because the vkb went away), and the page
- // is smaller than the new viewport size, increase the page size so that the panzoomcontroller
- // doesn't zoom in to make it fit (bug 718270). this page size change is in anticipation of
- // gecko increasing the page size to match the new viewport size, which will happen the next
- // time we get a draw update.
- if (size.width >= oldWidth && size.height >= oldHeight) {
- FloatSize pageSize = mViewportMetrics.getPageSize();
- if (pageSize.width < size.width || pageSize.height < size.height) {
- mViewportMetrics.setPageSize(new FloatSize(Math.max(pageSize.width, size.width),
- Math.max(pageSize.height, size.height)));
- }
- }
-
- PointF newFocus = new PointF(size.width / 2.0f, size.height / 2.0f);
- float newZoomFactor = size.width * oldZoomFactor / oldWidth;
- mViewportMetrics.scaleTo(newZoomFactor, newFocus);
-
- Log.d(LOGTAG, "setViewportSize: " + mViewportMetrics);
- setForceRedraw();
-
- if (mLayerClient != null)
- mLayerClient.viewportSizeChanged();
-
- notifyLayerClientOfGeometryChange();
- mPanZoomController.abortAnimation();
- mView.requestRender();
- }
-
- public FloatSize getPageSize() {
- return mViewportMetrics.getPageSize();
- }
-
- /**
- * Sets the current page size. You must hold the monitor while calling this.
- */
- public void setPageSize(FloatSize size) {
- if (mViewportMetrics.getPageSize().fuzzyEquals(size))
- return;
-
- mViewportMetrics.setPageSize(size);
- Log.d(LOGTAG, "setPageSize: " + mViewportMetrics);
-
- // Page size is owned by the LayerClient, so no need to notify it of
- // this change.
-
- mView.post(new Runnable() {
- public void run() {
- mPanZoomController.pageSizeUpdated();
- mView.requestRender();
- }
- });
- }
-
- public PointF getOrigin() {
- return mViewportMetrics.getOrigin();
- }
-
- public float getZoomFactor() {
- return mViewportMetrics.getZoomFactor();
- }
-
- public Bitmap getBackgroundPattern() {
- return getDrawable("background");
- }
-
- public Bitmap getShadowPattern() {
- return getDrawable("shadow");
- }
-
- public PanZoomController getPanZoomController() {
- return mPanZoomController;
- }
-
- public GestureDetector.OnGestureListener getGestureListener() {
- return mPanZoomController;
- }
-
- public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() {
- return mPanZoomController;
- }
-
- public GestureDetector.OnDoubleTapListener getDoubleTapListener() {
- return mPanZoomController;
- }
-
- public Bitmap getDrawable(String name) {
- Resources resources = mContext.getResources();
- int resourceID = resources.getIdentifier(name, "drawable", mContext.getPackageName());
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- return BitmapFactory.decodeResource(mContext.getResources(), resourceID, options);
- }
-
- public Bitmap getDrawable16(String name) {
- Resources resources = mContext.getResources();
- int resourceID = resources.getIdentifier(name, "drawable", mContext.getPackageName());
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- options.inPreferredConfig = Bitmap.Config.RGB_565;
- return BitmapFactory.decodeResource(mContext.getResources(), resourceID, options);
- }
-
- /**
- * Scrolls the viewport by the given offset. You must hold the monitor while calling this.
- */
- public void scrollBy(PointF point) {
- PointF origin = mViewportMetrics.getOrigin();
- origin.offset(point.x, point.y);
- mViewportMetrics.setOrigin(origin);
- Log.d(LOGTAG, "scrollBy: " + mViewportMetrics);
-
- notifyLayerClientOfGeometryChange();
- //GeckoApp.mAppContext.repositionPluginViews(false);
- mView.requestRender();
- }
-
- /**
- * Scales the viewport, keeping the given focus point in the same place before and after the
- * scale operation. You must hold the monitor while calling this.
- */
- public void scaleWithFocus(float zoomFactor, PointF focus) {
- mViewportMetrics.scaleTo(zoomFactor, focus);
- Log.d(LOGTAG, "scaleWithFocus: " + mViewportMetrics + "; zf=" + zoomFactor);
-
- // We assume the zoom level will only be modified by the
- // PanZoomController, so no need to notify it of this change.
- notifyLayerClientOfGeometryChange();
- //GeckoApp.mAppContext.repositionPluginViews(false);
- mView.requestRender();
- }
-
- public boolean post(Runnable action) {
- return mView.post(action);
- }
-
- public void setOnTouchListener(OnTouchListener onTouchListener) {
- mOnTouchListener = onTouchListener;
- }
-
- /**
- * The view as well as the controller itself use this method to notify the layer client that
- * the geometry changed.
- */
- public void notifyLayerClientOfGeometryChange() {
- if (mLayerClient != null)
- mLayerClient.geometryChanged();
- }
-
- /**
- * Aborts any pan/zoom animation that is currently in progress.
- */
- public void abortPanZoomAnimation() {
- if (mPanZoomController != null) {
- mView.post(new Runnable() {
- public void run() {
- mPanZoomController.abortAnimation();
- }
- });
- }
- }
-
- /**
- * Returns true if this controller is fine with performing a redraw operation or false if it
- * would prefer that the action didn't take place.
- */
- public boolean getRedrawHint() {
- // FIXME: Allow redraw while a finger is down, but only if we're about to checkerboard.
- // This requires fixing aboutToCheckerboard() to know about the new buffer size.
-
- if (mForceRedraw) {
- mForceRedraw = false;
- return true;
- }
-
- return mPanZoomController.getRedrawHint();
- }
-
- private RectF getTileRect() {
- if (mRootLayer == null)
- return new RectF();
-
- float x = mRootLayer.getOrigin().x, y = mRootLayer.getOrigin().y;
- IntSize layerSize = mRootLayer.getSize();
- return new RectF(x, y, x + layerSize.width, y + layerSize.height);
- }
-
- // Returns true if a checkerboard is about to be visible.
- private boolean aboutToCheckerboard() {
- // Increase the size of the viewport (and clamp to page boundaries), and
- // intersect it with the tile's displayport to determine whether we're
- // close to checkerboarding.
- FloatSize pageSize = getPageSize();
- RectF adjustedViewport = RectUtils.expand(getViewport(), DANGER_ZONE_X, DANGER_ZONE_Y);
- if (adjustedViewport.top < 0) adjustedViewport.top = 0;
- if (adjustedViewport.left < 0) adjustedViewport.left = 0;
- if (adjustedViewport.right > pageSize.width) adjustedViewport.right = pageSize.width;
- if (adjustedViewport.bottom > pageSize.height) adjustedViewport.bottom = pageSize.height;
-
- return !getTileRect().contains(adjustedViewport);
- }
-
- /**
- * Converts a point from layer view coordinates to layer coordinates. In other words, given a
- * point measured in pixels from the top left corner of the layer view, returns the point in
- * pixels measured from the top left corner of the root layer, in the coordinate system of the
- * layer itself. This method is used by the viewport controller as part of the process of
- * translating touch events to Gecko's coordinate system.
- */
- public PointF convertViewPointToLayerPoint(PointF viewPoint) {
- if (mRootLayer == null)
- return null;
-
- // Undo the transforms.
- PointF origin = mViewportMetrics.getOrigin();
- PointF newPoint = new PointF(origin.x, origin.y);
- newPoint.offset(viewPoint.x, viewPoint.y);
-
- Point rootOrigin = mRootLayer.getOrigin();
- newPoint.offset(-rootOrigin.x, -rootOrigin.y);
-
- return newPoint;
- }
-
- /*
- * Gesture detection. This is handled only at a high level in this class; we dispatch to the
- * pan/zoom controller to do the dirty work.
- */
- public boolean onTouchEvent(MotionEvent event) {
- int action = event.getAction();
- PointF point = new PointF(event.getX(), event.getY());
-
- if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
- mView.clearEventQueue();
- initialTouchLocation = point;
- allowDefaultActions = !mWaitForTouchListeners;
- post(new Runnable() {
- public void run() {
- preventPanning(mWaitForTouchListeners);
- }
- });
- }
-
- // After the initial touch, ignore touch moves until they exceed a minimum distance.
- if (initialTouchLocation != null && (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE) {
- if (PointUtils.subtract(point, initialTouchLocation).length() > PanZoomController.PAN_THRESHOLD) {
- initialTouchLocation = null;
- } else {
- return !allowDefaultActions;
- }
- }
-
- if (mOnTouchListener != null)
- mOnTouchListener.onTouch(mView, event);
-
- if (!mWaitForTouchListeners)
- return !allowDefaultActions;
-
- boolean createTimer = false;
- switch (action & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_MOVE: {
- if (!inTouchSession && allowDefaultTimer == null) {
- inTouchSession = true;
- createTimer = true;
- }
- break;
- }
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP: {
- // if we still have initialTouchLocation, we haven't fired any
- // touchmove events. We should start the timer to wait for preventDefault
- // from touchstart. If we don't hear from it we fire mouse events
- if (initialTouchLocation != null)
- createTimer = true;
- inTouchSession = false;
- }
- }
-
- if (createTimer) {
- if (allowDefaultTimer != null) {
- allowDefaultTimer.cancel();
- }
- allowDefaultTimer = new Timer();
- allowDefaultTimer.schedule(new TimerTask() {
- public void run() {
- post(new Runnable() {
- public void run() {
- preventPanning(false);
- }
- });
- }
- }, PREVENT_DEFAULT_TIMEOUT);
- }
-
- return !allowDefaultActions;
- }
-
- public void preventPanning(boolean aValue) {
- if (allowDefaultTimer != null) {
- allowDefaultTimer.cancel();
- allowDefaultTimer.purge();
- allowDefaultTimer = null;
- }
- if (aValue == allowDefaultActions) {
- allowDefaultActions = !aValue;
-
- if (aValue) {
- mView.clearEventQueue();
- mPanZoomController.cancelTouch();
- } else {
- mView.processEventQueue();
- }
- }
- }
-
- public void setWaitForTouchListeners(boolean aValue) {
- mWaitForTouchListeners = aValue;
- }
-
- /**
- * Retrieves whether we should show checkerboard checks or not.
- */
- public boolean checkerboardShouldShowChecks() {
- return mCheckerboardShouldShowChecks;
- }
-
- /**
- * Retrieves the color that the checkerboard should be.
- */
- public int getCheckerboardColor() {
- return mCheckerboardColor;
- }
-
- /**
- * Sets a new color for the checkerboard.
- */
- public void setCheckerboardColor(int newColor) {
- mCheckerboardColor = newColor;
- mView.requestRender();
- }
-
- /**
- * Sets whether or not the checkerboard should show checkmarks.
- */
- public void setCheckerboardShowChecks(boolean showChecks) {
- mCheckerboardShouldShowChecks = showChecks;
- mView.requestRender();
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java
deleted file mode 100644
index 6690aad8ec16..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java
+++ /dev/null
@@ -1,689 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.gfx.BufferedCairoImage;
-import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.Layer.RenderContext;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.NinePatchTileLayer;
-import org.mozilla.gecko.gfx.SingleTileLayer;
-import org.mozilla.gecko.gfx.TextureReaper;
-import org.mozilla.gecko.gfx.TextureGenerator;
-import org.mozilla.gecko.gfx.TextLayer;
-import org.mozilla.gecko.gfx.TileLayer;
-//import org.mozilla.gecko.GeckoAppShell;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.RegionIterator;
-import android.opengl.GLES20;
-import android.opengl.GLSurfaceView;
-import android.os.SystemClock;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.WindowManager;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.util.ArrayList;
-
-/**
- * The layer renderer implements the rendering logic for a layer view.
- */
-public class LayerRenderer implements GLSurfaceView.Renderer {
- private static final String LOGTAG = "GeckoLayerRenderer";
- private static final String PROFTAG = "GeckoLayerRendererProf";
-
- /*
- * The amount of time a frame is allowed to take to render before we declare it a dropped
- * frame.
- */
- private static final int MAX_FRAME_TIME = 16; /* 1000 ms / 60 FPS */
-
- private static final int FRAME_RATE_METER_WIDTH = 64;
- private static final int FRAME_RATE_METER_HEIGHT = 32;
-
- private final LayerView mView;
- private final SingleTileLayer mBackgroundLayer;
- private final CheckerboardImage mCheckerboardImage;
- private final SingleTileLayer mCheckerboardLayer;
- private final NinePatchTileLayer mShadowLayer;
- private final TextLayer mFrameRateLayer;
- private final ScrollbarLayer mHorizScrollLayer;
- private final ScrollbarLayer mVertScrollLayer;
- private final FadeRunnable mFadeRunnable;
- private final FloatBuffer mCoordBuffer;
- private RenderContext mLastPageContext;
- private int mMaxTextureSize;
-
- private ArrayList<Layer> mExtraLayers = new ArrayList<Layer>();
-
- // Dropped frames display
- private int[] mFrameTimings;
- private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames;
- private boolean mShowFrameRate;
-
- // Render profiling output
- private int mFramesRendered;
- private float mCompleteFramesRendered;
- private boolean mProfileRender;
- private long mProfileOutputTime;
-
- /* Used by robocop for testing purposes */
- private IntBuffer mPixelBuffer;
-
- // Used by GLES 2.0
- private int mProgram;
- private int mPositionHandle;
- private int mTextureHandle;
- private int mSampleHandle;
- private int mTMatrixHandle;
-
- // column-major matrix applied to each vertex to shift the viewport from
- // one ranging from (-1, -1),(1,1) to (0,0),(1,1) and to scale all sizes by
- // a factor of 2 to fill up the screen
- private static final float[] TEXTURE_MATRIX = {
- 2.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 2.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 2.0f, 0.0f,
- -1.0f, -1.0f, 0.0f, 1.0f
- };
-
- private static final int COORD_BUFFER_SIZE = 20;
-
- // The shaders run on the GPU directly, the vertex shader is only applying the
- // matrix transform detailed above
- private static final String VERTEX_SHADER =
- "uniform mat4 uTMatrix;\n" +
- "attribute vec4 vPosition;\n" +
- "attribute vec2 aTexCoord;\n" +
- "varying vec2 vTexCoord;\n" +
- "void main() {\n" +
- " gl_Position = uTMatrix * vPosition;\n" +
- " vTexCoord = aTexCoord;\n" +
- "}\n";
-
- // Note we flip the y-coordinate in the fragment shader from a
- // coordinate system with (0,0) in the top left to one with (0,0) in
- // the bottom left.
- private static final String FRAGMENT_SHADER =
- "precision mediump float;\n" +
- "varying vec2 vTexCoord;\n" +
- "uniform sampler2D sTexture;\n" +
- "void main() {\n" +
- " gl_FragColor = texture2D(sTexture, vec2(vTexCoord.x, 1.0 - vTexCoord.y));\n" +
- "}\n";
-
- public LayerRenderer(LayerView view) {
- mView = view;
-
- LayerController controller = view.getController();
-
- CairoImage backgroundImage = new BufferedCairoImage(controller.getBackgroundPattern());
- mBackgroundLayer = new SingleTileLayer(true, backgroundImage);
-
- mCheckerboardImage = new CheckerboardImage();
- mCheckerboardLayer = new SingleTileLayer(true, mCheckerboardImage);
-
- CairoImage shadowImage = new BufferedCairoImage(controller.getShadowPattern());
- mShadowLayer = new NinePatchTileLayer(shadowImage);
-
- IntSize frameRateLayerSize = new IntSize(FRAME_RATE_METER_WIDTH, FRAME_RATE_METER_HEIGHT);
- mFrameRateLayer = TextLayer.create(frameRateLayerSize, "-- ms/--");
-
- mHorizScrollLayer = ScrollbarLayer.create(false);
- mVertScrollLayer = ScrollbarLayer.create(true);
- mFadeRunnable = new FadeRunnable();
-
- mFrameTimings = new int[60];
- mCurrentFrame = mFrameTimingsSum = mDroppedFrames = 0;
- mShowFrameRate = false;
-
- // Initialize the FloatBuffer that will be used to store all vertices and texture
- // coordinates in draw() commands.
- ByteBuffer byteBuffer = LOKitShell.allocateDirectBuffer(COORD_BUFFER_SIZE * 4);
- byteBuffer.order(ByteOrder.nativeOrder());
- mCoordBuffer = byteBuffer.asFloatBuffer();
- }
-
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- checkMonitoringEnabled();
- createProgram();
- activateProgram();
- }
-
- public void createProgram() {
- int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER);
- int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
-
- mProgram = GLES20.glCreateProgram();
- GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
- GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
- GLES20.glLinkProgram(mProgram); // creates OpenGL program executables
-
- // Get handles to the vertex shader's vPosition, aTexCoord, sTexture, and uTMatrix members.
- mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
- mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord");
- mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
- mTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uTMatrix");
-
- int maxTextureSizeResult[] = new int[1];
- GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0);
- mMaxTextureSize = maxTextureSizeResult[0];
- }
-
- // Activates the shader program.
- public void activateProgram() {
- // Add the program to the OpenGL environment
- GLES20.glUseProgram(mProgram);
-
- // Set the transformation matrix
- GLES20.glUniformMatrix4fv(mTMatrixHandle, 1, false, TEXTURE_MATRIX, 0);
-
- Log.e(LOGTAG, "### Position handle is " + mPositionHandle + ", texture handle is " +
- mTextureHandle + ", last error is " + GLES20.glGetError());
-
- // Enable the arrays from which we get the vertex and texture coordinates
- GLES20.glEnableVertexAttribArray(mPositionHandle);
- GLES20.glEnableVertexAttribArray(mTextureHandle);
-
- GLES20.glUniform1i(mSampleHandle, 0);
-
- TextureGenerator.get().fill();
-
- // TODO: Move these calls into a separate deactivate() call that is called after the
- // underlay and overlay are rendered.
- }
-
- // Deactivates the shader program. This must be done to avoid crashes after returning to the
- // Gecko C++ compositor from Java.
- public void deactivateProgram() {
- GLES20.glDisableVertexAttribArray(mTextureHandle);
- GLES20.glDisableVertexAttribArray(mPositionHandle);
- GLES20.glUseProgram(0);
- }
-
- public int getMaxTextureSize() {
- return mMaxTextureSize;
- }
-
- public void addLayer(Layer layer) {
- LayerController controller = mView.getController();
-
- synchronized (controller) {
- if (mExtraLayers.contains(layer)) {
- mExtraLayers.remove(layer);
- }
-
- mExtraLayers.add(layer);
- }
- }
-
- public void removeLayer(Layer layer) {
- LayerController controller = mView.getController();
-
- synchronized (controller) {
- mExtraLayers.remove(layer);
- }
- }
-
- /**
- * Called whenever a new frame is about to be drawn.
- */
- public void onDrawFrame(GL10 gl) {
- RenderContext pageContext = createPageContext(), screenContext = createScreenContext();
- Frame frame = createFrame(pageContext, screenContext);
- synchronized (mView.getController()) {
- frame.beginDrawing();
- frame.drawBackground();
- frame.drawRootLayer();
- frame.drawForeground();
- frame.endDrawing();
- }
- }
-
- private void printCheckerboardStats() {
- Log.d(PROFTAG, "Frames rendered over last 1000ms: " + mCompleteFramesRendered + "/" + mFramesRendered);
- mFramesRendered = 0;
- mCompleteFramesRendered = 0;
- }
-
- /** Used by robocop for testing purposes. Not for production use! */
- IntBuffer getPixels() {
- IntBuffer pixelBuffer = IntBuffer.allocate(mView.getWidth() * mView.getHeight());
- synchronized (pixelBuffer) {
- mPixelBuffer = pixelBuffer;
- mView.requestRender();
- try {
- pixelBuffer.wait();
- } catch (InterruptedException ie) {
- }
- mPixelBuffer = null;
- }
- return pixelBuffer;
- }
-
- public RenderContext createScreenContext() {
- LayerController layerController = mView.getController();
- IntSize viewportSize = new IntSize(layerController.getViewportSize());
- RectF viewport = new RectF(0.0f, 0.0f, viewportSize.width, viewportSize.height);
- FloatSize pageSize = new FloatSize(layerController.getPageSize());
- return createContext(viewport, pageSize, 1.0f);
- }
-
- public RenderContext createPageContext() {
- LayerController layerController = mView.getController();
-
- Rect viewport = new Rect();
- layerController.getViewport().round(viewport);
-
- FloatSize pageSize = new FloatSize(layerController.getPageSize());
- float zoomFactor = layerController.getZoomFactor();
- return createContext(new RectF(viewport), pageSize, zoomFactor);
- }
-
- private RenderContext createContext(RectF viewport, FloatSize pageSize, float zoomFactor) {
- return new RenderContext(viewport, pageSize, zoomFactor, mPositionHandle, mTextureHandle,
- mCoordBuffer);
- }
-
- private Rect getPageRect() {
- LayerController controller = mView.getController();
-
- Point origin = PointUtils.round(controller.getOrigin());
- IntSize pageSize = new IntSize(controller.getPageSize());
-
- origin.negate();
-
- return new Rect(origin.x, origin.y,
- origin.x + pageSize.width, origin.y + pageSize.height);
- }
-
- private Rect transformToScissorRect(Rect rect) {
- LayerController controller = mView.getController();
- IntSize screenSize = new IntSize(controller.getViewportSize());
-
- int left = Math.max(0, rect.left);
- int top = Math.max(0, rect.top);
- int right = Math.min(screenSize.width, rect.right);
- int bottom = Math.min(screenSize.height, rect.bottom);
-
- return new Rect(left, screenSize.height - bottom, right,
- (screenSize.height - bottom) + (bottom - top));
- }
-
- public void onSurfaceChanged(GL10 gl, final int width, final int height) {
- GLES20.glViewport(0, 0, width, height);
-
- // updating the state in the view/controller/client should be
- // done on the main UI thread, not the GL renderer thread
- mView.post(new Runnable() {
- public void run() {
- mView.setViewportSize(new IntSize(width, height));
- moveFrameRateLayer(width, height);
- }
- });
-
- /* TODO: Throw away tile images? */
- }
-
- private void updateDroppedFrames(long frameStartTime) {
- int frameElapsedTime = (int)(SystemClock.uptimeMillis() - frameStartTime);
-
- /* Update the running statistics. */
- mFrameTimingsSum -= mFrameTimings[mCurrentFrame];
- mFrameTimingsSum += frameElapsedTime;
- mDroppedFrames -= (mFrameTimings[mCurrentFrame] + 1) / MAX_FRAME_TIME;
- mDroppedFrames += (frameElapsedTime + 1) / MAX_FRAME_TIME;
-
- mFrameTimings[mCurrentFrame] = frameElapsedTime;
- mCurrentFrame = (mCurrentFrame + 1) % mFrameTimings.length;
-
- int averageTime = mFrameTimingsSum / mFrameTimings.length;
- mFrameRateLayer.beginTransaction();
- try {
- mFrameRateLayer.setText(averageTime + " ms/" + mDroppedFrames);
- } finally {
- mFrameRateLayer.endTransaction();
- }
- }
-
- /* Given the new dimensions for the surface, moves the frame rate layer appropriately. */
- private void moveFrameRateLayer(int width, int height) {
- mFrameRateLayer.beginTransaction();
- try {
- Point origin = new Point(width - FRAME_RATE_METER_WIDTH - 8,
- height - FRAME_RATE_METER_HEIGHT + 8);
- mFrameRateLayer.setOrigin(origin);
- } finally {
- mFrameRateLayer.endTransaction();
- }
- }
-
- private void checkMonitoringEnabled() {
- /* Do this I/O off the main thread to minimize its impact on startup time. */
- new Thread(new Runnable() {
- @Override
- public void run() {
- Context context = mView.getContext();
- SharedPreferences preferences = context.getSharedPreferences("GeckoApp", 0);
- mShowFrameRate = preferences.getBoolean("showFrameRate", false);
- mProfileRender = Log.isLoggable(PROFTAG, Log.DEBUG);
- }
- }).start();
- }
-
- private void updateCheckerboardLayer(RenderContext renderContext) {
- int checkerboardColor = mView.getController().getCheckerboardColor();
- boolean showChecks = mView.getController().checkerboardShouldShowChecks();
- if (checkerboardColor == mCheckerboardImage.getColor() &&
- showChecks == mCheckerboardImage.getShowChecks()) {
- return;
- }
-
- mCheckerboardLayer.beginTransaction();
- try {
- mCheckerboardImage.update(showChecks, checkerboardColor);
- mCheckerboardLayer.invalidate();
- } finally {
- mCheckerboardLayer.endTransaction();
- }
-
- mCheckerboardLayer.update(renderContext);
- }
-
- /*
- * create a vertex shader type (GLES20.GL_VERTEX_SHADER)
- * or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
- */
- private int loadShader(int type, String shaderCode) {
- int shader = GLES20.glCreateShader(type);
- GLES20.glShaderSource(shader, shaderCode);
- GLES20.glCompileShader(shader);
- return shader;
- }
-
- public Frame createFrame(RenderContext pageContext, RenderContext screenContext) {
- return new Frame(pageContext, screenContext);
- }
-
- class FadeRunnable implements Runnable {
- private boolean mStarted;
- private long mRunAt;
-
- void scheduleStartFade(long delay) {
- mRunAt = SystemClock.elapsedRealtime() + delay;
- if (!mStarted) {
- mView.postDelayed(this, delay);
- mStarted = true;
- }
- }
-
- void scheduleNextFadeFrame() {
- if (mStarted) {
- Log.e(LOGTAG, "scheduleNextFadeFrame() called while scheduled for starting fade");
- }
- mView.postDelayed(this, 1000L / 60L); // request another frame at 60fps
- }
-
- boolean timeToFade() {
- return !mStarted;
- }
-
- public void run() {
- long timeDelta = mRunAt - SystemClock.elapsedRealtime();
- if (timeDelta > 0) {
- // the run-at time was pushed back, so reschedule
- mView.postDelayed(this, timeDelta);
- } else {
- // reached the run-at time, execute
- mStarted = false;
- mView.requestRender();
- }
- }
- }
-
- public class Frame {
- // The timestamp recording the start of this frame.
- private long mFrameStartTime;
- // A rendering context for page-positioned layers, and one for screen-positioned layers.
- private RenderContext mPageContext, mScreenContext;
- // Whether a layer was updated.
- private boolean mUpdated;
-
- public Frame(RenderContext pageContext, RenderContext screenContext) {
- mPageContext = pageContext;
- mScreenContext = screenContext;
- }
-
- private void setScissorRect() {
- Rect scissorRect = transformToScissorRect(getPageRect());
- GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
- GLES20.glScissor(scissorRect.left, scissorRect.top,
- scissorRect.width(), scissorRect.height());
- }
-
- public void beginDrawing() {
- mFrameStartTime = SystemClock.uptimeMillis();
-
- TextureReaper.get().reap();
- TextureGenerator.get().fill();
-
- mUpdated = true;
-
- LayerController controller = mView.getController();
- Layer rootLayer = controller.getRoot();
-
- if (!mPageContext.fuzzyEquals(mLastPageContext)) {
- // the viewport or page changed, so show the scrollbars again
- // as per UX decision
- mVertScrollLayer.unfade();
- mHorizScrollLayer.unfade();
- mFadeRunnable.scheduleStartFade(ScrollbarLayer.FADE_DELAY);
- } else if (mFadeRunnable.timeToFade()) {
- boolean stillFading = mVertScrollLayer.fade() | mHorizScrollLayer.fade();
- if (stillFading) {
- mFadeRunnable.scheduleNextFadeFrame();
- }
- }
- mLastPageContext = mPageContext;
-
- /* Update layers. */
- if (rootLayer != null) mUpdated &= rootLayer.update(mPageContext);
- mUpdated &= mBackgroundLayer.update(mScreenContext);
- mUpdated &= mShadowLayer.update(mPageContext);
- updateCheckerboardLayer(mScreenContext);
- mUpdated &= mFrameRateLayer.update(mScreenContext);
- mUpdated &= mVertScrollLayer.update(mPageContext);
- mUpdated &= mHorizScrollLayer.update(mPageContext);
-
- for (Layer layer : mExtraLayers)
- mUpdated &= layer.update(mPageContext);
-
- GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
-
- // If a layer update requires further work, schedule another redraw
- if (!mUpdated)
- mView.requestRender();
-
- PanningPerfAPI.recordFrameTime();
-
- /* Used by robocop for testing purposes */
- IntBuffer pixelBuffer = mPixelBuffer;
- if (mUpdated && pixelBuffer != null) {
- synchronized (pixelBuffer) {
- pixelBuffer.position(0);
- GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(),
- (int)mScreenContext.viewport.height(), GLES20.GL_RGBA,
- GLES20.GL_UNSIGNED_BYTE, pixelBuffer);
- pixelBuffer.notify();
- }
- }
- }
-
- public void drawBackground() {
- /* Draw the background. */
- mBackgroundLayer.draw(mScreenContext);
-
- /* Draw the drop shadow, if we need to. */
- Rect pageRect = getPageRect();
- RectF untransformedPageRect = new RectF(0.0f, 0.0f, pageRect.width(),
- pageRect.height());
- if (!untransformedPageRect.contains(mView.getController().getViewport()))
- mShadowLayer.draw(mPageContext);
-
- /* Draw the checkerboard. */
- setScissorRect();
- mCheckerboardLayer.draw(mScreenContext);
- GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
- }
-
- // Draws the layer the client added to us.
- void drawRootLayer() {
- Layer rootLayer = mView.getController().getRoot();
- if (rootLayer == null) {
- return;
- }
-
- setScissorRect();
- rootLayer.draw(mPageContext);
- GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
- }
-
- public void drawForeground() {
- Rect pageRect = getPageRect();
- LayerController controller = mView.getController();
-
- /* Draw any extra layers that were added (likely plugins) */
- for (Layer layer : mExtraLayers)
- layer.draw(mPageContext);
-
- /* Draw the vertical scrollbar. */
- IntSize screenSize = new IntSize(controller.getViewportSize());
- if (pageRect.height() > screenSize.height)
- mVertScrollLayer.draw(mPageContext);
-
- /* Draw the horizontal scrollbar. */
- if (pageRect.width() > screenSize.width)
- mHorizScrollLayer.draw(mPageContext);
-
- /* Measure how much of the screen is checkerboarding */
- Layer rootLayer = controller.getRoot();
- if ((rootLayer != null) &&
- (mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) {
- // Find out how much of the viewport area is valid
- Rect viewport = RectUtils.round(mPageContext.viewport);
- Region validRegion = rootLayer.getValidRegion(mPageContext);
- validRegion.op(viewport, Region.Op.INTERSECT);
-
- float checkerboard = 0.0f;
- if (!(validRegion.isRect() && validRegion.getBounds().equals(viewport))) {
- int screenArea = viewport.width() * viewport.height();
- validRegion.op(viewport, Region.Op.REVERSE_DIFFERENCE);
-
- // XXX The assumption here is that a Region never has overlapping
- // rects. This is true, as evidenced by reading the SkRegion
- // source, but is not mentioned in the Android documentation,
- // and so is liable to change.
- // If it does change, this code will need to be reevaluated.
- Rect r = new Rect();
- int checkerboardArea = 0;
- for (RegionIterator i = new RegionIterator(validRegion); i.next(r);) {
- checkerboardArea += r.width() * r.height();
- }
-
- checkerboard = checkerboardArea / (float)screenArea;
- }
-
- PanningPerfAPI.recordCheckerboard(checkerboard);
-
- mCompleteFramesRendered += 1.0f - checkerboard;
- mFramesRendered ++;
-
- if (mFrameStartTime - mProfileOutputTime > 1000) {
- mProfileOutputTime = mFrameStartTime;
- printCheckerboardStats();
- }
- }
-
- /* Draw the FPS. */
- if (mShowFrameRate) {
- updateDroppedFrames(mFrameStartTime);
-
- try {
- GLES20.glEnable(GLES20.GL_BLEND);
- GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
- mFrameRateLayer.draw(mScreenContext);
- } finally {
- GLES20.glDisable(GLES20.GL_BLEND);
- }
- }
- }
-
- public void endDrawing() {
- // If a layer update requires further work, schedule another redraw
- if (!mUpdated)
- mView.requestRender();
-
- PanningPerfAPI.recordFrameTime();
-
- /* Used by robocop for testing purposes */
- IntBuffer pixelBuffer = mPixelBuffer;
- if (mUpdated && pixelBuffer != null) {
- synchronized (pixelBuffer) {
- pixelBuffer.position(0);
- GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(),
- (int)mScreenContext.viewport.height(), GLES20.GL_RGBA,
- GLES20.GL_UNSIGNED_BYTE, pixelBuffer);
- pixelBuffer.notify();
- }
- }
- }
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java
deleted file mode 100644
index a3c04fa600f2..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoInputConnection;
-import org.mozilla.gecko.gfx.FloatSize;
-import org.mozilla.gecko.gfx.InputConnectionHandler;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
-import android.content.Context;
-import android.opengl.GLSurfaceView;
-import android.view.View;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.view.ScaleGestureDetector;
-import android.widget.RelativeLayout;
-import android.util.Log;
-import java.nio.IntBuffer;
-import java.util.LinkedList;
-
-/**
- * A view rendered by the layer compositor.
- *
- * This view delegates to LayerRenderer to actually do the drawing. Its role is largely that of a
- * mediator between the LayerRenderer and the LayerController.
- */
-public class LayerView extends FlexibleGLSurfaceView {
- private Context mContext;
- private LayerController mController;
- private InputConnectionHandler mInputConnectionHandler;
- private LayerRenderer mRenderer;
- private GestureDetector mGestureDetector;
- private SimpleScaleGestureDetector mScaleGestureDetector;
- private long mRenderTime;
- private boolean mRenderTimeReset;
- private static String LOGTAG = "GeckoLayerView";
- /* List of events to be processed if the page does not prevent them. Should only be touched on the main thread */
- private LinkedList<MotionEvent> mEventQueue = new LinkedList<MotionEvent>();
-
-
- public LayerView(Context context, LayerController controller) {
- super(context);
-
- mContext = context;
- mController = controller;
- mRenderer = new LayerRenderer(this);
- setRenderer(mRenderer);
- mGestureDetector = new GestureDetector(context, controller.getGestureListener());
- mScaleGestureDetector =
- new SimpleScaleGestureDetector(controller.getScaleGestureListener());
- mGestureDetector.setOnDoubleTapListener(controller.getDoubleTapListener());
- mInputConnectionHandler = null;
-
- setFocusable(true);
- setFocusableInTouchMode(true);
-
- createGLThread();
- }
-
- private void addToEventQueue(MotionEvent event) {
- MotionEvent copy = MotionEvent.obtain(event);
- mEventQueue.add(copy);
- }
-
- public void processEventQueue() {
- MotionEvent event = mEventQueue.poll();
- while(event != null) {
- processEvent(event);
- event = mEventQueue.poll();
- }
- }
-
- public void clearEventQueue() {
- mEventQueue.clear();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (mController.onTouchEvent(event)) {
- addToEventQueue(event);
- return true;
- }
- return processEvent(event);
- }
-
- private boolean processEvent(MotionEvent event) {
- if (mGestureDetector.onTouchEvent(event))
- return true;
- mScaleGestureDetector.onTouchEvent(event);
- if (mScaleGestureDetector.isInProgress())
- return true;
- mController.getPanZoomController().onTouchEvent(event);
- return true;
- }
-
- public LayerController getController() { return mController; }
-
- /** The LayerRenderer calls this to indicate that the window has changed size. */
- public void setViewportSize(IntSize size) {
- mController.setViewportSize(new FloatSize(size));
- }
-
- //public GeckoInputConnection setInputConnectionHandler() {
- // GeckoInputConnection geckoInputConnection = GeckoInputConnection.create(this);
- // mInputConnectionHandler = geckoInputConnection;
- // return geckoInputConnection;
- //}
-
- @Override
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.onCreateInputConnection(outAttrs);
- return null;
- }
-
- @Override
- public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.onKeyPreIme(keyCode, event);
- return false;
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.onKeyDown(keyCode, event);
- return false;
- }
-
- @Override
- public boolean onKeyLongPress(int keyCode, KeyEvent event) {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.onKeyLongPress(keyCode, event);
- return false;
- }
-
- @Override
- public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.onKeyMultiple(keyCode, repeatCount, event);
- return false;
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (mInputConnectionHandler != null)
- return mInputConnectionHandler.onKeyUp(keyCode, event);
- return false;
- }
-
- @Override
- public void requestRender() {
- super.requestRender();
-
- synchronized(this) {
- if (!mRenderTimeReset) {
- mRenderTimeReset = true;
- mRenderTime = System.nanoTime();
- }
- }
- }
-
- public void addLayer(Layer layer) {
- mRenderer.addLayer(layer);
- }
-
- public void removeLayer(Layer layer) {
- mRenderer.removeLayer(layer);
- }
-
- /**
- * Returns the time elapsed between the first call of requestRender() after
- * the last call of getRenderTime(), in nanoseconds.
- */
- public long getRenderTime() {
- synchronized(this) {
- mRenderTimeReset = false;
- return System.nanoTime() - mRenderTime;
- }
- }
-
- public int getMaxTextureSize() {
- return mRenderer.getMaxTextureSize();
- }
-
- /** Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop. */
- public IntBuffer getPixels() {
- return mRenderer.getPixels();
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java
deleted file mode 100644
index a958a54eb303..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
-* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1/GPL 2.0/LGPL 2.1
-*
-* The contents of this file are subject to the Mozilla Public License Version
-* 1.1 (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.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS IS" basis,
-* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-* for the specific language governing rights and limitations under the
-* License.
-*
-* The Original Code is Mozilla Android code.
-*
-* The Initial Developer of the Original Code is Mozilla Foundation.
-* Portions created by the Initial Developer are Copyright (C) 2011-2012
-* the Initial Developer. All Rights Reserved.
-*
-* Contributor(s):
-* Chris Lord <chrislord.net@gmail.com>
-* Arkady Blyakher <rkadyb@mit.edu>
-*
-* Alternatively, the contents of this file may be used under the terms of
-* either the GNU General Public License Version 2 or later (the "GPL"), or
-* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-* in which case the provisions of the GPL or the LGPL are applicable instead
-* of those above. If you wish to allow use of your version of this file only
-* under the terms of either the GPL or the LGPL, and not to allow others to
-* use your version of this file under the terms of the MPL, indicate your
-* decision by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL or the LGPL. If you do not delete
-* the provisions above, a recipient may use your version of this file under
-* the terms of any one of the MPL, the GPL or the LGPL.
-*
-* ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.util.Log;
-
-import org.libreoffice.LOKitShell;
-
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-/**
- * Encapsulates the logic needed to draw a layer made of multiple tiles.
- * <p/>
- * TODO: Support repeating.
- */
-public class MultiTileLayer extends Layer {
- private static final String LOGTAG = "GeckoMultiTileLayer";
-
- private final ArrayList<SubTile> mTiles;
- private IntSize mTileSize;
- private IntSize mSize;
-
- public MultiTileLayer(IntSize tileSize) {
- super();
- mTileSize = tileSize;
- mTiles = new ArrayList<SubTile>();
- mSize = new IntSize(0,0);
- }
-
- public void invalidate(Rect dirtyRect) {
- if (!inTransaction()) {
- throw new RuntimeException("invalidate() is only valid inside a transaction");
- }
-
- for (SubTile layer : mTiles) {
- IntSize tileSize = layer.getSize();
- Rect tileRect = new Rect(layer.x, layer.y, layer.x + tileSize.width, layer.y + tileSize.height);
-
- if (tileRect.intersect(dirtyRect)) {
- tileRect.offset(-layer.x, -layer.y);
- layer.invalidate(tileRect);
- }
- }
- }
-
- public void invalidate() {
- for (SubTile layer : mTiles) {
- layer.invalidate();
- }
- }
-
- public void setSize(IntSize size) {
- mSize = size;
- }
-
- @Override
- public IntSize getSize() {
- return mSize;
- }
-
- private void validateTiles() {
- Log.i(LOGTAG, "validateTiles()");
-
- // Set tile origins and resolution
- refreshTileMetrics(getOrigin(), getResolution(), false);
- }
-
- @Override
- protected boolean performUpdates(RenderContext context) {
- super.performUpdates(context);
-
- validateTiles();
-
- // Iterate over the tiles and decide which ones we'll be drawing
- int dirtyTiles = 0;
- boolean screenUpdateDone = false;
- SubTile firstDirtyTile = null;
- for (SubTile layer : mTiles) {
- // First do a non-texture update to make sure coordinates are
- // up-to-date.
- boolean invalid = layer.getSkipTextureUpdate();
- layer.setSkipTextureUpdate(true);
- layer.performUpdates(context);
-
- RectF layerBounds = layer.getBounds(context, new FloatSize(layer.getSize()));
- boolean isDirty = layer.isDirty();
-
- if (isDirty) {
- if (!RectF.intersects(layerBounds, context.viewport)) {
- if (firstDirtyTile == null)
- firstDirtyTile = layer;
- dirtyTiles++;
- invalid = true;
- } else {
- // This tile intersects with the screen and is dirty,
- // update it immediately.
- layer.setSkipTextureUpdate(false);
- screenUpdateDone = true;
- layer.performUpdates(context);
- invalid = false;
- }
- }
-
- // We use the SkipTextureUpdate flag as a marker of a tile's
- // validity. This is required, as sometimes layers are drawn
- // without updating first, and we mustn't draw tiles that have
- // been marked as invalid that we haven't updated.
- layer.setSkipTextureUpdate(invalid);
- }
-
- // Now if no tiles that intersect with the screen were updated, update
- // a single tile that doesn't (if there are any). This has the effect
- // of spreading out non-critical texture upload over time, and smoothing
- // upload-related hitches.
- if (!screenUpdateDone && firstDirtyTile != null) {
- firstDirtyTile.setSkipTextureUpdate(false);
- firstDirtyTile.performUpdates(context);
- dirtyTiles--;
- }
-
- return (dirtyTiles == 0);
- }
-
- private void refreshTileMetrics(Point origin, float resolution, boolean inTransaction) {
- IntSize size = getSize();
- for (SubTile layer : mTiles) {
- if (!inTransaction) {
- layer.beginTransaction();
- }
-
- if (origin != null) {
- layer.setOrigin(new Point(origin.x + layer.x, origin.y + layer.y));
- }
- if (resolution >= 0.0f) {
- layer.setResolution(resolution);
- }
-
- if (!inTransaction) {
- layer.endTransaction();
- }
- }
- }
-
- @Override
- public void setOrigin(Point newOrigin) {
- super.setOrigin(newOrigin);
- refreshTileMetrics(newOrigin, -1, true);
- }
-
- @Override
- public void setResolution(float newResolution) {
- super.setResolution(newResolution);
- refreshTileMetrics(null, newResolution, true);
- }
-
- @Override
- public void beginTransaction() {
- super.beginTransaction();
-
- for (SubTile layer : mTiles) {
- layer.beginTransaction();
- }
- }
-
- @Override
- public void endTransaction() {
- for (SubTile layer : mTiles) {
- layer.endTransaction();
- }
-
- super.endTransaction();
- }
-
- @Override
- public void draw(RenderContext context) {
- for (SubTile layer : mTiles) {
- // We use the SkipTextureUpdate flag as a validity flag. If it's false,
- // the contents of this tile are invalid and we shouldn't draw it.
- if (layer.getSkipTextureUpdate())
- continue;
-
- // Avoid work, only draw tiles that intersect with the viewport
- RectF layerBounds = layer.getBounds(context, new FloatSize(layer.getSize()));
- if (RectF.intersects(layerBounds, context.viewport))
- layer.draw(context);
- }
- }
-
- @Override
- public Region getValidRegion(RenderContext context) {
- Region validRegion = new Region();
- for (SubTile tile : mTiles) {
- if (tile.getSkipTextureUpdate())
- continue;
- validRegion.op(tile.getValidRegion(context), Region.Op.UNION);
- }
-
- return validRegion;
- }
-
- public void addTile(Bitmap bitmap, int x, int y) {
- SubTile tile = new SubTile(new BufferedCairoImage(bitmap), x,y);
- tile.beginTransaction();
- mTiles.add(tile);
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java
deleted file mode 100644
index f139b202c7b5..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.gfx.FloatSize;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.opengl.GLES11;
-import android.opengl.GLES11Ext;
-import android.util.Log;
-import javax.microedition.khronos.opengles.GL10;
-import java.nio.FloatBuffer;
-
-/**
- * Encapsulates the logic needed to draw a nine-patch bitmap using OpenGL ES.
- *
- * For more information on nine-patch bitmaps, see the following document:
- * http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
- */
-public class NinePatchTileLayer extends TileLayer {
- private static final int PATCH_SIZE = 16;
- private static final int TEXTURE_SIZE = 48;
-
- public NinePatchTileLayer(CairoImage image) {
- super(false, image);
- }
-
- @Override
- public void draw(RenderContext context) {
- if (!initialized())
- return;
-
- GLES11.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
- GLES11.glEnable(GL10.GL_BLEND);
- try {
- GLES11.glBindTexture(GL10.GL_TEXTURE_2D, getTextureID());
- drawPatches(context);
- } finally {
- GLES11.glDisable(GL10.GL_BLEND);
- }
- }
-
- private void drawPatches(RenderContext context) {
- /*
- * We divide the nine-patch bitmap up as follows:
- *
- * +---+---+---+
- * | 0 | 1 | 2 |
- * +---+---+---+
- * | 3 | | 4 |
- * +---+---+---+
- * | 5 | 6 | 7 |
- * +---+---+---+
- */
-
- FloatSize size = context.pageSize;
- float width = size.width, height = size.height;
-
- drawPatch(context, 0, 0, /* 0 */
- 0.0f, 0.0f, PATCH_SIZE, PATCH_SIZE);
- drawPatch(context, PATCH_SIZE, 0, /* 1 */
- PATCH_SIZE, 0.0f, width, PATCH_SIZE);
- drawPatch(context, PATCH_SIZE * 2, 0, /* 2 */
- PATCH_SIZE + width, 0.0f, PATCH_SIZE, PATCH_SIZE);
- drawPatch(context, 0, PATCH_SIZE, /* 3 */
- 0.0f, PATCH_SIZE, PATCH_SIZE, height);
- drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE, /* 4 */
- PATCH_SIZE + width, PATCH_SIZE, PATCH_SIZE, height);
- drawPatch(context, 0, PATCH_SIZE * 2, /* 5 */
- 0.0f, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
- drawPatch(context, PATCH_SIZE, PATCH_SIZE * 2, /* 6 */
- PATCH_SIZE, PATCH_SIZE + height, width, PATCH_SIZE);
- drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 2, /* 7 */
- PATCH_SIZE + width, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE);
- }
-
- private void drawPatch(RenderContext context, int textureX, int textureY, float tileX,
- float tileY, float tileWidth, float tileHeight) {
- int[] cropRect = { textureX, textureY + PATCH_SIZE, PATCH_SIZE, -PATCH_SIZE };
- GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect,
- 0);
-
- RectF viewport = context.viewport;
- float viewportHeight = viewport.height();
- float drawX = tileX - viewport.left - PATCH_SIZE;
- float drawY = viewportHeight - (tileY + tileHeight - viewport.top - PATCH_SIZE);
- GLES11Ext.glDrawTexfOES(drawX, drawY, 0.0f, tileWidth, tileHeight);
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java
deleted file mode 100644
index c9414ac8ecf0..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Kartikaya Gupta <kgupta@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import java.util.ArrayList;
-import java.util.List;
-import android.os.SystemClock;
-import android.util.Log;
-
-public class PanningPerfAPI {
- private static final String LOGTAG = "GeckoPanningPerfAPI";
-
- // make this large enough to avoid having to resize the frame time
- // list, as that may be expensive and impact the thing we're trying
- // to measure.
- private static final int EXPECTED_FRAME_COUNT = 2048;
-
- private static boolean mRecordingFrames = false;
- private static List<Long> mFrameTimes;
- private static long mFrameStartTime;
-
- private static boolean mRecordingCheckerboard = false;
- private static List<Float> mCheckerboardAmounts;
- private static long mCheckerboardStartTime;
-
- public static void startFrameTimeRecording() {
- if (mRecordingFrames) {
- Log.e(LOGTAG, "Error: startFrameTimeRecording() called while already recording!");
- return;
- }
- mRecordingFrames = true;
- if (mFrameTimes == null) {
- mFrameTimes = new ArrayList<Long>(EXPECTED_FRAME_COUNT);
- } else {
- mFrameTimes.clear();
- }
- mFrameStartTime = SystemClock.uptimeMillis();
- }
-
- public static List<Long> stopFrameTimeRecording() {
- if (!mRecordingFrames) {
- Log.e(LOGTAG, "Error: stopFrameTimeRecording() called when not recording!");
- return null;
- }
- mRecordingFrames = false;
- return mFrameTimes;
- }
-
- public static void recordFrameTime() {
- // this will be called often, so try to make it as quick as possible
- if (mRecordingFrames) {
- mFrameTimes.add(SystemClock.uptimeMillis() - mFrameStartTime);
- }
- }
-
- public static boolean isRecordingCheckerboard() {
- return mRecordingCheckerboard;
- }
-
- public static void startCheckerboardRecording() {
- if (mRecordingCheckerboard) {
- Log.e(LOGTAG, "Error: startCheckerboardRecording() called while already recording!");
- return;
- }
- mRecordingCheckerboard = true;
- if (mCheckerboardAmounts == null) {
- mCheckerboardAmounts = new ArrayList<Float>(EXPECTED_FRAME_COUNT);
- } else {
- mCheckerboardAmounts.clear();
- }
- mCheckerboardStartTime = SystemClock.uptimeMillis();
- }
-
- public static List<Float> stopCheckerboardRecording() {
- if (!mRecordingCheckerboard) {
- Log.e(LOGTAG, "Error: stopCheckerboardRecording() called when not recording!");
- return null;
- }
- mRecordingCheckerboard = false;
- return mCheckerboardAmounts;
- }
-
- public static void recordCheckerboard(float amount) {
- // this will be called often, so try to make it as quick as possible
- if (mRecordingCheckerboard) {
- mCheckerboardAmounts.add(amount);
- }
- }
-} \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java
deleted file mode 100644
index bff9f9f345a1..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Kartikaya Gupta <kgupta@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.util.FloatMath;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-import org.mozilla.gecko.util.FloatUtils;
-
-import java.lang.Math;
-
-public final class PointUtils {
- public static PointF add(PointF one, PointF two) {
- return new PointF(one.x + two.x, one.y + two.y);
- }
-
- public static PointF subtract(PointF one, PointF two) {
- return new PointF(one.x - two.x, one.y - two.y);
- }
-
- public static PointF scale(PointF point, float factor) {
- return new PointF(point.x * factor, point.y * factor);
- }
-
- public static Point round(PointF point) {
- return new Point(Math.round(point.x), Math.round(point.y));
- }
-
- /* Returns a new point that is a linear interpolation between start and end points. weight conrols the weighting
- * of each of the original points (weight = 1 returns endPoint, weight = 0 returns startPoint)
- */
- public static PointF interpolate(PointF startPoint, PointF endPoint, float weight) {
- float x = FloatUtils.interpolate(startPoint.x, endPoint.x, weight);
- float y = FloatUtils.interpolate(startPoint.y, endPoint.y, weight);
- return new PointF(x, y);
- }
-
- /* Computes the magnitude of the given vector. */
- public static float distance(PointF point) {
- return (float)Math.sqrt(point.x * point.x + point.y * point.y);
- }
-
- /** Computes the scalar distance between two points. */
- public static float distance(PointF one, PointF two) {
- return PointF.length(one.x - two.x, one.y - two.y);
- }
-
- public static JSONObject toJSON(PointF point) throws JSONException {
- // Ensure we put ints, not longs, because Gecko message handlers call getInt().
- int x = Math.round(point.x);
- int y = Math.round(point.y);
- JSONObject json = new JSONObject();
- json.put("x", x);
- json.put("y", y);
- return json;
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java
deleted file mode 100644
index 9a5049781c45..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Kartikaya Gupta <kgupta@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.util.FloatUtils;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-public final class RectUtils {
- public static Rect create(JSONObject json) {
- try {
- int x = json.getInt("x");
- int y = json.getInt("y");
- int width = json.getInt("width");
- int height = json.getInt("height");
- return new Rect(x, y, x + width, y + height);
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static Rect contract(Rect rect, int lessWidth, int lessHeight) {
- float halfLessWidth = lessWidth / 2.0f;
- float halfLessHeight = lessHeight / 2.0f;
- return new Rect(Math.round(rect.left + halfLessWidth),
- Math.round(rect.top + halfLessHeight),
- Math.round(rect.right - halfLessWidth),
- Math.round(rect.bottom - halfLessHeight));
- }
-
- public static RectF contract(RectF rect, float lessWidth, float lessHeight) {
- float halfLessWidth = lessWidth / 2;
- float halfLessHeight = lessHeight / 2;
- return new RectF(rect.left + halfLessWidth,
- rect.top + halfLessHeight,
- rect.right - halfLessWidth,
- rect.bottom - halfLessHeight);
- }
-
- public static RectF expand(RectF rect, float moreWidth, float moreHeight) {
- float halfMoreWidth = moreWidth / 2;
- float halfMoreHeight = moreHeight / 2;
- return new RectF(rect.left - halfMoreWidth,
- rect.top - halfMoreHeight,
- rect.right + halfMoreWidth,
- rect.bottom + halfMoreHeight);
- }
-
- public static RectF intersect(RectF one, RectF two) {
- float left = Math.max(one.left, two.left);
- float top = Math.max(one.top, two.top);
- float right = Math.min(one.right, two.right);
- float bottom = Math.min(one.bottom, two.bottom);
- return new RectF(left, top, Math.max(right, left), Math.max(bottom, top));
- }
-
- public static RectF scale(RectF rect, float scale) {
- float x = rect.left * scale;
- float y = rect.top * scale;
- return new RectF(x, y,
- x + (rect.width() * scale),
- y + (rect.height() * scale));
- }
-
- /** Returns the nearest integer rect of the given rect. */
- public static Rect round(RectF rect) {
- return new Rect(Math.round(rect.left), Math.round(rect.top),
- Math.round(rect.right), Math.round(rect.bottom));
- }
-
- public static IntSize getSize(Rect rect) {
- return new IntSize(rect.width(), rect.height());
- }
-
- public static Point getOrigin(Rect rect) {
- return new Point(rect.left, rect.top);
- }
-
- public static PointF getOrigin(RectF rect) {
- return new PointF(rect.left, rect.top);
- }
-
- /*
- * Returns the rect that represents a linear transition between `from` and `to` at time `t`,
- * which is on the scale [0, 1).
- */
- public static RectF interpolate(RectF from, RectF to, float t) {
- return new RectF(FloatUtils.interpolate(from.left, to.left, t),
- FloatUtils.interpolate(from.top, to.top, t),
- FloatUtils.interpolate(from.right, to.right, t),
- FloatUtils.interpolate(from.bottom, to.bottom, t));
- }
-
- public static boolean fuzzyEquals(RectF a, RectF b) {
- return FloatUtils.fuzzyEquals(a.top, b.top)
- && FloatUtils.fuzzyEquals(a.left, b.left)
- && FloatUtils.fuzzyEquals(a.right, b.right)
- && FloatUtils.fuzzyEquals(a.bottom, b.bottom);
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java
deleted file mode 100644
index 68b7265b368b..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Kartikaya Gupta <kgupta@mozilla.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.opengl.GLES20;
-
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.util.FloatUtils;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-
-/**
- * Draws a small rect. This is scaled to become a scrollbar.
- */
-public class ScrollbarLayer extends TileLayer {
- public static final long FADE_DELAY = 500; // milliseconds before fade-out starts
- private static final float FADE_AMOUNT = 0.03f; // how much (as a percent) the scrollbar should fade per frame
-
- private static final int PADDING = 1; // gap between scrollbar and edge of viewport
- private static final int BAR_SIZE = 6;
- private static final int CAP_RADIUS = (BAR_SIZE / 2);
- // Dimensions of the texture image
- private static final float TEX_HEIGHT = 8.0f;
- private static final float TEX_WIDTH = 8.0f;
- // Texture coordinates for the scrollbar's body
- // We take a 1x1 pixel from the center of the image and scale it to become the bar
- private static final float[] BODY_TEX_COORDS = {
- // x, y
- CAP_RADIUS / TEX_WIDTH, CAP_RADIUS / TEX_HEIGHT,
- CAP_RADIUS / TEX_WIDTH, (CAP_RADIUS + 1) / TEX_HEIGHT,
- (CAP_RADIUS + 1) / TEX_WIDTH, CAP_RADIUS / TEX_HEIGHT,
- (CAP_RADIUS + 1) / TEX_WIDTH, (CAP_RADIUS + 1) / TEX_HEIGHT
- };
- // Texture coordinates for the top cap of the scrollbar
- private static final float[] TOP_CAP_TEX_COORDS = {
- // x, y
- 0, 1.0f - CAP_RADIUS / TEX_HEIGHT,
- 0, 1.0f,
- BAR_SIZE / TEX_WIDTH, 1.0f - CAP_RADIUS / TEX_HEIGHT,
- BAR_SIZE / TEX_WIDTH, 1.0f
- };
- // Texture coordinates for the bottom cap of the scrollbar
- private static final float[] BOT_CAP_TEX_COORDS = {
- // x, y
- 0, 1.0f - BAR_SIZE / TEX_HEIGHT,
- 0, 1.0f - CAP_RADIUS / TEX_HEIGHT,
- BAR_SIZE / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT,
- BAR_SIZE / TEX_WIDTH, 1.0f - CAP_RADIUS / TEX_HEIGHT
- };
- // Texture coordinates for the left cap of the scrollbar
- private static final float[] LEFT_CAP_TEX_COORDS = {
- // x, y
- 0, 1.0f - BAR_SIZE / TEX_HEIGHT,
- 0, 1.0f,
- CAP_RADIUS / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT,
- CAP_RADIUS / TEX_WIDTH, 1.0f
- };
- // Texture coordinates for the right cap of the scrollbar
- private static final float[] RIGHT_CAP_TEX_COORDS = {
- // x, y
- CAP_RADIUS / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT,
- CAP_RADIUS / TEX_WIDTH, 1.0f,
- BAR_SIZE / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT,
- BAR_SIZE / TEX_WIDTH, 1.0f
- };
- private final boolean mVertical;
- private final ByteBuffer mBuffer;
- private final Bitmap mBitmap;
- private final Canvas mCanvas;
- private float mOpacity;
- private boolean mFinalized = false;
-
- private ScrollbarLayer(CairoImage image, boolean vertical, ByteBuffer buffer) {
- super(false, image);
- mVertical = vertical;
- mBuffer = buffer;
-
- IntSize size = image.getSize();
- mBitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
- mCanvas = new Canvas(mBitmap);
- }
-
- public static ScrollbarLayer create(boolean vertical) {
- // just create an empty image for now, it will get drawn
- // on demand anyway
- int imageSize = IntSize.nextPowerOfTwo(BAR_SIZE);
- ByteBuffer buffer = LOKitShell.allocateDirectBuffer(imageSize * imageSize * 4);
- CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize,
- CairoImage.FORMAT_ARGB32);
- return new ScrollbarLayer(image, vertical, buffer);
- }
-
- protected void finalize() throws Throwable {
- try {
- if (!mFinalized && mBuffer != null)
- LOKitShell.freeDirectBuffer(mBuffer);
- mFinalized = true;
- } finally {
- super.finalize();
- }
- }
-
- /**
- * Decrease the opacity of the scrollbar by one frame's worth.
- * Return true if the opacity was decreased, or false if the scrollbars
- * are already fully faded out.
- */
- public boolean fade() {
- if (FloatUtils.fuzzyEquals(mOpacity, 0.0f)) {
- return false;
- }
- beginTransaction();
- try {
- setOpacity(Math.max(mOpacity - FADE_AMOUNT, 0.0f));
- invalidate();
- } finally {
- endTransaction();
- }
- return true;
- }
-
- /**
- * Restore the opacity of the scrollbar to fully opaque.
- * Return true if the opacity was changed, or false if the scrollbars
- * are already fully opaque.
- */
- public boolean unfade() {
- if (FloatUtils.fuzzyEquals(mOpacity, 1.0f)) {
- return false;
- }
- beginTransaction();
- try {
- setOpacity(1.0f);
- invalidate();
- } finally {
- endTransaction();
- }
- return true;
- }
-
- private void setOpacity(float opacity) {
- mOpacity = opacity;
-
- Paint foregroundPaint = new Paint();
- foregroundPaint.setAntiAlias(true);
- foregroundPaint.setStyle(Paint.Style.FILL);
- // use a (a,r,g,b) color of (127,0,0,0), and multiply the alpha by mOpacity for fading
- foregroundPaint.setColor(Color.argb(Math.round(mOpacity * 127), 0, 0, 0));
-
- mCanvas.drawColor(Color.argb(0, 0, 0, 0), PorterDuff.Mode.CLEAR);
- mCanvas.drawCircle(CAP_RADIUS, CAP_RADIUS, CAP_RADIUS, foregroundPaint);
-
- mBitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
- }
-
- @Override
- public void draw(RenderContext context) {
- if (!initialized())
- return;
-
- try {
- GLES20.glEnable(GLES20.GL_BLEND);
- GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
-
- Rect rect = RectUtils.round(mVertical
- ? getVerticalRect(context)
- : getHorizontalRect(context));
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
-
- float viewWidth = context.viewport.width();
- float viewHeight = context.viewport.height();
-
- float top = viewHeight - rect.top;
- float bot = viewHeight - rect.bottom;
-
- // Coordinates for the scrollbar's body combined with the texture coordinates
- float[] bodyCoords = {
- // x, y, z, texture_x, texture_y
- rect.left / viewWidth, bot / viewHeight, 0,
- BODY_TEX_COORDS[0], BODY_TEX_COORDS[1],
-
- rect.left / viewWidth, (bot + rect.height()) / viewHeight, 0,
- BODY_TEX_COORDS[2], BODY_TEX_COORDS[3],
-
- (rect.left + rect.width()) / viewWidth, bot / viewHeight, 0,
- BODY_TEX_COORDS[4], BODY_TEX_COORDS[5],
-
- (rect.left + rect.width()) / viewWidth, (bot + rect.height()) / viewHeight, 0,
- BODY_TEX_COORDS[6], BODY_TEX_COORDS[7]
- };
-
- // Get the buffer and handles from the context
- FloatBuffer coordBuffer = context.coordBuffer;
- int positionHandle = context.positionHandle;
- int textureHandle = context.textureHandle;
-
- // Make sure we are at position zero in the buffer in case other draw methods did not
- // clean up after themselves
- coordBuffer.position(0);
- coordBuffer.put(bodyCoords);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- // Reset the position in the buffer for the next set of vertex and texture coordinates.
- coordBuffer.position(0);
-
- if (mVertical) {
- // top endcap
- float[] topCap = {
- // x, y, z, texture_x, texture_y
- rect.left / viewWidth, top / viewHeight, 0,
- TOP_CAP_TEX_COORDS[0], TOP_CAP_TEX_COORDS[1],
-
- rect.left / viewWidth, (top + CAP_RADIUS) / viewHeight, 0,
- TOP_CAP_TEX_COORDS[2], TOP_CAP_TEX_COORDS[3],
-
- (rect.left + BAR_SIZE) / viewWidth, top / viewHeight, 0,
- TOP_CAP_TEX_COORDS[4], TOP_CAP_TEX_COORDS[5],
-
- (rect.left + BAR_SIZE) / viewWidth, (top + CAP_RADIUS) / viewHeight, 0,
- TOP_CAP_TEX_COORDS[6], TOP_CAP_TEX_COORDS[7]
- };
-
- coordBuffer.put(topCap);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the
- // buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- // Reset the position in the buffer for the next set of vertex and texture
- // coordinates.
- coordBuffer.position(0);
-
- // bottom endcap
- float[] botCap = {
- // x, y, z, texture_x, texture_y
- rect.left / viewWidth, (bot - CAP_RADIUS) / viewHeight, 0,
- BOT_CAP_TEX_COORDS[0], BOT_CAP_TEX_COORDS[1],
-
- rect.left / viewWidth, (bot) / viewHeight, 0,
- BOT_CAP_TEX_COORDS[2], BOT_CAP_TEX_COORDS[3],
-
- (rect.left + BAR_SIZE) / viewWidth, (bot - CAP_RADIUS) / viewHeight, 0,
- BOT_CAP_TEX_COORDS[4], BOT_CAP_TEX_COORDS[5],
-
- (rect.left + BAR_SIZE) / viewWidth, (bot) / viewHeight, 0,
- BOT_CAP_TEX_COORDS[6], BOT_CAP_TEX_COORDS[7]
- };
-
- coordBuffer.put(botCap);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the
- // buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- // Reset the position in the buffer for the next set of vertex and texture
- // coordinates.
- coordBuffer.position(0);
- } else {
- // left endcap
- float[] leftCap = {
- // x, y, z, texture_x, texture_y
- (rect.left - CAP_RADIUS) / viewWidth, bot / viewHeight, 0,
- LEFT_CAP_TEX_COORDS[0], LEFT_CAP_TEX_COORDS[1],
- (rect.left - CAP_RADIUS) / viewWidth, (bot + BAR_SIZE) / viewHeight, 0,
- LEFT_CAP_TEX_COORDS[2], LEFT_CAP_TEX_COORDS[3],
- (rect.left) / viewWidth, bot / viewHeight, 0, LEFT_CAP_TEX_COORDS[4],
- LEFT_CAP_TEX_COORDS[5],
- (rect.left) / viewWidth, (bot + BAR_SIZE) / viewHeight, 0,
- LEFT_CAP_TEX_COORDS[6], LEFT_CAP_TEX_COORDS[7]
- };
-
- coordBuffer.put(leftCap);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the
- // buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- // Reset the position in the buffer for the next set of vertex and texture
- // coordinates.
- coordBuffer.position(0);
-
- // right endcap
- float[] rightCap = {
- // x, y, z, texture_x, texture_y
- rect.right / viewWidth, (bot) / viewHeight, 0,
- RIGHT_CAP_TEX_COORDS[0], RIGHT_CAP_TEX_COORDS[1],
-
- rect.right / viewWidth, (bot + BAR_SIZE) / viewHeight, 0,
- RIGHT_CAP_TEX_COORDS[2], RIGHT_CAP_TEX_COORDS[3],
-
- (rect.right + CAP_RADIUS) / viewWidth, (bot) / viewHeight, 0,
- RIGHT_CAP_TEX_COORDS[4], RIGHT_CAP_TEX_COORDS[5],
-
- (rect.right + CAP_RADIUS) / viewWidth, (bot + BAR_SIZE) / viewHeight, 0,
- RIGHT_CAP_TEX_COORDS[6], RIGHT_CAP_TEX_COORDS[7]
- };
-
- coordBuffer.put(rightCap);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the
- // buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20,
- coordBuffer);
-
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
- }
- } finally {
- GLES20.glDisable(GLES20.GL_BLEND);
- }
- }
-
- private RectF getVerticalRect(RenderContext context) {
- RectF viewport = context.viewport;
- FloatSize pageSize = context.pageSize;
- float barStart = (viewport.height() * viewport.top / pageSize.height) + CAP_RADIUS;
- float barEnd = (viewport.height() * viewport.bottom / pageSize.height) - CAP_RADIUS;
- if (barStart > barEnd) {
- float middle = (barStart + barEnd) / 2.0f;
- barStart = barEnd = middle;
- }
- float right = viewport.width() - PADDING;
- return new RectF(right - BAR_SIZE, barStart, right, barEnd);
- }
-
- private RectF getHorizontalRect(RenderContext context) {
- RectF viewport = context.viewport;
- FloatSize pageSize = context.pageSize;
- float barStart = (viewport.width() * viewport.left / pageSize.width) + CAP_RADIUS;
- float barEnd = (viewport.width() * viewport.right / pageSize.width) - CAP_RADIUS;
- if (barStart > barEnd) {
- float middle = (barStart + barEnd) / 2.0f;
- barStart = barEnd = middle;
- }
- float bottom = viewport.height() - PADDING;
- return new RectF(barStart, bottom - BAR_SIZE, barEnd, bottom);
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java
deleted file mode 100644
index d18579e1a117..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.mozilla.gecko.gfx.CairoImage;
-import org.mozilla.gecko.gfx.CairoUtils;
-import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.TileLayer;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.opengl.GLES20;
-import android.util.Log;
-import java.nio.FloatBuffer;
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * Encapsulates the logic needed to draw a single textured tile.
- *
- * TODO: Repeating textures really should be their own type of layer.
- */
-public class SingleTileLayer extends TileLayer {
- public SingleTileLayer(CairoImage image) { this(false, image); }
-
- public SingleTileLayer(boolean repeat, CairoImage image) {
- super(repeat, image);
- }
-
- @Override
- public void draw(RenderContext context) {
- // mTextureIDs may be null here during startup if Layer.java's draw method
- // failed to acquire the transaction lock and call performUpdates.
- if (!initialized())
- return;
-
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
-
- RectF bounds;
- int[] cropRect;
- IntSize size = getSize();
- RectF viewport = context.viewport;
-
- if (repeats()) {
- bounds = new RectF(0.0f, 0.0f, viewport.width(), viewport.height());
- int width = Math.round(viewport.width());
- int height = Math.round(viewport.height());
- cropRect = new int[] { 0, 0, width, height };
- } else {
- bounds = getBounds(context, new FloatSize(size));
- cropRect = new int[] { 0, 0, size.width, size.height };
- }
-
- float height = bounds.height();
- float left = bounds.left - viewport.left;
- float top = viewport.height() - (bounds.top + height - viewport.top);
-
- float[] coords = {
- //x, y, z, texture_x, texture_y
- left/viewport.width(), top/viewport.height(), 0,
- cropRect[0]/(float)size.width, cropRect[1]/(float)size.height,
-
- left/viewport.width(), (top+height)/viewport.height(), 0,
- cropRect[0]/(float)size.width, cropRect[3]/(float)size.height,
-
- (left+bounds.width())/viewport.width(), top/viewport.height(), 0,
- cropRect[2]/(float)size.width, cropRect[1]/(float)size.height,
-
- (left+bounds.width())/viewport.width(), (top+height)/viewport.height(), 0,
- cropRect[2]/(float)size.width, cropRect[3]/(float)size.height
- };
-
- FloatBuffer coordBuffer = context.coordBuffer;
- int positionHandle = context.positionHandle;
- int textureHandle = context.textureHandle;
-
- // Make sure we are at position zero in the buffer in case other draw methods did not clean
- // up after themselves
- coordBuffer.position(0);
- coordBuffer.put(coords);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java
deleted file mode 100644
index 0c40c3c1b7df..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.mozilla.gecko.gfx;
-
-/**
-* Created by quikee on 29.6.2014.
-*/
-public class SubTile extends SingleTileLayer {
- public int x;
- public int y;
-
- public SubTile(CairoImage mImage, int mX, int mY) {
- super(mImage);
- x = mX;
- y = mY;
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java
deleted file mode 100644
index f2cc640baaa7..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-//import org.mozilla.gecko.GeckoAppShell;
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.gfx.BufferedCairoImage;
-import org.mozilla.gecko.gfx.CairoImage;
-import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.SingleTileLayer;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.util.Log;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-
-/**
- * Draws text on a layer. This is used for the frame rate meter.
- */
-public class TextLayer extends SingleTileLayer {
- private final ByteBuffer mBuffer;
- private final IntSize mSize;
- private boolean mFinalized = false;
-
- /*
- * This awkward pattern is necessary due to Java's restrictions on when one can call superclass
- * constructors.
- */
- private TextLayer(ByteBuffer buffer, BufferedCairoImage image, IntSize size, String text) {
- super(false, image);
- mBuffer = buffer;
- mSize = size;
- renderText(text);
- }
-
- protected void finalize() throws Throwable {
- try {
- if (!mFinalized && mBuffer != null)
- /*GeckoAppShell*/ LOKitShell.freeDirectBuffer(mBuffer);
- mFinalized = true;
- } finally {
- super.finalize();
- }
- }
-
- public static TextLayer create(IntSize size, String text) {
- ByteBuffer buffer = /*GeckoAppShell*/LOKitShell.allocateDirectBuffer(size.width * size.height * 4);
- BufferedCairoImage image = new BufferedCairoImage(buffer, size.width, size.height,
- CairoImage.FORMAT_ARGB32);
- return new TextLayer(buffer, image, size, text);
- }
-
- public void setText(String text) {
- renderText(text);
- invalidate();
- }
-
- private void renderText(String text) {
- Bitmap bitmap = Bitmap.createBitmap(mSize.width, mSize.height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
-
- Paint textPaint = new Paint();
- textPaint.setAntiAlias(true);
- textPaint.setColor(Color.WHITE);
- textPaint.setFakeBoldText(true);
- textPaint.setTextSize(18.0f);
- textPaint.setTypeface(Typeface.DEFAULT_BOLD);
- float width = textPaint.measureText(text) + 18.0f;
-
- Paint backgroundPaint = new Paint();
- backgroundPaint.setColor(Color.argb(127, 0, 0, 0));
- canvas.drawRect(0.0f, 0.0f, width, 18.0f + 6.0f, backgroundPaint);
-
- canvas.drawText(text, 6.0f, 18.0f, textPaint);
-
- bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java
deleted file mode 100644
index 4392c55e1ae7..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * James Willcox <jwillcox@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.opengl.GLES10;
-import java.util.Stack;
-
-public class TextureGenerator {
- private static final int MIN_TEXTURES = 5;
-
- private static TextureGenerator sSharedInstance;
- private Stack<Integer> mTextureIds;
-
- private TextureGenerator() { mTextureIds = new Stack<Integer>(); }
-
- public static TextureGenerator get() {
- if (sSharedInstance == null)
- sSharedInstance = new TextureGenerator();
- return sSharedInstance;
- }
-
- public synchronized int take() {
- if (mTextureIds.empty())
- return 0;
-
- return (int)mTextureIds.pop();
- }
-
- public synchronized void fill() {
- int[] textures = new int[1];
- while (mTextureIds.size() < MIN_TEXTURES) {
- GLES10.glGenTextures(1, textures, 0);
- mTextureIds.push(textures[0]);
- }
- }
-}
-
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java
deleted file mode 100644
index e18139cb9bc9..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.opengl.GLES20;
-import java.util.ArrayList;
-
-/** Manages a list of dead tiles, so we don't leak resources. */
-public class TextureReaper {
- private static TextureReaper sSharedInstance;
- private ArrayList<Integer> mDeadTextureIDs;
-
- private TextureReaper() { mDeadTextureIDs = new ArrayList<Integer>(); }
-
- public static TextureReaper get() {
- if (sSharedInstance == null)
- sSharedInstance = new TextureReaper();
- return sSharedInstance;
- }
-
- public void add(int[] textureIDs) {
- for (int textureID : textureIDs)
- add(textureID);
- }
-
- public void add(int textureID) {
- mDeadTextureIDs.add(textureID);
- }
-
- public void reap() {
- int[] deadTextureIDs = new int[mDeadTextureIDs.size()];
- for (int i = 0; i < deadTextureIDs.length; i++)
- deadTextureIDs[i] = mDeadTextureIDs.get(i);
- mDeadTextureIDs.clear();
-
- GLES20.glDeleteTextures(deadTextureIDs.length, deadTextureIDs, 0);
- }
-}
-
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java
deleted file mode 100644
index 64ec94dc694a..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.opengl.GLES20;
-import android.util.Log;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-/**
- * Base class for tile layers, which encapsulate the logic needed to draw textured tiles in OpenGL
- * ES.
- */
-public abstract class TileLayer extends Layer {
- private static final String LOGTAG = "GeckoTileLayer";
-
- private final Rect mDirtyRect;
- private final CairoImage mImage;
- private final boolean mRepeat;
- private IntSize mSize;
- private boolean mSkipTextureUpdate;
- private int[] mTextureIDs;
-
- public TileLayer(boolean repeat, CairoImage image) {
- mRepeat = repeat;
- mImage = image;
- mSize = new IntSize(0, 0);
- mSkipTextureUpdate = false;
-
- IntSize bufferSize = mImage.getSize();
- mDirtyRect = new Rect();
- }
-
- @Override
- public IntSize getSize() { return mImage.getSize(); }
-
- protected boolean repeats() { return mRepeat; }
- protected int getTextureID() { return mTextureIDs[0]; }
- protected boolean initialized() { return mImage != null && mTextureIDs != null; }
-
- @Override
- protected void finalize() throws Throwable {
- if (mTextureIDs != null)
- TextureReaper.get().add(mTextureIDs);
- }
-
- /**
- * Invalidates the given rect so that it will be uploaded again. Only valid inside a
- * transaction.
- */
- public void invalidate(Rect rect) {
- if (!inTransaction())
- throw new RuntimeException("invalidate() is only valid inside a transaction");
- mDirtyRect.union(rect);
- }
-
- public void invalidate() {
- IntSize bufferSize = mImage.getSize();
- invalidate(new Rect(0, 0, bufferSize.width, bufferSize.height));
- }
-
- public boolean isDirty() {
- return mImage.getSize().isPositive() && (mTextureIDs == null || !mDirtyRect.isEmpty());
- }
-
- private void validateTexture() {
- /* Calculate the ideal texture size. This must be a power of two if
- * the texture is repeated or OpenGL ES 2.0 isn't supported, as
- * OpenGL ES 2.0 is required for NPOT texture support (without
- * extensions), but doesn't support repeating NPOT textures.
- *
- * XXX Currently, we don't pick a GLES 2.0 context, so always round.
- */
- IntSize bufferSize = mImage.getSize();
- IntSize textureSize = bufferSize;
-
- textureSize = bufferSize.nextPowerOfTwo();
-
- if (!textureSize.equals(mSize)) {
- mSize = textureSize;
-
- // Delete the old texture
- if (mTextureIDs != null) {
- TextureReaper.get().add(mTextureIDs);
- mTextureIDs = null;
-
- // Free the texture immediately, so we don't incur a
- // temporarily increased memory usage.
- TextureReaper.get().reap();
- }
- }
- }
-
- /** Tells the tile not to update the texture on the next update. */
- public void setSkipTextureUpdate(boolean skip) {
- mSkipTextureUpdate = skip;
- }
-
- public boolean getSkipTextureUpdate() {
- return mSkipTextureUpdate;
- }
-
- @Override
- protected boolean performUpdates(RenderContext context) {
- super.performUpdates(context);
-
- if (mSkipTextureUpdate) {
- return false;
- }
-
- // Reallocate the texture if the size has changed
- validateTexture();
-
- // Don't do any work if the image has an invalid size.
- if (!mImage.getSize().isPositive())
- return true;
-
- // If we haven't allocated a texture, assume the whole region is dirty
- if (mTextureIDs == null) {
- uploadFullTexture();
- } else {
- uploadDirtyRect(mDirtyRect);
- }
-
- mDirtyRect.setEmpty();
-
- return true;
- }
-
- private void uploadFullTexture() {
- IntSize bufferSize = mImage.getSize();
- uploadDirtyRect(new Rect(0, 0, bufferSize.width, bufferSize.height));
- }
-
- private void uploadDirtyRect(Rect dirtyRect) {
- // If we have nothing to upload, just return for now
- if (dirtyRect.isEmpty())
- return;
-
- // It's possible that the buffer will be null, check for that and return
- ByteBuffer imageBuffer = mImage.getBuffer();
- if (imageBuffer == null)
- return;
-
- boolean newlyCreated = false;
-
- if (mTextureIDs == null) {
- mTextureIDs = new int[1];
- GLES20.glGenTextures(mTextureIDs.length, mTextureIDs, 0);
- newlyCreated = true;
- }
-
- IntSize bufferSize = mImage.getSize();
- Rect bufferRect = new Rect(0, 0, bufferSize.width, bufferSize.height);
-
- int cairoFormat = mImage.getFormat();
- CairoGLInfo glInfo = new CairoGLInfo(cairoFormat);
-
- bindAndSetGLParameters();
-
- if (newlyCreated || dirtyRect.contains(bufferRect)) {
- if (mSize.equals(bufferSize)) {
- GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width,
- mSize.height, 0, glInfo.format, glInfo.type, imageBuffer);
- return;
- } else {
- GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width,
- mSize.height, 0, glInfo.format, glInfo.type, null);
- GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, bufferSize.width,
- bufferSize.height, glInfo.format, glInfo.type, imageBuffer);
- return;
- }
- }
-
- // Make sure that the dirty region intersects with the buffer rect,
- // otherwise we'll end up with an invalid buffer pointer.
- if (!Rect.intersects(dirtyRect, bufferRect)) {
- return;
- }
-
- /*
- * Upload the changed rect. We have to widen to the full width of the texture
- * because we can't count on the device having support for GL_EXT_unpack_subimage,
- * and going line-by-line is too slow.
- *
- * XXX We should still use GL_EXT_unpack_subimage when available.
- */
- Buffer viewBuffer = imageBuffer.slice();
- int bpp = CairoUtils.bitsPerPixelForCairoFormat(cairoFormat) / 8;
- int position = dirtyRect.top * bufferSize.width * bpp;
- if (position > viewBuffer.limit()) {
- Log.e(LOGTAG, "### Position outside tile! " + dirtyRect.top);
- return;
- }
-
- viewBuffer.position(position);
- GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, dirtyRect.top, bufferSize.width,
- Math.min(bufferSize.height - dirtyRect.top, dirtyRect.height()),
- glInfo.format, glInfo.type, viewBuffer);
- }
-
- private void bindAndSetGLParameters() {
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
- GLES20.GL_NEAREST);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
- GLES20.GL_LINEAR);
-
- int repeatMode = mRepeat ? GLES20.GL_REPEAT : GLES20.GL_CLAMP_TO_EDGE;
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, repeatMode);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, repeatMode);
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java
deleted file mode 100644
index 9f443ea52894..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-public class ViewTransform {
- public float x;
- public float y;
- public float scale;
-
- public ViewTransform(float inX, float inY, float inScale) {
- x = inX;
- y = inY;
- scale = inScale;
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java
deleted file mode 100644
index d98b47421520..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.util.DisplayMetrics;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.libreoffice.LibreOfficeMainActivity;
-import org.mozilla.gecko.util.FloatUtils;
-
-/**
- * ViewportMetrics manages state and contains some utility functions related to
- * the page viewport for the Gecko layer client to use.
- */
-public class ViewportMetrics {
- private static final String LOGTAG = "GeckoViewportMetrics";
- private static final float MAX_BIAS = 0.8f;
- private FloatSize mPageSize;
- private RectF mViewportRect;
- private PointF mViewportOffset;
- private float mZoomFactor;
- // A scale from -1,-1 to 1,1 that represents what edge of the displayport
- // we want the viewport to be biased towards.
- private PointF mViewportBias;
-
- public ViewportMetrics() {
- DisplayMetrics metrics = new DisplayMetrics();
- LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
-
- mPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels);
- mViewportRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels);
- mViewportOffset = new PointF(0, 0);
- mZoomFactor = 1.0f;
- mViewportBias = new PointF(0.0f, 0.0f);
- }
-
- public ViewportMetrics(ViewportMetrics viewport) {
- mPageSize = new FloatSize(viewport.getPageSize());
- mViewportRect = new RectF(viewport.getViewport());
- PointF offset = viewport.getViewportOffset();
- mViewportOffset = new PointF(offset.x, offset.y);
- mZoomFactor = viewport.getZoomFactor();
- mViewportBias = viewport.mViewportBias;
- }
-
- public ViewportMetrics(JSONObject json) throws JSONException {
- float x = (float) json.getDouble("x");
- float y = (float) json.getDouble("y");
- float width = (float) json.getDouble("width");
- float height = (float) json.getDouble("height");
- float pageWidth = (float) json.getDouble("pageWidth");
- float pageHeight = (float) json.getDouble("pageHeight");
- float offsetX = (float) json.getDouble("offsetX");
- float offsetY = (float) json.getDouble("offsetY");
- float zoom = (float) json.getDouble("zoom");
-
- mPageSize = new FloatSize(pageWidth, pageHeight);
- mViewportRect = new RectF(x, y, x + width, y + height);
- mViewportOffset = new PointF(offsetX, offsetY);
- mZoomFactor = zoom;
- mViewportBias = new PointF(0.0f, 0.0f);
- }
-
- public PointF getOptimumViewportOffset(IntSize displayportSize) {
- /* XXX Until bug #524925 is fixed, changing the viewport origin will
- * cause unnecessary relayouts. This may cause rendering time to
- * increase and should be considered.
- */
- RectF viewport = getClampedViewport();
-
- FloatSize bufferSpace = new FloatSize(displayportSize.width - viewport.width(),
- displayportSize.height - viewport.height());
- PointF optimumOffset =
- new PointF(bufferSpace.width * ((mViewportBias.x + 1.0f) / 2.0f),
- bufferSpace.height * ((mViewportBias.y + 1.0f) / 2.0f));
-
- // Make sure this offset won't cause wasted pixels in the displayport
- // (i.e. make sure the resultant displayport intersects with the page
- // as much as possible)
- if (viewport.left - optimumOffset.x < 0)
- optimumOffset.x = viewport.left;
- else if ((bufferSpace.width - optimumOffset.x) + viewport.right > mPageSize.width)
- optimumOffset.x = bufferSpace.width - (mPageSize.width - viewport.right);
-
- if (viewport.top - optimumOffset.y < 0)
- optimumOffset.y = viewport.top;
- else if ((bufferSpace.height - optimumOffset.y) + viewport.bottom > mPageSize.height)
- optimumOffset.y = bufferSpace.height - (mPageSize.height - viewport.bottom);
-
- return new PointF(Math.round(optimumOffset.x), Math.round(optimumOffset.y));
- }
-
- public PointF getOrigin() {
- return new PointF(mViewportRect.left, mViewportRect.top);
- }
-
- public void setOrigin(PointF origin) {
- // When the origin is set, we compare it with the last value set and
- // change the viewport bias accordingly, so that any viewport based
- // on these metrics will have a larger buffer in the direction of
- // movement.
-
- // XXX Note the comment about bug #524925 in getOptimumViewportOffset.
- // Ideally, the viewport bias would be a sliding scale, but we
- // don't want to change it too often at the moment.
- if (FloatUtils.fuzzyEquals(origin.x, mViewportRect.left))
- mViewportBias.x = 0;
- else
- mViewportBias.x = ((mViewportRect.left - origin.x) > 0) ? MAX_BIAS : -MAX_BIAS;
- if (FloatUtils.fuzzyEquals(origin.y, mViewportRect.top))
- mViewportBias.y = 0;
- else
- mViewportBias.y = ((mViewportRect.top - origin.y) > 0) ? MAX_BIAS : -MAX_BIAS;
-
- mViewportRect.set(origin.x, origin.y,
- origin.x + mViewportRect.width(),
- origin.y + mViewportRect.height());
- }
-
- public PointF getDisplayportOrigin() {
- return new PointF(mViewportRect.left - mViewportOffset.x,
- mViewportRect.top - mViewportOffset.y);
- }
-
- public FloatSize getSize() {
- return new FloatSize(mViewportRect.width(), mViewportRect.height());
- }
-
- public void setSize(FloatSize size) {
- mViewportRect.right = mViewportRect.left + size.width;
- mViewportRect.bottom = mViewportRect.top + size.height;
- }
-
- public RectF getViewport() {
- return mViewportRect;
- }
-
- public void setViewport(RectF viewport) {
- mViewportRect = viewport;
- }
-
- /**
- * Returns the viewport rectangle, clamped within the page-size.
- */
- public RectF getClampedViewport() {
- RectF clampedViewport = new RectF(mViewportRect);
-
- // While the viewport size ought to never exceed the page size, we
- // do the clamping in this order to make sure that the origin is
- // never negative.
- if (clampedViewport.right > mPageSize.width)
- clampedViewport.offset(mPageSize.width - clampedViewport.right, 0);
- if (clampedViewport.left < 0)
- clampedViewport.offset(-clampedViewport.left, 0);
-
- if (clampedViewport.bottom > mPageSize.height)
- clampedViewport.offset(0, mPageSize.height - clampedViewport.bottom);
- if (clampedViewport.top < 0)
- clampedViewport.offset(0, -clampedViewport.top);
-
- return clampedViewport;
- }
-
- public PointF getViewportOffset() {
- return mViewportOffset;
- }
-
- public void setViewportOffset(PointF offset) {
- mViewportOffset = offset;
- }
-
- public FloatSize getPageSize() {
- return mPageSize;
- }
-
- public void setPageSize(FloatSize pageSize) {
- mPageSize = pageSize;
- }
-
- public float getZoomFactor() {
- return mZoomFactor;
- }
-
- public void setZoomFactor(float zoomFactor) {
- mZoomFactor = zoomFactor;
- }
-
- /* This will set the zoom factor and re-scale page-size and viewport offset
- * accordingly. The given focus will remain at the same point on the screen
- * after scaling.
- */
- public void scaleTo(float newZoomFactor, PointF focus) {
- float scaleFactor = newZoomFactor / mZoomFactor;
-
- mPageSize = mPageSize.scale(scaleFactor);
-
- PointF origin = getOrigin();
- origin.offset(focus.x, focus.y);
- origin = PointUtils.scale(origin, scaleFactor);
- origin.offset(-focus.x, -focus.y);
- setOrigin(origin);
-
- mZoomFactor = newZoomFactor;
-
- // Similar to setOrigin, set the viewport bias based on the focal point
- // of the zoom so that a viewport based on these metrics will have a
- // larger buffer based on the direction of movement when scaling.
- //
- // This is biased towards scaling outwards, as zooming in doesn't
- // really require a viewport bias.
- mViewportBias.set(((focus.x / mViewportRect.width()) * (2.0f * MAX_BIAS)) - MAX_BIAS,
- ((focus.y / mViewportRect.height()) * (2.0f * MAX_BIAS)) - MAX_BIAS);
- }
-
- /*
- * Returns the viewport metrics that represent a linear transition between `from` and `to` at
- * time `t`, which is on the scale [0, 1). This function interpolates the viewport rect, the
- * page size, the offset, and the zoom factor.
- */
- public ViewportMetrics interpolate(ViewportMetrics to, float t) {
- ViewportMetrics result = new ViewportMetrics();
- result.mPageSize = mPageSize.interpolate(to.mPageSize, t);
- result.mZoomFactor = FloatUtils.interpolate(mZoomFactor, to.mZoomFactor, t);
- result.mViewportRect = RectUtils.interpolate(mViewportRect, to.mViewportRect, t);
- result.mViewportOffset = PointUtils.interpolate(mViewportOffset, to.mViewportOffset, t);
- return result;
- }
-
- public boolean fuzzyEquals(ViewportMetrics other) {
- return mPageSize.fuzzyEquals(other.mPageSize)
- && RectUtils.fuzzyEquals(mViewportRect, other.mViewportRect)
- && FloatUtils.fuzzyEquals(mViewportOffset, other.mViewportOffset)
- && FloatUtils.fuzzyEquals(mZoomFactor, other.mZoomFactor);
- }
-
- public String toJSON() {
- // Round off height and width. Since the height and width are the size of the screen, it
- // makes no sense to send non-integer coordinates to Gecko.
- int height = Math.round(mViewportRect.height());
- int width = Math.round(mViewportRect.width());
-
- StringBuffer sb = new StringBuffer(256);
- sb.append("{ \"x\" : ").append(mViewportRect.left)
- .append(", \"y\" : ").append(mViewportRect.top)
- .append(", \"width\" : ").append(width)
- .append(", \"height\" : ").append(height)
- .append(", \"pageWidth\" : ").append(mPageSize.width)
- .append(", \"pageHeight\" : ").append(mPageSize.height)
- .append(", \"offsetX\" : ").append(mViewportOffset.x)
- .append(", \"offsetY\" : ").append(mViewportOffset.y)
- .append(", \"zoom\" : ").append(mZoomFactor)
- .append(" }");
- return sb.toString();
- }
-
- @Override
- public String toString() {
- StringBuffer buff = new StringBuffer(128);
- buff.append("v=").append(mViewportRect.toString())
- .append(" p=").append(mPageSize.toString())
- .append(" z=").append(mZoomFactor)
- .append(" o=").append(mViewportOffset.x)
- .append(',').append(mViewportOffset.y);
- return buff.toString();
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java
deleted file mode 100644
index 0f314ae71620..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Chris Lord <chrislord.net@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import android.graphics.Point;
-
-public class VirtualLayer extends Layer {
- private Listener mListener;
- private IntSize mSize;
-
- public void setListener(Listener listener) {
- mListener = listener;
- }
-
- @Override
- public void draw(RenderContext context) {
- // No-op.
- }
-
- @Override
- public IntSize getSize() {
- return mSize;
- }
-
- public void setSize(IntSize size) {
- mSize = size;
- }
-
- @Override
- protected boolean performUpdates(RenderContext context) {
- boolean dimensionsChanged = dimensionChangesPending();
- boolean result = super.performUpdates(context);
- if (dimensionsChanged && mListener != null) {
- mListener.dimensionsChanged(getOrigin(), getResolution());
- }
-
- return result;
- }
-
- public interface Listener {
- void dimensionsChanged(Point newOrigin, float newResolution);
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java
deleted file mode 100644
index b123d55c403d..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * James Willcox <jwillcox@mozilla.com>
- * Arkady Blyakher <rkadyb@mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.gfx;
-
-import org.libreoffice.LOKitShell;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.SingleTileLayer;
-//import org.mozilla.gecko.GeckoAppShell;
-import android.graphics.RectF;
-import android.util.Log;
-import android.opengl.GLES20;
-import java.nio.FloatBuffer;
-
-/**
- * Encapsulates the logic needed to draw the single-tiled Gecko texture
- */
-public class WidgetTileLayer extends Layer {
- private static final String LOGTAG = "WidgetTileLayer";
-
- private int[] mTextureIDs;
- private CairoImage mImage;
-
- public WidgetTileLayer(CairoImage image) {
- mImage = image;
- }
-
- protected boolean initialized() { return mTextureIDs != null; }
-
- @Override
- public IntSize getSize() { return mImage.getSize(); }
-
- protected void bindAndSetGLParameters() {
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
- GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
- }
-
- @Override
- protected void finalize() throws Throwable {
- if (mTextureIDs != null)
- TextureReaper.get().add(mTextureIDs);
- }
-
- @Override
- protected boolean performUpdates(RenderContext context) {
- super.performUpdates(context);
-
- if (mTextureIDs == null) {
- mTextureIDs = new int[1];
- GLES20.glGenTextures(1, mTextureIDs, 0);
- }
-
- bindAndSetGLParameters();
- LOKitShell.bindWidgetTexture();
-
- return true;
- }
-
- @Override
- public void draw(RenderContext context) {
- // mTextureIDs may be null here during startup if Layer.java's draw method
- // failed to acquire the transaction lock and call performUpdates.
- if (!initialized())
- return;
-
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]);
-
- RectF bounds;
- int[] cropRect;
- IntSize size = getSize();
- RectF viewport = context.viewport;
-
- bounds = getBounds(context, new FloatSize(size));
- cropRect = new int[] { 0, 0, size.width, size.height };
- bounds.offset(-viewport.left, -viewport.top);
-
- float top = viewport.height() - (bounds.top + bounds.height());
-
- // There may be errors from a previous GL call, so clear them first because
- // we want to check for one below
- while (GLES20.glGetError() != GLES20.GL_NO_ERROR);
-
- float[] coords = {
- //x, y, z, texture_x, texture_y
- bounds.left/viewport.width(), top/viewport.height(), 0,
- cropRect[0]/size.width, cropRect[1]/size.height,
-
- bounds.left/viewport.width(), (top+bounds.height())/viewport.height(), 0,
- cropRect[0]/size.width, cropRect[3]/size.height,
-
- (bounds.left+bounds.width())/viewport.width(), top/viewport.height(), 0,
- cropRect[2]/size.width, cropRect[1]/size.height,
-
- (bounds.left+bounds.width())/viewport.width(), (top+bounds.height())/viewport.height(),
- 0,
- cropRect[2]/size.width, cropRect[3]/size.height
- };
-
- // Get the buffer and handles from the context
- FloatBuffer coordBuffer = context.coordBuffer;
- int positionHandle = context.positionHandle;
- int textureHandle = context.textureHandle;
-
- // Make sure we are at position zero in the buffer in case other draw methods did not clean
- // up after themselves
- coordBuffer.position(0);
- coordBuffer.put(coords);
-
- // Vertex coordinates are x,y,z starting at position 0 into the buffer.
- coordBuffer.position(0);
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
-
- // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
- coordBuffer.position(3);
- GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-
- int error = GLES20.glGetError();
- if (error != GLES20.GL_NO_ERROR) {
- Log.i(LOGTAG, "Failed to draw texture: " + error);
- }
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java
deleted file mode 100644
index 8c0fce4c73b3..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Kartikaya Gupta <kgupta@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.ui;
-
-import org.mozilla.gecko.util.FloatUtils;
-
-/**
- * This class represents the physics for one axis of movement (i.e. either
- * horizontal or vertical). It tracks the different properties of movement
- * like displacement, velocity, viewport dimensions, etc. pertaining to
- * a particular axis.
- */
-abstract class Axis {
- // This fraction of velocity remains after every animation frame when the velocity is low.
- private static final float FRICTION_SLOW = 0.85f;
- // This fraction of velocity remains after every animation frame when the velocity is high.
- private static final float FRICTION_FAST = 0.97f;
- // Below this velocity (in pixels per frame), the friction starts increasing from FRICTION_FAST
- // to FRICTION_SLOW.
- private static final float VELOCITY_THRESHOLD = 10.0f;
- // The maximum velocity change factor between events, per ms, in %.
- // Direction changes are excluded.
- private static final float MAX_EVENT_ACCELERATION = 0.012f;
-
- // The rate of deceleration when the surface has overscrolled.
- private static final float OVERSCROLL_DECEL_RATE = 0.04f;
- // The percentage of the surface which can be overscrolled before it must snap back.
- private static final float SNAP_LIMIT = 0.75f;
-
- // The minimum amount of space that must be present for an axis to be considered scrollable,
- // in pixels.
- private static final float MIN_SCROLLABLE_DISTANCE = 0.5f;
- // The number of milliseconds per frame assuming 60 fps
- private static final float MS_PER_FRAME = 1000.0f / 60.0f;
-
- private enum FlingStates {
- STOPPED,
- PANNING,
- FLINGING,
- }
-
- private enum Overscroll {
- NONE,
- MINUS, // Overscrolled in the negative direction
- PLUS, // Overscrolled in the positive direction
- BOTH, // Overscrolled in both directions (page is zoomed to smaller than screen)
- }
-
- private final SubdocumentScrollHelper mSubscroller;
-
- private float mFirstTouchPos; /* Position of the first touch event on the current drag. */
- private float mTouchPos; /* Position of the most recent touch event on the current drag. */
- private float mLastTouchPos; /* Position of the touch event before touchPos. */
- private float mVelocity; /* Velocity in this direction; pixels per animation frame. */
- public boolean mScrollingDisabled; /* Whether movement on this axis is locked. */
- private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */
- private float mDisplacement;
-
- private FlingStates mFlingState; /* The fling state we're in on this axis. */
-
- protected abstract float getOrigin();
- protected abstract float getViewportLength();
- protected abstract float getPageLength();
-
- Axis(SubdocumentScrollHelper subscroller) {
- mSubscroller = subscroller;
- }
-
- private float getViewportEnd() {
- return getOrigin() + getViewportLength();
- }
-
- void startTouch(float pos) {
- mVelocity = 0.0f;
- mScrollingDisabled = false;
- mFirstTouchPos = mTouchPos = mLastTouchPos = pos;
- }
-
- float panDistance(float currentPos) {
- return currentPos - mFirstTouchPos;
- }
-
- void setScrollingDisabled(boolean disabled) {
- mScrollingDisabled = disabled;
- }
-
- void saveTouchPos() {
- mLastTouchPos = mTouchPos;
- }
-
- void updateWithTouchAt(float pos, float timeDelta) {
- float newVelocity = (mTouchPos - pos) / timeDelta * MS_PER_FRAME;
-
- // If there's a direction change, or current velocity is very low,
- // allow setting of the velocity outright. Otherwise, use the current
- // velocity and a maximum change factor to set the new velocity.
- boolean curVelocityIsLow = Math.abs(mVelocity) < 1.0f;
- boolean directionChange = (mVelocity > 0) != (newVelocity > 0);
- if (curVelocityIsLow || (directionChange && !FloatUtils.fuzzyEquals(newVelocity, 0.0f))) {
- mVelocity = newVelocity;
- } else {
- float maxChange = Math.abs(mVelocity * timeDelta * MAX_EVENT_ACCELERATION);
- mVelocity = Math.min(mVelocity + maxChange, Math.max(mVelocity - maxChange, newVelocity));
- }
-
- mTouchPos = pos;
- }
-
- boolean overscrolled() {
- return getOverscroll() != Overscroll.NONE;
- }
-
- private Overscroll getOverscroll() {
- boolean minus = (getOrigin() < 0.0f);
- boolean plus = (getViewportEnd() > getPageLength());
- if (minus && plus) {
- return Overscroll.BOTH;
- } else if (minus) {
- return Overscroll.MINUS;
- } else if (plus) {
- return Overscroll.PLUS;
- } else {
- return Overscroll.NONE;
- }
- }
-
- // Returns the amount that the page has been overscrolled. If the page hasn't been
- // overscrolled on this axis, returns 0.
- private float getExcess() {
- switch (getOverscroll()) {
- case MINUS: return -getOrigin();
- case PLUS: return getViewportEnd() - getPageLength();
- case BOTH: return getViewportEnd() - getPageLength() - getOrigin();
- default: return 0.0f;
- }
- }
-
- /*
- * Returns true if the page is zoomed in to some degree along this axis such that scrolling is
- * possible and this axis has not been scroll locked while panning. Otherwise, returns false.
- */
- private boolean scrollable() {
- return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE &&
- !mScrollingDisabled;
- }
-
- /*
- * Returns the resistance, as a multiplier, that should be taken into account when
- * tracking or pinching.
- */
- float getEdgeResistance() {
- float excess = getExcess();
- if (excess > 0.0f) {
- // excess can be greater than viewport length, but the resistance
- // must never drop below 0.0
- return Math.max(0.0f, SNAP_LIMIT - excess / getViewportLength());
- }
- return 1.0f;
- }
-
- /* Returns the velocity. If the axis is locked, returns 0. */
- float getRealVelocity() {
- return scrollable() ? mVelocity : 0f;
- }
-
- void startPan() {
- mFlingState = FlingStates.PANNING;
- }
-
- void startFling(boolean stopped) {
- mDisableSnap = mSubscroller.scrolling();
-
- if (stopped) {
- mFlingState = FlingStates.STOPPED;
- } else {
- mFlingState = FlingStates.FLINGING;
- }
- }
-
- /* Advances a fling animation by one step. */
- boolean advanceFling() {
- if (mFlingState != FlingStates.FLINGING) {
- return false;
- }
- if (mSubscroller.scrolling() && !mSubscroller.lastScrollSucceeded()) {
- // if the subdocument stopped scrolling, it's because it reached the end
- // of the subdocument. we don't do overscroll on subdocuments, so there's
- // no point in continuing this fling.
- return false;
- }
-
- float excess = getExcess();
- if (mDisableSnap || FloatUtils.fuzzyEquals(excess, 0.0f)) {
- // If we aren't overscrolled, just apply friction.
- if (Math.abs(mVelocity) >= VELOCITY_THRESHOLD) {
- mVelocity *= FRICTION_FAST;
- } else {
- float t = mVelocity / VELOCITY_THRESHOLD;
- mVelocity *= FloatUtils.interpolate(FRICTION_SLOW, FRICTION_FAST, t);
- }
- } else {
- // Otherwise, decrease the velocity linearly.
- float elasticity = 1.0f - excess / (getViewportLength() * SNAP_LIMIT);
- if (getOverscroll() == Overscroll.MINUS) {
- mVelocity = Math.min((mVelocity + OVERSCROLL_DECEL_RATE) * elasticity, 0.0f);
- } else { // must be Overscroll.PLUS
- mVelocity = Math.max((mVelocity - OVERSCROLL_DECEL_RATE) * elasticity, 0.0f);
- }
- }
-
- return true;
- }
-
- void stopFling() {
- mVelocity = 0.0f;
- mFlingState = FlingStates.STOPPED;
- }
-
- // Performs displacement of the viewport position according to the current velocity.
- void displace() {
- if (!mSubscroller.scrolling() && !scrollable())
- return;
-
- if (mFlingState == FlingStates.PANNING)
- mDisplacement += (mLastTouchPos - mTouchPos) * getEdgeResistance();
- else
- mDisplacement += mVelocity;
- }
-
- float resetDisplacement() {
- float d = mDisplacement;
- mDisplacement = 0.0f;
- return d;
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java
deleted file mode 100644
index c3cacccf805e..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java
+++ /dev/null
@@ -1,921 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2009-2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- * Kartikaya Gupta <kgupta@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.ui;
-
-import org.json.JSONObject;
-import org.json.JSONException;
-import org.libreoffice.LOKitShell;
-import org.libreoffice.LibreOfficeMainActivity;
-import org.mozilla.gecko.gfx.FloatSize;
-import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.PointUtils;
-import org.mozilla.gecko.gfx.ViewportMetrics;
-import org.mozilla.gecko.util.FloatUtils;
-import org.mozilla.gecko.GeckoEventListener;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.util.FloatMath;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import java.util.Timer;
-import java.util.TimerTask;
-
-/*
- * Handles the kinetic scrolling and zooming physics for a layer controller.
- *
- * Many ideas are from Joe Hewitt's Scrollability:
- * https://github.com/joehewitt/scrollability/
- */
-public class PanZoomController
- extends GestureDetector.SimpleOnGestureListener
- implements SimpleScaleGestureDetector.SimpleScaleGestureListener, GeckoEventListener
-{
- private static final String LOGTAG = "GeckoPanZoomController";
-
- private static String MESSAGE_ZOOM_RECT = "Browser:ZoomToRect";
- private static String MESSAGE_ZOOM_PAGE = "Browser:ZoomToPageWidth";
-
- // Animation stops if the velocity is below this value when overscrolled or panning.
- private static final float STOPPED_THRESHOLD = 4.0f;
-
- // Animation stops is the velocity is below this threshold when flinging.
- private static final float FLING_STOPPED_THRESHOLD = 0.1f;
-
- // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans
- // between the touch-down and touch-up of a click). In units of density-independent pixels.
- public static final float PAN_THRESHOLD = 1/16f * LOKitShell.getDpi();
-
- // Angle from axis within which we stay axis-locked
- private static final double AXIS_LOCK_ANGLE = Math.PI / 6.0; // 30 degrees
-
- // The maximum amount we allow you to zoom into a page
- private static final float MAX_ZOOM = 4.0f;
-
- /* 16 precomputed frames of the _ease-out_ animation from the CSS Transitions specification. */
- private static final float[] EASE_OUT_ANIMATION_FRAMES = {
- 0.00000f, /* 0 */
- 0.10211f, /* 1 */
- 0.19864f, /* 2 */
- 0.29043f, /* 3 */
- 0.37816f, /* 4 */
- 0.46155f, /* 5 */
- 0.54054f, /* 6 */
- 0.61496f, /* 7 */
- 0.68467f, /* 8 */
- 0.74910f, /* 9 */
- 0.80794f, /* 10 */
- 0.86069f, /* 11 */
- 0.90651f, /* 12 */
- 0.94471f, /* 13 */
- 0.97401f, /* 14 */
- 0.99309f, /* 15 */
- };
-
- private enum PanZoomState {
- NOTHING, /* no touch-start events received */
- FLING, /* all touches removed, but we're still scrolling page */
- TOUCHING, /* one touch-start event received */
- PANNING_LOCKED, /* touch-start followed by move (i.e. panning with axis lock) */
- PANNING, /* panning without axis lock */
- PANNING_HOLD, /* in panning, but not moving.
- * similar to TOUCHING but after starting a pan */
- PANNING_HOLD_LOCKED, /* like PANNING_HOLD, but axis lock still in effect */
- PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */
- ANIMATED_ZOOM /* animated zoom to a new rect */
- }
-
- private final LayerController mController;
- private final SubdocumentScrollHelper mSubscroller;
- private final Axis mX;
- private final Axis mY;
-
- private Thread mMainThread;
-
- /* The timer that handles flings or bounces. */
- private Timer mAnimationTimer;
- /* The runnable being scheduled by the animation timer. */
- private AnimationRunnable mAnimationRunnable;
- /* The zoom focus at the first zoom event (in page coordinates). */
- private PointF mLastZoomFocus;
- /* The time the last motion event took place. */
- private long mLastEventTime;
- /* Current state the pan/zoom UI is in. */
- private PanZoomState mState;
-
- public PanZoomController(LayerController controller) {
- mController = controller;
- mSubscroller = new SubdocumentScrollHelper(this);
- mX = new AxisX(mSubscroller);
- mY = new AxisY(mSubscroller);
-
- mMainThread = LibreOfficeMainActivity.mAppContext.getMainLooper().getThread();
- checkMainThread();
-
- mState = PanZoomState.NOTHING;
-
- //GeckoAppShell.registerGeckoEventListener(MESSAGE_ZOOM_RECT, this);
- //GeckoAppShell.registerGeckoEventListener(MESSAGE_ZOOM_PAGE, this);
- }
-
- // for debugging bug 713011; it can be taken out once that is resolved.
- private void checkMainThread() {
- if (mMainThread != Thread.currentThread()) {
- // log with full stack trace
- Log.e(LOGTAG, "Uh-oh, we're running on the wrong thread!", new Exception());
- }
- }
-
- public void handleMessage(String event, JSONObject message) {
- Log.i(LOGTAG, "Got message: " + event);
- try {
- if (MESSAGE_ZOOM_RECT.equals(event)) {
- float x = (float)message.getDouble("x");
- float y = (float)message.getDouble("y");
- final RectF zoomRect = new RectF(x, y,
- x + (float)message.getDouble("w"),
- y + (float)message.getDouble("h"));
- mController.post(new Runnable() {
- public void run() {
- animatedZoomTo(zoomRect);
- }
- });
- } else if (MESSAGE_ZOOM_PAGE.equals(event)) {
- FloatSize pageSize = mController.getPageSize();
-
- RectF viewableRect = mController.getViewport();
- float y = viewableRect.top;
- // attempt to keep zoom keep focused on the center of the viewport
- float newHeight = viewableRect.height() * pageSize.width / viewableRect.width();
- float dh = viewableRect.height() - newHeight; // increase in the height
- final RectF r = new RectF(0.0f,
- y + dh/2,
- pageSize.width,
- y + dh/2 + newHeight);
- mController.post(new Runnable() {
- public void run() {
- animatedZoomTo(r);
- }
- });
- }
- } catch (Exception e) {
- Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
- }
- }
-
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN: return onTouchStart(event);
- case MotionEvent.ACTION_MOVE: return onTouchMove(event);
- case MotionEvent.ACTION_UP: return onTouchEnd(event);
- case MotionEvent.ACTION_CANCEL: return onTouchCancel(event);
- default: return false;
- }
- }
-
- /** This function must be called from the UI thread. */
- public void abortAnimation() {
- checkMainThread();
- // this happens when gecko changes the viewport on us or if the device is rotated.
- // if that's the case, abort any animation in progress and re-zoom so that the page
- // snaps to edges. for other cases (where the user's finger(s) are down) don't do
- // anything special.
- switch (mState) {
- case FLING:
- mX.stopFling();
- mY.stopFling();
- mState = PanZoomState.NOTHING;
- // fall through
- case ANIMATED_ZOOM:
- // the zoom that's in progress likely makes no sense any more (such as if
- // the screen orientation changed) so abort it
- // fall through
- case NOTHING:
- // Don't do animations here; they're distracting and can cause flashes on page
- // transitions.
- mController.setViewportMetrics(getValidViewportMetrics());
- mController.notifyLayerClientOfGeometryChange();
- break;
- }
- }
-
- /** This must be called on the UI thread. */
- public void pageSizeUpdated() {
- if (mState == PanZoomState.NOTHING) {
- ViewportMetrics validated = getValidViewportMetrics();
- if (! mController.getViewportMetrics().fuzzyEquals(validated)) {
- // page size changed such that we are now in overscroll. snap to the
- // the nearest valid viewport
- mController.setViewportMetrics(validated);
- mController.notifyLayerClientOfGeometryChange();
- }
- }
- }
-
- /*
- * Panning/scrolling
- */
-
- private boolean onTouchStart(MotionEvent event) {
- Log.d(LOGTAG, "onTouchStart in state " + mState);
- // user is taking control of movement, so stop
- // any auto-movement we have going
- stopAnimationTimer();
- mSubscroller.cancel();
-
- switch (mState) {
- case ANIMATED_ZOOM:
- return false;
- case FLING:
- case NOTHING:
- startTouch(event.getX(0), event.getY(0), event.getEventTime());
- return false;
- case TOUCHING:
- case PANNING:
- case PANNING_LOCKED:
- case PANNING_HOLD:
- case PANNING_HOLD_LOCKED:
- case PINCHING:
- Log.e(LOGTAG, "Received impossible touch down while in " + mState);
- return false;
- }
- Log.e(LOGTAG, "Unhandled case " + mState + " in onTouchStart");
- return false;
- }
-
- private boolean onTouchMove(MotionEvent event) {
- Log.d(LOGTAG, "onTouchMove in state " + mState);
-
- switch (mState) {
- case NOTHING:
- case FLING:
- // should never happen
- Log.e(LOGTAG, "Received impossible touch move while in " + mState);
- return false;
-
- case TOUCHING:
- if (panDistance(event) < PAN_THRESHOLD) {
- return false;
- }
- cancelTouch();
- startPanning(event.getX(0), event.getY(0), event.getEventTime());
- //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */);
- //GeckoApp.mAutoCompletePopup.hide();
- track(event);
- return true;
-
- case PANNING_HOLD_LOCKED:
- //GeckoApp.mAutoCompletePopup.hide();
- mState = PanZoomState.PANNING_LOCKED;
- // fall through
- case PANNING_LOCKED:
- track(event);
- return true;
-
- case PANNING_HOLD:
- //GeckoApp.mAutoCompletePopup.hide();
- mState = PanZoomState.PANNING;
- // fall through
- case PANNING:
- track(event);
- return true;
-
- case ANIMATED_ZOOM:
- case PINCHING:
- // scale gesture listener will handle this
- return false;
- }
- Log.e(LOGTAG, "Unhandled case " + mState + " in onTouchMove");
- return false;
- }
-
- private boolean onTouchEnd(MotionEvent event) {
- Log.d(LOGTAG, "onTouchEnd in " + mState);
-
- switch (mState) {
- case NOTHING:
- case FLING:
- // should never happen
- Log.e(LOGTAG, "Received impossible touch end while in " + mState);
- return false;
- case TOUCHING:
- mState = PanZoomState.NOTHING;
- // the switch into TOUCHING might have happened while the page was
- // snapping back after overscroll. we need to finish the snap if that
- // was the case
- bounce();
- return false;
- case PANNING:
- case PANNING_LOCKED:
- case PANNING_HOLD:
- case PANNING_HOLD_LOCKED:
- mState = PanZoomState.FLING;
- fling();
- return true;
- case PINCHING:
- mState = PanZoomState.NOTHING;
- return true;
- case ANIMATED_ZOOM:
- return false;
- }
- Log.e(LOGTAG, "Unhandled case " + mState + " in onTouchEnd");
- return false;
- }
-
- private boolean onTouchCancel(MotionEvent event) {
- Log.d(LOGTAG, "onTouchCancel in " + mState);
-
- mState = PanZoomState.NOTHING;
- // ensure we snap back if we're overscrolled
- bounce();
- return false;
- }
-
- private void startTouch(float x, float y, long time) {
- mX.startTouch(x);
- mY.startTouch(y);
- mState = PanZoomState.TOUCHING;
- mLastEventTime = time;
- }
-
- private void startPanning(float x, float y, long time) {
- float dx = mX.panDistance(x);
- float dy = mY.panDistance(y);
- double angle = Math.atan2(dy, dx); // range [-pi, pi]
- angle = Math.abs(angle); // range [0, pi]
-
- // When the touch move breaks through the pan threshold, reposition the touch down origin
- // so the page won't jump when we start panning.
- mX.startTouch(x);
- mY.startTouch(y);
- mLastEventTime = time;
-
- if (angle < AXIS_LOCK_ANGLE || angle > (Math.PI - AXIS_LOCK_ANGLE)) {
- mY.setScrollingDisabled(true);
- mState = PanZoomState.PANNING_LOCKED;
- } else if (Math.abs(angle - (Math.PI / 2)) < AXIS_LOCK_ANGLE) {
- mX.setScrollingDisabled(true);
- mState = PanZoomState.PANNING_LOCKED;
- } else {
- mState = PanZoomState.PANNING;
- }
- }
-
- private float panDistance(MotionEvent move) {
- float dx = mX.panDistance(move.getX(0));
- float dy = mY.panDistance(move.getY(0));
- return FloatMath.sqrt(dx * dx + dy * dy);
- }
-
- private void track(float x, float y, long time) {
- float timeDelta = (float)(time - mLastEventTime);
- if (FloatUtils.fuzzyEquals(timeDelta, 0)) {
- // probably a duplicate event, ignore it. using a zero timeDelta will mess
- // up our velocity
- return;
- }
- mLastEventTime = time;
-
- mX.updateWithTouchAt(x, timeDelta);
- mY.updateWithTouchAt(y, timeDelta);
- }
-
- private void track(MotionEvent event) {
- mX.saveTouchPos();
- mY.saveTouchPos();
-
- for (int i = 0; i < event.getHistorySize(); i++) {
- track(event.getHistoricalX(0, i),
- event.getHistoricalY(0, i),
- event.getHistoricalEventTime(i));
- }
- track(event.getX(0), event.getY(0), event.getEventTime());
-
- if (stopped()) {
- if (mState == PanZoomState.PANNING) {
- mState = PanZoomState.PANNING_HOLD;
- } else if (mState == PanZoomState.PANNING_LOCKED) {
- mState = PanZoomState.PANNING_HOLD_LOCKED;
- } else {
- // should never happen, but handle anyway for robustness
- Log.e(LOGTAG, "Impossible case " + mState + " when stopped in track");
- mState = PanZoomState.PANNING_HOLD_LOCKED;
- }
- }
-
- mX.startPan();
- mY.startPan();
- updatePosition();
- }
-
- private void fling() {
- updatePosition();
-
- stopAnimationTimer();
-
- boolean stopped = stopped();
- mX.startFling(stopped);
- mY.startFling(stopped);
-
- startAnimationTimer(new FlingRunnable());
- }
-
- /* Performs a bounce-back animation to the given viewport metrics. */
- private void bounce(ViewportMetrics metrics) {
- stopAnimationTimer();
-
- ViewportMetrics bounceStartMetrics = new ViewportMetrics(mController.getViewportMetrics());
- if (bounceStartMetrics.fuzzyEquals(metrics)) {
- mState = PanZoomState.NOTHING;
- return;
- }
-
- mState = PanZoomState.FLING;
- Log.d(LOGTAG, "end bounce at " + metrics);
-
- startAnimationTimer(new BounceRunnable(bounceStartMetrics, metrics));
- }
-
- /* Performs a bounce-back animation to the nearest valid viewport metrics. */
- private void bounce() {
- bounce(getValidViewportMetrics());
- }
-
- /* Starts the fling or bounce animation. */
- private void startAnimationTimer(final AnimationRunnable runnable) {
- if (mAnimationTimer != null) {
- Log.e(LOGTAG, "Attempted to start a new fling without canceling the old one!");
- stopAnimationTimer();
- }
-
- //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */);
-
- mAnimationTimer = new Timer("Animation Timer");
- mAnimationRunnable = runnable;
- mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() { mController.post(runnable); }
- }, 0, 1000L/60L);
- }
-
- /* Stops the fling or bounce animation. */
- private void stopAnimationTimer() {
- if (mAnimationTimer != null) {
- mAnimationTimer.cancel();
- mAnimationTimer = null;
- }
- if (mAnimationRunnable != null) {
- mAnimationRunnable.terminate();
- mAnimationRunnable = null;
- }
-
- //GeckoApp.mAppContext.showPlugins();
- }
-
- private float getVelocity() {
- float xvel = mX.getRealVelocity();
- float yvel = mY.getRealVelocity();
- return FloatMath.sqrt(xvel * xvel + yvel * yvel);
- }
-
- private boolean stopped() {
- return getVelocity() < STOPPED_THRESHOLD;
- }
-
- PointF getDisplacement() {
- return new PointF(mX.resetDisplacement(), mY.resetDisplacement());
- }
-
- private void updatePosition() {
- mX.displace();
- mY.displace();
- PointF displacement = getDisplacement();
- if (! mSubscroller.scrollBy(displacement)) {
- synchronized (mController) {
- mController.scrollBy(displacement);
- }
- }
- }
-
- private abstract class AnimationRunnable implements Runnable {
- private boolean mAnimationTerminated;
-
- /* This should always run on the UI thread */
- public final void run() {
- /*
- * Since the animation timer queues this runnable on the UI thread, it
- * is possible that even when the animation timer is cancelled, there
- * are multiple instances of this queued, so we need to have another
- * mechanism to abort. This is done by using the mAnimationTerminated flag.
- */
- if (mAnimationTerminated) {
- return;
- }
- animateFrame();
- }
-
- protected abstract void animateFrame();
-
- /* This should always run on the UI thread */
- protected final void terminate() {
- mAnimationTerminated = true;
- }
- }
-
- /* The callback that performs the bounce animation. */
- private class BounceRunnable extends AnimationRunnable {
- /* The current frame of the bounce-back animation */
- private int mBounceFrame;
- /*
- * The viewport metrics that represent the start and end of the bounce-back animation,
- * respectively.
- */
- private ViewportMetrics mBounceStartMetrics;
- private ViewportMetrics mBounceEndMetrics;
-
- BounceRunnable(ViewportMetrics startMetrics, ViewportMetrics endMetrics) {
- mBounceStartMetrics = startMetrics;
- mBounceEndMetrics = endMetrics;
- }
-
- protected void animateFrame() {
- /*
- * The pan/zoom controller might have signaled to us that it wants to abort the
- * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
- * out.
- */
- if (mState != PanZoomState.FLING) {
- finishAnimation();
- return;
- }
-
- /* Perform the next frame of the bounce-back animation. */
- if (mBounceFrame < EASE_OUT_ANIMATION_FRAMES.length) {
- advanceBounce();
- return;
- }
-
- /* Finally, if there's nothing else to do, complete the animation and go to sleep. */
- finishBounce();
- finishAnimation();
- mState = PanZoomState.NOTHING;
- }
-
- /* Performs one frame of a bounce animation. */
- private void advanceBounce() {
- synchronized (mController) {
- float t = EASE_OUT_ANIMATION_FRAMES[mBounceFrame];
- ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
- mController.setViewportMetrics(newMetrics);
- mController.notifyLayerClientOfGeometryChange();
- mBounceFrame++;
- }
- }
-
- /* Concludes a bounce animation and snaps the viewport into place. */
- private void finishBounce() {
- synchronized (mController) {
- mController.setViewportMetrics(mBounceEndMetrics);
- mController.notifyLayerClientOfGeometryChange();
- mBounceFrame = -1;
- }
- }
- }
-
- // The callback that performs the fling animation.
- private class FlingRunnable extends AnimationRunnable {
- protected void animateFrame() {
- /*
- * The pan/zoom controller might have signaled to us that it wants to abort the
- * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail
- * out.
- */
- if (mState != PanZoomState.FLING) {
- finishAnimation();
- return;
- }
-
- /* Advance flings, if necessary. */
- boolean flingingX = mX.advanceFling();
- boolean flingingY = mY.advanceFling();
-
- boolean overscrolled = (mX.overscrolled() || mY.overscrolled());
-
- /* If we're still flinging in any direction, update the origin. */
- if (flingingX || flingingY) {
- updatePosition();
-
- /*
- * Check to see if we're still flinging with an appreciable velocity. The threshold is
- * higher in the case of overscroll, so we bounce back eagerly when overscrolling but
- * coast smoothly to a stop when not. In other words, require a greater velocity to
- * maintain the fling once we enter overscroll.
- */
- float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD);
- if (getVelocity() >= threshold) {
- // we're still flinging
- return;
- }
-
- mX.stopFling();
- mY.stopFling();
- }
-
- /* Perform a bounce-back animation if overscrolled. */
- if (overscrolled) {
- bounce();
- } else {
- finishAnimation();
- mState = PanZoomState.NOTHING;
- }
- }
- }
-
- private void finishAnimation() {
- checkMainThread();
-
- Log.d(LOGTAG, "Finishing animation at " + mController.getViewportMetrics());
- stopAnimationTimer();
-
- // Force a viewport synchronisation
- //GeckoApp.mAppContext.showPlugins();
- mController.setForceRedraw();
- mController.notifyLayerClientOfGeometryChange();
- }
-
- /* Returns the nearest viewport metrics with no overscroll visible. */
- private ViewportMetrics getValidViewportMetrics() {
- return getValidViewportMetrics(new ViewportMetrics(mController.getViewportMetrics()));
- }
-
- private ViewportMetrics getValidViewportMetrics(ViewportMetrics viewportMetrics) {
- Log.d(LOGTAG, "generating valid viewport using " + viewportMetrics);
-
- /* First, we adjust the zoom factor so that we can make no overscrolled area visible. */
- float zoomFactor = viewportMetrics.getZoomFactor();
- FloatSize pageSize = viewportMetrics.getPageSize();
- RectF viewport = viewportMetrics.getViewport();
-
- float focusX = viewport.width() / 2.0f;
- float focusY = viewport.height() / 2.0f;
- float minZoomFactor = 0.0f;
- if (viewport.width() > pageSize.width && pageSize.width > 0) {
- float scaleFactor = viewport.width() / pageSize.width;
- minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
- focusX = 0.0f;
- }
- if (viewport.height() > pageSize.height && pageSize.height > 0) {
- float scaleFactor = viewport.height() / pageSize.height;
- minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
- focusY = 0.0f;
- }
-
- if (!FloatUtils.fuzzyEquals(minZoomFactor, 0.0f)) {
- // if one (or both) of the page dimensions is smaller than the viewport,
- // zoom using the top/left as the focus on that axis. this prevents the
- // scenario where, if both dimensions are smaller than the viewport, but
- // by different scale factors, we end up scrolled to the end on one axis
- // after applying the scale
- PointF center = new PointF(focusX, focusY);
- viewportMetrics.scaleTo(minZoomFactor, center);
- } else if (zoomFactor > MAX_ZOOM) {
- PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f);
- viewportMetrics.scaleTo(MAX_ZOOM, center);
- }
-
- /* Now we pan to the right origin. */
- viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
- Log.d(LOGTAG, "generated valid viewport as " + viewportMetrics);
-
- return viewportMetrics;
- }
-
- private class AxisX extends Axis {
- AxisX(SubdocumentScrollHelper subscroller) { super(subscroller); }
- @Override
- public float getOrigin() { return mController.getOrigin().x; }
- @Override
- protected float getViewportLength() { return mController.getViewportSize().width; }
- @Override
- protected float getPageLength() { return mController.getPageSize().width; }
- }
-
- private class AxisY extends Axis {
- AxisY(SubdocumentScrollHelper subscroller) { super(subscroller); }
- @Override
- public float getOrigin() { return mController.getOrigin().y; }
- @Override
- protected float getViewportLength() { return mController.getViewportSize().height; }
- @Override
- protected float getPageLength() { return mController.getPageSize().height; }
- }
-
- /*
- * Zooming
- */
- @Override
- public boolean onScaleBegin(SimpleScaleGestureDetector detector) {
- Log.d(LOGTAG, "onScaleBegin in " + mState);
-
- if (mState == PanZoomState.ANIMATED_ZOOM)
- return false;
-
- mState = PanZoomState.PINCHING;
- mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
- //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers, only views */);
- //GeckoApp.mAutoCompletePopup.hide();
- cancelTouch();
-
- return true;
- }
-
- @Override
- public boolean onScale(SimpleScaleGestureDetector detector) {
- Log.d(LOGTAG, "onScale in state " + mState);
-
- if (mState == PanZoomState.ANIMATED_ZOOM)
- return false;
-
- float prevSpan = detector.getPreviousSpan();
- if (FloatUtils.fuzzyEquals(prevSpan, 0.0f)) {
- // let's eat this one to avoid setting the new zoom to infinity (bug 711453)
- return true;
- }
-
- float spanRatio = detector.getCurrentSpan() / prevSpan;
-
- /*
- * Apply edge resistance if we're zoomed out smaller than the page size by scaling the zoom
- * factor toward 1.0.
- */
- float resistance = Math.min(mX.getEdgeResistance(), mY.getEdgeResistance());
- if (spanRatio > 1.0f)
- spanRatio = 1.0f + (spanRatio - 1.0f) * resistance;
- else
- spanRatio = 1.0f - (1.0f - spanRatio) * resistance;
-
- synchronized (mController) {
- float newZoomFactor = mController.getZoomFactor() * spanRatio;
- if (newZoomFactor >= MAX_ZOOM) {
- // apply resistance when zooming past MAX_ZOOM,
- // such that it asymptotically reaches MAX_ZOOM + 1.0
- // but never exceeds that
- float excessZoom = newZoomFactor - MAX_ZOOM;
- excessZoom = 1.0f - (float)Math.exp(-excessZoom);
- newZoomFactor = MAX_ZOOM + excessZoom;
- }
-
- mController.scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(),
- mLastZoomFocus.y - detector.getFocusY()));
- PointF focus = new PointF(detector.getFocusX(), detector.getFocusY());
- mController.scaleWithFocus(newZoomFactor, focus);
- }
-
- mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY());
-
- return true;
- }
-
- @Override
- public void onScaleEnd(SimpleScaleGestureDetector detector) {
- Log.d(LOGTAG, "onScaleEnd in " + mState);
-
- if (mState == PanZoomState.ANIMATED_ZOOM)
- return;
-
- // switch back to the touching state
- startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime());
-
- // Force a viewport synchronisation
- //GeckoApp.mAppContext.showPlugins();
- mController.setForceRedraw();
- mController.notifyLayerClientOfGeometryChange();
- }
-
- public boolean getRedrawHint() {
- return (mState != PanZoomState.PINCHING && mState != PanZoomState.ANIMATED_ZOOM);
- }
-
- private void sendPointToGecko(String event, MotionEvent motionEvent) {
- String json;
- try {
- PointF point = new PointF(motionEvent.getX(), motionEvent.getY());
- point = mController.convertViewPointToLayerPoint(point);
- if (point == null) {
- return;
- }
- json = PointUtils.toJSON(point).toString();
- } catch (Exception e) {
- Log.e(LOGTAG, "Unable to convert point to JSON for " + event, e);
- return;
- }
-
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(event, json));
- }
-
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- sendPointToGecko("Gesture:LongPress", motionEvent);
- }
-
- @Override
- public boolean onDown(MotionEvent motionEvent) {
- sendPointToGecko("Gesture:ShowPress", motionEvent);
- return false;
- }
-
- @Override
- public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
- //GeckoApp.mAutoCompletePopup.hide();
- sendPointToGecko("Gesture:SingleTap", motionEvent);
- return true;
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent motionEvent) {
- sendPointToGecko("Gesture:DoubleTap", motionEvent);
- return true;
- }
-
- public void cancelTouch() {
- //GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", "");
- //GeckoAppShell.sendEventToGecko(e);
- }
-
- private boolean animatedZoomTo(RectF zoomToRect) {
- //GeckoApp.mAutoCompletePopup.hide();
-
- mState = PanZoomState.ANIMATED_ZOOM;
- final float startZoom = mController.getZoomFactor();
-
- RectF viewport = mController.getViewport();
- // 1. adjust the aspect ratio of zoomToRect to match that of the current viewport,
- // enlarging as necessary (if it gets too big, it will get shrunk in the next step).
- // while enlarging make sure we enlarge equally on both sides to keep the target rect
- // centered.
- float targetRatio = viewport.width() / viewport.height();
- float rectRatio = zoomToRect.width() / zoomToRect.height();
- if (FloatUtils.fuzzyEquals(targetRatio, rectRatio)) {
- // all good, do nothing
- } else if (targetRatio < rectRatio) {
- // need to increase zoomToRect height
- float newHeight = zoomToRect.width() / targetRatio;
- zoomToRect.top -= (newHeight - zoomToRect.height()) / 2;
- zoomToRect.bottom = zoomToRect.top + newHeight;
- } else { // targetRatio > rectRatio) {
- // need to increase zoomToRect width
- float newWidth = targetRatio * zoomToRect.height();
- zoomToRect.left -= (newWidth - zoomToRect.width()) / 2;
- zoomToRect.right = zoomToRect.left + newWidth;
- }
-
- float finalZoom = viewport.width() * startZoom / zoomToRect.width();
-
- ViewportMetrics finalMetrics = new ViewportMetrics(mController.getViewportMetrics());
- finalMetrics.setOrigin(new PointF(zoomToRect.left, zoomToRect.top));
- finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f));
-
- // 2. now run getValidViewportMetrics on it, so that the target viewport is
- // clamped down to prevent overscroll, over-zoom, and other bad conditions.
- finalMetrics = getValidViewportMetrics(finalMetrics);
-
- bounce(finalMetrics);
- return true;
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java
deleted file mode 100644
index 4f9e39857e81..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Patrick Walton <pcwalton@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.ui;
-
-import org.mozilla.gecko.gfx.PointUtils;
-import org.json.JSONException;
-import android.graphics.PointF;
-import android.util.Log;
-import android.view.MotionEvent;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Stack;
-
-/**
- * A less buggy, and smoother, replacement for the built-in Android ScaleGestureDetector.
- *
- * This gesture detector is more reliable than the built-in ScaleGestureDetector because:
- *
- * - It doesn't assume that pointer IDs are numbered 0 and 1.
- *
- * - It doesn't attempt to correct for "slop" when resting one's hand on the device. On some
- * devices (e.g. the Droid X) this can cause the ScaleGestureDetector to lose track of how many
- * pointers are down, with disastrous results (bug 706684).
- *
- * - Cancelling a zoom into a pan is handled correctly.
- *
- * - Starting with three or more fingers down, releasing fingers so that only two are down, and
- * then performing a scale gesture is handled correctly.
- *
- * - It doesn't take pressure into account, which results in smoother scaling.
- */
-public class SimpleScaleGestureDetector {
- private static final String LOGTAG = "GeckoSimpleScaleGestureDetector";
-
- private SimpleScaleGestureListener mListener;
- private long mLastEventTime;
-
- /* Information about all pointers that are down. */
- private LinkedList<PointerInfo> mPointerInfo;
-
- /** Creates a new gesture detector with the given listener. */
- public SimpleScaleGestureDetector(SimpleScaleGestureListener listener) {
- mListener = listener;
- mPointerInfo = new LinkedList<PointerInfo>();
- }
-
- /** Forward touch events to this function. */
- public void onTouchEvent(MotionEvent event) {
- switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_POINTER_DOWN:
- onTouchStart(event);
- break;
- case MotionEvent.ACTION_MOVE:
- onTouchMove(event);
- break;
- case MotionEvent.ACTION_POINTER_UP:
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- onTouchEnd(event);
- break;
- }
- }
-
- private int getPointersDown() {
- return mPointerInfo.size();
- }
-
- private int getActionIndex(MotionEvent event) {
- return (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
- >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
- }
-
- private void onTouchStart(MotionEvent event) {
- mLastEventTime = event.getEventTime();
- mPointerInfo.addFirst(PointerInfo.create(event, getActionIndex(event)));
- if (getPointersDown() == 2) {
- sendScaleGesture(EventType.BEGIN);
- }
- }
-
- private void onTouchMove(MotionEvent event) {
- mLastEventTime = event.getEventTime();
- for (int i = 0; i < event.getPointerCount(); i++) {
- PointerInfo pointerInfo = pointerInfoForEventIndex(event, i);
- if (pointerInfo != null) {
- pointerInfo.populate(event, i);
- }
- }
-
- if (getPointersDown() == 2) {
- sendScaleGesture(EventType.CONTINUE);
- }
- }
-
- private void onTouchEnd(MotionEvent event) {
- mLastEventTime = event.getEventTime();
-
- int id = event.getPointerId(getActionIndex(event));
- ListIterator<PointerInfo> iterator = mPointerInfo.listIterator();
- while (iterator.hasNext()) {
- PointerInfo pointerInfo = iterator.next();
- if (pointerInfo.getId() != id) {
- continue;
- }
-
- // One of the pointers we were tracking was lifted. Remove its info object from the
- // list, recycle it to avoid GC pauses, and send an onScaleEnd() notification if this
- // ended the gesture.
- iterator.remove();
- pointerInfo.recycle();
- if (getPointersDown() == 1) {
- sendScaleGesture(EventType.END);
- }
- }
- }
-
- /**
- * Returns the X coordinate of the focus location (the midpoint of the two fingers). If only
- * one finger is down, returns the location of that finger.
- */
- public float getFocusX() {
- switch (getPointersDown()) {
- case 1:
- return mPointerInfo.getFirst().getCurrent().x;
- case 2:
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- return (pointerA.getCurrent().x + pointerB.getCurrent().x) / 2.0f;
- }
-
- Log.e(LOGTAG, "No gesture taking place in getFocusX()!");
- return 0.0f;
- }
-
- /**
- * Returns the Y coordinate of the focus location (the midpoint of the two fingers). If only
- * one finger is down, returns the location of that finger.
- */
- public float getFocusY() {
- switch (getPointersDown()) {
- case 1:
- return mPointerInfo.getFirst().getCurrent().y;
- case 2:
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- return (pointerA.getCurrent().y + pointerB.getCurrent().y) / 2.0f;
- }
-
- Log.e(LOGTAG, "No gesture taking place in getFocusY()!");
- return 0.0f;
- }
-
- /** Returns the most recent distance between the two pointers. */
- public float getCurrentSpan() {
- if (getPointersDown() != 2) {
- Log.e(LOGTAG, "No gesture taking place in getCurrentSpan()!");
- return 0.0f;
- }
-
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- return PointUtils.distance(pointerA.getCurrent(), pointerB.getCurrent());
- }
-
- /** Returns the second most recent distance between the two pointers. */
- public float getPreviousSpan() {
- if (getPointersDown() != 2) {
- Log.e(LOGTAG, "No gesture taking place in getPreviousSpan()!");
- return 0.0f;
- }
-
- PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast();
- PointF a = pointerA.getPrevious(), b = pointerB.getPrevious();
- if (a == null || b == null) {
- a = pointerA.getCurrent();
- b = pointerB.getCurrent();
- }
-
- return PointUtils.distance(a, b);
- }
-
- /** Returns the time of the last event related to the gesture. */
- public long getEventTime() {
- return mLastEventTime;
- }
-
- /** Returns true if the scale gesture is in progress and false otherwise. */
- public boolean isInProgress() {
- return getPointersDown() == 2;
- }
-
- /* Sends the requested scale gesture notification to the listener. */
- private void sendScaleGesture(EventType eventType) {
- switch (eventType) {
- case BEGIN: mListener.onScaleBegin(this); break;
- case CONTINUE: mListener.onScale(this); break;
- case END: mListener.onScaleEnd(this); break;
- }
- }
-
- /*
- * Returns the pointer info corresponding to the given pointer index, or null if the pointer
- * isn't one that's being tracked.
- */
- private PointerInfo pointerInfoForEventIndex(MotionEvent event, int index) {
- int id = event.getPointerId(index);
- for (PointerInfo pointerInfo : mPointerInfo) {
- if (pointerInfo.getId() == id) {
- return pointerInfo;
- }
- }
- return null;
- }
-
- private enum EventType {
- BEGIN,
- CONTINUE,
- END,
- }
-
- /* Encapsulates information about one of the two fingers involved in the gesture. */
- private static class PointerInfo {
- /* A free list that recycles pointer info objects, to reduce GC pauses. */
- private static Stack<PointerInfo> sPointerInfoFreeList;
-
- private int mId;
- private PointF mCurrent, mPrevious;
-
- private PointerInfo() {
- // External users should use create() instead.
- }
-
- /* Creates or recycles a new PointerInfo instance from an event and a pointer index. */
- public static PointerInfo create(MotionEvent event, int index) {
- if (sPointerInfoFreeList == null) {
- sPointerInfoFreeList = new Stack<PointerInfo>();
- }
-
- PointerInfo pointerInfo;
- if (sPointerInfoFreeList.empty()) {
- pointerInfo = new PointerInfo();
- } else {
- pointerInfo = sPointerInfoFreeList.pop();
- }
-
- pointerInfo.populate(event, index);
- return pointerInfo;
- }
-
- /*
- * Fills in the fields of this instance from the given motion event and pointer index
- * within that event.
- */
- public void populate(MotionEvent event, int index) {
- mId = event.getPointerId(index);
- mPrevious = mCurrent;
- mCurrent = new PointF(event.getX(index), event.getY(index));
- }
-
- public void recycle() {
- mId = -1;
- mPrevious = mCurrent = null;
- sPointerInfoFreeList.push(this);
- }
-
- public int getId() { return mId; }
- public PointF getCurrent() { return mCurrent; }
- public PointF getPrevious() { return mPrevious; }
-
- @Override
- public String toString() {
- if (mId == -1) {
- return "(up)";
- }
-
- try {
- String prevString;
- if (mPrevious == null) {
- prevString = "n/a";
- } else {
- prevString = PointUtils.toJSON(mPrevious).toString();
- }
-
- // The current position should always be non-null.
- String currentString = PointUtils.toJSON(mCurrent).toString();
- return "id=" + mId + " cur=" + currentString + " prev=" + prevString;
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public static interface SimpleScaleGestureListener {
- public boolean onScale(SimpleScaleGestureDetector detector);
- public boolean onScaleBegin(SimpleScaleGestureDetector detector);
- public void onScaleEnd(SimpleScaleGestureDetector detector);
- }
-}
-
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java
deleted file mode 100644
index f24a5b7adaa1..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Android code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2012
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Kartikaya Gupta <kgupta@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package org.mozilla.gecko.ui;
-
-
-import android.graphics.PointF;
-import android.os.Handler;
-import android.util.Log;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.mozilla.gecko.GeckoEventListener;
-
-class SubdocumentScrollHelper implements GeckoEventListener {
- private static final String LOGTAG = "GeckoSubdocumentScrollHelper";
-
- private static String MESSAGE_PANNING_OVERRIDE = "Panning:Override";
- private static String MESSAGE_CANCEL_OVERRIDE = "Panning:CancelOverride";
- private static String MESSAGE_SCROLL = "Gesture:Scroll";
- private static String MESSAGE_SCROLL_ACK = "Gesture:ScrollAck";
-
- private final PanZoomController mPanZoomController;
- private final Handler mUiHandler;
-
- private boolean mOverridePanning;
- private boolean mOverrideScrollAck;
- private boolean mOverrideScrollPending;
- private boolean mScrollSucceeded;
-
- SubdocumentScrollHelper(PanZoomController controller) {
- mPanZoomController = controller;
- // mUiHandler will be bound to the UI thread since that's where this constructor runs
- mUiHandler = new Handler();
-
- //GeckoAppShell.registerGeckoEventListener(MESSAGE_PANNING_OVERRIDE, this);
- //GeckoAppShell.registerGeckoEventListener(MESSAGE_CANCEL_OVERRIDE, this);
- //GeckoAppShell.registerGeckoEventListener(MESSAGE_SCROLL_ACK, this);
- }
-
- boolean scrollBy(PointF displacement) {
- if (!mOverridePanning) {
- return false;
- }
-
- if (!mOverrideScrollAck) {
- mOverrideScrollPending = true;
- return true;
- }
-
- mOverrideScrollAck = false;
- mOverrideScrollPending = false;
-
- JSONObject json = new JSONObject();
- try {
- json.put("x", displacement.x);
- json.put("y", displacement.y);
- } catch (JSONException e) {
- Log.e(LOGTAG, "Error forming subwindow scroll message: ", e);
- }
- //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(MESSAGE_SCROLL, json.toString()));
-
- return true;
- }
-
- void cancel() {
- mOverridePanning = false;
- }
-
- boolean scrolling() {
- return mOverridePanning;
- }
-
- boolean lastScrollSucceeded() {
- return mScrollSucceeded;
- }
-
- // GeckoEventListener implementation
-
- public void handleMessage(final String event, final JSONObject message) {
- // this comes in on the gecko thread; hand off the handling to the UI thread
- mUiHandler.post(new Runnable() {
- public void run() {
- Log.i(LOGTAG, "Got message: " + event);
- try {
- if (MESSAGE_PANNING_OVERRIDE.equals(event)) {
- mOverridePanning = true;
- mOverrideScrollAck = true;
- mOverrideScrollPending = false;
- mScrollSucceeded = true;
- } else if (MESSAGE_CANCEL_OVERRIDE.equals(event)) {
- mOverridePanning = false;
- } else if (MESSAGE_SCROLL_ACK.equals(event)) {
- mOverrideScrollAck = true;
- mScrollSucceeded = message.getBoolean("scrolled");
- if (mOverridePanning && mOverrideScrollPending) {
- scrollBy(mPanZoomController.getDisplacement());
- }
- }
- } catch (Exception e) {
- Log.e(LOGTAG, "Exception handling message", e);
- }
- }
- });
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java
deleted file mode 100644
index b4bb249c4d5f..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.util;
-
-import android.graphics.PointF;
-
-import java.lang.IllegalArgumentException;
-
-public final class FloatUtils {
- private FloatUtils() {}
-
- public static boolean fuzzyEquals(float a, float b) {
- return (Math.abs(a - b) < 1e-6);
- }
-
- public static boolean fuzzyEquals(PointF a, PointF b) {
- return fuzzyEquals(a.x, b.x) && fuzzyEquals(a.y, b.y);
- }
-
- /*
- * Returns the value that represents a linear transition between `from` and `to` at time `t`,
- * which is on the scale [0, 1). Thus with t = 0.0f, this returns `from`; with t = 1.0f, this
- * returns `to`; with t = 0.5f, this returns the value halfway from `from` to `to`.
- */
- public static float interpolate(float from, float to, float t) {
- return from + (to - from) * t;
- }
-
- /**
- * Returns 'value', clamped so that it isn't any lower than 'low', and it
- * isn't any higher than 'high'.
- */
- public static float clamp(float value, float low, float high) {
- if (high < low) {
- throw new IllegalArgumentException(
- "clamp called with invalid parameters (" + high + " < " + low + ")" );
- }
- return Math.max(low, Math.min(high, value));
- }
-}
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.png
deleted file mode 100644
index 729dbcd82ebf..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.png
deleted file mode 100644
index a3f5fd4d80c0..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png
deleted file mode 100644
index 72713b58a39a..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png
deleted file mode 100644
index 4a1070335804..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png
deleted file mode 100644
index 2150c890ed6f..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png
deleted file mode 100644
index 8a12a76b46ca..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png
deleted file mode 100644
index 5a72e1701b3c..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png
deleted file mode 100644
index 3abb776699ab..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png
deleted file mode 100644
index 9e46db76a416..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png
deleted file mode 100644
index c6091ae0ff7e..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png
deleted file mode 100644
index 978606d5b462..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.png
deleted file mode 100644
index b3ee11426a04..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.png
deleted file mode 100644
index c58d276e7085..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 96a442e5b8e9..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.png
deleted file mode 100644
index d5f16694f342..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.png
deleted file mode 100644
index 5909f05bf089..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.png
deleted file mode 100644
index 2ef86417e69e..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.png
deleted file mode 100644
index 7e8e2a05e2da..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.png
deleted file mode 100644
index 50b8dc863bff..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.png
deleted file mode 100644
index 7e8e2a05e2da..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.png
deleted file mode 100644
index 611592b5167a..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.png
deleted file mode 100644
index 729dbcd82ebf..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.png
deleted file mode 100644
index a3f5fd4d80c0..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.png
deleted file mode 100644
index ab34ae5638e1..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.png
deleted file mode 100644
index b3ee11426a04..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 359047dfa4ed..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.png
deleted file mode 100644
index 835fc9290727..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.png
deleted file mode 100644
index 5909f05bf089..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.png
deleted file mode 100644
index 4f3f89beadc2..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.png
deleted file mode 100644
index 3ce69155c6b5..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.png
deleted file mode 100644
index 2f4abcb280cd..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.png
deleted file mode 100644
index 729dbcd82ebf..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.png
deleted file mode 100644
index a3f5fd4d80c0..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.png
deleted file mode 100644
index b3ee11426a04..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 71c6d760f051..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.png
deleted file mode 100644
index c8005425416a..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.png
deleted file mode 100644
index 5909f05bf089..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.png
deleted file mode 100644
index 2f4abcb280cd..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644
index 4df18946442e..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml b/android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index 7b53d58a2b5c..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/main_layout"
- android:background="#fff"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <RelativeLayout
- android:id="@+id/gecko_layout"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1"/>
-
-</LinearLayout> \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/app/src/main/res/menu/main.xml b/android/experimental/LOAndroid2/app/src/main/res/menu/main.xml
deleted file mode 100644
index e9709c90d729..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/menu/main.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- tools:context="org.libreoffice.MainActivity" >
- <item android:id="@+id/action_settings"
- android:title="@string/action_settings"
- android:orderInCategory="100" />
-</menu>
diff --git a/android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml b/android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml
deleted file mode 100644
index 63fc81644461..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<resources>
- <!-- Example customization of dimensions originally defined in res/values/dimens.xml
- (such as screen margins) for screens with more than 820dp of available width. This
- would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
- <dimen name="activity_horizontal_margin">64dp</dimen>
-</resources>
diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/colors.xml b/android/experimental/LOAndroid2/app/src/main/res/values/colors.xml
deleted file mode 100644
index f8e207d4e00e..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<resources>
- <color name="background_light">#FFECF0F3</color>
- <color name="background_normal">#FFCED7DE</color>
- <color name="background_private">#FF292C29</color>
- <color name="background_tabs">#FF363B40</color>
- <color name="highlight">#33000000</color>
- <color name="highlight_focused">#1A000000</color>
- <color name="highlight_dark">#33FFFFFF</color>
- <color name="highlight_dark_focused">#1AFFFFFF</color>
-
- <!-- highlight on shaped button: 20% white over background_tabs -->
- <color name="highlight_shaped">#FF696D71</color>
-
- <!-- highlight-focused on shaped button: 10% white over background_tabs -->
- <color name="highlight_shaped_focused">#FF565B60</color>
-
- <!-- highlight on nav button: 20% black over background_normal -->
- <color name="highlight_nav">#FFA5ACB2</color>
-
- <!-- highlight-focused on nav button: 10% black over background_normal -->
- <color name="highlight_nav_focused">#FFB9C1C7</color>
-
- <!-- highlight on private nav button: 20% white over background_private -->
- <color name="highlight_nav_pb">#FF545654</color>
-
- <!-- highlight-focused on private nav button: 10% white over background_private -->
- <color name="highlight_nav_focused_pb">#FF3F423F</color>
-
- <!--
- Application theme colors
- -->
- <!-- Default colors -->
- <color name="text_color_primary">#222222</color>
- <color name="text_color_secondary">#777777</color>
- <color name="text_color_tertiary">#9198A1</color>
-
- <!-- Default inverse colors -->
- <color name="text_color_primary_inverse">#FFFFFF</color>
- <color name="text_color_secondary_inverse">#DDDDDD</color>
- <color name="text_color_tertiary_inverse">#A4A7A9</color>
-
- <!-- Disabled colors -->
- <color name="text_color_primary_disable_only">#999999</color>
-
- <!-- Hint colors -->
- <color name="text_color_hint">#666666</color>
- <color name="text_color_hint_inverse">#7F828A</color>
-
- <!-- Highlight colors -->
- <color name="text_color_highlight">#FF9500</color>
- <color name="text_color_highlight_inverse">#D06BFF</color>
-
- <!-- Link colors -->
- <color name="text_color_link">#22629E</color>
-
- <color name="splash_background">#000000</color>
- <color name="splash_msgfont">#ffffff</color>
- <color name="splash_urlfont">#000000</color>
- <color name="splash_content">#ffffff</color>
-
- <color name="doorhanger_text">#FF222222</color>
- <color name="doorhanger_link">#FF2AA1FE</color>
- <color name="doorhanger_divider_light">#FFD1D5DA</color>
- <color name="doorhanger_divider_dark">#FFB3C2CE</color>
- <color name="doorhanger_background_dark">#FFDDE4EA</color>
-
- <color name="validation_message_text">#ffffff</color>
- <color name="url_bar_text_highlight">#FFFF9500</color>
- <color name="url_bar_text_highlight_pb">#FFD06BFF</color>
- <color name="suggestion_primary">#dddddd</color>
- <color name="suggestion_pressed">#bbbbbb</color>
- <color name="tab_row_pressed">#4D000000</color>
- <color name="dialogtitle_textcolor">#ffffff</color>
-
- <color name="textbox_background">#FFF</color>
- <color name="textbox_background_disabled">#DDD</color>
- <color name="textbox_stroke">#000</color>
- <color name="textbox_stroke_disabled">#666</color>
-
- <color name="url_bar_urltext">#A6A6A6</color>
- <color name="url_bar_domaintext">#000</color>
- <color name="url_bar_domaintext_private">#FFF</color>
- <color name="url_bar_blockedtext">#b14646</color>
- <color name="url_bar_shadow">#12000000</color>
-
- <color name="home_last_tab_bar_bg">#FFF5F7F9</color>
-
- <color name="panel_grid_item_image_background">#D1D9E1</color>
-</resources>
-
diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml b/android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml
deleted file mode 100644
index 47c82246738c..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<resources>
- <!-- Default screen margins, per the Android Design guidelines. -->
- <dimen name="activity_horizontal_margin">16dp</dimen>
- <dimen name="activity_vertical_margin">16dp</dimen>
-</resources>
diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/strings.xml b/android/experimental/LOAndroid2/app/src/main/res/values/strings.xml
deleted file mode 100644
index 8864167560f8..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
- <string name="app_name">LOAndroid</string>
- <string name="hello_world">Hello world!</string>
- <string name="action_settings">Settings</string>
-
-</resources>
diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/styles.xml b/android/experimental/LOAndroid2/app/src/main/res/values/styles.xml
deleted file mode 100644
index ff6c9d2c0fb9..000000000000
--- a/android/experimental/LOAndroid2/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
-
- <!-- Base application theme. -->
- <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
- <!-- Customize your theme here. -->
- </style>
-
-</resources>
diff --git a/android/experimental/LOAndroid2/build.gradle b/android/experimental/LOAndroid2/build.gradle
deleted file mode 100644
index e33f142839c8..000000000000
--- a/android/experimental/LOAndroid2/build.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:0.12.+'
- }
-}
-
-allprojects {
- repositories {
- mavenCentral()
- }
-}
diff --git a/android/experimental/LOAndroid2/gradle.properties b/android/experimental/LOAndroid2/gradle.properties
deleted file mode 100644
index 5d08ba75bb97..000000000000
--- a/android/experimental/LOAndroid2/gradle.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Settings specified in this file will override any Gradle settings
-# configured through the IDE.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true \ No newline at end of file
diff --git a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jar b/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 8c0fb64a8698..000000000000
--- a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties b/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 2405fae37f2f..000000000000
--- a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Mon Jun 09 10:23:20 CEST 2014
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
diff --git a/android/experimental/LOAndroid2/gradlew b/android/experimental/LOAndroid2/gradlew
deleted file mode 100755
index 91a7e269e19d..000000000000
--- a/android/experimental/LOAndroid2/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/android/experimental/LOAndroid2/gradlew.bat b/android/experimental/LOAndroid2/gradlew.bat
deleted file mode 100644
index aec99730b4e8..000000000000
--- a/android/experimental/LOAndroid2/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/android/experimental/LOAndroid2/settings.gradle b/android/experimental/LOAndroid2/settings.gradle
deleted file mode 100644
index e7b4def49cb5..000000000000
--- a/android/experimental/LOAndroid2/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-include ':app'