Bug 1018504 - (Part 2) Mute/unmute tab when tapping audio indicator. r=mhaigh
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Fri, 31 Jul 2015 11:32:46 -0700
changeset 287593 23e480296ddcfdea0cf7950b22d88d3c70a29297
parent 287592 d065e876a83b7903f87b54cb2f1ea7c6fd157ba7
child 287594 e85843f65f893fed86c5455a505283e37f47cb9c
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhaigh
bugs1018504
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1018504 - (Part 2) Mute/unmute tab when tapping audio indicator. r=mhaigh
mobile/android/base/tabs/TabStripItemView.java
mobile/android/base/tabs/TabsLayoutItemView.java
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/tabs/TabStripItemView.java
+++ b/mobile/android/base/tabs/TabStripItemView.java
@@ -1,42 +1,47 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.tabs;
 
 import org.mozilla.gecko.AboutPages;
+import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
 import org.mozilla.gecko.widget.ResizablePathDrawable;
 import org.mozilla.gecko.widget.ResizablePathDrawable.NonScaledPathShape;
 import org.mozilla.gecko.widget.ThemedImageButton;
 import org.mozilla.gecko.widget.ThemedLinearLayout;
 import org.mozilla.gecko.widget.ThemedTextView;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.Region;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.Checkable;
 import android.widget.ImageView;
 
 public class TabStripItemView extends ThemedLinearLayout
                               implements Checkable {
-    @SuppressWarnings("unused")
     private static final String LOGTAG = "GeckoTabStripItem";
 
     private static final int[] STATE_CHECKED = {
         android.R.attr.state_checked
     };
 
     private int id = -1;
     private boolean checked;
@@ -98,16 +103,33 @@ public class TabStripItemView extends Th
                 }
 
                 final Tabs tabs = Tabs.getInstance();
                 tabs.closeTab(tabs.getTab(id), true);
             }
         });
 
         audioPlayingView = (ThemedImageButton) findViewById(R.id.audio_playing);
+        audioPlayingView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (id < 0) {
+                    throw new IllegalStateException("Invalid tab id:" + id);
+                }
+
+                // TODO: Toggle icon in the UI as well (bug 1190301)
+                final JSONObject args = new JSONObject();
+                try {
+                    args.put("tabId", id);
+                    GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:ToggleMuteAudio", args.toString()));
+                } catch (JSONException e) {
+                    Log.e(LOGTAG, "Error toggling mute audio: error building json arguments", e);
+                }
+            }
+        });
     }
 
     @Override
     protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
         super.onSizeChanged(width, height, oldWidth, oldHeight);
 
         // Queue a tab region update in the next draw() call. We don't
         // update it immediately here because we need the new path from
--- a/mobile/android/base/tabs/TabsLayoutItemView.java
+++ b/mobile/android/base/tabs/TabsLayoutItemView.java
@@ -1,23 +1,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.tabs;
 
+import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.widget.TabThumbnailWrapper;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.TypedValue;
 import android.view.TouchDelegate;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.widget.Checkable;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -95,16 +101,34 @@ public class TabsLayoutItemView extends 
         mThumbnail = (ImageView) findViewById(R.id.thumbnail);
         mCloseButton = (ImageView) findViewById(R.id.close);
         mAudioPlayingButton = (ImageView) findViewById(R.id.audio_playing);
         mThumbnailWrapper = (TabThumbnailWrapper) findViewById(R.id.wrapper);
 
         if (HardwareUtils.isTablet()) {
             growCloseButtonHitArea();
         }
+
+        mAudioPlayingButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mTabId < 0) {
+                    throw new IllegalStateException("Invalid tab id:" + mTabId);
+                }
+
+                // TODO: Toggle icon in the UI as well (bug 1190301)
+                final JSONObject args = new JSONObject();
+                try {
+                    args.put("tabId", mTabId);
+                    GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:ToggleMuteAudio", args.toString()));
+                } catch (JSONException e) {
+                    Log.e(LOGTAG, "Error toggling mute audio: error building json arguments", e);
+                }
+            }
+        });
     }
 
     private void growCloseButtonHitArea() {
         getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
             @Override
             public boolean onPreDraw() {
                 getViewTreeObserver().removeOnPreDrawListener(this);
 
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -447,16 +447,17 @@ var BrowserApp = {
 
     Services.androidBridge.browserApp = this;
 
     Services.obs.addObserver(this, "Locale:OS", false);
     Services.obs.addObserver(this, "Locale:Changed", false);
     Services.obs.addObserver(this, "Tab:Load", false);
     Services.obs.addObserver(this, "Tab:Selected", false);
     Services.obs.addObserver(this, "Tab:Closed", false);
+    Services.obs.addObserver(this, "Tab:ToggleMuteAudio", false);
     Services.obs.addObserver(this, "Session:Back", false);
     Services.obs.addObserver(this, "Session:Forward", false);
     Services.obs.addObserver(this, "Session:Navigate", false);
     Services.obs.addObserver(this, "Session:Reload", false);
     Services.obs.addObserver(this, "Session:Stop", false);
     Services.obs.addObserver(this, "SaveAs:PDF", false);
     Services.obs.addObserver(this, "Browser:Quit", false);
     Services.obs.addObserver(this, "Preferences:Set", false);
@@ -1859,16 +1860,23 @@ var BrowserApp = {
         break;
 
       case "Tab:Closed": {
         let data = JSON.parse(aData);
         this._handleTabClosed(this.getTabForId(data.tabId), data.showUndoToast);
         break;
       }
 
+      case "Tab:ToggleMuteAudio": {
+        let data = JSON.parse(aData);
+        let tab = this.getTabForId(data.tabId);
+        tab.toggleMuteAudio();
+        break;
+      }
+
       case "keyword-search":
         // This event refers to a search via the URL bar, not a bookmarks
         // keyword search. Note that this code assumes that the user can only
         // perform a keyword search on the selected tab.
         this.selectedTab.isSearch = true;
 
         // Don't store queries in private browsing mode.
         let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.selectedTab.browser);
@@ -4242,16 +4250,24 @@ Tab.prototype = {
           type: "Link:OpenSearch",
           tabID: this.id,
           visible: true
         };
       });
     }
   },
 
+  toggleMuteAudio: function() {
+    if (this.browser.audioMuted) {
+      this.browser.unmute();
+    } else {
+      this.browser.mute();
+    }
+  },
+
   handleEvent: function(aEvent) {
     switch (aEvent.type) {
       case "DOMContentLoaded": {
         let target = aEvent.originalTarget;
 
         // ignore on frames and other documents
         if (target != this.browser.contentDocument)
           return;