Home | History | Annotate | Download | only in bindings
      1 // Copyright 2016 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
      7 
      8 #include "base/macros.h"
      9 #include "base/threading/thread_restrictions.h"
     10 #include "mojo/public/cpp/bindings/bindings_export.h"
     11 
     12 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
     13 #define ENABLE_SYNC_CALL_RESTRICTIONS 1
     14 #else
     15 #define ENABLE_SYNC_CALL_RESTRICTIONS 0
     16 #endif
     17 
     18 class ChromeSelectFileDialogFactory;
     19 
     20 namespace sync_preferences {
     21 class PrefServiceSyncable;
     22 }
     23 
     24 namespace content {
     25 class BlinkTestController;
     26 }
     27 
     28 namespace display {
     29 class ForwardingDisplayDelegate;
     30 }
     31 
     32 namespace leveldb {
     33 class LevelDBMojoProxy;
     34 }
     35 
     36 namespace prefs {
     37 class PersistentPrefStoreClient;
     38 }
     39 
     40 namespace ui {
     41 class ClipboardClient;
     42 class HostContextFactoryPrivate;
     43 }  // namespace ui
     44 
     45 namespace viz {
     46 class HostFrameSinkManager;
     47 }
     48 
     49 namespace mojo {
     50 class ScopedAllowSyncCallForTesting;
     51 
     52 // In some processes, sync calls are disallowed. For example, in the browser
     53 // process we don't want any sync calls to child processes for performance,
     54 // security and stability reasons. SyncCallRestrictions helps to enforce such
     55 // rules.
     56 //
     57 // Before processing a sync call, the bindings call
     58 // SyncCallRestrictions::AssertSyncCallAllowed() to check whether sync calls are
     59 // allowed. By default sync calls are allowed but they may be globally
     60 // disallowed within a process by calling DisallowSyncCall().
     61 //
     62 // If globally disallowed but you but you have a very compelling reason to
     63 // disregard that (which should be very very rare), you can override it by
     64 // constructing a ScopedAllowSyncCall object which allows making sync calls on
     65 // the current sequence during its lifetime.
     66 class MOJO_CPP_BINDINGS_EXPORT SyncCallRestrictions {
     67  public:
     68 #if ENABLE_SYNC_CALL_RESTRICTIONS
     69   // Checks whether the current sequence is allowed to make sync calls, and
     70   // causes a DCHECK if not.
     71   static void AssertSyncCallAllowed();
     72 
     73   // Disables sync calls within the calling process. Any caller who wishes to
     74   // make sync calls once this has been invoked must do so within the extent of
     75   // a ScopedAllowSyncCall or ScopedAllowSyncCallForTesting.
     76   static void DisallowSyncCall();
     77 
     78 #else
     79   // Inline the empty definitions of functions so that they can be compiled out.
     80   static void AssertSyncCallAllowed() {}
     81   static void DisallowSyncCall() {}
     82 #endif
     83 
     84  private:
     85   // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to mojo/OWNERS first.
     86   // BEGIN ALLOWED USAGE.
     87   // SynchronousCompositorHost is used for Android webview.
     88   friend class content::SynchronousCompositorHost;
     89   // LevelDBMojoProxy makes same-process sync calls from the DB thread.
     90   friend class leveldb::LevelDBMojoProxy;
     91   // Pref service connection is sync at startup.
     92   friend class prefs::PersistentPrefStoreClient;
     93   // Incognito pref service instances are created synchronously.
     94   friend class sync_preferences::PrefServiceSyncable;
     95   friend class mojo::ScopedAllowSyncCallForTesting;
     96   // For file open and save dialogs created synchronously.
     97   friend class ::ChromeSelectFileDialogFactory;
     98   // For synchronous system clipboard access.
     99   friend class ui::ClipboardClient;
    100   // For destroying the GL context/surface that draw to a platform window before
    101   // the platform window is destroyed.
    102   friend class viz::HostFrameSinkManager;
    103   // Allow for layout test pixel dumps.
    104   friend class content::BlinkTestController;
    105   // For preventing frame swaps of wrong size during resize on Windows.
    106   // (https://crbug.com/811945)
    107   friend class ui::HostContextFactoryPrivate;
    108   // END ALLOWED USAGE.
    109 
    110   // BEGIN USAGE THAT NEEDS TO BE FIXED.
    111   // In ash::Shell::Init() it assumes that NativeDisplayDelegate will be
    112   // synchronous at first. In mushrome ForwardingDisplayDelegate uses a
    113   // synchronous call to get the display snapshots as a workaround.
    114   friend class display::ForwardingDisplayDelegate;
    115   // END USAGE THAT NEEDS TO BE FIXED.
    116 
    117 #if ENABLE_SYNC_CALL_RESTRICTIONS
    118   static void IncreaseScopedAllowCount();
    119   static void DecreaseScopedAllowCount();
    120 #else
    121   static void IncreaseScopedAllowCount() {}
    122   static void DecreaseScopedAllowCount() {}
    123 #endif
    124 
    125   // If a process is configured to disallow sync calls in general, constructing
    126   // a ScopedAllowSyncCall object temporarily allows making sync calls on the
    127   // current sequence. Doing this is almost always incorrect, which is why we
    128   // limit who can use this through friend. If you find yourself needing to use
    129   // this, talk to mojo/OWNERS.
    130   class ScopedAllowSyncCall {
    131    public:
    132     ScopedAllowSyncCall() { IncreaseScopedAllowCount(); }
    133     ~ScopedAllowSyncCall() { DecreaseScopedAllowCount(); }
    134 
    135    private:
    136 #if ENABLE_SYNC_CALL_RESTRICTIONS
    137     base::ThreadRestrictions::ScopedAllowWait allow_wait_;
    138 #endif
    139 
    140     DISALLOW_COPY_AND_ASSIGN(ScopedAllowSyncCall);
    141   };
    142 
    143   DISALLOW_IMPLICIT_CONSTRUCTORS(SyncCallRestrictions);
    144 };
    145 
    146 class ScopedAllowSyncCallForTesting {
    147  public:
    148   ScopedAllowSyncCallForTesting() {}
    149   ~ScopedAllowSyncCallForTesting() {}
    150 
    151  private:
    152   SyncCallRestrictions::ScopedAllowSyncCall scoped_allow_sync_call_;
    153 
    154   DISALLOW_COPY_AND_ASSIGN(ScopedAllowSyncCallForTesting);
    155 };
    156 
    157 }  // namespace mojo
    158 
    159 #endif  // MOJO_PUBLIC_CPP_BINDINGS_SYNC_CALL_RESTRICTIONS_H_
    160