text:
using content::WebContents;
using content::WebContentsObserver;
using content::MediaSession;
using content::MediaSessionObserver;
using content::MediaSessionUmaHelper;

using ::testing::Expectation;

namespace {

class MockMediaSessionObserver : public MediaSessionObserver {
 public:
  MockMediaSessionObserver()
      : received_resume_calls_(0),
        received_suspend_calls_(0) {
  }

  ~MockMediaSessionObserver() override = default;

  // Implements MediaSessionObserver.
  void OnSuspend(int player_id) override {
    DCHECK(player_id >= 0);
    DCHECK(players_.size() > static_cast<size_t>(player_id));

    ++received_suspend_calls_;
    players_[player_id] = false;
  }
  void OnResume(int player_id) override {
    DCHECK(player_id >= 0);
    DCHECK(players_.size() > static_cast<size_t>(player_id));

    ++received_resume_calls_;
    players_[player_id] = true;
  }

  int StartNewPlayer() {
    players_.push_back(true);
    return players_.size() - 1;
  }

  bool IsPlaying(size_t player_id) {
    DCHECK(players_.size() > player_id);
    return players_[player_id];
  }

  void SetPlaying(size_t player_id, bool playing) {
    DCHECK(players_.size() > player_id);
    players_[player_id] = playing;
  }

  int received_suspend_calls() const {
    return received_suspend_calls_;
  }

  int received_resume_calls() const {
    return received_resume_calls_;
  }

 private:
  // Basic representation of the players. The position in the vector is the
  // player_id. The value of the vector is the playing status.
  std::vector<bool> players_;

  int received_resume_calls_;
  int received_suspend_calls_;
};

class MockWebContentsObserver : public WebContentsObserver {
 public:
  MockWebContentsObserver(WebContents* web_contents)
      : WebContentsObserver(web_contents) {}

  MOCK_METHOD2(MediaSessionStateChanged,
               void(bool is_controllable, bool is_suspended));
};

}  // namespace

class MediaSessionBrowserTest : public content::ContentBrowserTest {
 protected:
  MediaSessionBrowserTest() = default;

  void SetUpOnMainThread() override {
    ContentBrowserTest::SetUpOnMainThread();

    mock_web_contents_observer_.reset(
        new MockWebContentsObserver(shell()->web_contents()));
    media_session_ = MediaSession::Get(shell()->web_contents());
    media_session_->ResetJavaRefForTest();
    ASSERT_TRUE(media_session_);
  }

  void TearDownOnMainThread() override {
    mock_web_contents_observer_.reset();

    media_session_->RemoveAllPlayersForTest();
    media_session_ = nullptr;

    ContentBrowserTest::TearDownOnMainThread();
  }

  void StartNewPlayer(MockMediaSessionObserver* media_session_observer,
                      MediaSession::Type type) {
    bool result = AddPlayer(
        media_session_observer,
        media_session_observer->StartNewPlayer(),
        type);
    EXPECT_TRUE(result);
  }

  bool AddPlayer(MockMediaSessionObserver* media_session_observer,
                 int player_id,
                 MediaSession::Type type) {
    return media_session_->AddPlayer(media_session_observer, player_id, type);
  }

  void RemovePlayer(MockMediaSessionObserver* media_session_observer,
                    int player_id) {
    media_session_->RemovePlayer(media_session_observer, player_id);
  }

  void RemovePlayers(MockMediaSessionObserver* media_session_observer) {
    media_session_->RemovePlayers(media_session_observer);
  }

  bool HasAudioFocus() { return media_session_->IsActiveForTest(); }

  MediaSession::Type GetSessionType() {
    return media_session_->audio_focus_type_for_test();
  }

  bool IsControllable() { return media_session_->IsControllable(); }

  bool IsSuspended() { return media_session_->IsSuspended(); }

  void UIResume() {
    media_session_->Resume();
  }

  void SystemResume() {
    media_session_->OnResume(nullptr, nullptr);
  }

  void UISuspend() {
    media_session_->Suspend();
  }

  void SystemSuspend(bool temporary) {
    media_session_->OnSuspend(nullptr, nullptr, temporary);
  }

  MockWebContentsObserver* mock_web_contents_observer() {
    return mock_web_contents_observer_.get();
  }

  scoped_ptr<MediaSession> CreateDummyMediaSession() {
      return scoped_ptr<MediaSession>(new MediaSession(nullptr));
  }

  MediaSessionUmaHelper* GetMediaSessionUMAHelper() {
    return media_session_->uma_helper_for_test();
  }

 protected:
  MediaSession* media_session_;
  scoped_ptr<MockWebContentsObserver> mock_web_contents_observer_;

  DISALLOW_COPY_AND_ASSIGN(MediaSessionBrowserTest);
};

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       PlayersFromSameObserverDoNotStopEachOtherInSameSession) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_TRUE(media_session_observer->IsPlaying(0));
  EXPECT_TRUE(media_session_observer->IsPlaying(1));
  EXPECT_TRUE(media_session_observer->IsPlaying(2));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       PlayersFromManyObserverDoNotStopEachOtherInSameSession) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer_1(
      new MockMediaSessionObserver);
  scoped_ptr<MockMediaSessionObserver> media_session_observer_2(
      new MockMediaSessionObserver);
  scoped_ptr<MockMediaSessionObserver> media_session_observer_3(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer_1.get(), MediaSession::Type::Content);

  StartNewPlayer(media_session_observer_2.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer_3.get(), MediaSession::Type::Content);

  EXPECT_TRUE(media_session_observer_1->IsPlaying(0));
  EXPECT_TRUE(media_session_observer_2->IsPlaying(0));
  EXPECT_TRUE(media_session_observer_3->IsPlaying(0));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       SuspendedMediaSessionStopsPlayers) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(true);

  EXPECT_FALSE(media_session_observer->IsPlaying(0));
  EXPECT_FALSE(media_session_observer->IsPlaying(1));
  EXPECT_FALSE(media_session_observer->IsPlaying(2));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ResumedMediaSessionRestartsPlayers) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(true);
  SystemResume();

  EXPECT_TRUE(media_session_observer->IsPlaying(0));
  EXPECT_TRUE(media_session_observer->IsPlaying(1));
  EXPECT_TRUE(media_session_observer->IsPlaying(2));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       StartedPlayerOnSuspendedSessionPlaysAlone) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_TRUE(media_session_observer->IsPlaying(0));

  SystemSuspend(true);

  EXPECT_FALSE(media_session_observer->IsPlaying(0));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_FALSE(media_session_observer->IsPlaying(0));
  EXPECT_TRUE(media_session_observer->IsPlaying(1));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_FALSE(media_session_observer->IsPlaying(0));
  EXPECT_TRUE(media_session_observer->IsPlaying(1));
  EXPECT_TRUE(media_session_observer->IsPlaying(2));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, AudioFocusInitialState) {
  EXPECT_FALSE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, StartPlayerGivesFocus) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_TRUE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, SuspendGivesAwayAudioFocus) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(true);

  EXPECT_FALSE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ResumeGivesBackAudioFocus) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(true);
  SystemResume();

  EXPECT_TRUE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       RemovingLastPlayerDropsAudioFocus) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  RemovePlayer(media_session_observer.get(), 0);
  EXPECT_TRUE(HasAudioFocus());
  RemovePlayer(media_session_observer.get(), 1);
  EXPECT_TRUE(HasAudioFocus());
  RemovePlayer(media_session_observer.get(), 2);
  EXPECT_FALSE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       RemovingLastPlayerFromManyObserversDropsAudioFocus) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer_1(
      new MockMediaSessionObserver);
  scoped_ptr<MockMediaSessionObserver> media_session_observer_2(
      new MockMediaSessionObserver);
  scoped_ptr<MockMediaSessionObserver> media_session_observer_3(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer_1.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer_2.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer_3.get(), MediaSession::Type::Content);

  RemovePlayer(media_session_observer_1.get(), 0);
  EXPECT_TRUE(HasAudioFocus());
  RemovePlayer(media_session_observer_2.get(), 0);
  EXPECT_TRUE(HasAudioFocus());
  RemovePlayer(media_session_observer_3.get(), 0);
  EXPECT_FALSE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       RemovingAllPlayersFromObserversDropsAudioFocus) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer_1(
      new MockMediaSessionObserver);
  scoped_ptr<MockMediaSessionObserver> media_session_observer_2(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer_1.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer_1.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer_2.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer_2.get(), MediaSession::Type::Content);

  RemovePlayers(media_session_observer_1.get());
  EXPECT_TRUE(HasAudioFocus());
  RemovePlayers(media_session_observer_2.get());
  EXPECT_FALSE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ResumePlayGivesAudioFocus) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  RemovePlayer(media_session_observer.get(), 0);
  EXPECT_FALSE(HasAudioFocus());

  EXPECT_TRUE(
      AddPlayer(media_session_observer.get(), 0, MediaSession::Type::Content));
  EXPECT_TRUE(HasAudioFocus());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ResumeSuspendAreSentOnlyOncePerPlayers) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_EQ(0, media_session_observer->received_suspend_calls());
  EXPECT_EQ(0, media_session_observer->received_resume_calls());

  SystemSuspend(true);
  EXPECT_EQ(3, media_session_observer->received_suspend_calls());

  SystemResume();
  EXPECT_EQ(3, media_session_observer->received_resume_calls());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ResumeSuspendAreSentOnlyOncePerPlayersAddedTwice) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  // Adding the three players above again.
  EXPECT_TRUE(
      AddPlayer(media_session_observer.get(), 0, MediaSession::Type::Content));
  EXPECT_TRUE(
      AddPlayer(media_session_observer.get(), 1, MediaSession::Type::Content));
  EXPECT_TRUE(
      AddPlayer(media_session_observer.get(), 2, MediaSession::Type::Content));

  EXPECT_EQ(0, media_session_observer->received_suspend_calls());
  EXPECT_EQ(0, media_session_observer->received_resume_calls());

  SystemSuspend(true);
  EXPECT_EQ(3, media_session_observer->received_suspend_calls());

  SystemResume();
  EXPECT_EQ(3, media_session_observer->received_resume_calls());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       RemovingTheSamePlayerTwiceIsANoop) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  RemovePlayer(media_session_observer.get(), 0);
  RemovePlayer(media_session_observer.get(), 0);
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, MediaSessionType) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  // Starting a player with a given type should set the session to that type.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);
  EXPECT_EQ(MediaSession::Type::Transient, GetSessionType());

  // Adding a player of the same type should have no effect on the type.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);
  EXPECT_EQ(MediaSession::Type::Transient, GetSessionType());

  // Adding a player of Content type should override the current type.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  EXPECT_EQ(MediaSession::Type::Content, GetSessionType());

  // Adding a player of the Transient type should have no effect on the type.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);
  EXPECT_EQ(MediaSession::Type::Content, GetSessionType());

  EXPECT_TRUE(media_session_observer->IsPlaying(0));
  EXPECT_TRUE(media_session_observer->IsPlaying(1));
  EXPECT_TRUE(media_session_observer->IsPlaying(2));
  EXPECT_TRUE(media_session_observer->IsPlaying(3));

  SystemSuspend(true);

  EXPECT_FALSE(media_session_observer->IsPlaying(0));
  EXPECT_FALSE(media_session_observer->IsPlaying(1));
  EXPECT_FALSE(media_session_observer->IsPlaying(2));
  EXPECT_FALSE(media_session_observer->IsPlaying(3));

  EXPECT_EQ(MediaSession::Type::Content, GetSessionType());

  SystemResume();

  EXPECT_TRUE(media_session_observer->IsPlaying(0));
  EXPECT_TRUE(media_session_observer->IsPlaying(1));
  EXPECT_TRUE(media_session_observer->IsPlaying(2));
  EXPECT_TRUE(media_session_observer->IsPlaying(3));

  EXPECT_EQ(MediaSession::Type::Content, GetSessionType());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsShowForContent) {
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false));

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  // Starting a player with a content type should show the media controls.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsNoShowForTransient) {
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(false, false));

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  // Starting a player with a transient type should not show the media controls.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);

  EXPECT_FALSE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsHideWhenStopped) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(false, true))
      .After(showControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  RemovePlayers(media_session_observer.get());

  EXPECT_FALSE(IsControllable());
  EXPECT_TRUE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsShownAcceptTransient) {
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false));

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  // Transient player join the session without affecting the controls.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsShownAfterContentAdded) {
  Expectation dontShowControls = EXPECT_CALL(
      *mock_web_contents_observer(), MediaSessionStateChanged(false, false));
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false))
      .After(dontShowControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);

  // The controls are shown when the content player is added.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsStayIfOnlyOnePlayerHasBeenPaused) {
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false));

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);

  // Removing only content player doesn't hide the controls since the session
  // is still active.
  RemovePlayer(media_session_observer.get(), 0);

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsHideWhenTheLastPlayerIsStopped) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(false, true))
      .After(showControls);
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  RemovePlayer(media_session_observer.get(), 0);

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());

  RemovePlayer(media_session_observer.get(), 1);

  EXPECT_FALSE(IsControllable());
  EXPECT_TRUE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsHideWhenAllThePlayersAreRemoved) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(false, true))
      .After(showControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  RemovePlayers(media_session_observer.get());

  EXPECT_FALSE(IsControllable());
  EXPECT_TRUE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       SuspendTemporaryUpdatesControls) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, true))
      .After(showControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(true);

  EXPECT_TRUE(IsControllable());
  EXPECT_TRUE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsUpdatedWhenResumed) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(),
                                          MediaSessionStateChanged(true, true))
                                  .After(showControls);
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false))
      .After(pauseControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  SystemSuspend(true);
  SystemResume();

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsHideWhenSessionSuspendedPermanently) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(false, true))
      .After(showControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(false);

  EXPECT_FALSE(IsControllable());
  EXPECT_TRUE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsHideWhenSessionChangesFromContentToTransient) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(),
                                          MediaSessionStateChanged(true, true))
                                  .After(showControls);
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(false, false))
      .After(pauseControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  SystemSuspend(true);

  // This should reset the session and change it to a transient, so
  // hide the controls.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Transient);

  EXPECT_FALSE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsUpdatedWhenNewPlayerResetsSession) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(),
                                          MediaSessionStateChanged(true, true))
                                  .After(showControls);
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false))
      .After(pauseControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  SystemSuspend(true);

  // This should reset the session and update the controls.
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsResumedWhenPlayerIsResumed) {
  Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(),
                                         MediaSessionStateChanged(true, false));
  Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(),
                                          MediaSessionStateChanged(true, true))
                                  .After(showControls);
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false))
      .After(pauseControls);

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  SystemSuspend(true);

  // This should resume the session and update the controls.
  AddPlayer(media_session_observer.get(), 0, MediaSession::Type::Content);

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsNotUpdatedDueToResumeSessionAction) {
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false));

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  UISuspend();

  EXPECT_TRUE(IsControllable());
  EXPECT_TRUE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       ControlsNotUpdatedDueToSuspendSessionAction) {
  EXPECT_CALL(*mock_web_contents_observer(),
              MediaSessionStateChanged(true, false));

  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  UISuspend();
  UIResume();

  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       DontResumeBySystemUISuspendedSessions) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  UISuspend();
  EXPECT_TRUE(IsControllable());
  EXPECT_TRUE(IsSuspended());

  SystemResume();
  EXPECT_TRUE(IsControllable());
  EXPECT_TRUE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       AllowUIResumeForSystemSuspend) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(true);
  EXPECT_TRUE(IsControllable());
  EXPECT_TRUE(IsSuspended());

  UIResume();
  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ResumeSuspendFromUI) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  UISuspend();
  EXPECT_TRUE(IsControllable());
  EXPECT_TRUE(IsSuspended());

  UIResume();
  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ResumeSuspendFromSystem) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  SystemSuspend(true);
  EXPECT_TRUE(IsControllable());
  EXPECT_TRUE(IsSuspended());

  SystemResume();
  EXPECT_TRUE(IsControllable());
  EXPECT_FALSE(IsSuspended());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, UMA_Suspended_SystemTransient) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  base::HistogramTester tester;

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  SystemSuspend(true);

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
  EXPECT_EQ(1, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(0)); // System Transient
  EXPECT_EQ(0, samples->GetCount(1)); // System Permanent
  EXPECT_EQ(0, samples->GetCount(2)); // UI
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       UMA_Suspended_SystemPermantent) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  base::HistogramTester tester;

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  SystemSuspend(false);

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
  EXPECT_EQ(1, samples->TotalCount());
  EXPECT_EQ(0, samples->GetCount(0)); // System Transient
  EXPECT_EQ(1, samples->GetCount(1)); // System Permanent
  EXPECT_EQ(0, samples->GetCount(2)); // UI
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, UMA_Suspended_UI) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  base::HistogramTester tester;

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  UISuspend();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
  EXPECT_EQ(1, samples->TotalCount());
  EXPECT_EQ(0, samples->GetCount(0)); // System Transient
  EXPECT_EQ(0, samples->GetCount(1)); // System Permanent
  EXPECT_EQ(1, samples->GetCount(2)); // UI
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, UMA_Suspended_Multiple) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  base::HistogramTester tester;

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  UISuspend();
  UIResume();

  SystemSuspend(true);
  SystemResume();

  UISuspend();
  UIResume();

  SystemSuspend(false);

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
  EXPECT_EQ(4, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(0)); // System Transient
  EXPECT_EQ(1, samples->GetCount(1)); // System Permanent
  EXPECT_EQ(2, samples->GetCount(2)); // UI
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, UMA_Suspended_Crossing) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  base::HistogramTester tester;

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  UISuspend();
  SystemSuspend(true);
  SystemSuspend(false);
  UIResume();

  SystemSuspend(true);
  SystemSuspend(true);
  SystemSuspend(false);
  SystemResume();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
  EXPECT_EQ(2, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(0)); // System Transient
  EXPECT_EQ(0, samples->GetCount(1)); // System Permanent
  EXPECT_EQ(1, samples->GetCount(2)); // UI
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, UMA_Suspended_Stop) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
      new MockMediaSessionObserver);
  base::HistogramTester tester;

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  media_session_->Stop();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
  EXPECT_EQ(1, samples->TotalCount());
  EXPECT_EQ(0, samples->GetCount(0)); // System Transient
  EXPECT_EQ(0, samples->GetCount(1)); // System Permanent
  EXPECT_EQ(1, samples->GetCount(2)); // UI
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, UMA_ActiveTime_NoActivation) {
  base::HistogramTester tester;

  scoped_ptr<MediaSession> media_session = CreateDummyMediaSession();
  media_session.reset();

  // A MediaSession that wasn't active doesn't register an active time.
  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
  EXPECT_EQ(0, samples->TotalCount());
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       UMA_ActiveTime_SimpleActivation) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
    new MockMediaSessionObserver);
  base::HistogramTester tester;

  MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  clock->SetNow(base::Time::Now());
  media_session_uma_helper->SetClockForTest(
      scoped_ptr<base::SimpleTestClock>(clock));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  clock->Advance(base::TimeDelta::FromMilliseconds(1000));
  media_session_->Stop();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
  EXPECT_EQ(1, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(1000));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       UMA_ActiveTime_ActivationWithUISuspension) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
    new MockMediaSessionObserver);
  base::HistogramTester tester;

  MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  clock->SetNow(base::Time::Now());
  media_session_uma_helper->SetClockForTest(
      scoped_ptr<base::SimpleTestClock>(clock));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  clock->Advance(base::TimeDelta::FromMilliseconds(1000));
  UISuspend();

  clock->Advance(base::TimeDelta::FromMilliseconds(2000));
  UIResume();

  clock->Advance(base::TimeDelta::FromMilliseconds(1000));
  media_session_->Stop();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
  EXPECT_EQ(1, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(2000));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       UMA_ActiveTime_ActivationWithSystemSuspension) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
    new MockMediaSessionObserver);
  base::HistogramTester tester;

  MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  clock->SetNow(base::Time::Now());
  media_session_uma_helper->SetClockForTest(
      scoped_ptr<base::SimpleTestClock>(clock));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);

  clock->Advance(base::TimeDelta::FromMilliseconds(1000));
  SystemSuspend(true);

  clock->Advance(base::TimeDelta::FromMilliseconds(2000));
  SystemResume();

  clock->Advance(base::TimeDelta::FromMilliseconds(1000));
  media_session_->Stop();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
  EXPECT_EQ(1, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(2000));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       UMA_ActiveTime_ActivateSuspendedButNotStopped) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
    new MockMediaSessionObserver);
  base::HistogramTester tester;

  MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  clock->SetNow(base::Time::Now());
  media_session_uma_helper->SetClockForTest(
      scoped_ptr<base::SimpleTestClock>(clock));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  clock->Advance(base::TimeDelta::FromMilliseconds(500));
  SystemSuspend(true);

  {
    scoped_ptr<base::HistogramSamples> samples(
        tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
    EXPECT_EQ(0, samples->TotalCount());
  }

  SystemResume();
  clock->Advance(base::TimeDelta::FromMilliseconds(5000));
  UISuspend();

  {
    scoped_ptr<base::HistogramSamples> samples(
        tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
    EXPECT_EQ(0, samples->TotalCount());
  }
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       UMA_ActiveTime_ActivateSuspendStopTwice) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
    new MockMediaSessionObserver);
  base::HistogramTester tester;

  MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  clock->SetNow(base::Time::Now());
  media_session_uma_helper->SetClockForTest(
      scoped_ptr<base::SimpleTestClock>(clock));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  clock->Advance(base::TimeDelta::FromMilliseconds(500));
  SystemSuspend(true);
  media_session_->Stop();

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  clock->Advance(base::TimeDelta::FromMilliseconds(5000));
  SystemResume();
  media_session_->Stop();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
  EXPECT_EQ(2, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(500));
  EXPECT_EQ(1, samples->GetCount(5000));
}

IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest,
                       UMA_ActiveTime_MultipleActivations) {
  scoped_ptr<MockMediaSessionObserver> media_session_observer(
    new MockMediaSessionObserver);
  base::HistogramTester tester;

  MediaSessionUmaHelper* media_session_uma_helper = GetMediaSessionUMAHelper();
  base::SimpleTestClock* clock = new base::SimpleTestClock();
  clock->SetNow(base::Time::Now());
  media_session_uma_helper->SetClockForTest(
      scoped_ptr<base::SimpleTestClock>(clock));

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  clock->Advance(base::TimeDelta::FromMilliseconds(10000));
  RemovePlayer(media_session_observer.get(), 0);

  StartNewPlayer(media_session_observer.get(), MediaSession::Type::Content);
  clock->Advance(base::TimeDelta::FromMilliseconds(1000));
  media_session_->Stop();

  scoped_ptr<base::HistogramSamples> samples(
      tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
  EXPECT_EQ(2, samples->TotalCount());
  EXPECT_EQ(1, samples->GetCount(1000));
  EXPECT_EQ(1, samples->GetCount(10000));
}


text:
<!DOCTYPE html>

        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Hello World</title>

            Utilizando el API de Cordova device-orientation

        <input type="button" value="obtener información" onclick="getHeading();" />

redpajama_set_name: RedPajamaGithub


text: export { VirtualGroupsComponent } from './virtual-groups.component';


text:
namespace net {

class ClientSocketHandle;
class HttpAuthController;
class HttpNetworkSession;
class HttpStream;
class SpdySessionPool;
class NetLog;
struct SSLConfig;

// An HttpStreamRequestImpl exists for each stream which is in progress of being
// created for the StreamFactory.
class HttpStreamFactoryImpl::Job {
 public:
  // Delegate to report Job's status to Request and HttpStreamFactory.
  class NET_EXPORT_PRIVATE Delegate {
   public:
    virtual ~Delegate() {}

    // Invoked when |job| has an HttpStream ready.
    virtual void OnStreamReady(Job* job, const SSLConfig& used_ssl_config) = 0;

    // Invoked when |job| has a BidirectionalStream ready.
    virtual void OnBidirectionalStreamImplReady(
        Job* job,
        const SSLConfig& used_ssl_config,
        const ProxyInfo& used_proxy_info) = 0;

    // Invoked when |job| has a WebSocketHandshakeStream ready.
    virtual void OnWebSocketHandshakeStreamReady(
        Job* job,
        const SSLConfig& used_ssl_config,
        const ProxyInfo& used_proxy_info,
        WebSocketHandshakeStreamBase* stream) = 0;

    // Invoked when |job| fails to create a stream.
    virtual void OnStreamFailed(Job* job,
                                int status,
                                const SSLConfig& used_ssl_config) = 0;

    // Invoked when |job| has a certificate error for the Request.
    virtual void OnCertificateError(Job* job,
                                    int status,
                                    const SSLConfig& used_ssl_config,
                                    const SSLInfo& ssl_info) = 0;

    // Invoked when |job| has a failure of the CONNECT request through an HTTPS
    // proxy.
    virtual void OnHttpsProxyTunnelResponse(
        Job* job,
        const HttpResponseInfo& response_info,
        const SSLConfig& used_ssl_config,
        const ProxyInfo& used_proxy_info,
        HttpStream* stream) = 0;

    // Invoked when |job| raises failure for SSL Client Auth.
    virtual void OnNeedsClientAuth(Job* job,
                                   const SSLConfig& used_ssl_config,
                                   SSLCertRequestInfo* cert_info) = 0;

    // Invoked when |job| needs proxy authentication.
    virtual void OnNeedsProxyAuth(Job* job,
                                  const HttpResponseInfo& proxy_response,
                                  const SSLConfig& used_ssl_config,
                                  const ProxyInfo& used_proxy_info,
                                  HttpAuthController* auth_controller) = 0;

    // Returns true if the connection initialization to the proxy server
    // contained in |proxy_info| can be skipped.
    virtual bool OnInitConnection(const ProxyInfo& proxy_info) = 0;

    // Invoked when |job| has completed proxy resolution. The delegate may
    // create an alternative proxy server job to fetch the request.
    virtual void OnResolveProxyComplete(
        Job* job,
        const HttpRequestInfo& request_info,
        RequestPriority priority,
        const SSLConfig& server_ssl_config,
        const SSLConfig& proxy_ssl_config,
        HttpStreamRequest::StreamType stream_type) = 0;

    // Invoked to notify the Request and Factory of the readiness of new
    // SPDY session.
    virtual void OnNewSpdySessionReady(
        Job* job,
        const base::WeakPtr<SpdySession>& spdy_session,
        bool direct) = 0;

    // Invoked when the orphaned |job| finishes.
    virtual void OnOrphanedJobComplete(const Job* job) = 0;

    // Invoked when the |job| finishes pre-connecting sockets.
    virtual void OnPreconnectsComplete(Job* job) = 0;

    // Invoked to record connection attempts made by the socket layer to
    // Request if |job| is associated with Request.
    virtual void AddConnectionAttemptsToRequest(
        Job* job,
        const ConnectionAttempts& attempts) = 0;

    // Invoked when |job| finishes initiating a connection.
    virtual void OnConnectionInitialized(Job* job, int rv) = 0;

    // Return false if |job| can advance to the next state. Otherwise, |job|
    // will wait for Job::Resume() to be called before advancing.
    virtual bool ShouldWait(Job* job) = 0;

    // Called when |job| determines the appropriate |spdy_session_key| for the
    // Request. Note that this does not mean that SPDY is necessarily supported
    // for this SpdySessionKey, since we may need to wait for NPN to complete
    // before knowing if SPDY is available.
    virtual void SetSpdySessionKey(Job* job,
                                   const SpdySessionKey& spdy_session_key) = 0;

    // Remove session from the SpdySessionRequestMap.
    virtual void RemoveRequestFromSpdySessionRequestMapForJob(Job* job) = 0;

    virtual const NetLogWithSource* GetNetLog(Job* job) const = 0;

    virtual WebSocketHandshakeStreamBase::CreateHelper*
    websocket_handshake_stream_create_helper() = 0;

    virtual void MaybeSetWaitTimeForMainJob(const base::TimeDelta& delay) = 0;

    virtual bool for_websockets() = 0;
  };

  // Constructor for non-alternative Job.
  // Job is owned by |delegate|, hence |delegate| is valid for the
  // lifetime of the Job.
  Job(Delegate* delegate,
      JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      NetLog* net_log);

  // Constructor for the alternative Job. The Job is owned by |delegate|, hence
  // |delegate| is valid for the lifetime of the Job. If |alternative_service|
  // is initialized, then the Job will use the alternative service. On the
  // other hand, if |alternative_proxy_server| is a valid proxy server, then the
  // job will use that instead of using ProxyService for proxy resolution.
  // Further, if |alternative_proxy_server| is a valid but bad proxy, then
  // fallback proxies are not used. It is illegal to call this with an
  // initialized |alternative_service|, and a valid |alternative_proxy_server|.
  Job(Delegate* delegate,
      JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      AlternativeService alternative_service,
      const ProxyServer& alternative_proxy_server,
      NetLog* net_log);
  virtual ~Job();

  // Start initiates the process of creating a new HttpStream.
  // |delegate_| will be notified upon completion.
  void Start(HttpStreamRequest::StreamType stream_type);

  // Preconnect will attempt to request |num_streams| sockets from the
  // appropriate ClientSocketPool.
  int Preconnect(int num_streams);

  int RestartTunnelWithProxyAuth(const AuthCredentials& credentials);
  LoadState GetLoadState() const;

  // Tells |this| that |delegate_| has determined it still needs to continue
  // connecting.
  virtual void Resume();

  // Called to detach |this| Job. May resume the other Job, will disconnect
  // the socket for |this| Job, and notify |delegate| upon completion.
  void Orphan();

  void SetPriority(RequestPriority priority);

  RequestPriority priority() const { return priority_; }
  bool was_alpn_negotiated() const;
  NextProto negotiated_protocol() const;
  bool using_spdy() const;
  const NetLogWithSource& net_log() const { return net_log_; }
  HttpStreamRequest::StreamType stream_type() const { return stream_type_; }

  std::unique_ptr<HttpStream> ReleaseStream() { return std::move(stream_); }

  void SetStream(HttpStream* http_stream) { stream_.reset(http_stream); }

  std::unique_ptr<BidirectionalStreamImpl> ReleaseBidirectionalStream() {
    return std::move(bidirectional_stream_impl_);
  }

  bool is_waiting() const { return next_state_ == STATE_WAIT_COMPLETE; }
  const SSLConfig& server_ssl_config() const;
  const SSLConfig& proxy_ssl_config() const;
  const ProxyInfo& proxy_info() const;

  JobType job_type() const { return job_type_; }

  const AlternativeService alternative_service() const {
    return alternative_service_;
  }

  const ProxyServer alternative_proxy_server() const {
    return alternative_proxy_server_;
  }

  bool using_existing_quic_session() const {
    return using_existing_quic_session_;
  }

 private:
  friend class HttpStreamFactoryImplJobPeer;

  enum State {
    STATE_START,
    STATE_RESOLVE_PROXY,
    STATE_RESOLVE_PROXY_COMPLETE,

    // The main and alternative jobs are started in parallel.  The main job
    // waits after it finishes proxy resolution.  The alternative job never
    // waits.
    //
    // An HTTP/2 alternative job notifies the JobController in DoInitConnection
    // unless it can pool to an existing SpdySession.  JobController, in turn,
    // resumes the main job.
    //
    // A QUIC alternative job notifies the JobController in DoInitConnection
    // regardless of whether it pools to an existing QUIC session, but the main
    // job is only resumed after some delay.
    //
    // If the main job is resumed, then it races the alternative job.
    STATE_WAIT,
    STATE_WAIT_COMPLETE,

    STATE_INIT_CONNECTION,
    STATE_INIT_CONNECTION_COMPLETE,
    STATE_WAITING_USER_ACTION,
    STATE_RESTART_TUNNEL_AUTH,
    STATE_RESTART_TUNNEL_AUTH_COMPLETE,
    STATE_CREATE_STREAM,
    STATE_CREATE_STREAM_COMPLETE,
    STATE_DRAIN_BODY_FOR_AUTH_RESTART,
    STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
    STATE_DONE,
    STATE_NONE
  };

  void OnStreamReadyCallback();
  void OnBidirectionalStreamImplReadyCallback();
  void OnWebSocketHandshakeStreamReadyCallback();
  // This callback function is called when a new SPDY session is created.
  void OnNewSpdySessionReadyCallback();
  void OnStreamFailedCallback(int result);
  void OnCertificateErrorCallback(int result, const SSLInfo& ssl_info);
  void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info,
                                HttpAuthController* auth_controller);
  void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info);
  void OnHttpsProxyTunnelResponseCallback(const HttpResponseInfo& response_info,
                                          HttpStream* stream);
  void OnPreconnectsComplete();

  void OnIOComplete(int result);
  int RunLoop(int result);
  int DoLoop(int result);
  int StartInternal();
  int DoInitConnectionImpl();

  // Each of these methods corresponds to a State value.  Those with an input
  // argument receive the result from the previous state.  If a method returns
  // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
  // next state method as the result arg.
  int DoStart();
  int DoResolveProxy();
  int DoResolveProxyComplete(int result);
  int DoWait();
  int DoWaitComplete(int result);
  int DoInitConnection();
  int DoInitConnectionComplete(int result);
  int DoWaitingUserAction(int result);
  int DoCreateStream();
  int DoCreateStreamComplete(int result);
  int DoRestartTunnelAuth();
  int DoRestartTunnelAuthComplete(int result);

  // Creates a SpdyHttpStream or a BidirectionalStreamImpl from the given values
  // and sets to |stream_| or |bidirectional_stream_impl_| respectively. Does
  // nothing if |stream_factory_| is for WebSockets.
  int SetSpdyHttpStreamOrBidirectionalStreamImpl(
      base::WeakPtr<SpdySession> session,
      bool direct);

  // Returns to STATE_INIT_CONNECTION and resets some state.
  void ReturnToStateInitConnection(bool close_connection);

  // Set the motivation for this request onto the underlying socket.
  void SetSocketMotivation();

  bool IsHttpsProxyAndHttpUrl() const;

  // Is this a SPDY or QUIC alternative Job?
  bool IsSpdyAlternative() const;
  bool IsQuicAlternative() const;

  // Sets several fields of |ssl_config| based on the proxy info and other
  // factors.
  void InitSSLConfig(SSLConfig* ssl_config, bool is_proxy) const;

  // Retrieve SSLInfo from our SSL Socket.
  // This must only be called when we are using an SSLSocket.
  // After calling, the caller can use ssl_info_.
  void GetSSLInfo();

  SpdySessionKey GetSpdySessionKey() const;

  // Returns true if the current request can use an existing spdy session.
  bool CanUseExistingSpdySession() const;

  // Called when we encounter a network error that could be resolved by trying
  // a new proxy configuration.  If there is another proxy configuration to try
  // then this method sets next_state_ appropriately and returns either OK or
  // ERR_IO_PENDING depending on whether or not the new proxy configuration is
  // available synchronously or asynchronously.  Otherwise, the given error
  // code is simply returned.
  int ReconsiderProxyAfterError(int error);

  // Called to handle a certificate error.  Stores the certificate in the
  // allowed_bad_certs list, and checks if the error can be ignored.  Returns
  // OK if it can be ignored, or the error code otherwise.
  int HandleCertificateError(int error);

  // Called to handle a client certificate request.
  int HandleCertificateRequest(int error);

  // Should we force QUIC for this stream request.
  bool ShouldForceQuic() const;

  ClientSocketPoolManager::SocketGroupType GetSocketGroup() const;

  void MaybeCopyConnectionAttemptsFromSocketOrHandle();

  // Record histograms of latency until Connect() completes.
  static void LogHttpConnectedMetrics(const ClientSocketHandle& handle);

  // Invoked by the transport socket pool after host resolution is complete
  // to allow the connection to be aborted, if a matching SPDY session can
  // be found.  Will return ERR_SPDY_SESSION_ALREADY_EXISTS if such a
  // session is found, and OK otherwise.
  static int OnHostResolution(SpdySessionPool* spdy_session_pool,
                              const SpdySessionKey& spdy_session_key,
                              const GURL& origin_url,
                              const AddressList& addresses,
                              const NetLogWithSource& net_log);

  const HttpRequestInfo request_info_;
  RequestPriority priority_;
  ProxyInfo proxy_info_;
  SSLConfig server_ssl_config_;
  SSLConfig proxy_ssl_config_;
  const NetLogWithSource net_log_;

  CompletionCallback io_callback_;
  std::unique_ptr<ClientSocketHandle> connection_;
  HttpNetworkSession* const session_;
  State next_state_;
  ProxyService::PacRequest* pac_request_;
  SSLInfo ssl_info_;

  // The server we are trying to reach, could be that of the origin or of the
  // alternative service (after applying host mapping rules).
  const HostPortPair destination_;

  // The origin url we're trying to reach. This url may be different from the
  // original request when host mapping rules are set-up.
  const GURL origin_url_;

  // AlternativeService for this Job if this is an alternative Job.
  const AlternativeService alternative_service_;

  // Alternative proxy server that should be used by |this| to fetch the
  // request.
  const ProxyServer alternative_proxy_server_;

  // Unowned. |this| job is owned by |delegate_|.
  Delegate* delegate_;

  const JobType job_type_;

  // True if handling a HTTPS request, or using SPDY with SSL
  bool using_ssl_;

  // True if this network transaction is using SPDY instead of HTTP.
  bool using_spdy_;

  // True if this network transaction is using QUIC instead of HTTP.
  bool using_quic_;
  QuicStreamRequest quic_request_;

  // True if this job used an existing QUIC session.
  bool using_existing_quic_session_;

  // Force quic for a specific port.
  int force_quic_port_;

  scoped_refptr<HttpAuthController>
      auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];

  // True when the tunnel is in the process of being established - we can't
  // read from the socket until the tunnel is done.
  bool establishing_tunnel_;

  std::unique_ptr<HttpStream> stream_;
  std::unique_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
  std::unique_ptr<BidirectionalStreamImpl> bidirectional_stream_impl_;

  // True if we negotiated ALPN.
  bool was_alpn_negotiated_;

  // Protocol negotiated with the server.
  NextProto negotiated_protocol_;

  // 0 if we're not preconnecting. Otherwise, the number of streams to
  // preconnect.
  int num_streams_;

  // Initialized when we create a new SpdySession.
  base::WeakPtr<SpdySession> new_spdy_session_;

  // Initialized when we have an existing SpdySession.
  base::WeakPtr<SpdySession> existing_spdy_session_;

  // Only used if |new_spdy_session_| is non-NULL.
  bool spdy_session_direct_;

  // Type of stream that is requested.
  HttpStreamRequest::StreamType stream_type_;

  base::WeakPtrFactory<Job> ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(Job);
};

// Factory for creating Jobs.
class HttpStreamFactoryImpl::JobFactory {
 public:
  virtual ~JobFactory() {}

  // Creates an alternative service Job.
  virtual HttpStreamFactoryImpl::Job* CreateJob(
      HttpStreamFactoryImpl::Job::Delegate* delegate,
      HttpStreamFactoryImpl::JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      AlternativeService alternative_service,
      NetLog* net_log) = 0;

  // Creates an alternative proxy server Job.
  virtual HttpStreamFactoryImpl::Job* CreateJob(
      HttpStreamFactoryImpl::Job::Delegate* delegate,
      HttpStreamFactoryImpl::JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      const ProxyServer& alternative_proxy_server,
      NetLog* net_log) = 0;

  // Creates a non-alternative Job.
  virtual HttpStreamFactoryImpl::Job* CreateJob(
      HttpStreamFactoryImpl::Job::Delegate* delegate,
      HttpStreamFactoryImpl::JobType job_type,
      HttpNetworkSession* session,
      const HttpRequestInfo& request_info,
      RequestPriority priority,
      const SSLConfig& server_ssl_config,
      const SSLConfig& proxy_ssl_config,
      HostPortPair destination,
      GURL origin_url,
      NetLog* net_log) = 0;
};

}  // namespace net

#endif  // NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_H_


text:
package org.beanio.stream.util;

import java.io.*;

/**
 * Skips commented lines read from an input stream.  The input stream must support marking (i.e.
 * {@link Reader#markSupported()} must return true).  A line is considered commented if it starts
 * with one of the configured comment indicators.
 *
 * @author Kevin Seim
 * @since 1.2
 */
public class CommentReader {

    private Reader in;
    private String[] comments;
    private char[] commentBuffer;
    private char recordTerminator = 0;
    private boolean skipLF;
    private boolean eof;

    /**
     * Constructs a new CommentReader.
     * @param in the input stream to read
     * @param comments an array of comment identifying strings
     * @throws IllegalArgumentException if the configured comments are invalid or the reader does
     *   not support marking
     */
    public CommentReader(Reader in, String [] comments) throws IllegalArgumentException {
        this(in, comments, null);
    }

    /**
     * Constructs a new CommentReader.
     * @param in the input stream to read from
     * @param comments an array of comment identifying strings
     * @param recordTerminator the record terminating character
     * @throws IllegalArgumentException if the configured comments are invalid or the reader does
     *   not support marking
     */
    public CommentReader(Reader in, String [] comments, Character recordTerminator) throws IllegalArgumentException {
        if (comments == null) {
            throw new IllegalArgumentException("Comments not set");
        }
        if (!in.markSupported()) {
            throw new IllegalArgumentException("Comments require reader.markSupported() to return true");
        }

        this.in = in;
        this.comments = comments;
        if (recordTerminator != null) {
            this.recordTerminator = recordTerminator;
        }

        int maximumCommentLength = 0;
        for (String s : comments) {
            if (s == null || s.length() == 0) {
                throw new IllegalArgumentException("Comment value cannot be null or empty string");
            }
            maximumCommentLength = Math.max(maximumCommentLength, s.length());
        }
        commentBuffer = new char[maximumCommentLength + 1];
    }

    /**
     * Returns whether the next character should be ignored if its a line feed.
     * @return true if the next line feed should be ignored
     */
    public boolean isSkipLF() {
        return skipLF;
    }

    /**
     * Returns whether the end of the stream was reached reading a commented line.
     * @return true if the end of the stream was reached reading a commented line.
     */
    public boolean isEOF() {
        return eof;
    }

    /**
     * Skips comments in the input stream and returns the number of commented lines read.
     * If no commented lines were read, the stream is positioned just as it had been before
     * this method is called.
     * @param initialSkipLF true if the first line feed character read should be ignored
     * @return the number of skipped comment lines
     * @throws IOException
     */
    public int skipComments(boolean initialSkipLF) throws IOException {
        skipLF = initialSkipLF;

        int lines = 0;
        while (true) {
            // mark our current position in the stream
            in.mark(commentBuffer.length);

            // read the start of the line
            int n = in.read(commentBuffer);
            if (n <= 0) {
                break;
            }

            String linePrefix;
            if (skipLF && commentBuffer[0] == '\n') {
                linePrefix = new String(commentBuffer, 1, n-1);
            }
            else {
                linePrefix = new String(commentBuffer, 0, n);
            }

            // determine if the line prefix matches a configured comment
            boolean commentFound = false;
            for (String s : comments) {
                if (linePrefix.startsWith(s)) {
                    commentFound = true;
                    ++lines;
                    break;
                }
            }

            // if no comment was found, break out
            if (!commentFound) {
                break;
            }

            // finish reading the entire line
            in.reset();
            while ((n = in.read()) != -1) {
                char c = (char) n;

                if (recordTerminator == 0) {
                    if (skipLF) {
                        skipLF = false;
                        if (c == '\n') {
                            continue;
                        }
                    }

                    if (c == '\n') {
                        break;
                    }
                    else if (c == '\r') {
                        skipLF = true;
                        break;
                    }
                }
                else if (c == recordTerminator) {
                    break;
                }
            }
            if (n == -1) {
                eof = true;
                return lines;
            }
        }

        in.reset();
        return lines;
    }
}


text:
RSpec.shared_context 'signature', shared_context: :metadata do
  let(:api_key) { 'test_api_key' }
  let(:api_secret) { 'test_api_secret' }
  let(:timestamp) { '1504106787' }
  let(:path) { '/api/v1/messages/1' }
  let(:signature_options) { { request_type: 'GET', path: path, timestamp: timestamp, access_key: api_key } }

  let(:valid_signature) { 'YvyR+VKY1VREooZDNLtCZ7Jhu7YkxQQ0a9Zk928bLYc=' }
end

RSpec.configure do |rspec|
  rspec.include_context 'signature', include_shared: true
end


text:
require "logger"
require "json"

module Refile
  class App
    def initialize(logger: nil, allow_origin: nil)
      @logger = logger
      @logger ||= ::Logger.new(nil)
      @allow_origin = allow_origin
    end

    class Proxy
      def initialize(peek, file)
        @peek = peek
        @file = file
      end

      def close
        @file.close
      end

      def each(&block)
        block.call(@peek)
        @file.each(&block)
      end
    end

    def call(env)
      @logger.info { "Refile: #{env["REQUEST_METHOD"]} #{env["PATH_INFO"]}" }

      backend_name, *args = env["PATH_INFO"].sub(/^\//, "").split("/")
      backend = Refile.backends[backend_name]

      if env["REQUEST_METHOD"] == "GET" and backend and args.length >= 2
        *process_args, id, filename = args
        format = ::File.extname(filename)[1..-1]

        @logger.debug { "Refile: serving #{id.inspect} from #{backend_name} backend which is of type #{backend.class}" }

        file = backend.get(id)

        unless process_args.empty?
          name = process_args.shift
          processor = Refile.processors[name]
          unless processor
            @logger.debug { "Refile: no such processor #{name.inspect}" }
            return not_found
          end
          file = if format
            processor.call(file, *process_args, format: format)
          else
            processor.call(file, *process_args)
          end
        end

        peek = begin
          file.read(Refile.read_chunk_size)
        rescue => e
          log_error(e)
          return not_found
        end

        headers = {}
        headers["Access-Control-Allow-Origin"] = @allow_origin if @allow_origin

        [200, headers, Proxy.new(peek, file)]
      elsif env["REQUEST_METHOD"] == "POST" and backend and args.empty? and Refile.direct_upload.include?(backend_name)
        @logger.debug { "Refile: uploading to #{backend_name} backend which is of type #{backend.class}" }

        tempfile = Rack::Request.new(env).params.fetch("file").fetch(:tempfile)
        file = backend.upload(tempfile)

        [200, { "Content-Type" => "application/json" }, [{ id: file.id }.to_json]]
      else
        not_found
      end
    rescue => e
      log_error(e)
      [500, {}, ["error"]]
    end

  private

    def not_found
      [404, {}, ["not found"]]
    end

    def log_error(e)
      if @logger.debug?
        @logger.debug "Refile: unable to read file"
        @logger.debug "#{e.class}: #{e.message}"
        e.backtrace.each do |line|
          @logger.debug "  #{line}"
        end
      end
    end
  end
end


text:
license: Licensed to the Apache Software Foundation (ASF) under one
         or more contributor license agreements.  See the NOTICE file
         distributed with this work for additional information
         regarding copyright ownership.  The ASF licenses this file
         to you 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.
---

batterylow
===========

This is an event that fires when a Cordova application detects the battery has reached the low level threshold.

    window.addEventListener("batterylow", yourCallbackFunction, false);

Details
-------

This event that fires when a Cordova application detects the percentage of battery has reached the low battery threshold. This value is device specific.

The batterylow handler will be called with an object that contains two properties:

- __level:__ The percentage of battery (0-100). _(Number)_
- __isPlugged:__ A boolean that represents whether or not the device is plugged in or not. _(Boolean)_

Typically, you will want to attach an event listener with `document.addEventListener` once you receive the Cordova 'deviceready' event.

Supported Platforms
-------------------

- iOS
- Android
- BlackBerry WebWorks (OS 5.0 and higher)

Quick Example
-------------

    window.addEventListener("batterylow", onBatteryLow, false);

    function onBatteryLow(info) {
        // Handle the battery low event
       	alert("Battery Level Low " + info.level + "%");
    }

Full Example
------------

    <!DOCTYPE html>
    <html>
      <head>
        <title>Cordova Device Ready Example</title>

        <script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
        <script type="text/javascript" charset="utf-8">

        // Call onDeviceReady when Cordova is loaded.
        //
        // At this point, the document has loaded but cordova-1.7.0.js has not.
        // When Cordova is loaded and talking with the native device,
        // it will call the event `deviceready`.
        //
	    function onLoad() {
    	    document.addEventListener("deviceready", onDeviceReady, false);
    	}

        // Cordova is loaded and it is now safe to make calls Cordova methods
        //
        function onDeviceReady() {
		    window.addEventListener("batterylow", onBatteryLow, false);
        }

        // Handle the batterylow event
        //
        function onBatteryLow(info) {
	       	alert("Battery Level Low " + info.level + "%");
        }

        </script>
      </head>
      <body onload="onLoad()">
      </body>
    </html>


text:
{{ widget.label|stringformat:'s' }}

        {{ widget.label.description }}


text:
<link href="//cdn-images.mailchimp.com/embedcode/classic-10_7.css" rel="stylesheet" type="text/css">

    <form action="//eleven-labs.us12.list-manage.com/subscribe/post?u=10742232891cd45dd4db4277e&id=4efc82ab14" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" novalidate>

Subscribe to our mailing list

* indicates required

                Email Address  *
                <input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">

                First Name
                <input type="text" value="" name="FNAME" class="" id="mce-FNAME">

                Last Name
                <input type="text" value="" name="LNAME" class="" id="mce-LNAME">

                What's your technical expertise ?

                        <input type="checkbox" value="1" name="group[11405][1]" id="mce-group[11405]-11405-0">
                        PHP

                        <input type="checkbox" value="2" name="group[11405][2]" id="mce-group[11405]-11405-1">
                        Javascript

                        <input type="checkbox" value="4" name="group[11405][4]" id="mce-group[11405]-11405-2">
                        Mobile

                        <input type="checkbox" value="8" name="group[11405][8]" id="mce-group[11405]-11405-3">
                        Other

<input type="text" name="b_10742232891cd45dd4db4277e_4efc82ab14" tabindex="-1" value="">

<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button">

    </form>


text:
Set the `PYTHONPATH` variable for module importing. To do this, you need to work in the command line.

### Mac OS X / Linux

    $ cd nyc-green-taxi-map-visualization
    $ export PYTHONPATH="$(pwd)"

## Working in a Virtual Environment \[RECOMMENDED\]

### Using vanilla `virtualenv`

### Using `virtualenvwrapper` \[RECOMMENDED\]

## Installing pip packages

    $ pip install -U pip
    $ pip install -r requirements_dev.txt

## Updating requirements \& dependencies

Make sure `pip-tools` has already been installed. If you ran `pip install -r requirements_dev.txt`, then `pip-tools==1.11.0` should be installed.

_NOTE: Never directly update `requirements.txt` or `requirements_dev.txt`._

Instead, use `pip-compile`

    $ pip-compile requirements.in
    $ pip-compile requirements_dev.in


text:
@interface CollectionViewCell : UICollectionViewCell
@property (strong, nonatomic) NSDictionary * photo;
@property (weak, nonatomic) IBOutlet ImageView *imageView;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;

@end


text:
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  XMonad.Layout.Accordion
-- Description :  Put non-focused windows in ribbons at the top and bottom of the screen.
-- Copyright   :  (c) glasser@mit.edu
-- License     :  BSD
--
-- Maintainer  :  glasser@mit.edu
-- Stability   :  stable
-- Portability :  unportable
--
-- LayoutClass that puts non-focused windows in ribbons at the top and bottom
-- of the screen.
-----------------------------------------------------------------------------

module XMonad.Layout.Accordion (
    -- * Usage
    -- $usage
    Accordion(Accordion)) where

import XMonad
import qualified XMonad.StackSet as W
import Data.Ratio

-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Layout.Accordion
--
-- Then edit your @layoutHook@ by adding the Accordion layout:
--
-- > myLayout = Accordion ||| Full ||| etc..
-- > main = xmonad def { layoutHook = myLayout }
--
-- For more detailed instructions on editing the layoutHook see
-- <https://xmonad.org/TUTORIAL.html#customizing-xmonad the tutorial> and
-- "XMonad.Doc.Extending#Editing_the_layout_hook".

data Accordion a = Accordion deriving ( Read, Show )

instance LayoutClass Accordion Window where
    pureLayout _ sc ws = zip ups tops ++ [(W.focus ws, mainPane)] ++ zip dns bottoms
     where
       ups    = reverse $ W.up ws
       dns    = W.down ws
       (top,  allButTop) = splitVerticallyBy (1%8 :: Ratio Int) sc
       (center,  bottom) = splitVerticallyBy (6%7 :: Ratio Int) allButTop
       (allButBottom, _) = splitVerticallyBy (7%8 :: Ratio Int) sc
       mainPane | ups /= [] && dns /= [] = center
                | ups /= []              = allButTop
                | dns /= []              = allButBottom
                | otherwise              = sc
       tops    = if ups /= [] then splitVertically (length ups) top    else []
       bottoms = if dns /= [] then splitVertically (length dns) bottom else []


text:
/**
 */
package uk.ac.kcl.inf.robotics.rigidBodies;

/**
 *
 * A representation of the model object 'Basic Locked Joint Type'.
 *
 *
 *

 * The following features are supported:
 *

 *

 *
{@link uk.ac.kcl.inf.robotics.rigidBodies.BasicLockedJointType#getType Type}

 *

 *
 * @see uk.ac.kcl.inf.robotics.rigidBodies.RigidBodiesPackage#getBasicLockedJointType()
 * @model
 * @generated
 */
public interface BasicLockedJointType extends LockedJointTypeExpression
{
  /**
   * Returns the value of the 'Type' containment reference.
   *
   *

   * If the meaning of the 'Type' containment reference isn't clear,
   * there really should be more of a description here...
   *

   *
   * @return the value of the 'Type' containment reference.
   * @see #setType(LockedJointMovement)
   * @see uk.ac.kcl.inf.robotics.rigidBodies.RigidBodiesPackage#getBasicLockedJointType_Type()
   * @model containment="true"
   * @generated
   */
  LockedJointMovement getType();

  /**
   * Sets the value of the '{@link uk.ac.kcl.inf.robotics.rigidBodies.BasicLockedJointType#getType Type}' containment reference.
   *
   *
   * @param value the new value of the 'Type' containment reference.
   * @see #getType()
   * @generated
   */
  void setType(LockedJointMovement value);

} // BasicLockedJointType


text:
layout: master
include: person
name: Erik Elmroth
home: UmU
country: "SE"
photo:
email:
phone:
on_contract:
has_been_on_contract: no
groups:
  neic2015-prg:
---


text:
module MongoTestServer #:nodoc:
  class Engine < ::Rails::Engine #:nodoc:
  end
end


text:
	<form method="post" action="#">

				<?php echo validation_errors('
', '
');?>

					<input type="email" class="form-control" name="email" placeholder="Email"/>

					<input type="password" class="form-control" name="password" placeholder="Password"/>

					<button type="submit" class="form-control btn btn-success" name="submit">Login</button>

	</form>


text:
package org.apache.ignite.internal.processors.security.thread;

import org.apache.ignite.internal.processors.security.IgniteSecurity;
import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor;

/**
 * Extends {@link IgniteStripedThreadPoolExecutor} with the ability to execute tasks in security context that was actual
 * when task was added to executor's queue.
 */
public class SecurityAwareStripedThreadPoolExecutor extends IgniteStripedThreadPoolExecutor {
    /** */
    private final IgniteSecurity security;

    /** */
    public SecurityAwareStripedThreadPoolExecutor(
        IgniteSecurity security,
        int concurrentLvl,
        String igniteInstanceName,
        String threadNamePrefix,
        Thread.UncaughtExceptionHandler eHnd,
        boolean allowCoreThreadTimeOut,
        long keepAliveTime
    ) {
        super(concurrentLvl, igniteInstanceName, threadNamePrefix, eHnd, allowCoreThreadTimeOut, keepAliveTime);
        this.security = security;
    }

    /** {@inheritDoc} */
    @Override public void execute(Runnable task, int idx) {
        super.execute(task == null ? null : new SecurityAwareRunnable(security, task), idx);
    }
}


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
null

#### Original name
Ancylogyne macrocnemis Nees

### Remarks
null


text:
package com.example.dateasy.activity;

/**
 * 欢迎界面
 * @author Xu
 */
import java.util.Timer;
import java.util.TimerTask;

import com.example.dateasy.R;
import com.example.dateasy.util.Utils;

import android.app.Activity;
import android.os.Bundle;

public class WelcomeActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.welcome);

		Timer timer = new Timer();
		TimerTask task = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Utils.toAnotherActivity(WelcomeActivity.this, MainActivity.class);
				finish();
			}
		};
		timer.schedule(task, 3000);
	}
}


text:
namespace SilverNeedle.Characters.Prerequisites
{
    using SilverNeedle.Characters.Magic;
    using SilverNeedle.Utility;

    public class IsSpellCaster : IPrerequisite
    {
        public bool IsQualified(ComponentContainer components)
        {
            return components.Contains<ISpellCasting>();
        }
    }
}


text:
using testing::AtLeast;
using testing::Invoke;
using testing::Mock;
using testing::Return;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::WithArg;
using testing::_;

class TestDownloadStatusUpdater : public DownloadStatusUpdater {
 public:
  TestDownloadStatusUpdater() : notification_count_(0),
                                acceptable_notification_item_(NULL) {
  }
  void SetAcceptableNotificationItem(content::DownloadItem* item) {
    acceptable_notification_item_ = item;
  }
  size_t NotificationCount() {
    return notification_count_;
  }
 protected:
  virtual void UpdateAppIconDownloadProgress(
      content::DownloadItem* download) OVERRIDE {
    ++notification_count_;
    if (acceptable_notification_item_)
      EXPECT_EQ(acceptable_notification_item_, download);
  }
 private:
  size_t notification_count_;
  content::DownloadItem* acceptable_notification_item_;
};

class DownloadStatusUpdaterTest : public testing::Test {
 public:
  DownloadStatusUpdaterTest()
      : updater_(new TestDownloadStatusUpdater()),
        ui_thread_(content::BrowserThread::UI, &loop_) {}

  virtual ~DownloadStatusUpdaterTest() {
    for (size_t mgr_idx = 0; mgr_idx < managers_.size(); ++mgr_idx) {
      EXPECT_CALL(*Manager(mgr_idx), RemoveObserver(_));
      for (size_t item_idx = 0; item_idx < manager_items_[mgr_idx].size();
           ++item_idx) {
        EXPECT_CALL(*Item(mgr_idx, item_idx), RemoveObserver(_));
      }
    }

    delete updater_;
    updater_ = NULL;
    VerifyAndClearExpectations();

    managers_.clear();
    for (std::vector<Items>::iterator it = manager_items_.begin();
         it != manager_items_.end(); ++it)
      STLDeleteContainerPointers(it->begin(), it->end());

    loop_.RunUntilIdle();  // Allow DownloadManager destruction.
  }

 protected:
  // Attach some number of DownloadManagers to the updater.
  void SetupManagers(int manager_count) {
    DCHECK_EQ(0U, managers_.size());
    for (int i = 0; i < manager_count; ++i) {
      content::MockDownloadManager* mgr =
          new StrictMock<content::MockDownloadManager>;
      managers_.push_back(mgr);
    }
  }

  void SetObserver(content::DownloadManager::Observer* observer) {
    manager_observers_[manager_observer_index_] = observer;
  }

  // Hook the specified manager into the updater.
  void LinkManager(int i) {
    content::MockDownloadManager* mgr = managers_[i];
    manager_observer_index_ = i;
    while (manager_observers_.size() <= static_cast<size_t>(i)) {
      manager_observers_.push_back(NULL);
    }
    EXPECT_CALL(*mgr, AddObserver(_))
        .WillOnce(WithArg<0>(Invoke(
            this, &DownloadStatusUpdaterTest::SetObserver)));
    updater_->AddManager(mgr);
  }

  // Add some number of Download items to a particular manager.
  void AddItems(int manager_index, int item_count, int in_progress_count) {
    DCHECK_GT(managers_.size(), static_cast<size_t>(manager_index));
    content::MockDownloadManager* manager = managers_[manager_index];

    if (manager_items_.size() <= static_cast<size_t>(manager_index))
      manager_items_.resize(manager_index+1);

    std::vector<content::DownloadItem*> item_list;
    for (int i = 0; i < item_count; ++i) {
      content::MockDownloadItem* item =
          new StrictMock<content::MockDownloadItem>;
      content::DownloadItem::DownloadState state =
          i < in_progress_count ? content::DownloadItem::IN_PROGRESS
              : content::DownloadItem::CANCELLED;
      EXPECT_CALL(*item, GetState()).WillRepeatedly(Return(state));
      EXPECT_CALL(*item, AddObserver(_))
          .WillOnce(Return());
      manager_items_[manager_index].push_back(item);
    }
    EXPECT_CALL(*manager, GetAllDownloads(_))
        .WillRepeatedly(SetArgPointee<0>(manager_items_[manager_index]));
  }

  // Return the specified manager.
  content::MockDownloadManager* Manager(int manager_index) {
    DCHECK_GT(managers_.size(), static_cast<size_t>(manager_index));
    return managers_[manager_index];
  }

  // Return the specified item.
  content::MockDownloadItem* Item(int manager_index, int item_index) {
    DCHECK_GT(manager_items_.size(), static_cast<size_t>(manager_index));
    DCHECK_GT(manager_items_[manager_index].size(),
              static_cast<size_t>(item_index));
    // All DownloadItems in manager_items_ are MockDownloadItems.
    return static_cast<content::MockDownloadItem*>(
        manager_items_[manager_index][item_index]);
  }

  // Set return values relevant to |DownloadStatusUpdater::GetProgress()|
  // for the specified item.
  void SetItemValues(int manager_index, int item_index,
                     int received_bytes, int total_bytes, bool notify) {
    content::MockDownloadItem* item(Item(manager_index, item_index));
    EXPECT_CALL(*item, GetReceivedBytes())
        .WillRepeatedly(Return(received_bytes));
    EXPECT_CALL(*item, GetTotalBytes())
        .WillRepeatedly(Return(total_bytes));
    if (notify)
      updater_->OnDownloadUpdated(managers_[manager_index], item);
  }

  // Transition specified item to completed.
  void CompleteItem(int manager_index, int item_index) {
    content::MockDownloadItem* item(Item(manager_index, item_index));
    EXPECT_CALL(*item, GetState())
        .WillRepeatedly(Return(content::DownloadItem::COMPLETE));
    updater_->OnDownloadUpdated(managers_[manager_index], item);
  }

  // Verify and clear all mocks expectations.
  void VerifyAndClearExpectations() {
    for (ScopedVector<content::MockDownloadManager>::iterator it
             = managers_.begin(); it != managers_.end(); ++it)
      Mock::VerifyAndClearExpectations(*it);
    for (std::vector<Items>::iterator it = manager_items_.begin();
         it != manager_items_.end(); ++it)
      for (Items::iterator sit = it->begin(); sit != it->end(); ++sit)
        Mock::VerifyAndClearExpectations(*sit);
  }

  ScopedVector<content::MockDownloadManager> managers_;
  // DownloadItem so that it can be assigned to the result of SearchDownloads.
  typedef std::vector<content::DownloadItem*> Items;
  std::vector<Items> manager_items_;
  int manager_observer_index_;

  std::vector<content::DownloadManager::Observer*> manager_observers_;

  // Pointer so we can verify that destruction triggers appropriate
  // changes.
  TestDownloadStatusUpdater *updater_;

  // Thread so that the DownloadManager (which is a DeleteOnUIThread
  // object) can be deleted.
  // TODO(rdsmith): This can be removed when the DownloadManager
  // is no longer required to be deleted on the UI thread.
  base::MessageLoop loop_;
  content::TestBrowserThread ui_thread_;
};

// Test null updater.
TEST_F(DownloadStatusUpdaterTest, Basic) {
  float progress = -1;
  int download_count = -1;
  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ(0.0f, progress);
  EXPECT_EQ(0, download_count);
}

// Test updater with null manager.
TEST_F(DownloadStatusUpdaterTest, OneManagerNoItems) {
  SetupManagers(1);
  AddItems(0, 0, 0);
  LinkManager(0);
  VerifyAndClearExpectations();

  float progress = -1;
  int download_count = -1;
  EXPECT_CALL(*managers_[0], GetAllDownloads(_))
      .WillRepeatedly(SetArgPointee<0>(manager_items_[0]));
  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ(0.0f, progress);
  EXPECT_EQ(0, download_count);
}

// Test updater with non-null manager, including transition an item to
// |content::DownloadItem::COMPLETE| and adding a new item.
TEST_F(DownloadStatusUpdaterTest, OneManagerManyItems) {
  SetupManagers(1);
  AddItems(0, 3, 2);
  LinkManager(0);

  // Prime items
  SetItemValues(0, 0, 10, 20, false);
  SetItemValues(0, 1, 50, 60, false);
  SetItemValues(0, 2, 90, 90, false);

  float progress = -1;
  int download_count = -1;
  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ((10+50)/(20.0f+60), progress);
  EXPECT_EQ(2, download_count);

  // Transition one item to completed and confirm progress is updated
  // properly.
  CompleteItem(0, 0);
  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ(50/60.0f, progress);
  EXPECT_EQ(1, download_count);

  // Add a new item to manager and confirm progress is updated properly.
  AddItems(0, 1, 1);
  SetItemValues(0, 3, 150, 200, false);
  manager_observers_[0]->OnDownloadCreated(
      managers_[0], manager_items_[0][manager_items_[0].size()-1]);

  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ((50+150)/(60+200.0f), progress);
  EXPECT_EQ(2, download_count);
}

// Test to ensure that the download progress notification is called correctly.
TEST_F(DownloadStatusUpdaterTest, ProgressNotification) {
  size_t expected_notifications = updater_->NotificationCount();
  SetupManagers(1);
  AddItems(0, 2, 2);
  LinkManager(0);

  // Expect two notifications, one for each item; which item will come first
  // isn't defined so it cannot be tested.
  expected_notifications += 2;
  ASSERT_EQ(expected_notifications, updater_->NotificationCount());

  // Make progress on the first item.
  updater_->SetAcceptableNotificationItem(Item(0, 0));
  SetItemValues(0, 0, 10, 20, true);
  ++expected_notifications;
  ASSERT_EQ(expected_notifications, updater_->NotificationCount());

  // Second item completes!
  updater_->SetAcceptableNotificationItem(Item(0, 1));
  CompleteItem(0, 1);
  ++expected_notifications;
  ASSERT_EQ(expected_notifications, updater_->NotificationCount());

  // First item completes.
  updater_->SetAcceptableNotificationItem(Item(0, 0));
  CompleteItem(0, 0);
  ++expected_notifications;
  ASSERT_EQ(expected_notifications, updater_->NotificationCount());

  updater_->SetAcceptableNotificationItem(NULL);
}

// Confirm we recognize the situation where we have an unknown size.
TEST_F(DownloadStatusUpdaterTest, UnknownSize) {
  SetupManagers(1);
  AddItems(0, 2, 2);
  LinkManager(0);

  // Prime items
  SetItemValues(0, 0, 10, 20, false);
  SetItemValues(0, 1, 50, -1, false);

  float progress = -1;
  int download_count = -1;
  EXPECT_FALSE(updater_->GetProgress(&progress, &download_count));
}

// Test many null managers.
TEST_F(DownloadStatusUpdaterTest, ManyManagersNoItems) {
  SetupManagers(1);
  AddItems(0, 0, 0);
  LinkManager(0);

  float progress = -1;
  int download_count = -1;
  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ(0.0f, progress);
  EXPECT_EQ(0, download_count);
}

// Test many managers with all items complete.
TEST_F(DownloadStatusUpdaterTest, ManyManagersEmptyItems) {
  SetupManagers(2);
  AddItems(0, 3, 0);
  LinkManager(0);
  AddItems(1, 3, 0);
  LinkManager(1);

  float progress = -1;
  int download_count = -1;
  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ(0.0f, progress);
  EXPECT_EQ(0, download_count);
}

// Test many managers with some non-complete items.
TEST_F(DownloadStatusUpdaterTest, ManyManagersMixedItems) {
  SetupManagers(2);
  AddItems(0, 3, 2);
  LinkManager(0);
  AddItems(1, 3, 1);
  LinkManager(1);

  SetItemValues(0, 0, 10, 20, false);
  SetItemValues(0, 1, 50, 60, false);
  SetItemValues(1, 0, 80, 90, false);

  float progress = -1;
  int download_count = -1;
  EXPECT_TRUE(updater_->GetProgress(&progress, &download_count));
  EXPECT_FLOAT_EQ((10+50+80)/(20.0f+60+90), progress);
  EXPECT_EQ(3, download_count);
}


text:
using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanCallUserExpression: Plan to call a single function
//----------------------------------------------------------------------

ThreadPlanCallUserExpression::ThreadPlanCallUserExpression (Thread &thread,
                                                Address &function,
                                                lldb::addr_t arg,
                                                bool stop_other_threads,
                                                bool unwind_on_error,
                                                bool ignore_breakpoints,
                                                lldb::addr_t *this_arg,
                                                lldb::addr_t *cmd_arg,
                                                ClangUserExpression::ClangUserExpressionSP &user_expression_sp) :
    ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, unwind_on_error, ignore_breakpoints, this_arg, cmd_arg),
    m_user_expression_sp (user_expression_sp)
{
    // User expressions are generally "User generated" so we should set them up to stop when done.
    SetIsMasterPlan (true);
    SetOkayToDiscard(false);
}

ThreadPlanCallUserExpression::~ThreadPlanCallUserExpression ()
{
}

void
ThreadPlanCallUserExpression::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    ThreadPlanCallFunction::GetDescription (s, level);
}

StopInfoSP
ThreadPlanCallUserExpression::GetRealStopInfo()
{
    StopInfoSP stop_info_sp = ThreadPlanCallFunction::GetRealStopInfo();

    if (stop_info_sp)
    {
        lldb::addr_t addr = GetStopAddress();
        DynamicCheckerFunctions *checkers = m_thread.GetProcess()->GetDynamicCheckers();
        StreamString s;

        if (checkers && checkers->DoCheckersExplainStop(addr, s))
            stop_info_sp->SetDescription(s.GetData());
    }

    return stop_info_sp;
}


text:
import { TabNavigator, StackNavigator } from 'react-navigation'

import React from 'react'

import HomeIndex from '../view/home/';
import InfoIndex from '../view/info/';
import Detail from '../view/home/detail/';
import Movie from '../view/home/movie/';
import ImageShow from '../view/home/ImageShow';
import Login from '../view/info/login/';
import MyInfo from '../view/info/myInfo/';

const Tabs = TabNavigator({
  home: {
    screen: HomeIndex,
  },
  info: {
    screen: InfoIndex,
  }
}, {
  animationEnabled: false,
  swipeEnabled: true,
  tabBarOptions: {
    activeTintColor: '#e25800',
    showIcon: true,
    mode: 'card',
    indicatorStyle: {
      height: 0
    },
    style: {
      backgroundColor: '#fff',
    },
  },
  tabBarPosition: 'bottom'
})

const Navigator = StackNavigator({
  tabs: {screen: Tabs},
  detail: {screen: Detail},
  login: {screen: Login},
  myInfo: {screen: MyInfo},
  movie: {screen: Movie},
  img: {screen: ImageShow},
}, {
  initialRouteName: 'tabs',
  cardStyle: {
    backgroundColor: '#F1F1F1'
  },
  headerMode: 'screen'
})

export default Navigator


text:
function SSH {
  env ssh -o StrictHostKeyChecking=no -o GSSAPIAuthentication=no \
      -o UserKnownHostsFile=/dev/null $@
}

function ssh_execute {
  local login=$1
  local cmds=$2 # a string of commands separated by ';'
  if [ -z "$login" ] || [ -z "$cmds" ]; then
    echo "#Usage: ssh_execute user@host 'cmd1 ; cmd2 ; cmd3 ; ...'"
    return
  fi
  echo "#Info: executing SSH $login $cmds"
  # N.B.:
  # 1. Quoting "$cmds" considered necessary
  # 2. '-t' specified to force tty allocation (for sudo commands)
  SSH -t $login "$cmds"
}

# set ip-host binding in /etc/hosts in ssh host.
function ssh_set_ip_host_binding {
  local ip=$1
  local host=$2
  if [ -z "$ip" ] || [ -z "$host" ] || \
     ! echo $host | grep '^[0-9A-Za-z\.-]*$' >/dev/null; then
    echo \
"Usage: ssh_set_ip_host_binding ip host-name [ user@host ],
  whereas 'user' defaults to current user and 'host' defaults to localhost.
Also, the host-name shall only contain characters from [0-9A-Za-z\.-]."
    return
  fi
  # The param $login is of the format 'user@host', or 'host' (user is the one
  # running this command), or null (interpreted as localhost). On modern
  # UNIX-like hosts, system commands are supposed to be executed as sudo,
  # therefore we execute commands here by 'sudo bash -c "commands"'. When login
  # is root@host, sudo asks no password and everything is OK.
  local login=$3
  if [ -z "$login" ]; then
    login='localhost'
  fi
  # remove any entry

  local c1="grep -v \"^[0-9].*$host$\" /etc/hosts > /tmp/hosts"
  # add new entry
  local entry="$ip $host"
  local c2="echo -e $entry >> /tmp/hosts"
  local c3="if grep \"$entry\" /tmp/hosts >/dev/null; then mv /tmp/hosts /etc/hosts ; fi"
  local c="$c1; $c2; $c3"
  ssh_execute $login "sudo bash -c '$c'"
}

# install my ssh key in remote computer to allow ssh login without password
function ssh_install_key {
  local dir=.ssh
  local ak=$dir/authorized_keys
  local login=$1
  if [ -z "$login" ] ; then
    login='localhost'
  fi
  local key=`ls ~/$dir/*.pub 2>/dev/null | head -n 1`
  if [ -z "$key" ] ; then
    ssh-keygen # do keygen only if necessary
  fi
  local key=`ls ~/$dir/*.pub 2>/dev/null | head -n 1`
  if [ -z "$key" ] ; then
    echo "#Error: cannot find ssh key file in ~/.ssh after ssh-keygen attempt."
    return
  fi
  local c1="mkdir $dir 1>/dev/null 2>/dev/null"
  local c2="echo '$(cat $key)' >> $ak"
  local c3="chmod 700 $dir"
  local c4="chmod 600 $ak"
  ssh_execute $login "$c1 ; $c2 ; $c3 ; $c4"
}

# set hostname of the ssh host
function ssh_set_hostname {
  local ip=$1
  local name=$2
  local user=root # setting hostname requires root; so default to root
  if [ -z "$ip" ] || [ -z "$name" ]; then
    echo "#Usage: ssh_set_hostname ip host-name"
    return
  fi
  local c1="hostname $name"
  local c2="echo '$name' > /etc/hostname"
  local c3="echo '127.0.0.1 $name' >> /etc/hosts"
  local c4="echo '::1 $name' >> /etc/hosts"
  ssh_execute $user@$ip "$c1 ; $c2 ; $c3 ; $c4"
}

function ssh_set_password {
  local login="$1"
  local user="$2"
  local password="$3"
  if [ -z "$login" ] || [ -z "$user" ] || [ -z "$password" ]; then
    echo "#Usage: ssh_set_password user@host user password-string"
    return
  fi
  ssh_execute $login "echo $password | passwd --stdin $user"
}