summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/AddonStatusHandler.cpp
blob: 3c6f478894e4f6257df284e31f30df931854b518 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */
#include "AddonStatusHandler.h"

#include "ServiceBroker.h"
#include "addons/AddonManager.h"
#include "addons/IAddonManagerCallback.h"
#include "addons/addoninfo/AddonInfo.h"
#include "addons/gui/GUIDialogAddonSettings.h"
#include "dialogs/GUIDialogKaiToast.h"
#include "dialogs/GUIDialogYesNo.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
#include "messaging/ApplicationMessenger.h"
#include "messaging/helpers/DialogOKHelper.h"
#include "utils/StringUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"

#include <mutex>
#include <utility>

using namespace KODI::MESSAGING;

namespace ADDON
{

/**********************************************************
 * CAddonStatusHandler - AddOn Status Report Class
 *
 * Used to inform the user about occurred errors and
 * changes inside Add-on's, and ask him what to do.
 *
 */

CCriticalSection CAddonStatusHandler::m_critSection;

CAddonStatusHandler::CAddonStatusHandler(const std::string& addonID,
                                         AddonInstanceId instanceId,
                                         ADDON_STATUS status,
                                         bool sameThread)
  : CThread(("AddonStatus " + std::to_string(instanceId) + "@" + addonID).c_str()),
    m_instanceId(instanceId),
    m_status(ADDON_STATUS_UNKNOWN)
{
  //! @todo The status handled CAddonStatusHandler by is related to the class, not the instance
  //! having CAddonMgr construct an instance makes no sense
  if (!CServiceBroker::GetAddonMgr().GetAddon(addonID, m_addon, OnlyEnabled::CHOICE_YES))
    return;

  CLog::Log(LOGINFO,
            "Called Add-on status handler for '{}' of clientName:{}, clientID:{}, instanceID:{} "
            "(same Thread={})",
            status, m_addon->Name(), m_addon->ID(), m_instanceId, sameThread ? "yes" : "no");

  m_status = status;

  if (sameThread)
  {
    Process();
  }
  else
  {
    Create(true);
  }
}

CAddonStatusHandler::~CAddonStatusHandler()
{
  StopThread();
}

void CAddonStatusHandler::OnStartup()
{
  SetPriority(ThreadPriority::LOWEST);
}

void CAddonStatusHandler::OnExit()
{
}

void CAddonStatusHandler::Process()
{
  std::unique_lock<CCriticalSection> lock(m_critSection);

  std::string heading = StringUtils::Format(
      "{}: {}", CAddonInfo::TranslateType(m_addon->Type(), true), m_addon->Name());

  /* Request to restart the AddOn and data structures need updated */
  if (m_status == ADDON_STATUS_NEED_RESTART)
  {
    HELPERS::ShowOKDialogLines(CVariant{heading}, CVariant{24074});
    CServiceBroker::GetAddonMgr()
        .GetCallbackForType(m_addon->Type())
        ->RequestRestart(m_addon->ID(), m_instanceId, true);
  }
  /* Some required settings are missing/invalid */
  else if (m_status == ADDON_STATUS_NEED_SETTINGS)
  {
    CGUIDialogYesNo* pDialogYesNo = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogYesNo>(WINDOW_DIALOG_YES_NO);
    if (!pDialogYesNo) return;

    pDialogYesNo->SetHeading(CVariant{heading});
    pDialogYesNo->SetLine(1, CVariant{24070});
    pDialogYesNo->SetLine(2, CVariant{24072});
    pDialogYesNo->Open();

    if (!pDialogYesNo->IsConfirmed()) return;

    if (!m_addon->HasSettings(m_instanceId))
      return;

    if (CGUIDialogAddonSettings::ShowForAddon(m_addon))
    {
      //! @todo Doesn't dialogaddonsettings save these automatically? It should do this.
      m_addon->SaveSettings(m_instanceId);
      CServiceBroker::GetAddonMgr()
          .GetCallbackForType(m_addon->Type())
          ->RequestRestart(m_addon->ID(), m_instanceId, true);
    }
  }
}


} /*namespace ADDON*/