merge fx-team to mozilla-central a=merge
@ -821,26 +821,26 @@ pref("plugin.state.f5 sam inspection host plugin", 2);
|
||||
pref("plugin.state.nprobloxproxy", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugins.state.nproblox", 2);
|
||||
pref("plugin.state.nproblox", 2);
|
||||
#endif
|
||||
|
||||
// Box Edit, bug 1029654
|
||||
#ifdef XP_WIN
|
||||
pref("plugins.state.npboxedit", 2);
|
||||
pref("plugin.state.npboxedit", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugins.state.box edit", 2);
|
||||
pref("plugin.state.box edit", 2);
|
||||
#endif
|
||||
|
||||
// Nexus Personal, bug 1024965
|
||||
#ifdef XP_WIN
|
||||
pref("plugins.state.np_prsnl", 2);
|
||||
pref("plugin.state.np_prsnl", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugins.state.personalplugin", 2);
|
||||
pref("plugin.state.personalplugin", 2);
|
||||
#endif
|
||||
#ifdef UNIX_BUT_NOT_MAC
|
||||
pref("plugins.state.libplugins", 2);
|
||||
pref("plugin.state.libplugins", 2);
|
||||
#endif
|
||||
|
||||
// display door hanger if flash not installed
|
||||
|
@ -464,11 +464,12 @@ SocialShare = {
|
||||
return;
|
||||
this.panel.hidden = false;
|
||||
// create and initialize the panel for this window
|
||||
let iframe = document.createElement("iframe");
|
||||
let iframe = document.createElement("browser");
|
||||
iframe.setAttribute("type", "content");
|
||||
iframe.setAttribute("class", "social-share-frame");
|
||||
iframe.setAttribute("context", "contentAreaContextMenu");
|
||||
iframe.setAttribute("tooltip", "aHTMLTooltip");
|
||||
iframe.setAttribute("disableglobalhistory", "true");
|
||||
iframe.setAttribute("flex", "1");
|
||||
panel.appendChild(iframe);
|
||||
this.populateProviderMenu();
|
||||
@ -591,7 +592,15 @@ SocialShare = {
|
||||
this.anchor.removeAttribute("open");
|
||||
this.iframe.removeEventListener("click", this._onclick, true);
|
||||
this.iframe.setAttribute("src", "data:text/plain;charset=utf8,");
|
||||
// make sure that the frame is unloaded after it is hidden
|
||||
this.iframe.docShell.createAboutBlankContentViewer(null);
|
||||
this.currentShare = null;
|
||||
// share panel use is over, purge any history
|
||||
if (this.iframe.sessionHistory) {
|
||||
let purge = this.iframe.sessionHistory.count;
|
||||
if (purge > 0)
|
||||
this.iframe.sessionHistory.PurgeHistory(purge);
|
||||
}
|
||||
},
|
||||
|
||||
setErrorMessage: function() {
|
||||
@ -702,6 +711,14 @@ SocialShare = {
|
||||
iframe.contentDocument.documentElement.dispatchEvent(evt);
|
||||
}, true);
|
||||
}
|
||||
// if the user switched between share providers we do not want that history
|
||||
// available.
|
||||
if (iframe.sessionHistory) {
|
||||
let purge = iframe.sessionHistory.count;
|
||||
if (purge > 0)
|
||||
iframe.sessionHistory.PurgeHistory(purge);
|
||||
}
|
||||
|
||||
// always ensure that origin belongs to the endpoint
|
||||
let uri = Services.io.newURI(shareEndpoint, null, null);
|
||||
iframe.setAttribute("origin", provider.origin);
|
||||
|
@ -81,7 +81,7 @@ function runSocialTestWithProvider(manifest, callback, finishcallback) {
|
||||
SessionStore.setWindowValue(window, "socialSidebar", "");
|
||||
for (let i = 0; i < manifests.length; i++) {
|
||||
let m = manifests[i];
|
||||
for (let what of ['sidebarURL', 'workerURL', 'iconURL']) {
|
||||
for (let what of ['sidebarURL', 'workerURL', 'iconURL', 'shareURL', 'markURL']) {
|
||||
if (m[what]) {
|
||||
yield promiseSocialUrlNotRemembered(m[what]);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
var port = navigator.mozSocial.getWorker().port;
|
||||
port.postMessage({topic: "share-data-message", result: shareData});
|
||||
// share windows self-close
|
||||
history.back(); // bug 1042991, ensure history is available
|
||||
window.close();
|
||||
})
|
||||
</script>
|
||||
|
@ -236,10 +236,17 @@ var gPermissionManager = {
|
||||
}
|
||||
this._tree.treeBoxObject.invalidate();
|
||||
}
|
||||
// No UI other than this window causes this method to be sent a "deleted"
|
||||
// notification, so we don't need to implement it since Delete is handled
|
||||
// directly by the Permission Removal handlers. If that ever changes, those
|
||||
// implementations will have to move into here.
|
||||
else if (aData == "deleted") {
|
||||
for (var i = 0; i < this._permissions.length; i++) {
|
||||
if (this._permissions[i].host == permission.host) {
|
||||
this._permissions.splice(i, 1);
|
||||
this._view._rowCount--;
|
||||
this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, -1);
|
||||
this._tree.treeBoxObject.invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -114,6 +114,17 @@ function windowLoad(event, win, dialog) {
|
||||
pm.remove("test.com", "popup");
|
||||
},
|
||||
},
|
||||
{
|
||||
test: function() {
|
||||
url.value = "test.com";
|
||||
btnAllow.doCommand();
|
||||
pm.remove("test.com", "cookie");
|
||||
is(tree.view.rowCount, 0, "display should update when cookie permission is deleted");
|
||||
},
|
||||
observances: [{ type: "cookie", host: "test.com", data: "added",
|
||||
capability: allow },
|
||||
{ type: "cookie", host: "test.com", data: "deleted" }]
|
||||
},
|
||||
];
|
||||
|
||||
let permObserver = {
|
||||
|
@ -14,6 +14,7 @@ import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.menu.MenuItemActionBar;
|
||||
import org.mozilla.gecko.menu.MenuItemDefault;
|
||||
import org.mozilla.gecko.tests.UITestContext;
|
||||
import org.mozilla.gecko.tests.helpers.DeviceHelper;
|
||||
import org.mozilla.gecko.tests.helpers.WaitHelper;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
|
||||
@ -27,9 +28,12 @@ import com.jayway.android.robotium.solo.Solo;
|
||||
* A class representing any interactions that take place on the app menu.
|
||||
*/
|
||||
public class AppMenuComponent extends BaseComponent {
|
||||
private Boolean hasLegacyMenu = null;
|
||||
|
||||
public enum MenuItem {
|
||||
FORWARD(R.string.forward),
|
||||
NEW_TAB(R.string.new_tab),
|
||||
PAGE(R.string.page),
|
||||
RELOAD(R.string.reload);
|
||||
|
||||
private final int resourceID;
|
||||
@ -48,6 +52,27 @@ public class AppMenuComponent extends BaseComponent {
|
||||
}
|
||||
};
|
||||
|
||||
public enum PageMenuItem {
|
||||
SAVE_AS_PDF(R.string.save_as_pdf);
|
||||
|
||||
private static final MenuItem PARENT_MENU = MenuItem.PAGE;
|
||||
|
||||
private final int resourceID;
|
||||
private String stringResource;
|
||||
|
||||
PageMenuItem(final int resourceID) {
|
||||
this.resourceID = resourceID;
|
||||
}
|
||||
|
||||
public String getString(final Solo solo) {
|
||||
if (stringResource == null) {
|
||||
stringResource = solo.getString(resourceID);
|
||||
}
|
||||
|
||||
return stringResource;
|
||||
}
|
||||
};
|
||||
|
||||
public AppMenuComponent(final UITestContext testContext) {
|
||||
super(testContext);
|
||||
}
|
||||
@ -56,6 +81,54 @@ public class AppMenuComponent extends BaseComponent {
|
||||
fAssertFalse("Menu is not open", isMenuOpen());
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy Android devices doesn't have hierarchical menus. Sub-menus, such as "Page", are missing in these devices.
|
||||
* Try to determine if the menu item "Page" is present.
|
||||
*
|
||||
* TODO : This fragile way to determine legacy menus should be replaced with a check for 6-panel menu item.
|
||||
*
|
||||
* @return true if there is a legacy menu.
|
||||
*/
|
||||
private boolean hasLegacyMenu() {
|
||||
if (hasLegacyMenu == null) {
|
||||
hasLegacyMenu = findAppMenuItemView(MenuItem.PAGE.getString(mSolo)) == null;
|
||||
}
|
||||
|
||||
return hasLegacyMenu;
|
||||
}
|
||||
|
||||
public void assertMenuItemIsDisabledAndVisible(PageMenuItem pageMenuItem) {
|
||||
openAppMenu();
|
||||
|
||||
if (!hasLegacyMenu()) {
|
||||
// Non-legacy devices have hierarchical menu, check for parent menu item "page".
|
||||
final View parentMenuItemView = findAppMenuItemView(MenuItem.PAGE.getString(mSolo));
|
||||
if (parentMenuItemView.isEnabled()) {
|
||||
fAssertTrue("The parent 'page' menu item is enabled", parentMenuItemView.isEnabled());
|
||||
fAssertEquals("The parent 'page' menu item is visible", View.VISIBLE,
|
||||
parentMenuItemView.getVisibility());
|
||||
|
||||
// Parent menu "page" is enabled, open page menu and check for menu item represented by pageMenuItem.
|
||||
pressMenuItem(MenuItem.PAGE.getString(mSolo));
|
||||
|
||||
final View pageMenuItemView = findAppMenuItemView(pageMenuItem.getString(mSolo));
|
||||
fAssertFalse("The page menu item is not enabled", pageMenuItemView.isEnabled());
|
||||
fAssertEquals("The page menu item is visible", View.VISIBLE, pageMenuItemView.getVisibility());
|
||||
} else {
|
||||
fAssertFalse("The parent 'page' menu item is not enabled", parentMenuItemView.isEnabled());
|
||||
fAssertEquals("The parent 'page' menu item is visible", View.VISIBLE, parentMenuItemView.getVisibility());
|
||||
}
|
||||
} else {
|
||||
// Legacy devices don't have parent menu item "page", check for menu item represented by pageMenuItem.
|
||||
final View pageMenuItemView = findAppMenuItemView(pageMenuItem.getString(mSolo));
|
||||
fAssertFalse("The page menu item is not enabled", pageMenuItemView.isEnabled());
|
||||
fAssertEquals("The page menu item is visible", View.VISIBLE, pageMenuItemView.getVisibility());
|
||||
}
|
||||
|
||||
// Close the App Menu.
|
||||
mSolo.goBack();
|
||||
}
|
||||
|
||||
private View getOverflowMenuButtonView() {
|
||||
return mSolo.getView(R.id.menu);
|
||||
}
|
||||
@ -87,32 +160,61 @@ public class AppMenuComponent extends BaseComponent {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void pressMenuItem(MenuItem menuItem) {
|
||||
openAppMenu();
|
||||
/**
|
||||
* Helper function to let Robotium locate and click menu item from legacy Android menu (devices with Android 2.x).
|
||||
*
|
||||
* Robotium will also try to open the menu if there are no open dialog.
|
||||
*
|
||||
* @param menuItemText, The title of menu item to open.
|
||||
*/
|
||||
private void pressLegacyMenuItem(final String menuItemTitle) {
|
||||
mSolo.clickOnMenuItem(menuItemTitle, true);
|
||||
}
|
||||
|
||||
final String text = menuItem.getString(mSolo);
|
||||
final View menuItemView = findAppMenuItemView(text);
|
||||
private void pressMenuItem(final String menuItemTitle) {
|
||||
fAssertTrue("Menu is open", isMenuOpen(menuItemTitle));
|
||||
|
||||
if (menuItemView != null) {
|
||||
fAssertTrue("The menu item is enabled", menuItemView.isEnabled());
|
||||
fAssertEquals("The menu item is visible", View.VISIBLE, menuItemView.getVisibility());
|
||||
if (!hasLegacyMenu()) {
|
||||
final View menuItemView = findAppMenuItemView(menuItemTitle);
|
||||
|
||||
fAssertTrue(String.format("The menu item %s is enabled", menuItemTitle), menuItemView.isEnabled());
|
||||
fAssertEquals(String.format("The menu item %s is visible", menuItemTitle), View.VISIBLE,
|
||||
menuItemView.getVisibility());
|
||||
|
||||
mSolo.clickOnView(menuItemView);
|
||||
} else {
|
||||
// We could not find a view representing this menu item: Let's let Robotium try to
|
||||
// locate and click it in the legacy Android menu (devices with Android 2.x).
|
||||
//
|
||||
// Even though we already opened the menu to see if we can locate the menu item,
|
||||
// Robotium will also try to open the menu if it doesn't find an open dialog (Does
|
||||
// not happen in this case).
|
||||
mSolo.clickOnMenuItem(text, true);
|
||||
pressLegacyMenuItem(menuItemTitle);
|
||||
}
|
||||
}
|
||||
|
||||
private void pressSubMenuItem(final String parentMenuItemTitle, final String childMenuItemTitle) {
|
||||
openAppMenu();
|
||||
|
||||
if (!hasLegacyMenu()) {
|
||||
pressMenuItem(parentMenuItemTitle);
|
||||
|
||||
// Child menu item is not pressed yet, Click on it.
|
||||
pressMenuItem(childMenuItemTitle);
|
||||
} else {
|
||||
pressLegacyMenuItem(childMenuItemTitle);
|
||||
}
|
||||
}
|
||||
|
||||
public void pressMenuItem(MenuItem menuItem) {
|
||||
openAppMenu();
|
||||
pressMenuItem(menuItem.getString(mSolo));
|
||||
}
|
||||
|
||||
public void pressMenuItem(final PageMenuItem pageMenuItem) {
|
||||
pressSubMenuItem(PageMenuItem.PARENT_MENU.getString(mSolo), pageMenuItem.getString(mSolo));
|
||||
}
|
||||
|
||||
private void openAppMenu() {
|
||||
assertMenuIsNotOpen();
|
||||
|
||||
if (HardwareUtils.hasMenuButton()) {
|
||||
// This is a hack needed for tablets where the OverflowMenuButton is always in the GONE state,
|
||||
// so we press the menu key instead.
|
||||
if (HardwareUtils.hasMenuButton() || DeviceHelper.isTablet()) {
|
||||
mSolo.sendKey(Solo.MENU);
|
||||
} else {
|
||||
pressOverflowMenuButton();
|
||||
@ -130,10 +232,24 @@ public class AppMenuComponent extends BaseComponent {
|
||||
mSolo.clickOnView(overflowMenuButton, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the app menu is open by searching for the text "New tab".
|
||||
*
|
||||
* @return true if app menu is open.
|
||||
*/
|
||||
private boolean isMenuOpen() {
|
||||
// The presence of the "New tab" menu item is our best guess about whether
|
||||
// the menu is open or not.
|
||||
return mSolo.searchText(MenuItem.NEW_TAB.getString(mSolo));
|
||||
return isMenuOpen(MenuItem.NEW_TAB.getString(mSolo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the app menu is open by searching for the text in menuItemTitle.
|
||||
*
|
||||
* @param menuItemTitle, The contentDescription of menu item to search.
|
||||
*
|
||||
* @return true if app menu is open.
|
||||
*/
|
||||
private boolean isMenuOpen(String menuItemTitle) {
|
||||
return mSolo.searchText(menuItemTitle);
|
||||
}
|
||||
|
||||
private void waitForMenuOpen() {
|
||||
|
@ -122,6 +122,7 @@ skip-if = android_version == "10"
|
||||
[testAboutHomeVisibility]
|
||||
# disabled on Android 2.3; bug 946656
|
||||
skip-if = android_version == "10"
|
||||
[testAppMenuPathways]
|
||||
[testEventDispatcher]
|
||||
[testInputConnection]
|
||||
# disabled on Android 2.3; bug 1025968
|
||||
|
34
mobile/android/base/tests/testAppMenuPathways.java
Normal file
@ -0,0 +1,34 @@
|
||||
package org.mozilla.gecko.tests;
|
||||
|
||||
import org.mozilla.gecko.tests.components.AppMenuComponent;
|
||||
import org.mozilla.gecko.tests.helpers.GeckoHelper;
|
||||
import org.mozilla.gecko.tests.helpers.NavigationHelper;
|
||||
|
||||
/**
|
||||
* Set of tests to test UI App menu and submenus the user interact with.
|
||||
*/
|
||||
public class testAppMenuPathways extends UITest {
|
||||
|
||||
/**
|
||||
* Robocop supports only a single test function per test class. Therefore, we
|
||||
* have a single top-level test function that dispatches to sub-tests.
|
||||
*/
|
||||
public void testAppMenuPathways() {
|
||||
GeckoHelper.blockForReady();
|
||||
|
||||
_testSaveAsPDFPathway();
|
||||
}
|
||||
|
||||
public void _testSaveAsPDFPathway() {
|
||||
// Page menu should be disabled in about:home.
|
||||
mAppMenu.assertMenuItemIsDisabledAndVisible(AppMenuComponent.PageMenuItem.SAVE_AS_PDF);
|
||||
|
||||
// Navigate to a page to test save as pdf functionality.
|
||||
NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
|
||||
mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
|
||||
|
||||
// Test save as pdf functionality.
|
||||
// The following call doesn't wait for the resulting pdf but checks that no exception are thrown.
|
||||
mAppMenu.pressMenuItem(AppMenuComponent.PageMenuItem.SAVE_AS_PDF);
|
||||
}
|
||||
}
|
@ -25,4 +25,6 @@ public class Constants {
|
||||
|
||||
public static final String INTENT_START_SEARCH = "org.mozilla.search.intent.START_SEARCH";
|
||||
public static final String INTENT_START_SEARCH_QUERY_EXTRA = "org.mozilla.search.intent.START_SEARCH_QUERY_EXTRA";
|
||||
|
||||
public static final int SUGGESTION_MAX = 5;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
@ -21,6 +22,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserContract.SearchHistory;
|
||||
import org.mozilla.search.AcceptsSearchQuery.SuggestionAnimation;
|
||||
|
||||
@ -34,7 +36,12 @@ public class PreSearchFragment extends Fragment {
|
||||
|
||||
private ListView listView;
|
||||
|
||||
private final String[] PROJECTION = new String[]{SearchHistory.QUERY, SearchHistory._ID};
|
||||
private static final String[] PROJECTION = new String[]{ SearchHistory.QUERY, SearchHistory._ID };
|
||||
|
||||
// Limit search history query results to 5 items. This value matches the number of search
|
||||
// suggestions we return in SearchFragment.
|
||||
private static final Uri SEARCH_HISTORY_URI = SearchHistory.CONTENT_URI.buildUpon().
|
||||
appendQueryParameter(BrowserContract.PARAM_LIMIT, String.valueOf(Constants.SUGGESTION_MAX)).build();
|
||||
|
||||
private static final int LOADER_ID_SEARCH_HISTORY = 1;
|
||||
|
||||
@ -128,8 +135,8 @@ public class PreSearchFragment extends Fragment {
|
||||
private class SearchHistoryLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
return new CursorLoader(getActivity(), SearchHistory.CONTENT_URI,
|
||||
PROJECTION, null, null, SearchHistory.DATE_LAST_VISITED + " DESC");
|
||||
return new CursorLoader(getActivity(), SEARCH_HISTORY_URI, PROJECTION, null, null,
|
||||
SearchHistory.DATE_LAST_VISITED + " DESC");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
124
mobile/android/search/java/org/mozilla/search/SearchWidget.java
Normal file
@ -0,0 +1,124 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; 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.search;
|
||||
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.widget.RemoteViews;
|
||||
import android.util.Log;
|
||||
|
||||
/* Provides a really simple widget with two buttons, one to launch Fennec
|
||||
* and one to launch the search activity. All intents are actually sent back
|
||||
* here and then forwarded on to start the real activity. */
|
||||
public class SearchWidget extends AppWidgetProvider {
|
||||
final private static String LOGTAG = "GeckoSearchWidget";
|
||||
|
||||
final public static String ACTION_LAUNCH_BROWSER = "org.mozilla.widget.LAUNCH_BROWSER";
|
||||
final public static String ACTION_LAUNCH_SEARCH = "org.mozilla.widget.LAUNCH_SEARCH";
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onUpdate(final Context context, final AppWidgetManager manager, final int[] ids) {
|
||||
for (int id : ids) {
|
||||
final Bundle bundle;
|
||||
if (AppConstants.Versions.feature16Plus) {
|
||||
bundle = manager.getAppWidgetOptions(id);
|
||||
} else {
|
||||
bundle = null;
|
||||
}
|
||||
addView(manager, context, id, bundle);
|
||||
}
|
||||
|
||||
super.onUpdate(context, manager, ids);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onAppWidgetOptionsChanged(final Context context,
|
||||
final AppWidgetManager manager,
|
||||
final int id,
|
||||
final Bundle options) {
|
||||
addView(manager, context, id, options);
|
||||
if (AppConstants.Versions.feature16Plus) {
|
||||
super.onAppWidgetOptionsChanged(context, manager, id, options);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
// This will hold the intent to redispatch
|
||||
final Intent redirect;
|
||||
Log.i(LOGTAG, "Got intent " + intent.getAction());
|
||||
if (intent.getAction().equals(ACTION_LAUNCH_BROWSER)) {
|
||||
redirect = buildRedirectIntent(Intent.ACTION_VIEW,
|
||||
AppConstants.ANDROID_PACKAGE_NAME,
|
||||
AppConstants.BROWSER_INTENT_CLASS_NAME,
|
||||
intent);
|
||||
} else if (intent.getAction().equals(ACTION_LAUNCH_SEARCH)) {
|
||||
redirect = buildRedirectIntent(Intent.ACTION_VIEW,
|
||||
AppConstants.SEARCH_PACKAGE_NAME,
|
||||
AppConstants.SEARCH_INTENT_CLASS_NAME,
|
||||
intent);
|
||||
} else {
|
||||
redirect = null;
|
||||
}
|
||||
|
||||
if (redirect != null) {
|
||||
try {
|
||||
context.startActivity(redirect);
|
||||
} catch(Exception ex) {
|
||||
// When this is built stand alone, its hardcoded to try and launch nightly.
|
||||
// If that fails, just fire a generic VIEW intent.
|
||||
Intent redirect2 = buildRedirectIntent(Intent.ACTION_VIEW, null, null, intent);
|
||||
context.startActivity(redirect2);
|
||||
}
|
||||
}
|
||||
|
||||
super.onReceive(context, intent);
|
||||
}
|
||||
|
||||
// Utility to create the view for this widget and attach any event listeners to it
|
||||
private void addView(final AppWidgetManager manager, final Context context, final int id, final Bundle options) {
|
||||
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.search_widget);
|
||||
|
||||
addClickIntent(context, views, R.id.search_button, ACTION_LAUNCH_SEARCH);
|
||||
addClickIntent(context, views, R.id.new_tab_button, ACTION_LAUNCH_BROWSER);
|
||||
// Clicking the logo also launches the browser
|
||||
addClickIntent(context, views, R.id.logo_button, ACTION_LAUNCH_BROWSER);
|
||||
|
||||
manager.updateAppWidget(id, views);
|
||||
}
|
||||
|
||||
// Utility for adding a pending intent to be fired when a View is clicked.
|
||||
private void addClickIntent(final Context context, final RemoteViews views, final int viewId, final String action) {
|
||||
final Intent intent = new Intent(context, SearchWidget.class);
|
||||
intent.setAction(action);
|
||||
intent.setData(Uri.parse("about:home"));
|
||||
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||
views.setOnClickPendingIntent(viewId, pendingIntent);
|
||||
}
|
||||
|
||||
// Utility for building an intent to be redispatched (i.e. to launch the browser or the search intent).
|
||||
private Intent buildRedirectIntent(final String action, final String pkg, final String className, final Intent source) {
|
||||
final Intent activity = new Intent(action);
|
||||
if (pkg != null && className != null) {
|
||||
activity.setClassName(pkg, className);
|
||||
}
|
||||
activity.setData(source.getData());
|
||||
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
return activity;
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,7 @@ import android.widget.ListView;
|
||||
|
||||
import org.mozilla.search.AcceptsSearchQuery;
|
||||
import org.mozilla.search.AcceptsSearchQuery.SuggestionAnimation;
|
||||
import org.mozilla.search.Constants;
|
||||
import org.mozilla.search.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -41,9 +42,6 @@ public class SearchFragment extends Fragment implements AcceptsJumpTaps {
|
||||
// Timeout for the suggestion client to respond
|
||||
private static final int SUGGESTION_TIMEOUT = 3000;
|
||||
|
||||
// Maximum number of results returned by the suggestion client
|
||||
private static final int SUGGESTION_MAX = 5;
|
||||
|
||||
// Color of search term match in search suggestion
|
||||
private static final int SUGGESTION_HIGHLIGHT_COLOR = 0xFF999999;
|
||||
|
||||
@ -80,9 +78,9 @@ public class SearchFragment extends Fragment implements AcceptsJumpTaps {
|
||||
|
||||
// TODO: Don't hard-code this template string (bug 1039758)
|
||||
final String template = "https://search.yahoo.com/sugg/ff?" +
|
||||
"output=fxjson&appid=ffm&command=__searchTerms__&nresults=" + SUGGESTION_MAX;
|
||||
"output=fxjson&appid=ffm&command=__searchTerms__&nresults=" + Constants.SUGGESTION_MAX;
|
||||
|
||||
suggestClient = new SuggestClient(activity, template, SUGGESTION_TIMEOUT, SUGGESTION_MAX);
|
||||
suggestClient = new SuggestClient(activity, template, SUGGESTION_TIMEOUT, Constants.SUGGESTION_MAX);
|
||||
suggestionLoaderCallbacks = new SuggestionLoaderCallbacks();
|
||||
|
||||
autoCompleteAdapter = new AutoCompleteAdapter(activity, this);
|
||||
|
@ -13,8 +13,28 @@
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<!-- Basic launcher widget. -->
|
||||
<receiver android:name="org.mozilla.search.SearchWidget"
|
||||
android:label="@string/search_widget_name">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="org.mozilla.widget.LAUNCH_BROWSER"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="org.mozilla.widget.LAUNCH_SEARCH"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.appwidget.provider" android:resource="@xml/search_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name="org.mozilla.search.SearchPreferenceActivity"
|
||||
android:label="@string/search_pref_title"
|
||||
|
BIN
mobile/android/search/res/drawable-hdpi/ic_widget_new_tab.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
mobile/android/search/res/drawable-hdpi/widget_active_bg.9.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
mobile/android/search/res/drawable-hdpi/widget_bg.9.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
mobile/android/search/res/drawable-mdpi/ic_widget_new_tab.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
mobile/android/search/res/drawable-mdpi/widget_active_bg.9.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mobile/android/search/res/drawable-mdpi/widget_bg.9.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
mobile/android/search/res/drawable-xhdpi/ic_widget_new_tab.png
Normal file
After Width: | Height: | Size: 144 B |
BIN
mobile/android/search/res/drawable-xhdpi/widget_active_bg.9.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
mobile/android/search/res/drawable-xhdpi/widget_bg.9.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
@ -2,24 +2,9 @@
|
||||
- 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/. -->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape>
|
||||
<padding
|
||||
android:bottom="@dimen/card_background_padding_y"
|
||||
android:top="@dimen/card_background_padding_y"
|
||||
android:left="@dimen/card_background_padding_x"
|
||||
android:right="@dimen/card_background_padding_x"/>
|
||||
<solid android:color="@android:color/transparent"/>
|
||||
</shape>
|
||||
</item>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Background -->
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="@color/card_background"/>
|
||||
<corners android:radius="5dp"/>
|
||||
<stroke android:width="1dp" android:color="@color/card_border" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
<item android:state_pressed="true" android:drawable="@drawable/search_card_pressed" />
|
||||
<item android:drawable="@drawable/search_card_default"/>
|
||||
|
||||
</selector>
|
||||
|
15
mobile/android/search/res/drawable/search_widget_button.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<!-- Drawable used for buttons in the launch widget -->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:constantSize="true">
|
||||
|
||||
<item android:state_pressed="true"
|
||||
android:drawable="@drawable/widget_active_bg"/>
|
||||
|
||||
<item android:drawable="@drawable/widget_bg"/>
|
||||
|
||||
</selector>
|
@ -26,6 +26,7 @@
|
||||
android:background="@color/global_background_color"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:listSelector="@android:color/transparent"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -12,7 +12,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"/>
|
||||
android:dividerHeight="0dp"
|
||||
android:listSelector="@android:color/transparent"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/settings_button"
|
||||
|
71
mobile/android/search/res/layout/search_widget.xml
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<!-- A homescreen widget for launching Fennec or the search activity. We can't use styles in here
|
||||
so make sure any changes you make are also made to launch_widget.xml which doesn't have
|
||||
the search widget button. -->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/widget_header_height">
|
||||
|
||||
<!-- Wrap in a linear layout to center the text in a flexible space. We use a negative margin
|
||||
to extend this into the firefox logo so that the button background appears to come from behind the logo, but
|
||||
highlights correctly when tapped. -->
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toLeftOf="@+id/logo_button"
|
||||
android:layout_marginRight="@dimen/widget_button_offset"
|
||||
android:paddingRight="@dimen/widget_button_padding"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/search_widget_button"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/search_button">
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@drawable/ic_url_bar_search"
|
||||
android:drawablePadding="@dimen/widget_drawable_padding"
|
||||
android:text="@string/search_widget_button_label"
|
||||
android:contentDescription="@string/search_widget_button_label"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/widget_text_size"
|
||||
android:textColor="@color/text_color_primary"
|
||||
android:id="@+id/search_button_label"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_toRightOf="@+id/logo_button"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/widget_button_offset"
|
||||
android:paddingLeft="@dimen/widget_button_padding"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/search_widget_button"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/new_tab_button">
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@drawable/ic_widget_new_tab"
|
||||
android:drawablePadding="@dimen/widget_drawable_padding"
|
||||
android:gravity="center"
|
||||
android:text="@string/new_tab"
|
||||
android:contentDescription="@string/new_tab"
|
||||
android:textSize="@dimen/widget_text_size"
|
||||
android:textColor="@color/text_color_primary"
|
||||
android:id="@+id/new_tab_button_label"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- The logo. adjustViewBounds is required for the buttons above to stretch underneath the logo. -->
|
||||
<ImageView android:id="@+id/logo_button"
|
||||
android:layout_centerInParent="true"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_width="@dimen/widget_header_height"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/icon"/>
|
||||
|
||||
</RelativeLayout>
|
@ -10,6 +10,7 @@
|
||||
|
||||
<!-- card colors -->
|
||||
<color name="card_background">#ffffff</color>
|
||||
<color name="card_background_pressed">#DCDCE1</color>
|
||||
<color name="card_border">#BFBFBF</color>
|
||||
|
||||
<!-- Search suggestion highlight color is defined in SearchFragment.java -->
|
||||
|
@ -23,4 +23,11 @@
|
||||
<dimen name="card_padding_x">38dp</dimen>
|
||||
<dimen name="card_padding_y">23dp</dimen>
|
||||
|
||||
<!-- Widget Buttons -->
|
||||
<dimen name="widget_header_height">70dp</dimen>
|
||||
<dimen name="widget_button_offset">-50dp</dimen>
|
||||
<dimen name="widget_button_padding">45dp</dimen>
|
||||
<dimen name="widget_text_size">15sp</dimen>
|
||||
<dimen name="widget_drawable_padding">2dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
12
mobile/android/search/res/xml/search_widget_info.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="300dp"
|
||||
android:minHeight="40dp"
|
||||
android:label="@string/search_widget_name"
|
||||
android:widgetCategory="home_screen"
|
||||
android:previewImage="@drawable/launcher_widget"
|
||||
android:initialLayout="@layout/search_widget"/>
|
@ -16,4 +16,5 @@ search_activity_sources = [
|
||||
'java/org/mozilla/search/PostSearchFragment.java',
|
||||
'java/org/mozilla/search/PreSearchFragment.java',
|
||||
'java/org/mozilla/search/SearchPreferenceActivity.java',
|
||||
'java/org/mozilla/search/SearchWidget.java',
|
||||
]
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<!ENTITY search_jump_arrow '↖'>
|
||||
|
||||
<!ENTITY search_app_name 'Firefox Search'>
|
||||
<!ENTITY search_app_name '&brandShortName; Search'>
|
||||
<!ENTITY search_for_something 'Search for something'>
|
||||
|
||||
<!ENTITY search_pref_title 'Settings'>
|
||||
@ -12,3 +12,6 @@
|
||||
<!ENTITY search_pref_clear_history_dialog_message 'Delete all search history from this device?'>
|
||||
<!ENTITY search_pref_clear_history_title 'Clear search history'>
|
||||
<!ENTITY search_pref_button_content_description 'Settings'>
|
||||
|
||||
<!ENTITY search_widget_button_label 'Search'>
|
||||
|
||||
|
@ -8,3 +8,6 @@
|
||||
<string name="search_pref_clear_history_dialog_message">&search_pref_clear_history_dialog_message;</string>
|
||||
<string name="search_pref_clear_history_title">&search_pref_clear_history_title;</string>
|
||||
<string name="search_pref_button_content_description">&search_pref_button_content_description;</string>
|
||||
|
||||
<string name="search_widget_name">&search_app_name;</string>
|
||||
<string name="search_widget_button_label">&search_widget_button_label;</string>
|
||||
|
@ -4,9 +4,37 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
const { Cc, Ci, Cu } = require("chrome");
|
||||
let protocol = require("devtools/server/protocol");
|
||||
let {method, RetVal} = protocol;
|
||||
let { method, RetVal } = protocol;
|
||||
const { reportException } = require("devtools/toolkit/DevToolsUtils");
|
||||
|
||||
/**
|
||||
* A method decorator that ensures the actor is in the expected state before
|
||||
* proceeding. If the actor is not in the expected state, the decorated method
|
||||
* returns a rejected promise.
|
||||
*
|
||||
* @param String expectedState
|
||||
* The expected state.
|
||||
*
|
||||
* @param Function method
|
||||
* The actor method to proceed with when the actor is in the expected
|
||||
* state.
|
||||
*
|
||||
* @returns Function
|
||||
* The decorated method.
|
||||
*/
|
||||
function expectState(expectedState, method) {
|
||||
return function(...args) {
|
||||
if (this.state !== expectedState) {
|
||||
const msg = "Wrong State: Expected '" + expectedState + "', but current "
|
||||
+ "state is '" + this.state + "'";
|
||||
return Promise.reject(new Error(msg));
|
||||
}
|
||||
|
||||
return method.apply(this, args);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* An actor that returns memory usage data for its parent actor's window.
|
||||
@ -17,18 +45,59 @@ let {method, RetVal} = protocol;
|
||||
let MemoryActor = protocol.ActorClass({
|
||||
typeName: "memory",
|
||||
|
||||
initialize: function(conn, tabActor) {
|
||||
get dbg() {
|
||||
if (!this._dbg) {
|
||||
this._dbg = this.parent.makeDebugger();
|
||||
}
|
||||
return this._dbg;
|
||||
},
|
||||
|
||||
initialize: function(conn, parent) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
this.tabActor = tabActor;
|
||||
this.parent = parent;
|
||||
this._mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
|
||||
.getService(Ci.nsIMemoryReporterManager);
|
||||
this.state = "detached";
|
||||
this._dbg = null;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this._mgr = null;
|
||||
if (this.state === "attached") {
|
||||
this.detach();
|
||||
}
|
||||
protocol.Actor.prototype.destroy.call(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach to this MemoryActor.
|
||||
*/
|
||||
attach: method(expectState("detached", function() {
|
||||
this.dbg.addDebuggees();
|
||||
this.dbg.enabled = true;
|
||||
this.state = "attached";
|
||||
}), {
|
||||
request: {},
|
||||
response: {
|
||||
type: "attached"
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Detach from this MemoryActor.
|
||||
*/
|
||||
detach: method(expectState("attached", function() {
|
||||
this.dbg.removeAllDebuggees();
|
||||
this.dbg.enabled = false;
|
||||
this._dbg = null;
|
||||
this.state = "detached";
|
||||
}), {
|
||||
request: {},
|
||||
response: {
|
||||
type: "detached"
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* A method that returns a detailed breakdown of the memory consumption of the
|
||||
* associated window.
|
||||
@ -49,7 +118,7 @@ let MemoryActor = protocol.ActorClass({
|
||||
let nonJSMilliseconds = {};
|
||||
|
||||
try {
|
||||
this._mgr.sizeOfTab(this.tabActor.window, jsObjectsSize, jsStringsSize, jsOtherSize,
|
||||
this._mgr.sizeOfTab(this.parent.window, jsObjectsSize, jsStringsSize, jsOtherSize,
|
||||
domSize, styleSize, otherSize, totalSize, jsMilliseconds, nonJSMilliseconds);
|
||||
result.total = totalSize.value;
|
||||
result.domSize = domSize.value;
|
||||
@ -61,9 +130,7 @@ let MemoryActor = protocol.ActorClass({
|
||||
result.jsMilliseconds = jsMilliseconds.value.toFixed(1);
|
||||
result.nonJSMilliseconds = nonJSMilliseconds.value.toFixed(1);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
let url = this.tabActor.url;
|
||||
console.error("Error getting size of " + url);
|
||||
reportException("MemoryActor.prototype.measure", e);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -7,6 +7,7 @@ support-files =
|
||||
nonchrome_unsafeDereference.html
|
||||
inspector_getImageData.html
|
||||
large-image.jpg
|
||||
memory-helpers.js
|
||||
small-image.gif
|
||||
Debugger.Source.prototype.element.js
|
||||
Debugger.Source.prototype.element-2.js
|
||||
@ -66,6 +67,8 @@ skip-if = buildapp == 'mulet'
|
||||
[test_inspector_getImageData.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_memory.html]
|
||||
[test_memory_attach_01.html]
|
||||
[test_memory_attach_02.html]
|
||||
[test_preference.html]
|
||||
[test_connectToChild.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
|
54
toolkit/devtools/server/tests/mochitest/memory-helpers.js
Normal file
@ -0,0 +1,54 @@
|
||||
let Cu = Components.utils;
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Always log packets when running tests.
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
SimpleTest.registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("devtools.debugger.log");
|
||||
});
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
let { require } = devtools;
|
||||
|
||||
let { MemoryFront } = require("devtools/server/actors/memory");
|
||||
|
||||
function startServerAndGetSelectedTabMemory() {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
var client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
client.connect(response => {
|
||||
if (response.error) {
|
||||
reject(new Error(response.error + ": " + response.message));
|
||||
return;
|
||||
}
|
||||
|
||||
client.listTabs(response => {
|
||||
if (response.error) {
|
||||
reject(new Error(response.error + ": " + response.message));
|
||||
return;
|
||||
}
|
||||
|
||||
var form = response.tabs[response.selected];
|
||||
var memory = MemoryFront(client, form);
|
||||
|
||||
resolve({ memory, client });
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function destroyServerAndFinish(client) {
|
||||
client.close(() => {
|
||||
DebuggerServer.destroy();
|
||||
SimpleTest.finish()
|
||||
});
|
||||
}
|
@ -11,59 +11,26 @@ Bug 923275 - Add a memory monitor widget to the developer toolbar
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="memory-helpers.js" type="application/javascript;version=1.8"></script>
|
||||
<script>
|
||||
|
||||
window.onload = function() {
|
||||
var Cu = Components.utils;
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Always log packets when running tests.
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
SimpleTest.registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("devtools.debugger.log");
|
||||
});
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var {MemoryFront} = devtools.require("devtools/server/actors/memory");
|
||||
|
||||
DebuggerServer.init(function () { return true; });
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
var client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
client.connect(function onConnect() {
|
||||
client.listTabs(function onListTabs(aResponse) {
|
||||
var form = aResponse.tabs[aResponse.selected];
|
||||
var front = MemoryFront(client, form);
|
||||
|
||||
front.measure().then(measurement => {
|
||||
ok(measurement.total > 0, "total memory is valid");
|
||||
ok(measurement.domSize > 0, "domSize is valid");
|
||||
ok(measurement.styleSize > 0, "styleSize is valid");
|
||||
ok(measurement.jsObjectsSize > 0, "jsObjectsSize is valid");
|
||||
ok(measurement.jsStringsSize > 0, "jsStringsSize is valid");
|
||||
ok(measurement.jsOtherSize > 0, "jsOtherSize is valid");
|
||||
ok(measurement.otherSize > 0, "otherSize is valid");
|
||||
ok(measurement.jsMilliseconds, "jsMilliseconds is valid");
|
||||
ok(measurement.nonJSMilliseconds, "nonJSMilliseconds is valid");
|
||||
|
||||
client.close(() => {
|
||||
DebuggerServer.destroy();
|
||||
SimpleTest.finish()
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
Task.spawn(function* () {
|
||||
var { memory, client } = yield startServerAndGetSelectedTabMemory();
|
||||
var measurement = yield memory.measure();
|
||||
ok(measurement.total > 0, "total memory is valid");
|
||||
ok(measurement.domSize > 0, "domSize is valid");
|
||||
ok(measurement.styleSize > 0, "styleSize is valid");
|
||||
ok(measurement.jsObjectsSize > 0, "jsObjectsSize is valid");
|
||||
ok(measurement.jsStringsSize > 0, "jsStringsSize is valid");
|
||||
ok(measurement.jsOtherSize > 0, "jsOtherSize is valid");
|
||||
ok(measurement.otherSize > 0, "otherSize is valid");
|
||||
ok(measurement.jsMilliseconds, "jsMilliseconds is valid");
|
||||
ok(measurement.nonJSMilliseconds, "nonJSMilliseconds is valid");
|
||||
destroyServerAndFinish(client);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Bug 960671 - Test attaching and detaching from a memory actor.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Memory monitoring actor test</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="memory-helpers.js" type="application/javascript;version=1.8"></script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Task.spawn(function* () {
|
||||
var { memory, client } = yield startServerAndGetSelectedTabMemory();
|
||||
yield memory.attach();
|
||||
ok(true, "Shouldn't have gotten an error attaching.");
|
||||
yield memory.detach();
|
||||
ok(true, "Shouldn't have gotten an error detaching.");
|
||||
destroyServerAndFinish(client);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,49 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Bug 960671 - Test attaching and detaching while in the wrong state.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Memory monitoring actor test</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="memory-helpers.js" type="application/javascript;version=1.8"></script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
Task.spawn(function* () {
|
||||
var { memory, client } = yield startServerAndGetSelectedTabMemory();
|
||||
|
||||
var e = null;
|
||||
try {
|
||||
yield memory.detach();
|
||||
}
|
||||
catch (ee) {
|
||||
e = ee;
|
||||
}
|
||||
ok(e, "Should have hit the wrongState error");
|
||||
|
||||
yield memory.attach();
|
||||
|
||||
e = null;
|
||||
try {
|
||||
yield memory.attach();
|
||||
}
|
||||
catch (ee) {
|
||||
e = ee;
|
||||
}
|
||||
ok(e, "Should have hit the wrongState error");
|
||||
|
||||
yield memory.detach();
|
||||
destroyServerAndFinish(client);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1001,7 +1001,7 @@ AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jintArray arr = mozilla::widget::android::GeckoAppShell::InitCameraWrapper
|
||||
(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height);
|
||||
(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) *width, (int32_t) *height);
|
||||
|
||||
if (!arr)
|
||||
return false;
|
||||
|