1// Copyright 2019 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package engine
5
6import (
7	"sync"
8	"time"
9
10	"github.com/keybase/client/go/libkb"
11)
12
13var ContactSyncBackgroundSettings = BackgroundTaskSettings{
14	Start: 5 * time.Second,
15	// in case we are foregrounding all the time, wait some more time because
16	// this sync is heavy, and the timer is reset so it could run more than
17	// once an hour if the mobile OS kills the app. But don't do this in
18	// background active mode, or we might not run before we are
19	// background passive'd.
20	MobileForegroundStartAddition: 1 * time.Minute,
21	StartStagger:                  5 * time.Second,
22	WakeUp:                        15 * time.Second,
23	Interval:                      1 * time.Hour,
24	Limit:                         5 * time.Minute,
25}
26
27type ContactSyncBackground struct {
28	libkb.Contextified
29	sync.Mutex
30
31	task *BackgroundTask
32}
33
34func NewContactSyncBackground(g *libkb.GlobalContext) *ContactSyncBackground {
35	task := NewBackgroundTask(g, &BackgroundTaskArgs{
36		Name:     "ContactSyncBackground",
37		F:        ContactSyncBackgroundRound,
38		Settings: ContactSyncBackgroundSettings,
39	})
40	return &ContactSyncBackground{
41		Contextified: libkb.NewContextified(g),
42		// Install the task early so that Shutdown can be called before RunEngine.
43		task: task,
44	}
45}
46
47func (e *ContactSyncBackground) Name() string {
48	return "ContactSyncBackground"
49}
50
51func (e *ContactSyncBackground) Prereqs() Prereqs {
52	return Prereqs{}
53}
54
55func (e *ContactSyncBackground) RequiredUIs() []libkb.UIKind {
56	return []libkb.UIKind{}
57}
58
59func (e *ContactSyncBackground) SubConsumers() []libkb.UIConsumer {
60	return []libkb.UIConsumer{}
61}
62
63// Run starts the engine.
64// Returns immediately, kicks off a background goroutine.
65func (e *ContactSyncBackground) Run(m libkb.MetaContext) (err error) {
66	return RunEngine2(m, e.task)
67}
68
69func (e *ContactSyncBackground) Shutdown() {
70	e.task.Shutdown()
71}
72
73func ContactSyncBackgroundRound(mctx libkb.MetaContext) error {
74	g := mctx.G()
75	if !g.ActiveDevice.Valid() {
76		mctx.Debug("ContactSyncBackgroundRound; not logged in")
77		return nil
78	}
79
80	if mctx.G().IsMobileAppType() {
81		netState := mctx.G().MobileNetState.State()
82		if netState.IsLimited() {
83			mctx.Debug("ContactSyncBackgroundRound: not running; network state: %v", netState)
84			return nil
85		}
86	}
87
88	ui, err := mctx.G().UIRouter.GetChatUI()
89	if err != nil || ui == nil {
90		mctx.Debug("ContactSyncBackgroundRound: no chat UI found; err: %s", err)
91		return nil
92	}
93
94	return ui.TriggerContactSync(mctx.Ctx())
95}
96