Improve keyapplet referencing

Don't unpack the keyapplet, copy it into place as a cache.jar.  To
avoid linking the Gerrit version number on the applet cache, use a
build time resource to tell us the actual version number of the
applet, thereby avoiding downloads even across Gerrit upgrades.

When loading the applet for the first time in this browser, give
the applet up to 30 seconds to start up.  It may need to show a
dialog to the user and ask them if its OK to execute.  The user
will need a few seconds to respond to this request before we can
actually hit the applet's API.

Change-Id: I0c4b9b8f7a382b343cfabff1d36d9f9034b74530
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2009-12-30 11:30:33 -08:00
parent 53eae8cdd3
commit e43a80361c
4 changed files with 125 additions and 78 deletions

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2009 The Android Open Source Project
//
// Licensed 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.
package com.google.gerrit.client.account;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.TextResource;
public interface AccountResources extends ClientBundle {
public static final AccountResources I = GWT.create(AccountResources.class);
@Source("keyapplet_jar")
TextResource keyapplet_jar();
}

View File

@@ -33,9 +33,8 @@ import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
@@ -77,6 +76,7 @@ class SshPanel extends Composite {
private Button clearNew;
private Button addNew;
private Button browse;
private Timer appletLoadTimer;
private NpTextArea addTxt;
private Button delSel;
@@ -184,7 +184,7 @@ class SshPanel extends Composite {
doBrowse();
}
});
browse.setVisible(GWT.isScript() && (!loadedApplet || applet != null));
browse.setVisible(!loadedApplet || applet != null);
buttons.add(browse);
addNew = new Button(Util.C.buttonAddSshKey());
@@ -281,12 +281,13 @@ class SshPanel extends Composite {
void doBrowse() {
browse.setEnabled(false);
if (!loadedApplet) {
applet = DOM.createElement("applet");
applet.setAttribute("code",
"com.google.gerrit.keyapplet.ReadPublicKey.class");
applet.setAttribute("archive", GWT.getModuleBaseURL()
+ "gerrit-keyapplet.cache.jar?v=" + Gerrit.getVersion());
+ AccountResources.I.keyapplet_jar().getText());
applet.setAttribute("mayscript", "true");
applet.setAttribute("width", "0");
applet.setAttribute("height", "0");
@@ -297,14 +298,27 @@ class SshPanel extends Composite {
// new applet tag we just created above, and actually load the
// applet into the runtime.
//
DeferredCommand.addCommand(new Command() {
public void execute() {
doBrowse();
appletLoadTimer = new Timer() {
private int attempts;
@Override
public void run() {
if (isAppletRunning(applet)) {
appletLoadTimer = null;
cancel();
doBrowse();
} else if (30000 / 200 < attempts++) {
appletLoadTimer = null;
cancel();
noBrowse();
}
}
});
};
appletLoadTimer.scheduleRepeating(200);
return;
}
if (applet == null) {
if (applet == null || !isAppletRunning(applet)) {
// If the applet element is null, the applet was determined
// to have failed to load, and we are dead. Hide the button.
//
@@ -355,6 +369,9 @@ class SshPanel extends Composite {
new ErrorDialog(Util.C.sshJavaAppletNotAvailable()).center();
}
private static native boolean isAppletRunning(Element keyapp)
/*-{ return keyapp['openPublicKey'] ? true : false }-*/;
private static native String openPublicKey(Element keyapp)
/*-{ var r = keyapp.openPublicKey(); return r == null ? null : ''+r; }-*/;
@@ -436,6 +453,16 @@ class SshPanel extends Composite {
});
}
@Override
protected void onUnload() {
if (appletLoadTimer != null) {
appletLoadTimer.cancel();
appletLoadTimer = null;
}
super.onUnload();
}
private void showAddKeyBlock(final boolean show) {
showAddKeyBlock.setVisible(!show);
addKeyBlock.setVisible(show);