<commit_before>/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2018 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *          Provides an implementation of the PlatformManager object
 *          for Linux platforms.
 */

#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <app-common/zap-generated/enums.h>
#include <app-common/zap-generated/ids/Events.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/DeviceControlServer.h>
#include <platform/Linux/DeviceInfoProviderImpl.h>
#include <platform/Linux/DiagnosticDataProviderImpl.h>
#include <platform/PlatformManager.h>
#include <platform/internal/GenericPlatformManagerImpl_POSIX.ipp>

#include <thread>

#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>

#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
#endif

using namespace ::chip::app::Clusters;

namespace chip {
namespace DeviceLayer {

PlatformManagerImpl PlatformManagerImpl::sInstance;

namespace {

void SignalHandler(int signum)
{
    ChipLogDetail(DeviceLayer, "Caught signal %d", signum);

    switch (signum)
    {
    case SIGUSR1:
        PlatformMgrImpl().HandleSoftwareFault(SoftwareDiagnostics::Events::SoftwareFault::Id);
        break;
    case SIGUSR2:
        PlatformMgrImpl().HandleGeneralFault(GeneralDiagnostics::Events::HardwareFaultChange::Id);
        break;
    case SIGHUP:
        PlatformMgrImpl().HandleGeneralFault(GeneralDiagnostics::Events::RadioFaultChange::Id);
        break;
    case SIGTERM:
        PlatformMgrImpl().HandleGeneralFault(GeneralDiagnostics::Events::NetworkFaultChange::Id);
        break;
    case SIGTSTP:
        PlatformMgrImpl().HandleSwitchEvent(Switch::Events::SwitchLatched::Id);
        break;
    default:
        break;
    }
}

#if CHIP_WITH_GIO
void GDBus_Thread()
{
    GMainLoop * loop = g_main_loop_new(nullptr, false);

    g_main_loop_run(loop);
    g_main_loop_unref(loop);
}
#endif
} // namespace

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
void PlatformManagerImpl::WiFIIPChangeListener()
{
    int sock;
    if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
    {
        ChipLogError(DeviceLayer, "Failed to init netlink socket for ip addresses.");
        return;
    }

    struct sockaddr_nl addr;
    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;
    addr.nl_groups = RTMGRP_IPV4_IFADDR;

    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1)
    {
        ChipLogError(DeviceLayer, "Failed to bind netlink socket for ip addresses.");
        return;
    }

    ssize_t len;
    char buffer[4096];
    for (struct nlmsghdr * header = reinterpret_cast<struct nlmsghdr *>(buffer); (len = recv(sock, header, sizeof(buffer), 0)) > 0;)
    {
        for (struct nlmsghdr * messageHeader = header;
             (NLMSG_OK(messageHeader, static_cast<uint32_t>(len))) && (messageHeader->nlmsg_type != NLMSG_DONE);
             messageHeader = NLMSG_NEXT(messageHeader, len))
        {
            if (header->nlmsg_type == RTM_NEWADDR)
            {
                struct ifaddrmsg * addressMessage = (struct ifaddrmsg *) NLMSG_DATA(header);
                struct rtattr * routeInfo         = IFA_RTA(addressMessage);
                size_t rtl                        = IFA_PAYLOAD(header);

                for (; rtl && RTA_OK(routeInfo, rtl); routeInfo = RTA_NEXT(routeInfo, rtl))
                {
                    if (routeInfo->rta_type == IFA_LOCAL)
                    {
                        char name[IFNAMSIZ];
                        if (if_indextoname(addressMessage->ifa_index, name) == nullptr)
                        {
                            ChipLogError(DeviceLayer, "Error %d when getting the interface name at index: %d", errno,
                                         addressMessage->ifa_index);
                            continue;
                        }

                        if (strcmp(name, ConnectivityManagerImpl::GetWiFiIfName()) != 0)
                        {
                            continue;
                        }

                        ChipDeviceEvent event;
                        event.Type                            = DeviceEventType::kInternetConnectivityChange;
                        event.InternetConnectivityChange.IPv4 = kConnectivity_Established;
                        event.InternetConnectivityChange.IPv6 = kConnectivity_NoChange;
                        inet_ntop(AF_INET, RTA_DATA(routeInfo), event.InternetConnectivityChange.address,
                                  sizeof(event.InternetConnectivityChange.address));

                        ChipLogDetail(DeviceLayer, "Got IP address on interface: %s IP: %s", name,
                                      event.InternetConnectivityChange.address);

                        CHIP_ERROR status = PlatformMgr().PostEvent(&event);
                        if (status != CHIP_NO_ERROR)
                        {
                            ChipLogDetail(DeviceLayer, "Failed to report IP address: %" CHIP_ERROR_FORMAT, status.Format());
                        }
                    }
                }
            }
        }
    }
}
#endif // #if CHIP_DEVICE_CONFIG_ENABLE_WIFI

CHIP_ERROR PlatformManagerImpl::_InitChipStack()
{
    struct sigaction action;

    memset(&action, 0, sizeof(action));
    action.sa_handler = SignalHandler;
    sigaction(SIGHUP, &action, nullptr);
    sigaction(SIGTERM, &action, nullptr);
    sigaction(SIGUSR1, &action, nullptr);
    sigaction(SIGUSR2, &action, nullptr);
    sigaction(SIGTSTP, &action, nullptr);

#if CHIP_WITH_GIO
    GError * error = nullptr;

    this->mpGDBusConnection = UniqueGDBusConnection(g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error));

    std::thread gdbusThread(GDBus_Thread);
    gdbusThread.detach();
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
    std::thread wifiIPThread(WiFIIPChangeListener);
    wifiIPThread.detach();
#endif

    // Initialize the configuration system.
    ReturnErrorOnFailure(Internal::PosixConfig::Init());
    SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance());
    SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance());
    SetDeviceInfoProvider(&DeviceInfoProviderImpl::GetDefaultInstance());

    // Call _InitChipStack() on the generic implementation base class
    // to finish the initialization process.
    ReturnErrorOnFailure(Internal::GenericPlatformManagerImpl_POSIX<PlatformManagerImpl>::_InitChipStack());

    mStartTime = System::SystemClock().GetMonotonicTimestamp();

    return CHIP_NO_ERROR;
}

CHIP_ERROR PlatformManagerImpl::_Shutdown()
{
    uint64_t upTime = 0;

    if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR)
    {
        uint32_t totalOperationalHours = 0;

        if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
        {
            ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast<uint32_t>(upTime / 3600));
        }
        else
        {
            ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
        }
    }
    else
    {
        ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot");
    }

    return Internal::GenericPlatformManagerImpl_POSIX<PlatformManagerImpl>::_Shutdown();
}

void PlatformManagerImpl::HandleGeneralFault(uint32_t EventId)
{
    GeneralDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetGeneralDiagnosticsDelegate();

    if (delegate == nullptr)
    {
        ChipLogError(DeviceLayer, "No delegate registered to handle General Diagnostics event");
        return;
    }

    if (EventId == GeneralDiagnostics::Events::HardwareFaultChange::Id)
    {
        GeneralFaults<kMaxHardwareFaults> previous;
        GeneralFaults<kMaxHardwareFaults> current;

#if CHIP_CONFIG_TEST
        // On Linux Simulation, set following hardware faults statically.
        ReturnOnFailure(previous.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO));
        ReturnOnFailure(previous.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE));

        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO));
        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_SENSOR));
        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE));
        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_USER_INTERFACE_FAULT));
#endif
        delegate->OnHardwareFaultsDetected(previous, current);
    }
    else if (EventId == GeneralDiagnostics::Events::RadioFaultChange::Id)
    {
        GeneralFaults<kMaxRadioFaults> previous;
        GeneralFaults<kMaxRadioFaults> current;

#if CHIP_CONFIG_TEST
        // On Linux Simulation, set following radio faults statically.
        ReturnOnFailure(previous.add(EMBER_ZCL_RADIO_FAULT_TYPE_WI_FI_FAULT));
        ReturnOnFailure(previous.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT));

        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_WI_FI_FAULT));
        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_CELLULAR_FAULT));
        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT));
        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_NFC_FAULT));
#endif
        delegate->OnRadioFaultsDetected(previous, current);
    }
    else if (EventId == GeneralDiagnostics::Events::NetworkFaultChange::Id)
    {
        GeneralFaults<kMaxNetworkFaults> previous;
        GeneralFaults<kMaxNetworkFaults> current;

#if CHIP_CONFIG_TEST
        // On Linux Simulation, set following radio faults statically.
        ReturnOnFailure(previous.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE));
        ReturnOnFailure(previous.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED));

        ReturnOnFailure(current.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE));
        ReturnOnFailure(current.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED));
        ReturnOnFailure(current.add(EMBER_ZCL_NETWORK_FAULT_TYPE_CONNECTION_FAILED));
#endif
        delegate->OnNetworkFaultsDetected(previous, current);
    }
    else
    {
        ChipLogError(DeviceLayer, "Unknow event ID:%d", EventId);
    }
}

void PlatformManagerImpl::HandleSoftwareFault(uint32_t EventId)
{
    SoftwareDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetSoftwareDiagnosticsDelegate();

    if (delegate != nullptr)
    {
        SoftwareDiagnostics::Structs::SoftwareFaultStruct::Type softwareFault;
        char threadName[kMaxThreadNameLength + 1];

        softwareFault.id = gettid();
        strncpy(threadName, std::to_string(softwareFault.id).c_str(), kMaxThreadNameLength);
        threadName[kMaxThreadNameLength] = '\0';
        softwareFault.name               = CharSpan::fromCharString(threadName);
        softwareFault.faultRecording     = ByteSpan(Uint8::from_const_char("FaultRecording"), strlen("FaultRecording"));

        delegate->OnSoftwareFaultDetected(softwareFault);
    }
}

void PlatformManagerImpl::HandleSwitchEvent(uint32_t EventId)
{
    SwitchDeviceControlDelegate * delegate = DeviceControlServer::DeviceControlSvr().GetSwitchDelegate();

    if (delegate == nullptr)
    {
        ChipLogError(DeviceLayer, "No delegate registered to handle Switch event");
        return;
    }

    if (EventId == Switch::Events::SwitchLatched::Id)
    {
        uint8_t newPosition = 0;

#if CHIP_CONFIG_TEST
        newPosition = 100;
#endif
        delegate->OnSwitchLatched(newPosition);
    }
    else if (EventId == Switch::Events::InitialPress::Id)
    {
        uint8_t newPosition = 0;

#if CHIP_CONFIG_TEST
        newPosition = 100;
#endif
        delegate->OnInitialPressed(newPosition);
    }
    else if (EventId == Switch::Events::LongPress::Id)
    {
        uint8_t newPosition = 0;

#if CHIP_CONFIG_TEST
        newPosition = 100;
#endif
        delegate->OnLongPressed(newPosition);
    }
    else if (EventId == Switch::Events::ShortRelease::Id)
    {
        uint8_t previousPosition = 0;

#if CHIP_CONFIG_TEST
        previousPosition = 50;
#endif
        delegate->OnShortReleased(previousPosition);
    }
    else if (EventId == Switch::Events::LongRelease::Id)
    {
        uint8_t previousPosition = 0;

#if CHIP_CONFIG_TEST
        previousPosition = 50;
#endif
        delegate->OnLongReleased(previousPosition);
    }
    else if (EventId == Switch::Events::MultiPressOngoing::Id)
    {
        uint8_t newPosition                   = 0;
        uint8_t currentNumberOfPressesCounted = 0;

#if CHIP_CONFIG_TEST
        newPosition                   = 10;
        currentNumberOfPressesCounted = 5;
#endif
        delegate->OnMultiPressOngoing(newPosition, currentNumberOfPressesCounted);
    }
    else if (EventId == Switch::Events::MultiPressComplete::Id)
    {
        uint8_t newPosition                 = 0;
        uint8_t totalNumberOfPressesCounted = 0;

#if CHIP_CONFIG_TEST
        newPosition                 = 10;
        totalNumberOfPressesCounted = 5;
#endif
        delegate->OnMultiPressComplete(newPosition, totalNumberOfPressesCounted);
    }
    else
    {
        ChipLogError(DeviceLayer, "Unknow event ID:%d", EventId);
    }
}

#if CHIP_WITH_GIO
GDBusConnection * PlatformManagerImpl::GetGDBusConnection()
{
    return this->mpGDBusConnection.get();
}
#endif

} // namespace DeviceLayer
} // namespace chip
<commit_msg>[linux] fix DUT is aborted when send network-fault-change event (#17465)<commit_after>/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2018 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *          Provides an implementation of the PlatformManager object
 *          for Linux platforms.
 */

#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <app-common/zap-generated/enums.h>
#include <app-common/zap-generated/ids/Events.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/DeviceControlServer.h>
#include <platform/Linux/DeviceInfoProviderImpl.h>
#include <platform/Linux/DiagnosticDataProviderImpl.h>
#include <platform/PlatformManager.h>
#include <platform/internal/GenericPlatformManagerImpl_POSIX.ipp>

#include <thread>

#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>

#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 30
#include <sys/syscall.h>
#define gettid() syscall(SYS_gettid)
#endif

using namespace ::chip::app::Clusters;

namespace chip {
namespace DeviceLayer {

PlatformManagerImpl PlatformManagerImpl::sInstance;

namespace {

void SignalHandler(int signum)
{
    ChipLogDetail(DeviceLayer, "Caught signal %d", signum);

    switch (signum)
    {
    case SIGUSR1:
        PlatformMgrImpl().HandleSoftwareFault(SoftwareDiagnostics::Events::SoftwareFault::Id);
        break;
    case SIGUSR2:
        PlatformMgrImpl().HandleGeneralFault(GeneralDiagnostics::Events::HardwareFaultChange::Id);
        break;
    case SIGHUP:
        PlatformMgrImpl().HandleGeneralFault(GeneralDiagnostics::Events::RadioFaultChange::Id);
        break;
    case SIGTTIN:
        PlatformMgrImpl().HandleGeneralFault(GeneralDiagnostics::Events::NetworkFaultChange::Id);
        break;
    case SIGTSTP:
        PlatformMgrImpl().HandleSwitchEvent(Switch::Events::SwitchLatched::Id);
        break;
    default:
        break;
    }
}

#if CHIP_WITH_GIO
void GDBus_Thread()
{
    GMainLoop * loop = g_main_loop_new(nullptr, false);

    g_main_loop_run(loop);
    g_main_loop_unref(loop);
}
#endif
} // namespace

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
void PlatformManagerImpl::WiFIIPChangeListener()
{
    int sock;
    if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1)
    {
        ChipLogError(DeviceLayer, "Failed to init netlink socket for ip addresses.");
        return;
    }

    struct sockaddr_nl addr;
    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;
    addr.nl_groups = RTMGRP_IPV4_IFADDR;

    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1)
    {
        ChipLogError(DeviceLayer, "Failed to bind netlink socket for ip addresses.");
        return;
    }

    ssize_t len;
    char buffer[4096];
    for (struct nlmsghdr * header = reinterpret_cast<struct nlmsghdr *>(buffer); (len = recv(sock, header, sizeof(buffer), 0)) > 0;)
    {
        for (struct nlmsghdr * messageHeader = header;
             (NLMSG_OK(messageHeader, static_cast<uint32_t>(len))) && (messageHeader->nlmsg_type != NLMSG_DONE);
             messageHeader = NLMSG_NEXT(messageHeader, len))
        {
            if (header->nlmsg_type == RTM_NEWADDR)
            {
                struct ifaddrmsg * addressMessage = (struct ifaddrmsg *) NLMSG_DATA(header);
                struct rtattr * routeInfo         = IFA_RTA(addressMessage);
                size_t rtl                        = IFA_PAYLOAD(header);

                for (; rtl && RTA_OK(routeInfo, rtl); routeInfo = RTA_NEXT(routeInfo, rtl))
                {
                    if (routeInfo->rta_type == IFA_LOCAL)
                    {
                        char name[IFNAMSIZ];
                        if (if_indextoname(addressMessage->ifa_index, name) == nullptr)
                        {
                            ChipLogError(DeviceLayer, "Error %d when getting the interface name at index: %d", errno,
                                         addressMessage->ifa_index);
                            continue;
                        }

                        if (strcmp(name, ConnectivityManagerImpl::GetWiFiIfName()) != 0)
                        {
                            continue;
                        }

                        ChipDeviceEvent event;
                        event.Type                            = DeviceEventType::kInternetConnectivityChange;
                        event.InternetConnectivityChange.IPv4 = kConnectivity_Established;
                        event.InternetConnectivityChange.IPv6 = kConnectivity_NoChange;
                        inet_ntop(AF_INET, RTA_DATA(routeInfo), event.InternetConnectivityChange.address,
                                  sizeof(event.InternetConnectivityChange.address));

                        ChipLogDetail(DeviceLayer, "Got IP address on interface: %s IP: %s", name,
                                      event.InternetConnectivityChange.address);

                        CHIP_ERROR status = PlatformMgr().PostEvent(&event);
                        if (status != CHIP_NO_ERROR)
                        {
                            ChipLogDetail(DeviceLayer, "Failed to report IP address: %" CHIP_ERROR_FORMAT, status.Format());
                        }
                    }
                }
            }
        }
    }
}
#endif // #if CHIP_DEVICE_CONFIG_ENABLE_WIFI

CHIP_ERROR PlatformManagerImpl::_InitChipStack()
{
    struct sigaction action;

    memset(&action, 0, sizeof(action));
    action.sa_handler = SignalHandler;
    sigaction(SIGHUP, &action, nullptr);
    sigaction(SIGTTIN, &action, nullptr);
    sigaction(SIGUSR1, &action, nullptr);
    sigaction(SIGUSR2, &action, nullptr);
    sigaction(SIGTSTP, &action, nullptr);

#if CHIP_WITH_GIO
    GError * error = nullptr;

    this->mpGDBusConnection = UniqueGDBusConnection(g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error));

    std::thread gdbusThread(GDBus_Thread);
    gdbusThread.detach();
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
    std::thread wifiIPThread(WiFIIPChangeListener);
    wifiIPThread.detach();
#endif

    // Initialize the configuration system.
    ReturnErrorOnFailure(Internal::PosixConfig::Init());
    SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance());
    SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance());
    SetDeviceInfoProvider(&DeviceInfoProviderImpl::GetDefaultInstance());

    // Call _InitChipStack() on the generic implementation base class
    // to finish the initialization process.
    ReturnErrorOnFailure(Internal::GenericPlatformManagerImpl_POSIX<PlatformManagerImpl>::_InitChipStack());

    mStartTime = System::SystemClock().GetMonotonicTimestamp();

    return CHIP_NO_ERROR;
}

CHIP_ERROR PlatformManagerImpl::_Shutdown()
{
    uint64_t upTime = 0;

    if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR)
    {
        uint32_t totalOperationalHours = 0;

        if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
        {
            ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast<uint32_t>(upTime / 3600));
        }
        else
        {
            ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
        }
    }
    else
    {
        ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot");
    }

    return Internal::GenericPlatformManagerImpl_POSIX<PlatformManagerImpl>::_Shutdown();
}

void PlatformManagerImpl::HandleGeneralFault(uint32_t EventId)
{
    GeneralDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetGeneralDiagnosticsDelegate();

    if (delegate == nullptr)
    {
        ChipLogError(DeviceLayer, "No delegate registered to handle General Diagnostics event");
        return;
    }

    if (EventId == GeneralDiagnostics::Events::HardwareFaultChange::Id)
    {
        GeneralFaults<kMaxHardwareFaults> previous;
        GeneralFaults<kMaxHardwareFaults> current;

#if CHIP_CONFIG_TEST
        // On Linux Simulation, set following hardware faults statically.
        ReturnOnFailure(previous.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO));
        ReturnOnFailure(previous.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE));

        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO));
        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_SENSOR));
        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE));
        ReturnOnFailure(current.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_USER_INTERFACE_FAULT));
#endif
        delegate->OnHardwareFaultsDetected(previous, current);
    }
    else if (EventId == GeneralDiagnostics::Events::RadioFaultChange::Id)
    {
        GeneralFaults<kMaxRadioFaults> previous;
        GeneralFaults<kMaxRadioFaults> current;

#if CHIP_CONFIG_TEST
        // On Linux Simulation, set following radio faults statically.
        ReturnOnFailure(previous.add(EMBER_ZCL_RADIO_FAULT_TYPE_WI_FI_FAULT));
        ReturnOnFailure(previous.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT));

        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_WI_FI_FAULT));
        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_CELLULAR_FAULT));
        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT));
        ReturnOnFailure(current.add(EMBER_ZCL_RADIO_FAULT_TYPE_NFC_FAULT));
#endif
        delegate->OnRadioFaultsDetected(previous, current);
    }
    else if (EventId == GeneralDiagnostics::Events::NetworkFaultChange::Id)
    {
        GeneralFaults<kMaxNetworkFaults> previous;
        GeneralFaults<kMaxNetworkFaults> current;

#if CHIP_CONFIG_TEST
        // On Linux Simulation, set following radio faults statically.
        ReturnOnFailure(previous.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE));
        ReturnOnFailure(previous.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED));

        ReturnOnFailure(current.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE));
        ReturnOnFailure(current.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED));
        ReturnOnFailure(current.add(EMBER_ZCL_NETWORK_FAULT_TYPE_CONNECTION_FAILED));
#endif
        delegate->OnNetworkFaultsDetected(previous, current);
    }
    else
    {
        ChipLogError(DeviceLayer, "Unknow event ID:%d", EventId);
    }
}

void PlatformManagerImpl::HandleSoftwareFault(uint32_t EventId)
{
    SoftwareDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetSoftwareDiagnosticsDelegate();

    if (delegate != nullptr)
    {
        SoftwareDiagnostics::Structs::SoftwareFaultStruct::Type softwareFault;
        char threadName[kMaxThreadNameLength + 1];

        softwareFault.id = gettid();
        strncpy(threadName, std::to_string(softwareFault.id).c_str(), kMaxThreadNameLength);
        threadName[kMaxThreadNameLength] = '\0';
        softwareFault.name               = CharSpan::fromCharString(threadName);
        softwareFault.faultRecording     = ByteSpan(Uint8::from_const_char("FaultRecording"), strlen("FaultRecording"));

        delegate->OnSoftwareFaultDetected(softwareFault);
    }
}

void PlatformManagerImpl::HandleSwitchEvent(uint32_t EventId)
{
    SwitchDeviceControlDelegate * delegate = DeviceControlServer::DeviceControlSvr().GetSwitchDelegate();

    if (delegate == nullptr)
    {
        ChipLogError(DeviceLayer, "No delegate registered to handle Switch event");
        return;
    }

    if (EventId == Switch::Events::SwitchLatched::Id)
    {
        uint8_t newPosition = 0;

#if CHIP_CONFIG_TEST
        newPosition = 100;
#endif
        delegate->OnSwitchLatched(newPosition);
    }
    else if (EventId == Switch::Events::InitialPress::Id)
    {
        uint8_t newPosition = 0;

#if CHIP_CONFIG_TEST
        newPosition = 100;
#endif
        delegate->OnInitialPressed(newPosition);
    }
    else if (EventId == Switch::Events::LongPress::Id)
    {
        uint8_t newPosition = 0;

#if CHIP_CONFIG_TEST
        newPosition = 100;
#endif
        delegate->OnLongPressed(newPosition);
    }
    else if (EventId == Switch::Events::ShortRelease::Id)
    {
        uint8_t previousPosition = 0;

#if CHIP_CONFIG_TEST
        previousPosition = 50;
#endif
        delegate->OnShortReleased(previousPosition);
    }
    else if (EventId == Switch::Events::LongRelease::Id)
    {
        uint8_t previousPosition = 0;

#if CHIP_CONFIG_TEST
        previousPosition = 50;
#endif
        delegate->OnLongReleased(previousPosition);
    }
    else if (EventId == Switch::Events::MultiPressOngoing::Id)
    {
        uint8_t newPosition                   = 0;
        uint8_t currentNumberOfPressesCounted = 0;

#if CHIP_CONFIG_TEST
        newPosition                   = 10;
        currentNumberOfPressesCounted = 5;
#endif
        delegate->OnMultiPressOngoing(newPosition, currentNumberOfPressesCounted);
    }
    else if (EventId == Switch::Events::MultiPressComplete::Id)
    {
        uint8_t newPosition                 = 0;
        uint8_t totalNumberOfPressesCounted = 0;

#if CHIP_CONFIG_TEST
        newPosition                 = 10;
        totalNumberOfPressesCounted = 5;
#endif
        delegate->OnMultiPressComplete(newPosition, totalNumberOfPressesCounted);
    }
    else
    {
        ChipLogError(DeviceLayer, "Unknow event ID:%d", EventId);
    }
}

#if CHIP_WITH_GIO
GDBusConnection * PlatformManagerImpl::GetGDBusConnection()
{
    return this->mpGDBusConnection.get();
}
#endif

} // namespace DeviceLayer
} // namespace chip
<|endoftext|>


<commit_before>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/android/vibration_message_filter.h"

#include <algorithm>

#include "base/safe_numerics.h"
#include "content/common/view_messages.h"
#include "jni/VibrationMessageFilter_jni.h"
#include "third_party/WebKit/public/platform/WebVibration.h"

using base::android::AttachCurrentThread;

namespace content {

// Minimum duration of a vibration is 1 millisecond.
const int64 kMinimumVibrationDurationMs = 1;

VibrationMessageFilter::VibrationMessageFilter() {
}

VibrationMessageFilter::~VibrationMessageFilter() {
}

// static
bool VibrationMessageFilter::Register(JNIEnv* env) {
  return RegisterNativesImpl(env);
}

bool VibrationMessageFilter::OnMessageReceived(
    const IPC::Message& message,
    bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(VibrationMessageFilter,
                           message,
                           *message_was_ok)
    IPC_MESSAGE_HANDLER(ViewHostMsg_Vibrate, OnVibrate)
    IPC_MESSAGE_HANDLER(ViewHostMsg_CancelVibration, OnCancelVibration)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP_EX()
  return handled;
}

void VibrationMessageFilter::OnVibrate(int64 milliseconds) {
  // Though the Blink implementation already sanitizes vibration times, don't
  // trust any values passed from the renderer.
  milliseconds = std::max(kMinimumVibrationDurationMs,
      std::min(milliseconds,
          base::checked_numeric_cast<int64>(WebKit::kVibrationDurationMax)));

  if (j_vibration_message_filter_.is_null()) {
    j_vibration_message_filter_.Reset(
        Java_VibrationMessageFilter_create(
            AttachCurrentThread(),
            base::android::GetApplicationContext()));
  }
  Java_VibrationMessageFilter_vibrate(AttachCurrentThread(),
                                j_vibration_message_filter_.obj(),
                                milliseconds);
}

void VibrationMessageFilter::OnCancelVibration() {
  Java_VibrationMessageFilter_cancelVibration(AttachCurrentThread(),
                                        j_vibration_message_filter_.obj());
}

}  // namespace content
<commit_msg>Vibration: don't instantiate Java object only to cancel vibration<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/android/vibration_message_filter.h"

#include <algorithm>

#include "base/safe_numerics.h"
#include "content/common/view_messages.h"
#include "jni/VibrationMessageFilter_jni.h"
#include "third_party/WebKit/public/platform/WebVibration.h"

using base::android::AttachCurrentThread;

namespace content {

// Minimum duration of a vibration is 1 millisecond.
const int64 kMinimumVibrationDurationMs = 1;

VibrationMessageFilter::VibrationMessageFilter() {
}

VibrationMessageFilter::~VibrationMessageFilter() {
}

// static
bool VibrationMessageFilter::Register(JNIEnv* env) {
  return RegisterNativesImpl(env);
}

bool VibrationMessageFilter::OnMessageReceived(
    const IPC::Message& message,
    bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(VibrationMessageFilter,
                           message,
                           *message_was_ok)
    IPC_MESSAGE_HANDLER(ViewHostMsg_Vibrate, OnVibrate)
    IPC_MESSAGE_HANDLER(ViewHostMsg_CancelVibration, OnCancelVibration)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP_EX()
  return handled;
}

void VibrationMessageFilter::OnVibrate(int64 milliseconds) {
  // Though the Blink implementation already sanitizes vibration times, don't
  // trust any values passed from the renderer.
  milliseconds = std::max(kMinimumVibrationDurationMs,
      std::min(milliseconds,
          base::checked_numeric_cast<int64>(WebKit::kVibrationDurationMax)));

  if (j_vibration_message_filter_.is_null()) {
    j_vibration_message_filter_.Reset(
        Java_VibrationMessageFilter_create(
            AttachCurrentThread(),
            base::android::GetApplicationContext()));
  }
  Java_VibrationMessageFilter_vibrate(AttachCurrentThread(),
                                      j_vibration_message_filter_.obj(),
                                      milliseconds);
}

void VibrationMessageFilter::OnCancelVibration() {
  // If somehow a cancel message is received before this object was
  // instantiated, it means there is no current vibration anyway. Just return.
  if (j_vibration_message_filter_.is_null())
    return;
  Java_VibrationMessageFilter_cancelVibration(AttachCurrentThread(),
      j_vibration_message_filter_.obj());
}

}  // namespace content
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if defined(ENABLE_GPU)

#include "content/common/gpu/image_transport_surface_linux.h"

// This conflicts with the defines in Xlib.h and must come first.
#include "content/common/gpu/gpu_messages.h"

#include <map>
#include <X11/Xlib.h>
#include <X11/extensions/Xcomposite.h>

#include "base/callback.h"
#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_bindings.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface_egl.h"
#include "ui/gfx/gl/gl_surface_glx.h"
#include "ui/gfx/surface/accelerated_surface_linux.h"

#if !defined(GL_DEPTH24_STENCIL8)
#define GL_DEPTH24_STENCIL8 0x88F0
#endif

namespace {

// We are backed by an Pbuffer offscreen surface for the purposes of creating a
// context, but use FBOs to render to X Pixmap backed EGLImages.
class EGLImageTransportSurface : public ImageTransportSurface,
                                 public gfx::PbufferGLSurfaceEGL {
 public:
  explicit EGLImageTransportSurface(GpuCommandBufferStub* stub);

  // GLSurface implementation
  virtual bool Initialize() OVERRIDE;
  virtual void Destroy() OVERRIDE;
  virtual bool IsOffscreen() OVERRIDE;
  virtual bool SwapBuffers() OVERRIDE;
  virtual gfx::Size GetSize() OVERRIDE;
  virtual void OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
  virtual unsigned int GetBackingFrameBufferObject() OVERRIDE;

 protected:
  // ImageTransportSurface implementation
  virtual void OnSetSurfaceACK(uint64 surface_id) OVERRIDE;
  virtual void OnBuffersSwappedACK() OVERRIDE;
  virtual void Resize(gfx::Size size) OVERRIDE;

 private:
  virtual ~EGLImageTransportSurface() OVERRIDE;
  void ReleaseSurface(scoped_refptr<AcceleratedSurface>& surface);

  uint32 fbo_id_;
  uint32 depth_id_;
  uint32 stencil_id_;
  gfx::Size buffer_size_;

  bool depth24_stencil8_supported_;

  scoped_refptr<AcceleratedSurface> back_surface_;
  scoped_refptr<AcceleratedSurface> front_surface_;

  DISALLOW_COPY_AND_ASSIGN(EGLImageTransportSurface);
};

// We are backed by an Pbuffer offscreen surface for the purposes of creating a
// context, but use FBOs to render to X Pixmap backed EGLImages.
class GLXImageTransportSurface : public ImageTransportSurface,
                                 public gfx::NativeViewGLSurfaceGLX {
 public:
  explicit GLXImageTransportSurface(GpuCommandBufferStub* stub);

  // gfx::GLSurface implementation:
  virtual bool Initialize() OVERRIDE;
  virtual void Destroy() OVERRIDE;
  virtual bool SwapBuffers() OVERRIDE;
  virtual gfx::Size GetSize() OVERRIDE;

 protected:
  // ImageTransportSurface implementation:
  void OnSetSurfaceACK(uint64 surface_id) OVERRIDE;
  void OnBuffersSwappedACK() OVERRIDE;
  void Resize(gfx::Size size) OVERRIDE;

 private:
  virtual ~GLXImageTransportSurface();

  // Tell the browser to release the surface.
  void ReleaseSurface();

  XID dummy_parent_;
  gfx::Size size_;

  // Whether or not the image has been bound on the browser side.
  bool bound_;

  DISALLOW_COPY_AND_ASSIGN(GLXImageTransportSurface);
};

EGLImageTransportSurface::EGLImageTransportSurface(GpuCommandBufferStub* stub)
    : ImageTransportSurface(stub),
      gfx::PbufferGLSurfaceEGL(false, gfx::Size(1, 1)),
      fbo_id_(0),
      depth_id_(0),
      stencil_id_(0),
      depth24_stencil8_supported_(false) {
}

EGLImageTransportSurface::~EGLImageTransportSurface() {
}

bool EGLImageTransportSurface::Initialize() {
  if (!ImageTransportSurface::Initialize())
    return false;
  return PbufferGLSurfaceEGL::Initialize();
}

void EGLImageTransportSurface::Destroy() {
  if (depth_id_) {
    glDeleteRenderbuffersEXT(1, &depth_id_);
    depth_id_ = 0;
  }

  if (stencil_id_) {
    glDeleteRenderbuffersEXT(1, &stencil_id_);
    stencil_id_ = 0;
  }

  if (back_surface_.get())
    ReleaseSurface(back_surface_);
  if (front_surface_.get())
    ReleaseSurface(front_surface_);

  ImageTransportSurface::Destroy();
  PbufferGLSurfaceEGL::Destroy();
}

bool EGLImageTransportSurface::IsOffscreen() {
  return false;
}

void EGLImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
  if (fbo_id_)
    return;

  depth24_stencil8_supported_ =
      context->HasExtension("GL_OES_packed_depth_stencil");

  glGenFramebuffersEXT(1, &fbo_id_);
  glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_);
  Resize(gfx::Size(1, 1));

  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
  if (status != GL_FRAMEBUFFER_COMPLETE) {
    LOG(ERROR) << "Framebuffer incomplete.";
  }
}

unsigned int EGLImageTransportSurface::GetBackingFrameBufferObject() {
  return fbo_id_;
}

void EGLImageTransportSurface::ReleaseSurface(
    scoped_refptr<AcceleratedSurface>& surface) {
  if (surface.get()) {
    GpuHostMsg_AcceleratedSurfaceRelease_Params params;
    params.renderer_id = stub()->renderer_id();
    params.render_view_id = stub()->render_view_id();
    params.identifier = back_surface_->pixmap();
    params.route_id = route_id();
    Send(new GpuHostMsg_AcceleratedSurfaceRelease(params));
    surface = NULL;
  }
}

void EGLImageTransportSurface::Resize(gfx::Size size) {
  if (back_surface_.get())
    ReleaseSurface(back_surface_);

  if (depth_id_ && buffer_size_ != size) {
    glDeleteRenderbuffersEXT(1, &depth_id_);

    if (stencil_id_)
      glDeleteRenderbuffersEXT(1, &stencil_id_);

    depth_id_ = stencil_id_ = 0;
  }

  if (!depth_id_) {
    if (depth24_stencil8_supported_) {
      glGenRenderbuffersEXT(1, &depth_id_);
      glBindRenderbufferEXT(GL_RENDERBUFFER, depth_id_);
      glRenderbufferStorageEXT(GL_RENDERBUFFER,
                               GL_DEPTH24_STENCIL8,
                               size.width(),
                               size.height());
    } else {
      glGenRenderbuffersEXT(1, &depth_id_);
      glBindRenderbufferEXT(GL_RENDERBUFFER, depth_id_);
      glRenderbufferStorageEXT(GL_RENDERBUFFER,
                               GL_DEPTH_COMPONENT16,
                               size.width(),
                               size.height());

      glGenRenderbuffersEXT(1, &stencil_id_);
      glBindRenderbufferEXT(GL_RENDERBUFFER, stencil_id_);
      glRenderbufferStorageEXT(GL_RENDERBUFFER,
                               GL_STENCIL_INDEX8,
                               size.width(),
                               size.height());
    }
    glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
                                 GL_DEPTH_ATTACHMENT,
                                 GL_RENDERBUFFER,
                                 depth_id_);
    if (stencil_id_)
      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
                                   GL_STENCIL_ATTACHMENT,
                                   GL_RENDERBUFFER,
                                   stencil_id_);
    buffer_size_ = size;
  }

  back_surface_ = new AcceleratedSurface(size);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
                            GL_COLOR_ATTACHMENT0,
                            GL_TEXTURE_2D,
                            back_surface_->texture(),
                            0);
  glFlush();

  GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.width = size.width();
  params.height = size.height();
  params.identifier = back_surface_->pixmap();
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params));

  scheduler()->SetScheduled(false);
}

bool EGLImageTransportSurface::SwapBuffers() {
  front_surface_.swap(back_surface_);
  DCHECK_NE(front_surface_.get(), static_cast<AcceleratedSurface*>(NULL));
  glFlush();

  GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.surface_id = front_surface_->pixmap();
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));

  gfx::Size expected_size = front_surface_->size();
  if (!back_surface_.get() || back_surface_->size() != expected_size) {
    Resize(expected_size);
  } else {
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_TEXTURE_2D,
                              back_surface_->texture(),
                              0);
  }
  scheduler()->SetScheduled(false);
  return true;
}

gfx::Size EGLImageTransportSurface::GetSize() {
  return back_surface_->size();
}

void EGLImageTransportSurface::OnSetSurfaceACK(
    uint64 surface_id) {
  DCHECK_EQ(back_surface_->pixmap(), surface_id);
  scheduler()->SetScheduled(true);
}

void EGLImageTransportSurface::OnBuffersSwappedACK() {
  scheduler()->SetScheduled(true);
}

GLXImageTransportSurface::GLXImageTransportSurface(GpuCommandBufferStub* stub)
     : ImageTransportSurface(stub),
       gfx::NativeViewGLSurfaceGLX(),
       dummy_parent_(0),
       size_(1, 1),
       bound_(false) {
}

GLXImageTransportSurface::~GLXImageTransportSurface() {
}

bool GLXImageTransportSurface::Initialize() {
  // Create a dummy window to host the real window.
  Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
  XSetWindowAttributes swa;
  swa.event_mask = StructureNotifyMask;
  swa.override_redirect = True;
  dummy_parent_ = XCreateWindow(
      dpy,
      RootWindow(dpy, DefaultScreen(dpy)),  // parent
      -100, -100, 1, 1,
      0,  // border width
      CopyFromParent,  // depth
      InputOutput,
      CopyFromParent,  // visual
      CWEventMask | CWOverrideRedirect, &swa);
  XMapWindow(dpy, dummy_parent_);

  swa.event_mask = StructureNotifyMask;
  swa.override_redirect = false;
  window_ = XCreateWindow(dpy,
                          dummy_parent_,
                          0, 0, size_.width(), size_.height(),
                          0,  // border width
                          CopyFromParent,  // depth
                          InputOutput,
                          CopyFromParent,  // visual
                          CWEventMask, &swa);
  XMapWindow(dpy, window_);
  while (1) {
    XEvent event;
    XNextEvent(dpy, &event);
    if (event.type == MapNotify && event.xmap.window == window_)
      break;
  }
  // Manual setting must be used to avoid unnecessary rendering by server.
  XCompositeRedirectWindow(dpy, window_, CompositeRedirectManual);
  Resize(size_);

  if (!ImageTransportSurface::Initialize())
    return false;
  return gfx::NativeViewGLSurfaceGLX::Initialize();
}

void GLXImageTransportSurface::Destroy() {
  if (bound_)
    ReleaseSurface();

  if (window_) {
    Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
    XDestroyWindow(dpy, window_);
    XDestroyWindow(dpy, dummy_parent_);
  }

  ImageTransportSurface::Destroy();
  gfx::NativeViewGLSurfaceGLX::Destroy();
}

void GLXImageTransportSurface::ReleaseSurface() {
  DCHECK(bound_);
  GpuHostMsg_AcceleratedSurfaceRelease_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.identifier = window_;
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceRelease(params));
}

void GLXImageTransportSurface::Resize(gfx::Size size) {
  size_ = size;
  if (bound_) {
    ReleaseSurface();
    bound_ = false;
  }

  Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
  XResizeWindow(dpy, window_, size_.width(), size_.height());
  XFlush(dpy);

  GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.width = size_.width();
  params.height = size_.height();
  params.identifier = window_;
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params));

  scheduler()->SetScheduled(false);
}

bool GLXImageTransportSurface::SwapBuffers() {
  gfx::NativeViewGLSurfaceGLX::SwapBuffers();
  glFlush();

  GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.surface_id = window_;
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));

  return true;
}

gfx::Size GLXImageTransportSurface::GetSize() {
  return size_;
}

void GLXImageTransportSurface::OnSetSurfaceACK(
    uint64 surface_id) {
  DCHECK(!bound_);
  bound_ = true;
  scheduler()->SetScheduled(true);
}

void GLXImageTransportSurface::OnBuffersSwappedACK() {
}

}  // namespace

ImageTransportSurface::ImageTransportSurface(GpuCommandBufferStub* stub)
    : stub_(stub) {
  GpuChannelManager* gpu_channel_manager
      = stub_->channel()->gpu_channel_manager();
  route_id_ = gpu_channel_manager->GenerateRouteID();
  gpu_channel_manager->AddRoute(route_id_, this);
}

ImageTransportSurface::~ImageTransportSurface() {
  GpuChannelManager* gpu_channel_manager
      = stub_->channel()->gpu_channel_manager();
  gpu_channel_manager->RemoveRoute(route_id_);
}

bool ImageTransportSurface::Initialize() {
  scheduler()->SetResizeCallback(
     NewCallback(this, &ImageTransportSurface::Resize));
  return true;
}

void ImageTransportSurface::Destroy() {
  scheduler()->SetResizeCallback(NULL);
}

bool ImageTransportSurface::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ImageTransportSurface, message)
    IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_SetSurfaceACK,
                        OnSetSurfaceACK)
    IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BuffersSwappedACK,
                        OnBuffersSwappedACK)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

bool ImageTransportSurface::Send(IPC::Message* message) {
  GpuChannelManager* gpu_channel_manager =
      stub_->channel()->gpu_channel_manager();
  return gpu_channel_manager->Send(message);
}

gpu::GpuScheduler* ImageTransportSurface::scheduler() {
  return stub_->scheduler();
}

// static
scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
    GpuCommandBufferStub* stub) {
  scoped_refptr<gfx::GLSurface> surface;
  switch (gfx::GetGLImplementation()) {
    case gfx::kGLImplementationDesktopGL:
      surface = new GLXImageTransportSurface(stub);
      break;
    case gfx::kGLImplementationEGLGLES2:
      surface = new EGLImageTransportSurface(stub);
      break;
    default:
      NOTREACHED();
      return NULL;
  }
  if (surface->Initialize())
    return surface;
  else
    return NULL;
}

#endif  // defined(USE_GPU)
<commit_msg>Get rid of unused depth and stencil buffers.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if defined(ENABLE_GPU)

#include "content/common/gpu/image_transport_surface_linux.h"

// This conflicts with the defines in Xlib.h and must come first.
#include "content/common/gpu/gpu_messages.h"

#include <map>
#include <X11/Xlib.h>
#include <X11/extensions/Xcomposite.h>

#include "base/callback.h"
#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_bindings.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface_egl.h"
#include "ui/gfx/gl/gl_surface_glx.h"
#include "ui/gfx/surface/accelerated_surface_linux.h"

namespace {

// We are backed by an Pbuffer offscreen surface for the purposes of creating a
// context, but use FBOs to render to X Pixmap backed EGLImages.
class EGLImageTransportSurface : public ImageTransportSurface,
                                 public gfx::PbufferGLSurfaceEGL {
 public:
  explicit EGLImageTransportSurface(GpuCommandBufferStub* stub);

  // GLSurface implementation
  virtual bool Initialize() OVERRIDE;
  virtual void Destroy() OVERRIDE;
  virtual bool IsOffscreen() OVERRIDE;
  virtual bool SwapBuffers() OVERRIDE;
  virtual gfx::Size GetSize() OVERRIDE;
  virtual void OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
  virtual unsigned int GetBackingFrameBufferObject() OVERRIDE;

 protected:
  // ImageTransportSurface implementation
  virtual void OnSetSurfaceACK(uint64 surface_id) OVERRIDE;
  virtual void OnBuffersSwappedACK() OVERRIDE;
  virtual void Resize(gfx::Size size) OVERRIDE;

 private:
  virtual ~EGLImageTransportSurface() OVERRIDE;
  void ReleaseSurface(scoped_refptr<AcceleratedSurface>& surface);

  uint32 fbo_id_;

  scoped_refptr<AcceleratedSurface> back_surface_;
  scoped_refptr<AcceleratedSurface> front_surface_;

  DISALLOW_COPY_AND_ASSIGN(EGLImageTransportSurface);
};

// We are backed by an Pbuffer offscreen surface for the purposes of creating a
// context, but use FBOs to render to X Pixmap backed EGLImages.
class GLXImageTransportSurface : public ImageTransportSurface,
                                 public gfx::NativeViewGLSurfaceGLX {
 public:
  explicit GLXImageTransportSurface(GpuCommandBufferStub* stub);

  // gfx::GLSurface implementation:
  virtual bool Initialize() OVERRIDE;
  virtual void Destroy() OVERRIDE;
  virtual bool SwapBuffers() OVERRIDE;
  virtual gfx::Size GetSize() OVERRIDE;

 protected:
  // ImageTransportSurface implementation:
  void OnSetSurfaceACK(uint64 surface_id) OVERRIDE;
  void OnBuffersSwappedACK() OVERRIDE;
  void Resize(gfx::Size size) OVERRIDE;

 private:
  virtual ~GLXImageTransportSurface();

  // Tell the browser to release the surface.
  void ReleaseSurface();

  XID dummy_parent_;
  gfx::Size size_;

  // Whether or not the image has been bound on the browser side.
  bool bound_;

  DISALLOW_COPY_AND_ASSIGN(GLXImageTransportSurface);
};

EGLImageTransportSurface::EGLImageTransportSurface(GpuCommandBufferStub* stub)
    : ImageTransportSurface(stub),
      gfx::PbufferGLSurfaceEGL(false, gfx::Size(1, 1)),
      fbo_id_(0) {
}

EGLImageTransportSurface::~EGLImageTransportSurface() {
}

bool EGLImageTransportSurface::Initialize() {
  if (!ImageTransportSurface::Initialize())
    return false;
  return PbufferGLSurfaceEGL::Initialize();
}

void EGLImageTransportSurface::Destroy() {
  if (back_surface_.get())
    ReleaseSurface(back_surface_);
  if (front_surface_.get())
    ReleaseSurface(front_surface_);

  ImageTransportSurface::Destroy();
  PbufferGLSurfaceEGL::Destroy();
}

bool EGLImageTransportSurface::IsOffscreen() {
  return false;
}

void EGLImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
  if (fbo_id_)
    return;

  glGenFramebuffersEXT(1, &fbo_id_);
  glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_id_);
  Resize(gfx::Size(1, 1));

  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
  if (status != GL_FRAMEBUFFER_COMPLETE) {
    LOG(ERROR) << "Framebuffer incomplete.";
  }
}

unsigned int EGLImageTransportSurface::GetBackingFrameBufferObject() {
  return fbo_id_;
}

void EGLImageTransportSurface::ReleaseSurface(
    scoped_refptr<AcceleratedSurface>& surface) {
  if (surface.get()) {
    GpuHostMsg_AcceleratedSurfaceRelease_Params params;
    params.renderer_id = stub()->renderer_id();
    params.render_view_id = stub()->render_view_id();
    params.identifier = back_surface_->pixmap();
    params.route_id = route_id();
    Send(new GpuHostMsg_AcceleratedSurfaceRelease(params));
    surface = NULL;
  }
}

void EGLImageTransportSurface::Resize(gfx::Size size) {
  if (back_surface_.get())
    ReleaseSurface(back_surface_);

  back_surface_ = new AcceleratedSurface(size);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
                            GL_COLOR_ATTACHMENT0,
                            GL_TEXTURE_2D,
                            back_surface_->texture(),
                            0);
  glFlush();

  GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.width = size.width();
  params.height = size.height();
  params.identifier = back_surface_->pixmap();
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params));

  scheduler()->SetScheduled(false);
}

bool EGLImageTransportSurface::SwapBuffers() {
  front_surface_.swap(back_surface_);
  DCHECK_NE(front_surface_.get(), static_cast<AcceleratedSurface*>(NULL));
  glFlush();

  GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.surface_id = front_surface_->pixmap();
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));

  gfx::Size expected_size = front_surface_->size();
  if (!back_surface_.get() || back_surface_->size() != expected_size) {
    Resize(expected_size);
  } else {
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
                              GL_COLOR_ATTACHMENT0,
                              GL_TEXTURE_2D,
                              back_surface_->texture(),
                              0);
  }
  scheduler()->SetScheduled(false);
  return true;
}

gfx::Size EGLImageTransportSurface::GetSize() {
  return back_surface_->size();
}

void EGLImageTransportSurface::OnSetSurfaceACK(
    uint64 surface_id) {
  DCHECK_EQ(back_surface_->pixmap(), surface_id);
  scheduler()->SetScheduled(true);
}

void EGLImageTransportSurface::OnBuffersSwappedACK() {
  scheduler()->SetScheduled(true);
}

GLXImageTransportSurface::GLXImageTransportSurface(GpuCommandBufferStub* stub)
     : ImageTransportSurface(stub),
       gfx::NativeViewGLSurfaceGLX(),
       dummy_parent_(0),
       size_(1, 1),
       bound_(false) {
}

GLXImageTransportSurface::~GLXImageTransportSurface() {
}

bool GLXImageTransportSurface::Initialize() {
  // Create a dummy window to host the real window.
  Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
  XSetWindowAttributes swa;
  swa.event_mask = StructureNotifyMask;
  swa.override_redirect = True;
  dummy_parent_ = XCreateWindow(
      dpy,
      RootWindow(dpy, DefaultScreen(dpy)),  // parent
      -100, -100, 1, 1,
      0,  // border width
      CopyFromParent,  // depth
      InputOutput,
      CopyFromParent,  // visual
      CWEventMask | CWOverrideRedirect, &swa);
  XMapWindow(dpy, dummy_parent_);

  swa.event_mask = StructureNotifyMask;
  swa.override_redirect = false;
  window_ = XCreateWindow(dpy,
                          dummy_parent_,
                          0, 0, size_.width(), size_.height(),
                          0,  // border width
                          CopyFromParent,  // depth
                          InputOutput,
                          CopyFromParent,  // visual
                          CWEventMask, &swa);
  XMapWindow(dpy, window_);
  while (1) {
    XEvent event;
    XNextEvent(dpy, &event);
    if (event.type == MapNotify && event.xmap.window == window_)
      break;
  }
  // Manual setting must be used to avoid unnecessary rendering by server.
  XCompositeRedirectWindow(dpy, window_, CompositeRedirectManual);
  Resize(size_);

  if (!ImageTransportSurface::Initialize())
    return false;
  return gfx::NativeViewGLSurfaceGLX::Initialize();
}

void GLXImageTransportSurface::Destroy() {
  if (bound_)
    ReleaseSurface();

  if (window_) {
    Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
    XDestroyWindow(dpy, window_);
    XDestroyWindow(dpy, dummy_parent_);
  }

  ImageTransportSurface::Destroy();
  gfx::NativeViewGLSurfaceGLX::Destroy();
}

void GLXImageTransportSurface::ReleaseSurface() {
  DCHECK(bound_);
  GpuHostMsg_AcceleratedSurfaceRelease_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.identifier = window_;
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceRelease(params));
}

void GLXImageTransportSurface::Resize(gfx::Size size) {
  size_ = size;
  if (bound_) {
    ReleaseSurface();
    bound_ = false;
  }

  Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
  XResizeWindow(dpy, window_, size_.width(), size_.height());
  XFlush(dpy);

  GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.width = size_.width();
  params.height = size_.height();
  params.identifier = window_;
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params));

  scheduler()->SetScheduled(false);
}

bool GLXImageTransportSurface::SwapBuffers() {
  gfx::NativeViewGLSurfaceGLX::SwapBuffers();
  glFlush();

  GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
  params.renderer_id = stub()->renderer_id();
  params.render_view_id = stub()->render_view_id();
  params.surface_id = window_;
  params.route_id = route_id();
  Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));

  return true;
}

gfx::Size GLXImageTransportSurface::GetSize() {
  return size_;
}

void GLXImageTransportSurface::OnSetSurfaceACK(
    uint64 surface_id) {
  DCHECK(!bound_);
  bound_ = true;
  scheduler()->SetScheduled(true);
}

void GLXImageTransportSurface::OnBuffersSwappedACK() {
}

}  // namespace

ImageTransportSurface::ImageTransportSurface(GpuCommandBufferStub* stub)
    : stub_(stub) {
  GpuChannelManager* gpu_channel_manager
      = stub_->channel()->gpu_channel_manager();
  route_id_ = gpu_channel_manager->GenerateRouteID();
  gpu_channel_manager->AddRoute(route_id_, this);
}

ImageTransportSurface::~ImageTransportSurface() {
  GpuChannelManager* gpu_channel_manager
      = stub_->channel()->gpu_channel_manager();
  gpu_channel_manager->RemoveRoute(route_id_);
}

bool ImageTransportSurface::Initialize() {
  scheduler()->SetResizeCallback(
     NewCallback(this, &ImageTransportSurface::Resize));
  return true;
}

void ImageTransportSurface::Destroy() {
  scheduler()->SetResizeCallback(NULL);
}

bool ImageTransportSurface::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ImageTransportSurface, message)
    IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_SetSurfaceACK,
                        OnSetSurfaceACK)
    IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BuffersSwappedACK,
                        OnBuffersSwappedACK)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

bool ImageTransportSurface::Send(IPC::Message* message) {
  GpuChannelManager* gpu_channel_manager =
      stub_->channel()->gpu_channel_manager();
  return gpu_channel_manager->Send(message);
}

gpu::GpuScheduler* ImageTransportSurface::scheduler() {
  return stub_->scheduler();
}

// static
scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
    GpuCommandBufferStub* stub) {
  scoped_refptr<gfx::GLSurface> surface;
  switch (gfx::GetGLImplementation()) {
    case gfx::kGLImplementationDesktopGL:
      surface = new GLXImageTransportSurface(stub);
      break;
    case gfx::kGLImplementationEGLGLES2:
      surface = new EGLImageTransportSurface(stub);
      break;
    default:
      NOTREACHED();
      return NULL;
  }
  if (surface->Initialize())
    return surface;
  else
    return NULL;
}

#endif  // defined(USE_GPU)
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "commonoptionspage.h"

#include "debuggeractions.h"
#include "debuggerconstants.h"
#include "debuggercore.h"
#include "debuggerstringutils.h"

#include <coreplugin/icore.h>
#include <coreplugin/manhattanstyle.h>

#include <projectexplorer/projectexplorer.h>

#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>

using namespace Core;
using namespace Debugger::Constants;
using namespace ProjectExplorer;

namespace Debugger {
namespace Internal {

///////////////////////////////////////////////////////////////////////
//
// CommonOptionsPage
//
///////////////////////////////////////////////////////////////////////

CommonOptionsPage::CommonOptionsPage()
{
}

QString CommonOptionsPage::id() const
{
    return _(DEBUGGER_COMMON_SETTINGS_ID);
}

QString CommonOptionsPage::displayName() const
{
    return QCoreApplication::translate("Debugger", DEBUGGER_COMMON_SETTINGS_NAME);}

QString CommonOptionsPage::category() const
{
    return _(DEBUGGER_SETTINGS_CATEGORY);
}

QString CommonOptionsPage::displayCategory() const
{
    return QCoreApplication::translate("Debugger", DEBUGGER_SETTINGS_TR_CATEGORY);}

QIcon CommonOptionsPage::categoryIcon() const
{
    return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON));
}

void CommonOptionsPage::apply()
{
    m_group.apply(ICore::instance()->settings());
}

void CommonOptionsPage::finish()
{
    m_group.finish();
}

QWidget *CommonOptionsPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    m_ui.setupUi(w);
    m_group.clear();

    m_group.insert(debuggerCore()->action(ListSourceFiles),
        m_ui.checkBoxListSourceFiles);
    m_group.insert(debuggerCore()->action(UseAlternatingRowColors),
        m_ui.checkBoxUseAlternatingRowColors);
    m_group.insert(debuggerCore()->action(UseToolTipsInMainEditor),
        m_ui.checkBoxUseToolTipsInMainEditor);
    m_group.insert(debuggerCore()->action(CloseBuffersOnExit),
        m_ui.checkBoxCloseBuffersOnExit);
    m_group.insert(debuggerCore()->action(SwitchModeOnExit),
        m_ui.checkBoxSwitchModeOnExit);
    m_group.insert(debuggerCore()->action(AutoDerefPointers), 0);
    m_group.insert(debuggerCore()->action(UseToolTipsInLocalsView), 0);
    m_group.insert(debuggerCore()->action(UseToolTipsInBreakpointsView), 0);
    m_group.insert(debuggerCore()->action(UseAddressInBreakpointsView), 0);
    m_group.insert(debuggerCore()->action(UseAddressInStackView), 0);
    m_group.insert(debuggerCore()->action(MaximalStackDepth),
        m_ui.spinBoxMaximalStackDepth);
    m_group.insert(debuggerCore()->action(ShowStdNamespace), 0);
    m_group.insert(debuggerCore()->action(ShowQtNamespace), 0);
    m_group.insert(debuggerCore()->action(SortStructMembers), 0);
    m_group.insert(debuggerCore()->action(LogTimeStamps), 0);
    m_group.insert(debuggerCore()->action(VerboseLog), 0);
    m_group.insert(debuggerCore()->action(BreakOnThrow), 0);
    m_group.insert(debuggerCore()->action(BreakOnCatch), 0);
    m_group.insert(debuggerCore()->action(QtSourcesLocation), 0);
#ifdef Q_OS_WIN
    Utils::SavedAction *registerAction = debuggerCore()->action(RegisterForPostMortem);
    m_group.insert(registerAction,
        m_ui.checkBoxRegisterForPostMortem);
    connect(registerAction, SIGNAL(toggled(bool)),
            m_ui.checkBoxRegisterForPostMortem, SLOT(setChecked(bool)));
#endif

    if (m_searchKeywords.isEmpty()) {
        QLatin1Char sep(' ');
        QTextStream(&m_searchKeywords)
                << sep << m_ui.checkBoxUseAlternatingRowColors->text()
                << sep << m_ui.checkBoxUseToolTipsInMainEditor->text()
                << sep << m_ui.checkBoxListSourceFiles->text()
#ifdef Q_OS_WIN
                << sep << m_ui.checkBoxRegisterForPostMortem->text()
#endif
                << sep << m_ui.checkBoxCloseBuffersOnExit->text()
                << sep << m_ui.checkBoxSwitchModeOnExit->text()
                << sep << m_ui.labelMaximalStackDepth->text()
                   ;
        m_searchKeywords.remove(QLatin1Char('&'));
    }
#ifndef Q_OS_WIN
    m_ui.checkBoxRegisterForPostMortem->setVisible(false);
#endif
    return w;
}

bool CommonOptionsPage::matches(const QString &s) const
{
    return m_searchKeywords.contains(s, Qt::CaseInsensitive);
}

///////////////////////////////////////////////////////////////////////
//
// DebuggingHelperOptionPage
//
///////////////////////////////////////////////////////////////////////

static bool oxygenStyle()
{
    const ManhattanStyle *ms = qobject_cast<const ManhattanStyle *>(qApp->style());
    return ms && !qstrcmp("OxygenStyle", ms->baseStyle()->metaObject()->className());
}

QString DebuggingHelperOptionPage::id() const
{
    return _("Z.DebuggingHelper");
}

QString DebuggingHelperOptionPage::displayName() const
{
    return tr("Debugging Helper");
}

QString DebuggingHelperOptionPage::category() const
{
    return _(DEBUGGER_SETTINGS_CATEGORY);
}

QString DebuggingHelperOptionPage::displayCategory() const
{
    return QCoreApplication::translate("Debugger", DEBUGGER_SETTINGS_TR_CATEGORY);
}

QIcon DebuggingHelperOptionPage::categoryIcon() const
{
    return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON));
}

void DebuggingHelperOptionPage::apply()
{
    m_group.apply(ICore::instance()->settings());
}

void DebuggingHelperOptionPage::finish()
{
    m_group.finish();
}

QWidget *DebuggingHelperOptionPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    m_ui.setupUi(w);

    m_ui.dumperLocationChooser->setExpectedKind(Utils::PathChooser::Command);
    m_ui.dumperLocationChooser->setPromptDialogTitle(tr("Choose DebuggingHelper Location"));
    m_ui.dumperLocationChooser->setInitialBrowsePathBackup(
        ICore::instance()->resourcePath() + "../../lib");

    m_group.clear();
    m_group.insert(debuggerCore()->action(UseDebuggingHelpers),
        m_ui.debuggingHelperGroupBox);
    m_group.insert(debuggerCore()->action(UseCustomDebuggingHelperLocation),
        m_ui.customLocationGroupBox);
    // Suppress Oxygen style's giving flat group boxes bold titles.
    if (oxygenStyle())
        m_ui.customLocationGroupBox->setStyleSheet(_("QGroupBox::title { font: ; }"));

    m_group.insert(debuggerCore()->action(CustomDebuggingHelperLocation),
        m_ui.dumperLocationChooser);

    m_group.insert(debuggerCore()->action(UseCodeModel),
        m_ui.checkBoxUseCodeModel);
    m_group.insert(debuggerCore()->action(ShowThreadNames),
        m_ui.checkBoxShowThreadNames);

#ifndef QT_DEBUG
#if 0
    cmd = am->registerAction(m_dumpLogAction,
        DUMP_LOG, globalcontext);
    //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+L")));
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F11")));
    mdebug->addAction(cmd);
#endif
#endif

    if (m_searchKeywords.isEmpty()) {
        QTextStream(&m_searchKeywords)
                << ' ' << m_ui.debuggingHelperGroupBox->title()
                << ' ' << m_ui.customLocationGroupBox->title()
                << ' ' << m_ui.dumperLocationLabel->text()
                << ' ' << m_ui.checkBoxUseCodeModel->text()
                << ' ' << m_ui.checkBoxShowThreadNames->text();
        m_searchKeywords.remove(QLatin1Char('&'));
    }
    return w;
}

bool DebuggingHelperOptionPage::matches(const QString &s) const
{
    return m_searchKeywords.contains(s, Qt::CaseInsensitive);
}

} // namespace Internal
} // namespace Debugger
<commit_msg>debugger: also save the new qt source location settings<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "commonoptionspage.h"

#include "debuggeractions.h"
#include "debuggerconstants.h"
#include "debuggercore.h"
#include "debuggerstringutils.h"

#include <coreplugin/icore.h>
#include <coreplugin/manhattanstyle.h>

#include <projectexplorer/projectexplorer.h>

#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>

using namespace Core;
using namespace Debugger::Constants;
using namespace ProjectExplorer;

namespace Debugger {
namespace Internal {

///////////////////////////////////////////////////////////////////////
//
// CommonOptionsPage
//
///////////////////////////////////////////////////////////////////////

CommonOptionsPage::CommonOptionsPage()
{
}

QString CommonOptionsPage::id() const
{
    return _(DEBUGGER_COMMON_SETTINGS_ID);
}

QString CommonOptionsPage::displayName() const
{
    return QCoreApplication::translate("Debugger", DEBUGGER_COMMON_SETTINGS_NAME);}

QString CommonOptionsPage::category() const
{
    return _(DEBUGGER_SETTINGS_CATEGORY);
}

QString CommonOptionsPage::displayCategory() const
{
    return QCoreApplication::translate("Debugger", DEBUGGER_SETTINGS_TR_CATEGORY);}

QIcon CommonOptionsPage::categoryIcon() const
{
    return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON));
}

void CommonOptionsPage::apply()
{
    m_group.apply(ICore::instance()->settings());
}

void CommonOptionsPage::finish()
{
    m_group.finish();
}

QWidget *CommonOptionsPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    m_ui.setupUi(w);
    m_group.clear();

    m_group.insert(debuggerCore()->action(ListSourceFiles),
        m_ui.checkBoxListSourceFiles);
    m_group.insert(debuggerCore()->action(UseAlternatingRowColors),
        m_ui.checkBoxUseAlternatingRowColors);
    m_group.insert(debuggerCore()->action(UseToolTipsInMainEditor),
        m_ui.checkBoxUseToolTipsInMainEditor);
    m_group.insert(debuggerCore()->action(CloseBuffersOnExit),
        m_ui.checkBoxCloseBuffersOnExit);
    m_group.insert(debuggerCore()->action(SwitchModeOnExit),
        m_ui.checkBoxSwitchModeOnExit);
    m_group.insert(debuggerCore()->action(AutoDerefPointers), 0);
    m_group.insert(debuggerCore()->action(UseToolTipsInLocalsView), 0);
    m_group.insert(debuggerCore()->action(UseToolTipsInBreakpointsView), 0);
    m_group.insert(debuggerCore()->action(UseAddressInBreakpointsView), 0);
    m_group.insert(debuggerCore()->action(UseAddressInStackView), 0);
    m_group.insert(debuggerCore()->action(MaximalStackDepth),
        m_ui.spinBoxMaximalStackDepth);
    m_group.insert(debuggerCore()->action(ShowStdNamespace), 0);
    m_group.insert(debuggerCore()->action(ShowQtNamespace), 0);
    m_group.insert(debuggerCore()->action(SortStructMembers), 0);
    m_group.insert(debuggerCore()->action(LogTimeStamps), 0);
    m_group.insert(debuggerCore()->action(VerboseLog), 0);
    m_group.insert(debuggerCore()->action(BreakOnThrow), 0);
    m_group.insert(debuggerCore()->action(BreakOnCatch), 0);
    m_group.insert(debuggerCore()->action(QtSourcesLocation),
        m_ui.qtSourcesChooser);
#ifdef Q_OS_WIN
    Utils::SavedAction *registerAction = debuggerCore()->action(RegisterForPostMortem);
    m_group.insert(registerAction,
        m_ui.checkBoxRegisterForPostMortem);
    connect(registerAction, SIGNAL(toggled(bool)),
            m_ui.checkBoxRegisterForPostMortem, SLOT(setChecked(bool)));
#endif

    if (m_searchKeywords.isEmpty()) {
        QLatin1Char sep(' ');
        QTextStream(&m_searchKeywords)
                << sep << m_ui.checkBoxUseAlternatingRowColors->text()
                << sep << m_ui.checkBoxUseToolTipsInMainEditor->text()
                << sep << m_ui.checkBoxListSourceFiles->text()
#ifdef Q_OS_WIN
                << sep << m_ui.checkBoxRegisterForPostMortem->text()
#endif
                << sep << m_ui.checkBoxCloseBuffersOnExit->text()
                << sep << m_ui.checkBoxSwitchModeOnExit->text()
                << sep << m_ui.labelMaximalStackDepth->text()
                   ;
        m_searchKeywords.remove(QLatin1Char('&'));
    }
#ifndef Q_OS_WIN
    m_ui.checkBoxRegisterForPostMortem->setVisible(false);
#endif
    return w;
}

bool CommonOptionsPage::matches(const QString &s) const
{
    return m_searchKeywords.contains(s, Qt::CaseInsensitive);
}

///////////////////////////////////////////////////////////////////////
//
// DebuggingHelperOptionPage
//
///////////////////////////////////////////////////////////////////////

static bool oxygenStyle()
{
    const ManhattanStyle *ms = qobject_cast<const ManhattanStyle *>(qApp->style());
    return ms && !qstrcmp("OxygenStyle", ms->baseStyle()->metaObject()->className());
}

QString DebuggingHelperOptionPage::id() const
{
    return _("Z.DebuggingHelper");
}

QString DebuggingHelperOptionPage::displayName() const
{
    return tr("Debugging Helper");
}

QString DebuggingHelperOptionPage::category() const
{
    return _(DEBUGGER_SETTINGS_CATEGORY);
}

QString DebuggingHelperOptionPage::displayCategory() const
{
    return QCoreApplication::translate("Debugger", DEBUGGER_SETTINGS_TR_CATEGORY);
}

QIcon DebuggingHelperOptionPage::categoryIcon() const
{
    return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON));
}

void DebuggingHelperOptionPage::apply()
{
    m_group.apply(ICore::instance()->settings());
}

void DebuggingHelperOptionPage::finish()
{
    m_group.finish();
}

QWidget *DebuggingHelperOptionPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    m_ui.setupUi(w);

    m_ui.dumperLocationChooser->setExpectedKind(Utils::PathChooser::Command);
    m_ui.dumperLocationChooser->setPromptDialogTitle(tr("Choose DebuggingHelper Location"));
    m_ui.dumperLocationChooser->setInitialBrowsePathBackup(
        ICore::instance()->resourcePath() + "../../lib");

    m_group.clear();
    m_group.insert(debuggerCore()->action(UseDebuggingHelpers),
        m_ui.debuggingHelperGroupBox);
    m_group.insert(debuggerCore()->action(UseCustomDebuggingHelperLocation),
        m_ui.customLocationGroupBox);
    // Suppress Oxygen style's giving flat group boxes bold titles.
    if (oxygenStyle())
        m_ui.customLocationGroupBox->setStyleSheet(_("QGroupBox::title { font: ; }"));

    m_group.insert(debuggerCore()->action(CustomDebuggingHelperLocation),
        m_ui.dumperLocationChooser);

    m_group.insert(debuggerCore()->action(UseCodeModel),
        m_ui.checkBoxUseCodeModel);
    m_group.insert(debuggerCore()->action(ShowThreadNames),
        m_ui.checkBoxShowThreadNames);

#ifndef QT_DEBUG
#if 0
    cmd = am->registerAction(m_dumpLogAction,
        DUMP_LOG, globalcontext);
    //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+L")));
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F11")));
    mdebug->addAction(cmd);
#endif
#endif

    if (m_searchKeywords.isEmpty()) {
        QTextStream(&m_searchKeywords)
                << ' ' << m_ui.debuggingHelperGroupBox->title()
                << ' ' << m_ui.customLocationGroupBox->title()
                << ' ' << m_ui.dumperLocationLabel->text()
                << ' ' << m_ui.checkBoxUseCodeModel->text()
                << ' ' << m_ui.checkBoxShowThreadNames->text();
        m_searchKeywords.remove(QLatin1Char('&'));
    }
    return w;
}

bool DebuggingHelperOptionPage::matches(const QString &s) const
{
    return m_searchKeywords.contains(s, Qt::CaseInsensitive);
}

} // namespace Internal
} // namespace Debugger
<|endoftext|>