15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 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_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/content_export.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalTimeDelta; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalTimeTicks; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RemoteTimeDelta; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RemoteTimeTicks; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Windows, TimeTicks are not consistent between processes. Often, the values 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on one process have a static offset relative to another. Occasionally, these 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// offsets shift while running. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To combat this, any TimeTicks values sent from the remote process to the 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// local process must be tweaked in order to appear monotonic. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In order to properly tweak ticks, we need 4 reference points: 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |local_lower_bound|: A known point, recorded on the local process, that 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// occurs before any remote values that will be 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// converted. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |remote_lower_bound|: The equivalent point on the remote process. This 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be recorded immediately after 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |local_lower_bound|. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |local_upper_bound|: A known point, recorded on the local process, that 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// occurs after any remote values that will be 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// converted. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - |remote_upper_bound|: The equivalent point on the remote process. This 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be recorded immediately before 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |local_upper_bound|. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Once these bounds are determined, values within the remote process's range 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can be converted to the local process's range. The values are converted as 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// follows: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1. If the remote's range exceeds the local's range, it is scaled to fit. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Any values converted will have the same scale factor applied. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. The remote's range is shifted so that it is centered within the 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// local's range. Any values converted will be shifted the same amount. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT InterProcessTimeTicksConverter { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterProcessTimeTicksConverter(const LocalTimeTicks& local_lower_bound, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LocalTimeTicks& local_upper_bound, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RemoteTimeTicks& remote_lower_bound, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RemoteTimeTicks& remote_upper_bound); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the value within the local's bounds that correlates to 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |remote_ms|. 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LocalTimeTicks ToLocalTimeTicks(const RemoteTimeTicks& remote_ms) const; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the equivalent delta after applying remote-to-local scaling to 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |remote_delta|. 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LocalTimeDelta ToLocalTimeDelta(const RemoteTimeDelta& remote_delta) const; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 Convert(int64 value) const; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The local time which |remote_lower_bound_| is mapped to. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 local_base_time_; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 numerator_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 denominator_; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 remote_lower_bound_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 remote_upper_bound_; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT LocalTimeDelta { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ToInt32() const { return value_; } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class InterProcessTimeTicksConverter; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class LocalTimeTicks; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalTimeDelta(int value) : value_(value) {} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int value_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT LocalTimeTicks { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static LocalTimeTicks FromTimeTicks(const base::TimeTicks& value) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LocalTimeTicks(value.ToInternalValue()); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks ToTimeTicks() { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::TimeTicks::FromInternalValue(value_); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalTimeTicks operator+(const LocalTimeDelta& delta) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LocalTimeTicks(value_ + delta.value_); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class InterProcessTimeTicksConverter; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalTimeTicks(int64 value) : value_(value) {} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 value_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT RemoteTimeDelta { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static RemoteTimeDelta FromRawDelta(int delta) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RemoteTimeDelta(delta); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class InterProcessTimeTicksConverter; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class RemoteTimeTicks; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoteTimeDelta(int value) : value_(value) {} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int value_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT RemoteTimeTicks { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static RemoteTimeTicks FromTimeTicks(const base::TimeTicks& ticks) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RemoteTimeTicks(ticks.ToInternalValue()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoteTimeDelta operator-(const RemoteTimeTicks& rhs) const { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RemoteTimeDelta(value_ - rhs.value_); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class InterProcessTimeTicksConverter; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoteTimeTicks(int64 value) : value_(value) {} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 value_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ 148