Bug 1352997 - Part 6 - Switch over web apps and implement additional startup logic for them. r=sebastian,walkingice

Web Apps are single task activities, but Android's task switcher will only ever return the intent that originally created the activity and will never ever update its stored intent for subsequent launches via onNewIntent, so we have to do this ourselves.

Additionally, web apps have some additional logic when being launched via a new intent that checks whether the currently loaded page matches the scope of the web app intent and then resets it if necessary. We now hook up this logic to the new SingleTabActivity wiring.

MozReview-Commit-ID: 9bo4gXbfPNg

--HG--
extra : rebase_source : 3f8cf1e2e96889313ef83ad9ba92b7a36985b82a
This commit is contained in:
Jan Henning 2017-04-04 21:50:33 +02:00
Родитель a31794fbba
Коммит 612ab15860
1 изменённых файлов: 43 добавлений и 43 удалений

Просмотреть файл

@ -15,6 +15,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
@ -27,8 +28,8 @@ import org.json.JSONException;
import org.mozilla.gecko.AppConstants; import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.EventDispatcher; import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.SingleTabActivity;
import org.mozilla.gecko.Telemetry; import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract; import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.icons.decoders.FaviconDecoder; import org.mozilla.gecko.icons.decoders.FaviconDecoder;
@ -45,34 +46,32 @@ import org.mozilla.gecko.widget.AnchoredPopup;
import static org.mozilla.gecko.Tabs.TabEvents; import static org.mozilla.gecko.Tabs.TabEvents;
public class WebAppActivity extends GeckoApp { public class WebAppActivity extends SingleTabActivity {
private static final String LOGTAG = "WebAppActivity"; private static final String LOGTAG = "WebAppActivity";
public static final String MANIFEST_PATH = "MANIFEST_PATH"; public static final String MANIFEST_PATH = "MANIFEST_PATH";
private static final String SAVED_INTENT = "savedIntent";
private TextView mUrlView; private TextView mUrlView;
private View doorhangerOverlay; private View doorhangerOverlay;
private String mManifestPath;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
Intent savedIntent = getIntent(); if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0 &&
savedInstanceState != null) {
// Even though we're a single task activity, Android's task switcher has the
// annoying habit of never updating its stored intent after our initial creation,
// even if we've been subsequently started with a new intent.
// This below is needed if we should ever decide to store a custom class as intent extra.
savedInstanceState.setClassLoader(getClass().getClassLoader());
Intent lastLaunchIntent = savedInstanceState.getParcelable(SAVED_INTENT);
setIntent(lastLaunchIntent);
}
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// GeckoApp's default behaviour is to reset the intent if we've got any
// savedInstanceState, which we don't want here.
setIntent(savedIntent);
if (savedInstanceState != null) {
mManifestPath = savedInstanceState.getString(WebAppActivity.MANIFEST_PATH, null);
} else {
mManifestPath = getIntent().getStringExtra(WebAppActivity.MANIFEST_PATH);
}
loadManifest(mManifestPath);
if (!mIsRestoringActivity || !hasGeckoTab(new SafeIntent(getIntent()))) {
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "customtab");
}
final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar); final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
@ -140,7 +139,7 @@ public class WebAppActivity extends GeckoApp {
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putString(WebAppActivity.MANIFEST_PATH, mManifestPath); outState.putParcelable(SAVED_INTENT, getIntent());
} }
@Override @Override
@ -159,42 +158,43 @@ public class WebAppActivity extends GeckoApp {
} }
@Override @Override
protected void onDone() { protected void onTabOpenFromIntent(Tab tab) {
finish(); super.onTabOpenFromIntent(tab);
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "webapp");
loadManifest(tab.getManifestPath());
} }
/** /**
* In case this activity is reused (the user has opened > 10 current web apps) * In case this activity and its tab are reused (the user has opened
* we check that app launched is still within the same host as the * > 10 current web apps), we check that app launched is still within
* shortcut has set, if not we reload the homescreens url * the same host as the intent has set.
* If it isn't, we reload the intent URL.
*/ */
@Override @Override
protected void onNewIntent(Intent externalIntent) { protected void onTabSelectFromIntent(Tab tab) {
super.onNewIntent(externalIntent); super.onTabSelectFromIntent(tab);
final SafeIntent intent = new SafeIntent(externalIntent); SafeIntent intent = new SafeIntent(getIntent());
if (hasGeckoTab(intent)) {
loadManifest(intent.getStringExtra(WebAppActivity.MANIFEST_PATH));
} else {
restoreLastSelectedTab();
final String launchUrl = intent.getDataString(); final String launchUrl = intent.getDataString();
final String currentUrl = Tabs.getInstance().getSelectedTab().getURL(); final String currentUrl = tab.getURL();
final boolean isSameDomain = Uri.parse(currentUrl).getHost() final boolean isSameDomain = Uri.parse(currentUrl).getHost()
.equals(Uri.parse(launchUrl).getHost()); .equals(Uri.parse(launchUrl).getHost());
final String manifestPath;
if (!isSameDomain) { if (!isSameDomain) {
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "webapp"); Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "webapp");
mManifestPath = externalIntent.getStringExtra(WebAppActivity.MANIFEST_PATH); manifestPath = intent.getStringExtra(MANIFEST_PATH);
loadManifest(mManifestPath); tab.setManifestUrl(manifestPath);
Tabs.getInstance().loadUrl(launchUrl); Tabs.getInstance().loadUrl(launchUrl);
} else {
manifestPath = tab.getManifestPath();
} }
} loadManifest(manifestPath);
} }
private void loadManifest(String manifestPath) { private void loadManifest(String manifestPath) {
if (manifestPath == null) { if (TextUtils.isEmpty(manifestPath)) {
Log.e(LOGTAG, "Missing manifest"); Log.e(LOGTAG, "Missing manifest");
return; return;
} }