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