Bug 1351605 - store start-intent in activity
`getIntent()` not always returns the intent whith start this Activity
due to GeckoApp.onCreate reset it. We make a copy here in case of this
activity is destroyed and re-created.
MozReview-Commit-ID: 7TF3b1WdbM2
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -53,39 +53,46 @@ import org.mozilla.gecko.widget.GeckoPop
import org.mozilla.gecko.util.GeckoBundle;
import java.util.List;
import static android.support.customtabs.CustomTabsIntent.EXTRA_TOOLBAR_COLOR;
public class CustomTabsActivity extends GeckoApp implements Tabs.OnTabsChangedListener {
private static final String LOGTAG = "CustomTabsActivity";
+ private static final String SAVED_START_INTENT = "saved_intent_which_started_this_activity";
private static final String SAVED_TOOLBAR_COLOR = "SavedToolbarColor";
@ColorInt
private static final int DEFAULT_ACTION_BAR_COLOR = 0xFF363b40; // default color to match design
private final SparseArrayCompat<PendingIntent> menuItemsIntent = new SparseArrayCompat<>();
private GeckoPopupMenu popupMenu;
private ActionBarPresenter actionBarPresenter;
private ProgressBar mProgressView;
// A state to indicate whether this activity is finishing with customize animation
private boolean usingCustomAnimation = false;
@ColorInt
private int toolbarColor = DEFAULT_ACTION_BAR_COLOR;
+ // Bug 1351605 - getIntent() not always returns the intent which started this activity.
+ // Therefore we make a copy in case of this Activity is re-created.
+ private Intent startIntent;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
+ startIntent = savedInstanceState.getParcelable(SAVED_START_INTENT);
toolbarColor = savedInstanceState.getInt(SAVED_TOOLBAR_COLOR, DEFAULT_ACTION_BAR_COLOR);
} else {
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "customtab");
+ startIntent = getIntent();
toolbarColor = getIntent().getIntExtra(EXTRA_TOOLBAR_COLOR, DEFAULT_ACTION_BAR_COLOR);
final String host = getReferrerHost();
recordCustomTabUsage(host);
}
// Translucent color does not make sense for toolbar color. Ensure it is 0xFF.
toolbarColor = 0xFF000000 | toolbarColor;
@@ -93,17 +100,17 @@ public class CustomTabsActivity extends
mProgressView = (ProgressBar) findViewById(R.id.page_progress);
final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar);
setSupportActionBar(toolbar);
final ActionBar actionBar = getSupportActionBar();
bindNavigationCallback(toolbar);
actionBarPresenter = new ActionBarPresenter(actionBar);
- actionBarPresenter.displayUrlOnly(getIntent().getDataString());
+ actionBarPresenter.displayUrlOnly(startIntent.getDataString());
actionBarPresenter.setBackgroundColor(toolbarColor, getWindow());
actionBarPresenter.setTextLongClickListener(new UrlCopyListener());
actionBar.setDisplayHomeAsUpEnabled(true);
Tabs.registerOnTabsChangedListener(this);
}
private void recordCustomTabUsage(final String host) {
@@ -128,31 +135,31 @@ public class CustomTabsActivity extends
// Bug 1329145: 3rd party app could specify customized exit-animation to this activity.
// Activity.overridePendingTransition will invoke getPackageName to retrieve that animation resource.
// In that case, to return different package name to get customized animation resource.
@Override
public String getPackageName() {
if (usingCustomAnimation) {
// Use its package name to retrieve animation resource
- return IntentUtil.getAnimationPackageName(getIntent());
+ return IntentUtil.getAnimationPackageName(startIntent);
} else {
return super.getPackageName();
}
}
@Override
public void finish() {
super.finish();
// When 3rd party app launch this Activity, it could also specify custom exit-animation.
- if (IntentUtil.hasExitAnimation(getIntent())) {
+ if (IntentUtil.hasExitAnimation(startIntent)) {
usingCustomAnimation = true;
- overridePendingTransition(IntentUtil.getEnterAnimationRes(getIntent()),
- IntentUtil.getExitAnimationRes(getIntent()));
+ overridePendingTransition(IntentUtil.getEnterAnimationRes(startIntent),
+ IntentUtil.getExitAnimationRes(startIntent));
usingCustomAnimation = false;
}
}
@Override
protected int getNewTabFlags() {
return Tabs.LOADURL_CUSTOMTAB | super.getNewTabFlags();
}
@@ -197,17 +204,17 @@ public class CustomTabsActivity extends
}
updateMenuItemForward();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
-
+ outState.putParcelable(SAVED_START_INTENT, startIntent);
outState.putInt(SAVED_TOOLBAR_COLOR, toolbarColor);
}
@Override
public void onResume() {
if (lastSelectedTabId >= 0) {
final Tabs tabs = Tabs.getInstance();
final Tab tab = tabs.getTab(lastSelectedTabId);
@@ -219,17 +226,17 @@ public class CustomTabsActivity extends
}
// Usually should use onCreateOptionsMenu() to initialize menu items. But GeckoApp overwrite
// it to support custom menu(Bug 739412). Then the parameter *menu* in this.onCreateOptionsMenu()
// and this.onPrepareOptionsMenu() are different instances - GeckoApp.onCreatePanelMenu() changed it.
// CustomTabsActivity only use standard menu in ActionBar, so initialize menu here.
@Override
public boolean onCreatePanelMenu(final int id, final Menu menu) {
- insertActionButton(menu, getIntent(), actionBarPresenter.getTextPrimaryColor());
+ insertActionButton(menu, startIntent, actionBarPresenter.getTextPrimaryColor());
popupMenu = createCustomPopupMenu();
// Create a ImageButton manually, and use it as an anchor for PopupMenu.
final ImageButton btn = new ImageButton(getContext(),
null, 0, R.style.Widget_MenuButtonCustomTabs);
btn.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
btn.setOnClickListener(new View.OnClickListener() {
@@ -349,31 +356,28 @@ public class CustomTabsActivity extends
// pass to to Activity.onMenuItemClick for consistency.
popupMenu.setOnMenuItemClickListener(new GeckoPopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return CustomTabsActivity.this.onMenuItemClick(item);
}
});
- // to add Fennec default menu
- final Intent intent = getIntent();
-
// to add custom menu items
- final List<String> titles = IntentUtil.getMenuItemsTitle(intent);
- final List<PendingIntent> intents = IntentUtil.getMenuItemsPendingIntent(intent);
+ final List<String> titles = IntentUtil.getMenuItemsTitle(startIntent);
+ final List<PendingIntent> intents = IntentUtil.getMenuItemsPendingIntent(startIntent);
menuItemsIntent.clear();
for (int i = 0; i < titles.size(); i++) {
final int menuId = Menu.FIRST + i;
geckoMenu.add(Menu.NONE, menuId, Menu.NONE, titles.get(i));
menuItemsIntent.put(menuId, intents.get(i));
}
// to add share menu item, if necessary
- if (IntentUtil.hasShareItem(intent) && !TextUtils.isEmpty(intent.getDataString())) {
+ if (IntentUtil.hasShareItem(startIntent) && !TextUtils.isEmpty(startIntent.getDataString())) {
geckoMenu.add(Menu.NONE, R.id.share, Menu.NONE, getString(R.string.share));
}
final MenuInflater inflater = new GeckoMenuInflater(this);
inflater.inflate(R.menu.customtabs_menu, geckoMenu);
// insert default browser name to title of menu-item-Open-In
final MenuItem openItem = geckoMenu.findItem(R.id.custom_tabs_menu_open_in);
@@ -448,17 +452,17 @@ public class CustomTabsActivity extends
final Intent intent = new Intent();
intent.setData(Uri.parse(tab.getURL()));
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent);
}
}
private void onActionButtonClicked() {
- PendingIntent pendingIntent = IntentUtil.getActionButtonPendingIntent(getIntent());
+ PendingIntent pendingIntent = IntentUtil.getActionButtonPendingIntent(startIntent);
performPendingIntent(pendingIntent);
}
/**
* Callback for Share menu item.
*/
private void onShareClicked() {
--- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/customtabs/TestCustomTabsActivity.java
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/customtabs/TestCustomTabsActivity.java
@@ -60,48 +60,48 @@ public class TestCustomTabsActivity {
/**
* Activity should not call overridePendingTransition if custom animation does not exist.
*/
@Test
public void testFinishWithoutCustomAnimation() {
final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
final Intent i = builder.build().intent;
- doReturn(i).when(spyActivity).getIntent();
+ Whitebox.setInternalState(spyActivity, "startIntent", i);
spyActivity.finish();
verify(spyActivity, times(0)).overridePendingTransition(anyInt(), anyInt());
}
/**
* Activity should call overridePendingTransition if custom animation exists.
*/
@Test
public void testFinish() {
final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setExitAnimations(spyContext, enterRes, exitRes);
final Intent i = builder.build().intent;
- doReturn(i).when(spyActivity).getIntent();
+ Whitebox.setInternalState(spyActivity, "startIntent", i);
spyActivity.finish();
verify(spyActivity, times(1)).overridePendingTransition(eq(enterRes), eq(exitRes));
}
/**
* To get 3rd party app's package name, if custom animation exists.
*/
@Test
public void testGetPackageName() {
final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setExitAnimations(spyContext, enterRes, exitRes);
final Intent i = builder.build().intent;
- doReturn(i).when(spyActivity).getIntent();
Whitebox.setInternalState(spyActivity, "usingCustomAnimation", true);
+ Whitebox.setInternalState(spyActivity, "startIntent", i);
Assert.assertEquals(THIRD_PARTY_PACKAGE_NAME, spyActivity.getPackageName());
}
@Test
public void testInsertActionButton() {
// create properties for CustomTabsIntent
final String description = "Description";