/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

include protocol PAudio;
include protocol PBlob;
include protocol PBluetooth;
include protocol PBrowser;
include protocol PCompositor;
include protocol PCrashReporter;
include protocol PExternalHelperApp;
include protocol PDeviceStorageRequest;
include protocol PHal;
include protocol PImageBridge;
include protocol PIndexedDB;
include protocol PMemoryReportRequest;
include protocol PNecko;
include protocol PSms;
include protocol PStorage;
include protocol PTestShell;
include DOMTypes;
include URIParams;

include "mozilla/chrome/RegistryMessageUtils.h";
include "mozilla/dom/TabMessageUtils.h";
include "mozilla/layout/RenderFrameUtils.h";
include "mozilla/net/NeckoMessageUtils.h";

include "nsGeoPositionIPCSerialiser.h";

using GeoPosition;
using PrefTuple;

using ChromePackage;
using ResourceMapping;
using OverrideMapping;
using IPC::Permission;
using mozilla::null_t;
using mozilla::void_t;
using mozilla::dom::AudioChannelType;
using mozilla::dom::NativeThreadId;
using mozilla::layout::ScrollingBehavior;
using gfxIntSize;

namespace mozilla {
namespace dom {

// Data required to clone an existing DOMStorageImpl in the parent
struct StorageClone
{
    // Existing cross-process storage actor to clone
    PStorage actor;
    // Result of calling IsCallerSecure() in the child
    bool callerSecure;
};

// When creating a new PStorage protocol, an existing one can be
// cloned (see nsDOMStorage2::Clone)
union StorageConstructData
{
    null_t;
    StorageClone;
};

struct FontListEntry {
    nsString  familyName;
    nsString  faceName;
    nsCString filepath;
    uint16_t  weight;
    int16_t   stretch;
    uint8_t   italic;
    uint8_t   index;
};

struct DeviceStorageStatParams
{
  nsString type;
  nsString fullpath;
};

struct DeviceStorageAddParams
{
  nsString type;
  PBlob blob;
  nsString name;
  nsString fullpath;
};

struct DeviceStorageGetParams
{
  nsString type;
  nsString name;
  nsString fullpath;
};

struct DeviceStorageDeleteParams
{
  nsString type;
  nsString fullpath;
};

struct DeviceStorageEnumerationParams
{
  nsString type;
  nsString fullpath;
  uint64_t since;
};

union DeviceStorageParams
{
  DeviceStorageAddParams;
  DeviceStorageGetParams;
  DeviceStorageDeleteParams;
  DeviceStorageEnumerationParams;
  DeviceStorageStatParams;
};

struct SlicedBlobConstructorParams
{
  PBlob source;
  uint64_t begin;
  uint64_t end;
  nsString contentType;
};

struct MysteryBlobConstructorParams
{
  // Nothing is known about this type of blob.
};

union BlobConstructorParams
{
  NormalBlobConstructorParams;
  FileBlobConstructorParams;
  SlicedBlobConstructorParams;
  MysteryBlobConstructorParams;
};

// An IPCTabContext which corresponds to a PBrowser opened by a child when it
// receives window.open().
//
// If isBrowserElement is false, this PopupIPCTabContext corresponds to an app
// frame, and the frame's app-id and app-frame-owner-app-id will be equal to the
// opener's values.
//
// If isBrowserElement is true, the frame's browserFrameOwnerAppId will be equal
// to the opener's app-id.
//
// It's an error to set isBrowserElement == false if opener is a browser
// element.  Such a PopupIPCTabContext should be rejected by code which receives
// it.
struct PopupIPCTabContext
{
  PBrowser opener;
  bool isBrowserElement;
};

// An IPCTabContext which corresponds to an app frame.
struct AppFrameIPCTabContext
{
  // The ID of the app this frame corresponds to.  May be NO_APP_ID.
  uint32_t ownAppId;

  // The ID of the app containing this frame.  May be NO_APP_ID.
  uint32_t appFrameOwnerAppId;
};

// An IPCTabContext which corresponds to a browser frame.
struct BrowserFrameIPCTabContext
{
  // The ID of the app which contains this browser frame.  May be NO_APP_ID.
  uint32_t browserFrameOwnerAppId;
};

// This is equivalent to AppFrameIPCTabContext with all fields set to NO_APP_ID.
struct VanillaFrameIPCTabContext
{};

// IPCTabContext is an analog to mozilla::dom::TabContext.  Both specify an
// iframe/PBrowser's own and containing app-ids and tell you whether the
// iframe/PBrowser is a browser frame.  But only IPCTabContext is allowed to
// travel over IPC.
//
// We need IPCTabContext (specifically, PopupIPCTabContext) to prevent a
// privilege escalation attack by a compromised child process.  See the comment
// on AllocPBrowser for details.
union IPCTabAppBrowserContext
{
  PopupIPCTabContext;
  AppFrameIPCTabContext;
  BrowserFrameIPCTabContext;
  VanillaFrameIPCTabContext;
};

struct IPCTabContext {
  IPCTabAppBrowserContext appBrowserContext;
  ScrollingBehavior scrollingBehavior;
};

union PrefValue {
  nsCString;
  int32_t;
  bool;
};

union MaybePrefValue {
  PrefValue;
  null_t;
};

struct PrefSetting {
  nsCString name;
  MaybePrefValue defaultValue;
  MaybePrefValue userValue;
};

rpc protocol PContent
{
    parent opens PCompositor;
    parent opens PImageBridge;

    manages PAudio;
    manages PBlob;
    manages PBluetooth;
    manages PBrowser;
    manages PCrashReporter;
    manages PDeviceStorageRequest;
    manages PExternalHelperApp;
    manages PHal;
    manages PIndexedDB;
    manages PMemoryReportRequest;
    manages PNecko;
    manages PSms;
    manages PStorage;
    manages PTestShell;

both:
    // Depending on exactly how the new browser is being created, it might be
    // created from either the child or parent process!
    //
    // The child creates the PBrowser as part of
    // TabChild::BrowserFrameProvideWindow (which happens when the child's
    // content calls window.open()), and the parent creates the PBrowser as part
    // of ContentParent::CreateTab.
    //
    // When the parent constructs a PBrowser, the child trusts the app token it
    // receives from the parent.  In that case, context can be any of the
    // IPCTabContext subtypes.
    //
    // When the child constructs a PBrowser, the parent doesn't trust the app
    // token it receives from the child.  In this case, context must have type
    // PopupIPCTabContext.  The browser created using a PopupIPCTabContext has
    // the opener PBrowser's app-id and containing-app-id.  The parent checks
    // that if the opener is a browser element, the context is also for a
    // browser element.
    //
    // This allows the parent to prevent a malicious child from escalating its
    // privileges by requesting a PBrowser corresponding to a highly-privileged
    // app; the child can only request privileges for an app which the child has
    // access to (in the form of a TabChild).
    async PBrowser(IPCTabContext context, uint32_t chromeFlags);

    async PBlob(BlobConstructorParams params);

child:
    PMemoryReportRequest();

    /**
     * Notify the AudioChannelService in the child processes.
     */
    async AudioChannelNotify();

    /**
     * Dump the contents of about:memory to a file in our temp directory.
     *
     * For documentation on the args, see
     * MemoryInfoDumper::dumpMemoryReportsToFile.
     */
    async DumpMemoryReportsToFile(nsString identifier,
                                  bool minimizeMemoryUsage,
                                  bool dumpChildProcesses);

    /**
     * Dump this process's GC and CC logs.
     *
     * For documentation on the args, see
     * MemoryInfoDumper::dumpGCAndCCLogsToFile.
     */
    async DumpGCAndCCLogsToFile(nsString identifier,
                                bool dumpChildProcesses);

    PTestShell();

    RegisterChrome(ChromePackage[] packages, ResourceMapping[] resources,
                   OverrideMapping[] overrides, nsCString locale);

    async SetOffline(bool offline);

    async NotifyVisited(URIParams uri);

    PreferenceUpdate(PrefSetting pref);

    NotifyAlertsObserver(nsCString topic, nsString data);

    GeolocationUpdate(GeoPosition somewhere);

    // nsIPermissionManager messages
    AddPermission(Permission permission);

    ScreenSizeChanged(gfxIntSize size);

    FlushMemory(nsString reason);

    GarbageCollect();
    CycleCollect();
    
    /**
     * Start accessibility engine in content process.
     */
    ActivateA11y();

    AppInfo(nsCString version, nsCString buildID);

    // Notify child that last-pb-context-exited notification was observed
    LastPrivateDocShellDestroyed();

    FilePathUpdate(nsString type, nsString filepath, nsCString reasons);

    FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState);

parent:
    /**
     * Tell the content process some attributes of itself.  This is
     * among the first information queried by content processes after
     * startup.  (The message is sync to allow the content process to
     * control when it receives the information.)
     *
     * |id| is a unique ID among all subprocesses.  When |isForApp &&
     * isForBrowser|, we're loading <browser> for an app.  When
     * |isForBrowser|, we're loading <browser>.  When |!isForApp &&
     * !isForBrowser|, we're probably loading <xul:browser remote>.
     */
    sync GetProcessAttributes()
        returns (uint64_t id, bool startBackground,
                 bool isForApp, bool isForBrowser);
    sync GetXPCOMProcessAttributes()
        returns (bool isOffline);

    PAudio(int32_t aNumChannels, int32_t aRate, int32_t aFormat);

    PDeviceStorageRequest(DeviceStorageParams params);

    sync PCrashReporter(NativeThreadId tid, uint32_t processType);

    PHal();

    PIndexedDB();

    PNecko();

    PSms();
    
    PStorage(StorageConstructData data);

    PBluetooth();

    // Services remoting

    async StartVisitedQuery(URIParams uri);
    async VisitURI(URIParams uri, OptionalURIParams referrer, uint32_t flags);
    async SetURITitle(URIParams uri, nsString title);
    
    // filepicker remoting
    sync ShowFilePicker(int16_t mode, int16_t selectedType, bool addToRecentDocs,
                        nsString title, nsString defaultFile, nsString defaultExtension,
                        nsString[] filters, nsString[] filterNames)
        returns (nsString[] files, int16_t retValue, nsresult result);

    async LoadURIExternal(URIParams uri);

    // PrefService message
    sync ReadPrefsArray() returns (PrefSetting[] prefs);

    sync ReadFontList() returns (FontListEntry[] retValue);

    sync SyncMessage(nsString aMessage, ClonedMessageData aData)
      returns (nsString[] retval);

    ShowAlertNotification(nsString imageUrl, 
                          nsString title, 
                          nsString text, 
                          bool textClickable,
                          nsString cookie,
                          nsString name);

    PExternalHelperApp(OptionalURIParams uri, nsCString aMimeContentType,
                       nsCString aContentDisposition, bool aForceSave,
                       int64_t aContentLength, OptionalURIParams aReferrer);

    AddGeolocationListener();
    RemoveGeolocationListener();

    ConsoleMessage(nsString message);
    ScriptError(nsString message, nsString sourceName, nsString sourceLine,
                uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
                nsCString category); 

    // nsIPermissionManager messages
    sync ReadPermissions() returns (Permission[] permissions);

    // These clipboard methods are only really used on Android since
    // the clipboard is not available in the content process.
    SetClipboardText(nsString text, bool isPrivateData, int32_t whichClipboard);
    sync GetClipboardText(int32_t whichClipboard)
        returns (nsString text);
    EmptyClipboard();
    sync ClipboardHasText()
        returns (bool hasText);

    sync GetSystemColors(uint32_t colorsCount)
        returns (uint32_t[] colors);

    sync GetIconForExtension(nsCString aFileExt, uint32_t aIconSize)
        returns (uint8_t[] bits);

    sync GetShowPasswordSetting()
        returns (bool showPassword);

    // Notify the parent of the presence or absence of private docshells
    PrivateDocShellsExist(bool aExist);

    // Tell the parent that the child has gone idle for the first time
    async FirstIdle();

    // Get Muted from the main AudioChannelService.
    sync AudioChannelGetMuted(AudioChannelType aType, bool aMozHidden)
        returns (bool value);

    async AudioChannelRegisterType(AudioChannelType aType);
    async AudioChannelUnregisterType(AudioChannelType aType);

both:
     AsyncMessage(nsString aMessage, ClonedMessageData aData);
};

}
}
