Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_H_ | 5 #ifndef COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_H_ |
| 6 #define COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_H_ | 6 #define COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_H_ |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 #include "google_apis/gaia/oauth2_token_service.h" | 54 #include "google_apis/gaia/oauth2_token_service.h" |
| 55 #include "net/base/backoff_entry.h" | 55 #include "net/base/backoff_entry.h" |
| 56 #include "url/gurl.h" | 56 #include "url/gurl.h" |
| 57 | 57 |
| 58 class Profile; | 58 class Profile; |
| 59 class ProfileOAuth2TokenService; | 59 class ProfileOAuth2TokenService; |
| 60 class SigninManagerWrapper; | 60 class SigninManagerWrapper; |
| 61 class SyncErrorController; | 61 class SyncErrorController; |
| 62 class SyncTypePreferenceProvider; | 62 class SyncTypePreferenceProvider; |
| 63 | 63 |
| 64 namespace browser_sync { | |
| 65 class BackendMigrator; | |
| 66 } // namespace browser_sync | |
| 67 | |
| 68 namespace sync_driver { | 64 namespace sync_driver { |
| 69 class DataTypeManager; | 65 class DataTypeManager; |
| 70 class DeviceInfoSyncService; | 66 class DeviceInfoSyncService; |
| 71 class DeviceInfoTracker; | 67 class DeviceInfoTracker; |
| 72 class LocalDeviceInfoProvider; | 68 class LocalDeviceInfoProvider; |
| 73 class SyncApiComponentFactory; | 69 class SyncApiComponentFactory; |
| 74 class SyncClient; | 70 class SyncClient; |
| 75 } // namespace sync_driver | 71 } // namespace sync_driver |
| 76 | 72 |
| 77 namespace sync_driver_v2 { | 73 namespace sync_driver_v2 { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 92 struct StatusCounters; | 88 struct StatusCounters; |
| 93 struct SyncCredentials; | 89 struct SyncCredentials; |
| 94 struct UpdateCounters; | 90 struct UpdateCounters; |
| 95 struct UserShare; | 91 struct UserShare; |
| 96 } // namespace syncer | 92 } // namespace syncer |
| 97 | 93 |
| 98 namespace sync_pb { | 94 namespace sync_pb { |
| 99 class EncryptedData; | 95 class EncryptedData; |
| 100 } // namespace sync_pb | 96 } // namespace sync_pb |
| 101 | 97 |
| 98 namespace browser_sync { | |
| 99 | |
|
skym
2016/09/22 17:25:59
Should this newline be here?
maxbogue
2016/09/22 19:41:15
Yes.
| |
| 100 class BackendMigrator; | |
| 101 | |
| 102 // ProfileSyncService is the layer between browser subsystems like bookmarks, | 102 // ProfileSyncService is the layer between browser subsystems like bookmarks, |
| 103 // and the sync backend. Each subsystem is logically thought of as being | 103 // and the sync backend. Each subsystem is logically thought of as being |
| 104 // a sync datatype. | 104 // a sync datatype. |
| 105 // | 105 // |
| 106 // Individual datatypes can, at any point, be in a variety of stages of being | 106 // Individual datatypes can, at any point, be in a variety of stages of being |
| 107 // "enabled". Here are some specific terms for concepts used in this class: | 107 // "enabled". Here are some specific terms for concepts used in this class: |
| 108 // | 108 // |
| 109 // 'Registered' (feature suppression for a datatype) | 109 // 'Registered' (feature suppression for a datatype) |
| 110 // | 110 // |
| 111 // When a datatype is registered, the user has the option of syncing it. | 111 // When a datatype is registered, the user has the option of syncing it. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 public sync_driver::SyncFrontend, | 182 public sync_driver::SyncFrontend, |
| 183 public sync_driver::SyncPrefObserver, | 183 public sync_driver::SyncPrefObserver, |
| 184 public sync_driver::DataTypeManagerObserver, | 184 public sync_driver::DataTypeManagerObserver, |
| 185 public syncer::UnrecoverableErrorHandler, | 185 public syncer::UnrecoverableErrorHandler, |
| 186 public KeyedService, | 186 public KeyedService, |
| 187 public OAuth2TokenService::Consumer, | 187 public OAuth2TokenService::Consumer, |
| 188 public OAuth2TokenService::Observer, | 188 public OAuth2TokenService::Observer, |
| 189 public SigninManagerBase::Observer, | 189 public SigninManagerBase::Observer, |
| 190 public GaiaCookieManagerService::Observer { | 190 public GaiaCookieManagerService::Observer { |
| 191 public: | 191 public: |
| 192 typedef browser_sync::SyncBackendHost::Status Status; | 192 typedef SyncBackendHost::Status Status; |
| 193 typedef base::Callback<bool(void)> PlatformSyncAllowedProvider; | 193 typedef base::Callback<bool(void)> PlatformSyncAllowedProvider; |
| 194 | 194 |
| 195 enum SyncEventCodes { | 195 enum SyncEventCodes { |
| 196 MIN_SYNC_EVENT_CODE = 0, | 196 MIN_SYNC_EVENT_CODE = 0, |
| 197 | 197 |
| 198 // Events starting the sync service. | 198 // Events starting the sync service. |
| 199 START_FROM_NTP = 1, // Sync was started from the ad in NTP | 199 START_FROM_NTP = 1, // Sync was started from the ad in NTP |
| 200 START_FROM_WRENCH = 2, // Sync was started from the Wrench menu. | 200 START_FROM_WRENCH = 2, // Sync was started from the Wrench menu. |
| 201 START_FROM_OPTIONS = 3, // Sync was started from Wrench->Options. | 201 START_FROM_OPTIONS = 3, // Sync was started from Wrench->Options. |
| 202 START_FROM_BOOKMARK_MANAGER = 4, // Sync was started from Bookmark manager. | 202 START_FROM_BOOKMARK_MANAGER = 4, // Sync was started from Bookmark manager. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 318 SyncTokenStatus GetSyncTokenStatus() const override; | 318 SyncTokenStatus GetSyncTokenStatus() const override; |
| 319 std::string QuerySyncStatusSummaryString() override; | 319 std::string QuerySyncStatusSummaryString() override; |
| 320 bool QueryDetailedSyncStatus(syncer::SyncStatus* result) override; | 320 bool QueryDetailedSyncStatus(syncer::SyncStatus* result) override; |
| 321 base::string16 GetLastSyncedTimeString() const override; | 321 base::string16 GetLastSyncedTimeString() const override; |
| 322 std::string GetBackendInitializationStateString() const override; | 322 std::string GetBackendInitializationStateString() const override; |
| 323 syncer::SyncCycleSnapshot GetLastCycleSnapshot() const override; | 323 syncer::SyncCycleSnapshot GetLastCycleSnapshot() const override; |
| 324 base::Value* GetTypeStatusMap() const override; | 324 base::Value* GetTypeStatusMap() const override; |
| 325 const GURL& sync_service_url() const override; | 325 const GURL& sync_service_url() const override; |
| 326 std::string unrecoverable_error_message() const override; | 326 std::string unrecoverable_error_message() const override; |
| 327 tracked_objects::Location unrecoverable_error_location() const override; | 327 tracked_objects::Location unrecoverable_error_location() const override; |
| 328 void AddProtocolEventObserver( | 328 void AddProtocolEventObserver(ProtocolEventObserver* observer) override; |
| 329 browser_sync::ProtocolEventObserver* observer) override; | 329 void RemoveProtocolEventObserver(ProtocolEventObserver* observer) override; |
| 330 void RemoveProtocolEventObserver( | |
| 331 browser_sync::ProtocolEventObserver* observer) override; | |
| 332 void AddTypeDebugInfoObserver( | 330 void AddTypeDebugInfoObserver( |
| 333 syncer::TypeDebugInfoObserver* observer) override; | 331 syncer::TypeDebugInfoObserver* observer) override; |
| 334 void RemoveTypeDebugInfoObserver( | 332 void RemoveTypeDebugInfoObserver( |
| 335 syncer::TypeDebugInfoObserver* observer) override; | 333 syncer::TypeDebugInfoObserver* observer) override; |
| 336 base::WeakPtr<syncer::JsController> GetJsController() override; | 334 base::WeakPtr<syncer::JsController> GetJsController() override; |
| 337 void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& | 335 void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& |
| 338 callback) override; | 336 callback) override; |
| 339 | 337 |
| 340 // Add a sync type preference provider. Each provider may only be added once. | 338 // Add a sync type preference provider. Each provider may only be added once. |
| 341 void AddPreferenceProvider(SyncTypePreferenceProvider* provider); | 339 void AddPreferenceProvider(SyncTypePreferenceProvider* provider); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 // TODO(akalin): These two functions are used only by | 470 // TODO(akalin): These two functions are used only by |
| 473 // ProfileSyncServiceHarness. Figure out a different way to expose | 471 // ProfileSyncServiceHarness. Figure out a different way to expose |
| 474 // this info to that class, and remove these functions. | 472 // this info to that class, and remove these functions. |
| 475 | 473 |
| 476 // Returns whether or not the underlying sync engine has made any | 474 // Returns whether or not the underlying sync engine has made any |
| 477 // local changes to items that have not yet been synced with the | 475 // local changes to items that have not yet been synced with the |
| 478 // server. | 476 // server. |
| 479 bool HasUnsyncedItems() const; | 477 bool HasUnsyncedItems() const; |
| 480 | 478 |
| 481 // Used by ProfileSyncServiceHarness. May return NULL. | 479 // Used by ProfileSyncServiceHarness. May return NULL. |
| 482 browser_sync::BackendMigrator* GetBackendMigratorForTest(); | 480 BackendMigrator* GetBackendMigratorForTest(); |
| 483 | 481 |
| 484 // Used by tests to inspect interaction with OAuth2TokenService. | 482 // Used by tests to inspect interaction with OAuth2TokenService. |
| 485 bool IsRetryingAccessTokenFetchForTest() const; | 483 bool IsRetryingAccessTokenFetchForTest() const; |
| 486 | 484 |
| 487 // Used by tests to inspect the OAuth2 access tokens used by PSS. | 485 // Used by tests to inspect the OAuth2 access tokens used by PSS. |
| 488 std::string GetAccessTokenForTest() const; | 486 std::string GetAccessTokenForTest() const; |
| 489 | 487 |
| 490 // TODO(sync): This is only used in tests. Can we remove it? | 488 // TODO(sync): This is only used in tests. Can we remove it? |
| 491 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out) const; | 489 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out) const; |
| 492 | 490 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 const std::string& message, | 621 const std::string& message, |
| 624 bool delete_sync_database); | 622 bool delete_sync_database); |
| 625 | 623 |
| 626 // This is a cache of the last authentication response we received from the | 624 // This is a cache of the last authentication response we received from the |
| 627 // sync server. The UI queries this to display appropriate messaging to the | 625 // sync server. The UI queries this to display appropriate messaging to the |
| 628 // user. | 626 // user. |
| 629 GoogleServiceAuthError last_auth_error_; | 627 GoogleServiceAuthError last_auth_error_; |
| 630 | 628 |
| 631 // Our asynchronous backend to communicate with sync components living on | 629 // Our asynchronous backend to communicate with sync components living on |
| 632 // other threads. | 630 // other threads. |
| 633 std::unique_ptr<browser_sync::SyncBackendHost> backend_; | 631 std::unique_ptr<SyncBackendHost> backend_; |
| 634 | 632 |
| 635 // Was the last SYNC_PASSPHRASE_REQUIRED notification sent because it | 633 // Was the last SYNC_PASSPHRASE_REQUIRED notification sent because it |
| 636 // was required for encryption, decryption with a cached passphrase, or | 634 // was required for encryption, decryption with a cached passphrase, or |
| 637 // because a new passphrase is required? | 635 // because a new passphrase is required? |
| 638 syncer::PassphraseRequiredReason passphrase_required_reason_; | 636 syncer::PassphraseRequiredReason passphrase_required_reason_; |
| 639 | 637 |
| 640 private: | 638 private: |
| 641 enum UnrecoverableErrorReason { | 639 enum UnrecoverableErrorReason { |
| 642 ERROR_REASON_UNSET, | 640 ERROR_REASON_UNSET, |
| 643 ERROR_REASON_SYNCER, | 641 ERROR_REASON_SYNCER, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 664 NOT_SIGNED_IN, // There is no signed in user. | 662 NOT_SIGNED_IN, // There is no signed in user. |
| 665 NOT_REQUESTED, // The user turned off sync. | 663 NOT_REQUESTED, // The user turned off sync. |
| 666 NOT_REQUESTED_NOT_SETUP, // The user turned off sync and setup completed | 664 NOT_REQUESTED_NOT_SETUP, // The user turned off sync and setup completed |
| 667 // is false. Might indicate a stop-and-clear. | 665 // is false. Might indicate a stop-and-clear. |
| 668 NEEDS_CONFIRMATION, // The user must confirm sync settings. | 666 NEEDS_CONFIRMATION, // The user must confirm sync settings. |
| 669 IS_MANAGED, // Sync is disallowed by enterprise policy. | 667 IS_MANAGED, // Sync is disallowed by enterprise policy. |
| 670 NOT_ALLOWED_BY_PLATFORM, // Sync is disallowed by the platform. | 668 NOT_ALLOWED_BY_PLATFORM, // Sync is disallowed by the platform. |
| 671 SYNC_INITIAL_STATE_LIMIT | 669 SYNC_INITIAL_STATE_LIMIT |
| 672 }; | 670 }; |
| 673 | 671 |
| 674 friend class ProfileSyncServicePasswordTest; | |
| 675 friend class SyncTest; | |
| 676 friend class TestProfileSyncService; | 672 friend class TestProfileSyncService; |
| 677 FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceTest, InitialState); | |
| 678 | 673 |
| 679 // Stops the sync engine. Does NOT set IsSyncRequested to false. Use | 674 // Stops the sync engine. Does NOT set IsSyncRequested to false. Use |
| 680 // RequestStop for that. |data_fate| controls whether the local sync data is | 675 // RequestStop for that. |data_fate| controls whether the local sync data is |
| 681 // deleted or kept when the engine shuts down. | 676 // deleted or kept when the engine shuts down. |
| 682 void StopImpl(SyncStopDataFate data_fate); | 677 void StopImpl(SyncStopDataFate data_fate); |
| 683 | 678 |
| 684 // Update the last auth error and notify observers of error state. | 679 // Update the last auth error and notify observers of error state. |
| 685 void UpdateAuthErrorState(const GoogleServiceAuthError& error); | 680 void UpdateAuthErrorState(const GoogleServiceAuthError& error); |
| 686 | 681 |
| 687 // Puts the backend's sync scheduler into NORMAL mode. | 682 // Puts the backend's sync scheduler into NORMAL mode. |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 872 | 867 |
| 873 // Information describing an unrecoverable error. | 868 // Information describing an unrecoverable error. |
| 874 UnrecoverableErrorReason unrecoverable_error_reason_; | 869 UnrecoverableErrorReason unrecoverable_error_reason_; |
| 875 std::string unrecoverable_error_message_; | 870 std::string unrecoverable_error_message_; |
| 876 tracked_objects::Location unrecoverable_error_location_; | 871 tracked_objects::Location unrecoverable_error_location_; |
| 877 | 872 |
| 878 // Manages the start and stop of the data types. | 873 // Manages the start and stop of the data types. |
| 879 std::unique_ptr<sync_driver::DataTypeManager> data_type_manager_; | 874 std::unique_ptr<sync_driver::DataTypeManager> data_type_manager_; |
| 880 | 875 |
| 881 base::ObserverList<sync_driver::SyncServiceObserver> observers_; | 876 base::ObserverList<sync_driver::SyncServiceObserver> observers_; |
| 882 base::ObserverList<browser_sync::ProtocolEventObserver> | 877 base::ObserverList<ProtocolEventObserver> protocol_event_observers_; |
| 883 protocol_event_observers_; | |
| 884 base::ObserverList<syncer::TypeDebugInfoObserver> type_debug_info_observers_; | 878 base::ObserverList<syncer::TypeDebugInfoObserver> type_debug_info_observers_; |
| 885 | 879 |
| 886 std::set<SyncTypePreferenceProvider*> preference_providers_; | 880 std::set<SyncTypePreferenceProvider*> preference_providers_; |
| 887 | 881 |
| 888 syncer::SyncJsController sync_js_controller_; | 882 syncer::SyncJsController sync_js_controller_; |
| 889 | 883 |
| 890 // This allows us to gracefully handle an ABORTED return code from the | 884 // This allows us to gracefully handle an ABORTED return code from the |
| 891 // DataTypeManager in the event that the server informed us to cease and | 885 // DataTypeManager in the event that the server informed us to cease and |
| 892 // desist syncing immediately. | 886 // desist syncing immediately. |
| 893 bool expect_sync_configuration_aborted_; | 887 bool expect_sync_configuration_aborted_; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 906 bool encrypt_everything_allowed_; | 900 bool encrypt_everything_allowed_; |
| 907 | 901 |
| 908 // Whether we want to encrypt everything. | 902 // Whether we want to encrypt everything. |
| 909 bool encrypt_everything_; | 903 bool encrypt_everything_; |
| 910 | 904 |
| 911 // Whether we're waiting for an attempt to encryption all sync data to | 905 // Whether we're waiting for an attempt to encryption all sync data to |
| 912 // complete. We track this at this layer in order to allow the user to cancel | 906 // complete. We track this at this layer in order to allow the user to cancel |
| 913 // if they e.g. don't remember their explicit passphrase. | 907 // if they e.g. don't remember their explicit passphrase. |
| 914 bool encryption_pending_; | 908 bool encryption_pending_; |
| 915 | 909 |
| 916 std::unique_ptr<browser_sync::BackendMigrator> migrator_; | 910 std::unique_ptr<BackendMigrator> migrator_; |
| 917 | 911 |
| 918 // This is the last |SyncProtocolError| we received from the server that had | 912 // This is the last |SyncProtocolError| we received from the server that had |
| 919 // an action set on it. | 913 // an action set on it. |
| 920 syncer::SyncProtocolError last_actionable_error_; | 914 syncer::SyncProtocolError last_actionable_error_; |
| 921 | 915 |
| 922 // Exposes sync errors to the UI. | 916 // Exposes sync errors to the UI. |
| 923 std::unique_ptr<SyncErrorController> sync_error_controller_; | 917 std::unique_ptr<SyncErrorController> sync_error_controller_; |
| 924 | 918 |
| 925 // Tracks the set of failed data types (those that encounter an error | 919 // Tracks the set of failed data types (those that encounter an error |
| 926 // or must delay loading for some reason). | 920 // or must delay loading for some reason). |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 973 std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device_; | 967 std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device_; |
| 974 | 968 |
| 975 // Locally owned SyncableService and ModelTypeService implementations. | 969 // Locally owned SyncableService and ModelTypeService implementations. |
| 976 std::unique_ptr<sync_sessions::SessionsSyncManager> sessions_sync_manager_; | 970 std::unique_ptr<sync_sessions::SessionsSyncManager> sessions_sync_manager_; |
| 977 std::unique_ptr<sync_driver::DeviceInfoSyncService> device_info_sync_service_; | 971 std::unique_ptr<sync_driver::DeviceInfoSyncService> device_info_sync_service_; |
| 978 std::unique_ptr<sync_driver_v2::DeviceInfoService> device_info_service_; | 972 std::unique_ptr<sync_driver_v2::DeviceInfoService> device_info_service_; |
| 979 | 973 |
| 980 std::unique_ptr<syncer::NetworkResources> network_resources_; | 974 std::unique_ptr<syncer::NetworkResources> network_resources_; |
| 981 | 975 |
| 982 StartBehavior start_behavior_; | 976 StartBehavior start_behavior_; |
| 983 std::unique_ptr<browser_sync::StartupController> startup_controller_; | 977 std::unique_ptr<StartupController> startup_controller_; |
| 984 | 978 |
| 985 // The full path to the sync data directory. | 979 // The full path to the sync data directory. |
| 986 base::FilePath directory_path_; | 980 base::FilePath directory_path_; |
| 987 | 981 |
| 988 std::unique_ptr<browser_sync::SyncStoppedReporter> sync_stopped_reporter_; | 982 std::unique_ptr<SyncStoppedReporter> sync_stopped_reporter_; |
| 989 | 983 |
| 990 // Listens for the system being under memory pressure. | 984 // Listens for the system being under memory pressure. |
| 991 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; | 985 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; |
| 992 | 986 |
| 993 // Nigori state after user switching to custom passphrase, saved until | 987 // Nigori state after user switching to custom passphrase, saved until |
| 994 // transition steps complete. It will be injected into new backend after sync | 988 // transition steps complete. It will be injected into new backend after sync |
| 995 // restart. | 989 // restart. |
| 996 std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> | 990 std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> |
| 997 saved_nigori_state_; | 991 saved_nigori_state_; |
| 998 | 992 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1019 // This weak factory invalidates its issued pointers when Sync is disabled. | 1013 // This weak factory invalidates its issued pointers when Sync is disabled. |
| 1020 base::WeakPtrFactory<ProfileSyncService> sync_enabled_weak_factory_; | 1014 base::WeakPtrFactory<ProfileSyncService> sync_enabled_weak_factory_; |
| 1021 | 1015 |
| 1022 base::WeakPtrFactory<ProfileSyncService> weak_factory_; | 1016 base::WeakPtrFactory<ProfileSyncService> weak_factory_; |
| 1023 | 1017 |
| 1024 DISALLOW_COPY_AND_ASSIGN(ProfileSyncService); | 1018 DISALLOW_COPY_AND_ASSIGN(ProfileSyncService); |
| 1025 }; | 1019 }; |
| 1026 | 1020 |
| 1027 bool ShouldShowActionOnUI(const syncer::SyncProtocolError& error); | 1021 bool ShouldShowActionOnUI(const syncer::SyncProtocolError& error); |
| 1028 | 1022 |
| 1023 } // namespace browser_sync | |
| 1024 | |
| 1029 #endif // COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_H_ | 1025 #endif // COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_H_ |
| OLD | NEW |