15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_BROWSER_RENDERER_HOST_COMPOSITOR_IMPL_ANDROID_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_BROWSER_RENDERER_HOST_COMPOSITOR_IMPL_ANDROID_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/cancelable_callback.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/weak_ptr.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host_client.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "cc/trees/layer_tree_host_single_thread_client.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/browser/android/ui_resource_provider_impl.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/renderer_host/image_transport_factory_android.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/content_export.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/common/gpu/client/context_provider_command_buffer.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/android/compositor.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "gpu/command_buffer/common/capabilities.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h" 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/base/android/system_ui_resource_manager.h" 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/base/android/window_android_compositor.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SkBitmap; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ANativeWindow; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Layer; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LayerTreeHost; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass CompositorClient; 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class UIResourceProvider; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Browser-side compositor that manages a tree of content and UI layers. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CONTENT_EXPORT CompositorImpl 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public Compositor, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public cc::LayerTreeHostClient, 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public cc::LayerTreeHostSingleThreadClient, 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public ImageTransportFactoryAndroidObserver, 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public ui::WindowAndroidCompositor { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CompositorImpl(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsInitialized(); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 524ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Creates a surface texture and returns a surface texture id. Returns -1 on 534ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // failure. 544ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch static int CreateSurfaceTexture(int child_process_id); 554ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 564ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Destroy all surface textures associated with |child_process_id|. 574ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch static void DestroyAllSurfaceTextures(int child_process_id); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void PopulateGpuCapabilities(gpu::Capabilities gpu_capabilities); 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compositor implementation. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetRootLayer(scoped_refptr<cc::Layer> root) OVERRIDE; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetSurface(jobject surface) OVERRIDE; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetVisible(bool visible) OVERRIDE; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void setDeviceScaleFactor(float factor) OVERRIDE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetWindowBounds(const gfx::Size& size) OVERRIDE; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetHasTransparentBackground(bool flag) OVERRIDE; 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void SetNeedsComposite() OVERRIDE; 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual UIResourceProvider& GetUIResourceProvider() OVERRIDE; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // LayerTreeHostClient implementation. 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void WillBeginMainFrame(int frame_id) OVERRIDE {} 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual void DidBeginMainFrame() OVERRIDE {} 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual void BeginMainFrame(const cc::BeginFrameArgs& args) OVERRIDE {} 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void Layout() OVERRIDE; 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void ApplyViewportDeltas( 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Vector2d& scroll_delta, 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci float page_scale, 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci float top_controls_delta) OVERRIDE {} 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void RequestNewOutputSurface(bool fallback) OVERRIDE; 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void DidInitializeOutputSurface() OVERRIDE {} 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void WillCommit() OVERRIDE {} 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void DidCommit() OVERRIDE; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DidCommitAndDrawFrame() OVERRIDE {} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void DidCompleteSwapBuffers() OVERRIDE; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // LayerTreeHostSingleThreadClient implementation. 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void ScheduleComposite() OVERRIDE; 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void ScheduleAnimation() OVERRIDE; 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void DidPostSwapBuffers() OVERRIDE; 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void DidAbortSwapBuffers() OVERRIDE; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // ImageTransportFactoryAndroidObserver implementation. 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void OnLostResources() OVERRIDE; 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // WindowAndroidCompositor implementation. 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) OVERRIDE; 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void RequestCopyOfOutputOnRootLayer( 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<cc::CopyOutputRequest> request) OVERRIDE; 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnVSync(base::TimeTicks frame_time, 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta vsync_period) OVERRIDE; 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void SetNeedsAnimate() OVERRIDE; 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual ui::SystemUIResourceManager& GetSystemUIResourceManager() OVERRIDE; 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void SetWindowSurface(ANativeWindow* window); 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) enum CompositingTrigger { 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DO_NOT_COMPOSITE, 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) COMPOSITE_IMMEDIATELY, 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) COMPOSITE_EVENTUALLY, 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void PostComposite(CompositingTrigger trigger); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void Composite(CompositingTrigger trigger); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void CreateOutputSurface(bool fallback); 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool WillCompositeThisFrame() const { 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return current_composite_task_ && 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !current_composite_task_->callback().is_null(); 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool DidCompositeThisFrame() const { 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return current_composite_task_ && 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_composite_task_->callback().is_null(); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool WillComposite() const { 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return WillCompositeThisFrame() || 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) composite_on_vsync_trigger_ != DO_NOT_COMPOSITE; 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void CancelComposite() { 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(WillComposite()); 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (WillCompositeThisFrame()) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_composite_task_->Cancel(); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_composite_task_.reset(); 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) composite_on_vsync_trigger_ = DO_NOT_COMPOSITE; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) will_composite_immediately_ = false; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void OnGpuChannelEstablished(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // root_layer_ is the persistent internal root layer, while subroot_layer_ 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // is the one attached by the compositor client. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<cc::Layer> root_layer_; 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<cc::Layer> subroot_layer_; 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<cc::LayerTreeHost> host_; 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) content::UIResourceProviderImpl ui_resource_provider_; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size size_; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_transparent_background_; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) float device_scale_factor_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ANativeWindow* window_; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int surface_id_; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CompositorClient* client_; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::NativeWindow root_window_; 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Used locally to track whether a call to LTH::Composite() did result in 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // a posted SwapBuffers(). 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool did_post_swapbuffers_; 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Used locally to inhibit ScheduleComposite() during Layout(). 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool ignore_schedule_composite_; 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Whether we need to composite in general because of any invalidation or 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // explicit request. 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool needs_composite_; 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Whether we need to update animations on the next composite. 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool needs_animate_; 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Whether we posted a task and are about to composite. 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool will_composite_immediately_; 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // How we should schedule Composite during the next vsync. 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CompositingTrigger composite_on_vsync_trigger_; 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The Composite operation scheduled for the current vsync interval. 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<base::CancelableClosure> current_composite_task_; 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The number of SwapBuffer calls that have not returned and ACK'd from 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the GPU thread. 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) unsigned int pending_swapbuffers_; 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta vsync_period_; 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeTicks last_vsync_; 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::WeakPtrFactory<CompositorImpl> weak_factory_; 18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CompositorImpl); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITOR_IMPL_ANDROID_H_ 196