Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 1 | Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
mukesh agrawal | 102a775 | 2011-07-28 14:57:14 -0700 | [diff] [blame] | 2 | Use of this source code is governed by a BSD-style license that can be |
| 3 | found in the LICENSE file. |
| 4 | |
| 5 | To keep the shill source code consistent, please follow the conventions below: |
| 6 | |
| 7 | - Use the Chromium Coding Style, as described at |
| 8 | http://www.chromium.org/developers/coding-style. |
| 9 | |
| 10 | If you use Emacs, the Google C Style mode will help you with the formatting |
| 11 | aspects of style. (Chromium Style generally follows Google Style). Get the |
| 12 | Emacs mode at |
| 13 | http://google-styleguide.googlecode.com/svn/trunk/google-c-style.el |
| 14 | |
mukesh agrawal | 102a775 | 2011-07-28 14:57:14 -0700 | [diff] [blame] | 15 | - When working with DBus::Variant: |
| 16 | - Read data via the appropriate named method, rather than depending on |
| 17 | implicit conversion. E.g., |
| 18 | |
mukesh agrawal | 6e27777 | 2011-09-29 15:04:23 -0700 | [diff] [blame] | 19 | ::DBus::Variant var; |
mukesh agrawal | 102a775 | 2011-07-28 14:57:14 -0700 | [diff] [blame] | 20 | int8 data = var.reader().get_byte(); |
| 21 | |
| 22 | rather than |
| 23 | |
mukesh agrawal | 6e27777 | 2011-09-29 15:04:23 -0700 | [diff] [blame] | 24 | ::DBus::Variant var; |
mukesh agrawal | 102a775 | 2011-07-28 14:57:14 -0700 | [diff] [blame] | 25 | int8 data = var; |
| 26 | |
| 27 | RATIONALE: The explicit version is only marginally longer than the |
| 28 | implicit version, and does not require the reader to understand C++ |
| 29 | conversion rules. |
| 30 | |
| 31 | - Where there is no named method, call the appropriate cast operator |
| 32 | explicitly. E.g. |
| 33 | |
mukesh agrawal | 6e27777 | 2011-09-29 15:04:23 -0700 | [diff] [blame] | 34 | ::DBus::Variant var; |
mukesh agrawal | 102a775 | 2011-07-28 14:57:14 -0700 | [diff] [blame] | 35 | vector<unsigned int> data = var.operator vector<unsigned int>(); |
| 36 | |
| 37 | RATIONALE: Calling the cast operator explicitly avoids conflicts with |
| 38 | constructors that might also be used to make the conversion. It also |
| 39 | avoids requiring that the reader understand C++ conversion rules. |
| 40 | |
mukesh agrawal | 6e27777 | 2011-09-29 15:04:23 -0700 | [diff] [blame] | 41 | - Write data via the appropriate named method. E.g., |
| 42 | |
| 43 | ::DBus::Variant var; |
| 44 | int16_t data; |
| 45 | var.writer().append_int16(data); |
| 46 | |
| 47 | rather than |
| 48 | |
| 49 | ::DBus::Variant var; |
| 50 | int16_t data; |
| 51 | var.writer() << data; |
| 52 | |
| 53 | RATIONALE: Similarly as for reading, the explicit version is only |
| 54 | marginally longer, and does not require the reader to understand |
| 55 | overload resolution. |
| 56 | |
| 57 | - Where there is no named method, write by using the stream |
| 58 | insertion operator. E.g. |
| 59 | |
| 60 | ::DBus::Variant var; |
| 61 | ::DBus::MessageIter writer; |
| 62 | map<string, string> data; |
| 63 | writer = var.writer(); |
| 64 | writer << data; |
| 65 | |
| 66 | RATIONALE: This case is somewhat unfortunate, because it's not as |
| 67 | clear as its analogue for reading. However, the alternative is to |
| 68 | duplicate the code of the stream insertion operator overloads. |
| 69 | |
| 70 | Note that the writer can't be omitted. E.g. |
| 71 | |
| 72 | ::DBus::Variant var; |
| 73 | map<string, string> data; |
| 74 | var.writer() << data; |
| 75 | |
mukesh agrawal | 1590839 | 2011-11-16 18:29:25 +0000 | [diff] [blame] | 76 | does not work. For an explanation of why the local variable |
| 77 | |writer| is needed, see the comment in |
| 78 | DBusAdaptor::ByteArraysToVariant. |
mukesh agrawal | 6e27777 | 2011-09-29 15:04:23 -0700 | [diff] [blame] | 79 | |
mukesh agrawal | 102a775 | 2011-07-28 14:57:14 -0700 | [diff] [blame] | 80 | - When deferring work from a signal handler (e.g. a D-Bus callback) to |
| 81 | the event loop, name the deferred work function by adding "Task" to |
| 82 | the name of the function deferring the work. E.g. |
| 83 | |
| 84 | void Modem::Init() { |
| 85 | dispatcher_->PostTask(task_factory_.NewRunnableMethod(&Modem::InitTask)); |
| 86 | } |
| 87 | |
| 88 | RATIONALE: The naming convention makes the relationship between the signal |
| 89 | handler and the task function obvious, at-a-glance. |
Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 90 | |
Ben Chan | 80326f3 | 2012-05-04 17:51:32 -0700 | [diff] [blame] | 91 | - C++ exceptions are not allowed in the code. An exception to this rule is |
| 92 | that try-catch blocks may be used in various D-Bus proxy classes to handle |
| 93 | DBus::Error exceptions thrown by the D-Bus C++ code. C++ exceptions should |
| 94 | be caught by const reference in general. |
| 95 | |
Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 96 | - When adding verbose log messages for debug purposes, use the SLOG marco and |
Christopher Wiley | b691efd | 2012-08-09 13:51:51 -0700 | [diff] [blame] | 97 | its variants (see logging.h for details). |
Ben Chan | fad4a0b | 2012-04-18 15:49:59 -0700 | [diff] [blame] | 98 | |
| 99 | - Choose the appropriate scope and verbose level for log messages. E.g. |
| 100 | |
| 101 | SLOG(WiFi, 1) << message; // for WiFi related code |
| 102 | |
| 103 | - Before defining a new scope, check if any existing scope defined in |
| 104 | scope_logger.h already fulfills the needs. |
| 105 | |
| 106 | - To add a new scope: |
| 107 | 1. Add a new value to the Scope enumerated type in scope_logger.h. |
| 108 | Keep the values sorted as instructed in the header file. |
| 109 | 2. Add the corresponding scope name to the kScopeNames array in |
| 110 | scope_logger.cc. |
| 111 | 3. Update the GetAllScopeNames test in scope_logger_unittest.cc. |
mukesh agrawal | bebf1b8 | 2013-04-23 15:06:33 -0700 | [diff] [blame] | 112 | |
| 113 | - When adding externally visible (i.e. via RPC) properties to an object, |
| 114 | make sure that a) its setter emits any change notification required by |
| 115 | Chrome, and that b) its setter properly handles no-op changes. |
| 116 | |
| 117 | Test that the property changes are handled correctly by adding test |
| 118 | cases similar to those in CellularServiceTest.PropertyChanges, and |
Paul Stewart | 6db7b24 | 2014-05-02 15:34:21 -0700 | [diff] [blame] | 119 | CellularServiceTest.CustomSetterNoopChange. |
| 120 | |
| 121 | - When performing trivial iteration through a container, prefer using |
| 122 | range based for loops, preferably: |
| 123 | |
Paul Stewart | 8ae1874 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 124 | for (const auto& element : container) { |
Paul Stewart | 6db7b24 | 2014-05-02 15:34:21 -0700 | [diff] [blame] | 125 | |
| 126 | Remove "const" where necessary if the element will be modified during |
| 127 | the loop. Removal of the "const" and reference for trivial types is |
| 128 | allowed but not necessary. |