Commit 3e6ef756 authored by Cosmin Sabou's avatar Cosmin Sabou
Browse files

Merge mozilla-central to autoland.

parents 8a1a29f2 90efd042
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -265,6 +265,11 @@ add_task(async function testDisabledBrowserLanguages() {
  // pl is now available since it is available remotely.
  assertAvailableLocales(available, ["fr", "pl"]);

  let installId = null;
  AddonTestUtils.promiseInstallEvent("onInstallEnded").then(([install]) => {
    installId = install.installId;
  });

  // Add pl.
  await selectLocale("pl", available, selected, dialogDoc);
  assertLocaleOrder(selected, "pl,en-US,he");
@@ -276,7 +281,6 @@ add_task(async function testDisabledBrowserLanguages() {

  let dialogId = getDialogId(dialogDoc);
  ok(dialogId, "There's a dialogId");
  let {installId} = pl.install;
  ok(installId, "There's an installId");

  await Promise.all(addons.map(addon => addon.uninstall()));
@@ -505,9 +509,16 @@ add_task(async function testInstallFromAMO() {
  let dicts = await AddonManager.getAddonsByTypes(["dictionary"]);
  is(dicts.length, 0, "There are no installed dictionaries");

  let installId = null;
  AddonTestUtils.promiseInstallEvent("onInstallEnded").then(([install]) => {
    installId = install.installId;
  });

  // Add Polish, this will install the langpack.
  await selectLocale("pl", available, selected, dialogDoc);

  ok(installId, "We got an installId for the langpack installation");

  let langpack = await AddonManager.getAddonByID(langpackId("pl"));
  Assert.deepEqual(
    langpack.installTelemetryInfo,
@@ -542,7 +553,6 @@ add_task(async function testInstallFromAMO() {

  // Disable the Polish langpack.
  langpack = await AddonManager.getAddonByID("langpack-pl@firefox.mozilla.org");
  let installId = langpack.install.installId;
  await langpack.disable();

  ({dialogDoc, available, selected} = await openDialog(doc, true));
@@ -565,7 +575,6 @@ add_task(async function testInstallFromAMO() {

  BrowserTestUtils.removeTab(gBrowser.selectedTab);

  ok(installId, "The langpack has an installId");
  assertTelemetryRecorded([
    // First dialog installs a locale and accepts.
    ["search", "main", firstDialogId],
+50 −13
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@
#include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsParent.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
#include "mozilla/dom/quota/CheckedUnsafePtr.h"
#include "mozilla/dom/quota/Client.h"
#include "mozilla/dom/quota/FileStreams.h"
#include "mozilla/dom/quota/OriginScope.h"
@@ -5661,7 +5662,9 @@ class WaitForTransactionsHelper final : public Runnable {
  NS_DECL_NSIRUNNABLE
};
class Database final : public PBackgroundIDBDatabaseParent {
class Database final
    : public PBackgroundIDBDatabaseParent,
      public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
  friend class VersionChangeTransaction;
  class StartTransactionOp;
@@ -6458,9 +6461,11 @@ class MutableFile : public BackgroundMutableFileParentBase {
  mozilla::ipc::IPCResult RecvGetFileId(int64_t* aFileId) override;
};
class FactoryOp : public DatabaseOperationBase,
class FactoryOp
    : public DatabaseOperationBase,
      public OpenDirectoryListener,
                  public PBackgroundIDBFactoryRequestParent {
      public PBackgroundIDBFactoryRequestParent,
      public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
 public:
  struct MaybeBlockedDatabaseInfo;
@@ -6557,6 +6562,7 @@ class FactoryOp : public DatabaseOperationBase,
  nsCString mDatabaseId;
  nsString mDatabaseFilePath;
  State mState;
  bool mWaitingForPermissionRetry;
  bool mEnforcingQuota;
  const bool mDeleting;
  bool mChromeWriteAccessAllowed;
@@ -6599,6 +6605,8 @@ class FactoryOp : public DatabaseOperationBase,
  nsresult ChallengePermission();
  void PermissionRetry();
  nsresult RetryCheckPermission();
  nsresult DirectoryOpen();
@@ -7689,7 +7697,7 @@ struct DatabaseActorInfo final {
  friend class nsAutoPtr<DatabaseActorInfo>;
  RefPtr<FullDatabaseMetadata> mMetadata;
  nsTArray<Database*> mLiveDatabases;
  nsTArray<CheckedUnsafePtr<Database>> mLiveDatabases;
  RefPtr<FactoryOp> mWaitingFactoryOp;
  DatabaseActorInfo(FullDatabaseMetadata* aMetadata, Database* aDatabase)
@@ -8940,7 +8948,7 @@ nsresult RemoveDatabaseFilesAndDirectory(nsIFile* aBaseDirectory,
// Counts the number of "live" Factory, FactoryOp and Database instances.
uint64_t gBusyCount = 0;
typedef nsTArray<RefPtr<FactoryOp>> FactoryOpArray;
typedef nsTArray<CheckedUnsafePtr<FactoryOp>> FactoryOpArray;
StaticAutoPtr<FactoryOpArray> gFactoryOps;
@@ -17162,7 +17170,7 @@ nsresult Maintenance::BeginDatabaseMaintenance() {
    static bool IsSafeToRunMaintenance(const nsAString& aDatabasePath) {
      if (gFactoryOps) {
        for (uint32_t index = gFactoryOps->Length(); index > 0; index--) {
          RefPtr<FactoryOp>& existingOp = (*gFactoryOps)[index - 1];
          CheckedUnsafePtr<FactoryOp>& existingOp = (*gFactoryOps)[index - 1];
          if (!existingOp->DatabaseFilePathIsKnown()) {
            continue;
@@ -19042,6 +19050,7 @@ FactoryOp::FactoryOp(Factory* aFactory,
      mContentParent(std::move(aContentParent)),
      mCommonParams(aCommonParams),
      mState(State::Initial),
      mWaitingForPermissionRetry(false),
      mEnforcingQuota(true),
      mDeleting(aDeleting),
      mChromeWriteAccessAllowed(false),
@@ -19128,9 +19137,24 @@ nsresult FactoryOp::ChallengePermission() {
    return NS_ERROR_FAILURE;
  }
  mWaitingForPermissionRetry = true;
  return NS_OK;
}
void FactoryOp::PermissionRetry() {
  AssertIsOnOwningThread();
  MOZ_ASSERT(mState == State::PermissionChallenge);
  mContentParent = BackgroundParent::GetContentParent(Manager()->Manager());
  mState = State::PermissionRetry;
  mWaitingForPermissionRetry = false;
  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(this));
}
nsresult FactoryOp::RetryCheckPermission() {
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(mState == State::PermissionRetry);
@@ -19181,7 +19205,7 @@ nsresult FactoryOp::DirectoryOpen() {
  bool delayed = false;
  bool foundThis = false;
  for (uint32_t index = gFactoryOps->Length(); index > 0; index--) {
    RefPtr<FactoryOp>& existingOp = (*gFactoryOps)[index - 1];
    CheckedUnsafePtr<FactoryOp>& existingOp = (*gFactoryOps)[index - 1];
    if (existingOp == this) {
      foundThis = true;
@@ -19742,17 +19766,30 @@ void FactoryOp::ActorDestroy(ActorDestroyReason aWhy) {
  AssertIsOnBackgroundThread();
  NoteActorDestroyed();
  // Assume ActorDestroy can happen at any time, so we can't probe the current
  // state since mState can be modified on any thread (only one thread at a time
  // based on the state machine).  However we can use mWaitingForPermissionRetry
  // which is only touched on the owning thread.  If mWaitingForPermissionRetry
  // is true, we can also modify mState since we are guaranteed that there are
  // no pending runnables which would probe mState to decide what code needs to
  // run (there shouldn't be any running runnables on other threads either).
  if (mWaitingForPermissionRetry) {
    PermissionRetry();
  }
  // We don't have to handle the case when mWaitingForPermissionRetry is not
  // true since it means that either nothing has been initialized yet, so
  // nothing to cleanup or there are pending runnables that will detect that the
  // actor has been destroyed and cleanup accordingly.
}
mozilla::ipc::IPCResult FactoryOp::RecvPermissionRetry() {
  AssertIsOnOwningThread();
  MOZ_ASSERT(!IsActorDestroyed());
  MOZ_ASSERT(mState == State::PermissionChallenge);
  mContentParent = BackgroundParent::GetContentParent(Manager()->Manager());
  mState = State::PermissionRetry;
  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(this));
  PermissionRetry();
  return IPC_OK();
}
+36 −34
Original line number Diff line number Diff line
@@ -1600,7 +1600,8 @@ class ConnectionThread final {
 * Snapshot instances Checkpoint their mutations locally accumulated in the
 * child LSSnapshots.
 */
class Datastore final {
class Datastore final
    : public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
  RefPtr<DirectoryLock> mDirectoryLock;
  RefPtr<Connection> mConnection;
  RefPtr<QuotaObject> mQuotaObject;
@@ -1692,18 +1693,10 @@ class Datastore final {

  void NoteFinishedPreparedDatastore(PreparedDatastore* aPreparedDatastore);

#ifdef DEBUG
  bool HasLivePreparedDatastores() const;
#endif

  void NoteLiveDatabase(Database* aDatabase);

  void NoteFinishedDatabase(Database* aDatabase);

#ifdef DEBUG
  bool HasLiveDatabases() const;
#endif

  void NoteActiveDatabase(Database* aDatabase);

  void NoteInactiveDatabase(Database* aDatabase);
@@ -2286,6 +2279,7 @@ class PrepareDatastoreOp
  int64_t mUsage;
  int64_t mSizeOfKeys;
  int64_t mSizeOfItems;
  uint64_t mDatastoreId;
  NestedState mNestedState;
  const bool mCreateIfNotExists;
  bool mDatabaseNotAvailable;
@@ -2736,7 +2730,22 @@ typedef nsTArray<CheckedUnsafePtr<PrepareDatastoreOp>> PrepareDatastoreOpArray;

StaticAutoPtr<PrepareDatastoreOpArray> gPrepareDatastoreOps;

typedef nsDataHashtable<nsCStringHashKey, Datastore*> DatastoreHashtable;
// nsCStringHashKey with disabled memmove
class nsCStringHashKeyDM : public nsCStringHashKey {
 public:
  explicit nsCStringHashKeyDM(const nsCStringHashKey::KeyTypePointer aKey)
      : nsCStringHashKey(aKey) {}
  enum { ALLOW_MEMMOVE = false };
};

// When CheckedUnsafePtr's checking is enabled, it's necessary to ensure that
// the hashtable uses the copy constructor instead of memmove for moving entries
// since memmove will break CheckedUnsafePtr in a memory-corrupting way.
typedef std::conditional<DiagnosticAssertEnabled::value, nsCStringHashKeyDM,
                         nsCStringHashKey>::type DatastoreHashKey;

typedef nsDataHashtable<DatastoreHashKey, CheckedUnsafePtr<Datastore>>
    DatastoreHashtable;

StaticAutoPtr<DatastoreHashtable> gDatastores;

@@ -4443,6 +4452,8 @@ Datastore::~Datastore() {
void Datastore::Close() {
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(!mClosed);
  MOZ_ASSERT(!mPrepareDatastoreOps.Count());
  MOZ_ASSERT(!mPreparedDatastores.Count());
  MOZ_ASSERT(!mDatabases.Count());
  MOZ_ASSERT(mDirectoryLock);

@@ -4528,14 +4539,6 @@ void Datastore::NoteFinishedPreparedDatastore(
  MaybeClose();
}

#ifdef DEBUG
bool Datastore::HasLivePreparedDatastores() const {
  AssertIsOnBackgroundThread();

  return mPreparedDatastores.Count();
}
#endif

void Datastore::NoteLiveDatabase(Database* aDatabase) {
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(aDatabase);
@@ -4559,14 +4562,6 @@ void Datastore::NoteFinishedDatabase(Database* aDatabase) {
  MaybeClose();
}

#ifdef DEBUG
bool Datastore::HasLiveDatabases() const {
  AssertIsOnBackgroundThread();

  return mDatabases.Count();
}
#endif

void Datastore::NoteActiveDatabase(Database* aDatabase) {
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(aDatabase);
@@ -5941,6 +5936,7 @@ PrepareDatastoreOp::PrepareDatastoreOp(
      mUsage(0),
      mSizeOfKeys(0),
      mSizeOfItems(0),
      mDatastoreId(0),
      mNestedState(NestedState::BeforeNesting),
      mCreateIfNotExists(aParams.type() ==
                         LSRequestParams::TLSRequestPrepareDatastoreParams),
@@ -6747,16 +6743,16 @@ void PrepareDatastoreOp::GetResponse(LSRequestResponse& aResponse) {
    gDatastores->Put(mOrigin, mDatastore);
  }

  uint64_t datastoreId = ++gLastDatastoreId;
  mDatastoreId = ++gLastDatastoreId;

  nsAutoPtr<PreparedDatastore> preparedDatastore(
      new PreparedDatastore(mDatastore, mContentParentId, mOrigin, datastoreId,
      new PreparedDatastore(mDatastore, mContentParentId, mOrigin, mDatastoreId,
                            /* aForPreload */ !mCreateIfNotExists));

  if (!gPreparedDatastores) {
    gPreparedDatastores = new PreparedDatastoreHashtable();
  }
  gPreparedDatastores->Put(datastoreId, preparedDatastore);
  gPreparedDatastores->Put(mDatastoreId, preparedDatastore);

  if (mInvalidated) {
    preparedDatastore->Invalidate();
@@ -6766,7 +6762,7 @@ void PrepareDatastoreOp::GetResponse(LSRequestResponse& aResponse) {

  if (mCreateIfNotExists) {
    LSRequestPrepareDatastoreResponse prepareDatastoreResponse;
    prepareDatastoreResponse.datastoreId() = datastoreId;
    prepareDatastoreResponse.datastoreId() = mDatastoreId;

    aResponse = prepareDatastoreResponse;
  } else {
@@ -6780,14 +6776,20 @@ void PrepareDatastoreOp::Cleanup() {
  AssertIsOnOwningThread();

  if (mDatastore) {
    MOZ_ASSERT(mDatastoreId > 0);
    MOZ_ASSERT(!mDirectoryLock);
    MOZ_ASSERT(!mConnection);

    if (NS_FAILED(ResultCode())) {
      MOZ_ASSERT(!mDatastore->IsClosed());
      MOZ_ASSERT(!mDatastore->HasLiveDatabases());
      MOZ_ASSERT(!mDatastore->HasLivePreparedDatastores());
      mDatastore->Close();
      // Just in case we failed to send datastoreId to the child, we need to
      // destroy prepared datastore, otherwise it won't be destroyed until the
      // timer fires (after 20 seconds).
      MOZ_ASSERT(gPreparedDatastores);
      MOZ_ASSERT(gPreparedDatastores->Get(mDatastoreId));

      nsAutoPtr<PreparedDatastore> preparedDatastore;
      gPreparedDatastores->Remove(mDatastoreId, &preparedDatastore);
      MOZ_ASSERT(preparedDatastore);
    }

    // Make sure to release the datastore on this thread.
+0 −49
Original line number Diff line number Diff line
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "mozilla/ModuleUtils.h"
#include "SpeechSynthesisService.h"

using namespace mozilla::dom;

#define ANDROIDSPEECHSERVICE_CID                     \
  {                                                  \
    0x311b2dab, 0xf4d3, 0x4be4, {                    \
      0x81, 0x23, 0x67, 0x32, 0x31, 0x3d, 0x95, 0xc2 \
    }                                                \
  }

#define ANDROIDSPEECHSERVICE_CONTRACTID "@mozilla.org/androidspeechsynth;1"

// Defines AndroidSpeechServiceConstructor
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(
    SpeechSynthesisService, SpeechSynthesisService::GetInstanceForService)

// Defines kANDROIDSPEECHSERVICE_CID
NS_DEFINE_NAMED_CID(ANDROIDSPEECHSERVICE_CID);

static const mozilla::Module::CIDEntry kCIDs[] = {
    {&kANDROIDSPEECHSERVICE_CID, true, nullptr,
     SpeechSynthesisServiceConstructor},
    {nullptr}};

static const mozilla::Module::ContractIDEntry kContracts[] = {
    {ANDROIDSPEECHSERVICE_CONTRACTID, &kANDROIDSPEECHSERVICE_CID}, {nullptr}};

static const mozilla::Module::CategoryEntry kCategories[] = {
    {"speech-synth-started", "Android Speech Synth",
     ANDROIDSPEECHSERVICE_CONTRACTID},
    {nullptr}};

extern const mozilla::Module kSpeechSynthModule = {
    mozilla::Module::kVersion,
    kCIDs,
    kContracts,
    kCategories,
    nullptr,
    nullptr,
    nullptr,
};
+17 −0
Original line number Diff line number Diff line
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.

Classes = [
    {
        'cid': '{311b2dab-f4d3-4be4-8123-6732313d95c2}',
        'contract_ids': ['@mozilla.org/androidspeechsynth;1'],
        'singleton': True,
        'type': 'mozilla::dom::SpeechSynthesisService',
        'headers': ['/dom/media/webspeech/synth/android/SpeechSynthesisService.h'],
        'constructor': 'mozilla::dom::SpeechSynthesisService::GetInstanceForService',
        'categories': {"speech-synth-started": 'Android Speech Synth'},
    },
]
Loading