Commit f0cedc91 authored by miguelg@chromium.org's avatar miguelg@chromium.org

[InfoBar] Upstram basic infobar flow for Android.

The Translate infobar and the relevant tests remain downstream for now

BUG=158817

Review URL: https://chromiumcodereview.appspot.com/24109002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223651 0039d316-1c4b-4281-b951-d872f2087c98
parent 5bacbef6
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@drawable/infobar_button_normal_floating_enabled" />
<item
android:drawable="@drawable/infobar_button_normal_floating_pressed" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@drawable/infobar_button_normal_full_left_enabled" />
<item
android:drawable="@drawable/infobar_button_normal_full_left_pressed" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@drawable/infobar_button_normal_full_right_enabled" />
<item
android:drawable="@drawable/infobar_button_normal_full_right_pressed" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="true"
android:color="#ff000000" />
<item
android:state_enabled="false"
android:color="#77000000" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@drawable/infobar_button_warning_floating_enabled" />
<item
android:drawable="@drawable/infobar_button_warning_floating_pressed" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@drawable/infobar_button_warning_full_left_enabled" />
<item
android:drawable="@drawable/infobar_button_warning_full_left_pressed" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@drawable/infobar_button_warning_full_right_enabled" />
<item
android:drawable="@drawable/infobar_button_warning_full_right_pressed" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="false"
android:state_focused="false"
android:drawable="@android:color/transparent" />
<item
android:state_pressed="false"
android:state_focused="true"
android:drawable="@drawable/infobar_close_button_focused" />
<item
android:drawable="@drawable/infobar_close_button_pressed" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="1dp" />
<solid android:color="@color/button_focused" />
<stroke
android:width="1px"
android:color="#80000000" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="1dp" />
<solid android:color="@color/button_pressed" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#fffbfbfb"
android:endColor="#fff2f2f2"
android:angle="270" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#ffffe991"
android:endColor="#fffee289"
android:angle="270" />
</shape>
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="60dp"
android:minHeight="@dimen/infobar_touch_target_height"
android:textSize="@dimen/infobar_button_text_size"
android:textColor="@drawable/infobar_button_text"
android:shadowColor="#FFF"
android:shadowDx="1.0"
android:shadowDy="1.0"
android:shadowRadius="1.0"
android:background="@drawable/infobar_button_normal_floating"
android:paddingStart="@dimen/infobar_button_horizontal_padding"
android:paddingEnd="@dimen/infobar_button_horizontal_padding"
android:paddingTop="5dp"
android:paddingBottom="5dp" />
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/infobar_message"
android:layout_marginTop="@dimen/infobar_margin"
android:layout_marginBottom="@dimen/infobar_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/infobar_text_size"
android:textColor="@color/infobar_text" />
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2013 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<resources>
<!-- LocationBar colors -->
<color name="locationbar_default_text">#111111</color>
<color name="locationbar_start_scheme_default">#a1a1a1</color>
<color name="locationbar_start_scheme_security_warning">#808080</color>
<color name="locationbar_start_scheme_security_error">#dd4b39</color>
<color name="locationbar_start_scheme_ev_secure">#009933</color>
<color name="locationbar_start_scheme_secure">#009933</color>
<color name="locationbar_scheme_to_domain">#a1a1a1</color>
<color name="locationbar_domain_and_registry">#111111</color>
<color name="locationbar_trailing_url">#a1a1a1</color>
<!-- The color of the divider between omnibox suggestions. -->
<color name="omnibox_divider">#cccccc</color>
<!-- Tab Count Colors -->
<color name="toolbar_tab_count_color">#717171</color>
<color name="toolbar_incognito_tab_count_color">#f8f8f8</color>
<color name="toolbar_switcher_tab_count_color">#f8f8f8</color>
<!-- Toolbar color -->
<color name="toolbar_color">#e0e0e0</color>
<!-- Find in Page colors -->
<color name="find_result_bar_background_color">#bfffffff</color>
<color name="find_result_bar_background_border_color">#bf666666</color>
<color name="find_result_bar_result_color">#ffde43</color>
<color name="find_result_bar_result_border_color">#c9af35</color>
<color name="find_result_bar_active_color">#ff9632</color>
<color name="find_result_bar_active_border_color">#c37e3b</color>
<color name="find_result_bar_no_results_background_color">#ff5f5f</color>
<!-- Colors were copied from browser/views/infobars/infobars.cc -->
<color name="infobar_text">#000000</color>
<color name="infobar_info_background_separator">#afafaf</color>
<color name="infobar_warning_background_separator">#ccb771</color>
<!-- Tab Switcher Colors -->
<color name="tab_switcher_background">#111111</color>
<color name="tab_title_bar_text">#555555</color>
<color name="tab_title_bar_text_incognito">#FFFFFFFF</color>
<color name="tab_title_bar_shadow">#AAFFFFFF</color>
<color name="tab_title_bar_shadow_incognito">#88000000</color>
<color name="tab_back">#D9D9D9</color>
<color name="tab_back_incognito">#4D5872</color>
<!-- First Run Experience Colors -->
<color name="fre_background_color">#f4f4f4</color>
<color name="fre_thin_line_color">#e4e5e7</color>
<color name="fre_text_color">#000000</color>
<color name="fre_positive_button_color">#FFFFFF</color>
<color name="fre_negative_button_color">#000000</color>
<!-- First Run colors for tablet -->
<color name="fre_text_color_tablet">#1e1e1e</color>
<color name="fre_light_text_color_tablet">#646464</color>
<color name="fre_negative_button_color_tablet">#545454</color>
<!-- App Launch Colors -->
<color name="light_background_color">#FFFFFF</color>
<!-- Data Reduction Colors -->
<color name="data_reduction_percent_color">#717171</color>
<!-- Button Colors -->
<color name="button_pressed">#ff77c5e1</color>
<color name="button_focused">#ffa9d0df</color>
<!-- Disabled Colors -->
<color name="disable_pref_activity">#808080</color>
<!-- Notification Colors -->
<drawable name="notification_icon_bg">#3333B5E5</drawable>
<!-- New Tab Page Colors -->
<color name="new_tab_page_bg">#f1f1f1</color>
<!-- WebappActivity colors -->
<color name="webapp_url_bar_scheme">#339922</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The number of thumbnails that the thumbnail cache can hold. -->
<integer name="default_thumbnail_cache_size">5</integer>
<!-- The number of approximation thumbnails that the approximation cache can hold. -->
<integer name="default_approximation_thumbnail_cache_size">32</integer>
<!-- The maximum size of the write queue in the thumbnail cache. -->
<integer name="default_write_queue_size">5</integer>
<!-- The maximum size of the compression queue in the thumbnail cache. -->
<integer name="default_compression_queue_size">5</integer>
<!-- The maximum indent depth of folders when selecting bookmarks. -->
<integer name="select_bookmark_folder_max_depth_indent">5</integer>
<!-- TabSwitcher - Maximum amount to tilt tabs in over scroll in degrees. -->
<integer name="over_scroll_angle">15</integer>
<!-- FRE and App Start -->
<!-- Long duration in ms for animation and callbacks -->
<integer name="fre_long_duration_ms">750</integer>
<!-- TabStrip text -->
<bool name="tab_title_fake_bold_text">true</bool>
<!-- Full Screen Constants -->
<!-- These constants were chosen empirically for their visually pleasant behavior.
Contact tedchoc@chromium.org or dtrainor@chromium.org for questions about
changing these values. -->
<item name="top_controls_show_threshold" format="float" type="floats">0.5</item>
<item name="top_controls_hide_threshold" format="float" type="floats">0.5</item>
<!-- InfoBar constants -->
<item type="id" name="infobar_message" />
<item type="id" name="infobar_close_button" />
<item type="id" name="button_primary" />
<item type="id" name="button_secondary" />
<item type="id" name="infobar_extra_check" />
<!-- Notifications -->
<item type="id" name="remote_notification" />
</resources>
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import org.chromium.base.ApiCompatibilityUtils;
import java.util.ArrayList;
/**
* Sets up animations to move InfoBars around inside of the InfoBarContainer.
*
* Animations proceed in several phases:
* 1) Prep work is done for the InfoBar so that the View being animated in (if it exists) is
* properly sized. This involves adding the View to a FrameLayout with a visibility of
* INVISIBLE and triggering a layout.
*
* 2) Once the View has an actual size, we compute all of the actions needed for the animation.
* We use translations primarily to slide things in and out of the screen as things are shown,
* hidden, or resized.
*
* 3) The animation is kicked off and the animations run. During this phase, the View being shown
* is added to ContentWrapperView.
*
* 4) At the end of the animation, we clean up everything and make sure all the children are in the
* right places.
*/
public class AnimationHelper implements ViewTreeObserver.OnGlobalLayoutListener {
private static final String TAG = "AnimationHelper";
private static final long ANIMATION_DURATION_MS = 250;
public static final int ANIMATION_TYPE_SHOW = 0;
public static final int ANIMATION_TYPE_SWAP = 1;
public static final int ANIMATION_TYPE_HIDE = 2;
public static final int ANIMATION_TYPE_BOUNDARY = 3;
private final InfoBarContainer mContainer;
private final InfoBar mInfoBar;
private final ContentWrapperView mTargetWrapperView;
private final AnimatorSet mAnimatorSet;
private final int mAnimationType;
private final View mToShow;
private boolean mAnimationStarted;
/**
* Creates and starts an animation.
* @param container InfoBarContainer that is having its InfoBars animated.
* @param target ContentWrapperView that is the focus of the animation and is being resized,
* shown, or hidden.
* @param infoBar InfoBar that goes with the specified ContentWrapperView.
* @param toShow If non-null, this View will replace whatever child View the ContentWrapperView
* is currently displaying.
* @param aniamtionType Type of animation being performed.
*/
public AnimationHelper(InfoBarContainer container, ContentWrapperView target, InfoBar infoBar,
View toShow, int animationType) {
mContainer = container;
mInfoBar = infoBar;
mTargetWrapperView = target;
mAnimatorSet = new AnimatorSet();
mAnimationType = animationType;
mToShow = toShow;
assert mContainer.indexOfChild(mTargetWrapperView) != -1;
}
/**
* Start the animation.
*/
public void start() {
mTargetWrapperView.prepareTransition(mToShow);
mContainer.prepareTransition(mToShow);
if (mToShow == null) {
// We've got a size already; start the animation immediately.
continueAnimation();
} else {
// Wait for the object to be sized.
mTargetWrapperView.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
}
/**
* @return the InfoBar being animated.
*/
public InfoBar getInfoBar() {
return mInfoBar;
}
/**
* @return the ContentWrapperView being animated.
*/
public ContentWrapperView getTarget() {
return mTargetWrapperView;
}
/**
* @return the type of animation being performed.
*/
public int getAnimationType() {
return mAnimationType;
}
/**
* Catch when the layout occurs, which lets us know when the View has been sized properly.
*/
@Override
public void onGlobalLayout() {
ApiCompatibilityUtils.removeOnGlobalLayoutListener(mTargetWrapperView, this);
continueAnimation();
}
private void continueAnimation() {
if (mAnimationStarted) return;
mAnimationStarted = true;
boolean infoBarsOnTop = mContainer.areInfoBarsOnTop();
int indexOfWrapperView = mContainer.indexOfChild(mTargetWrapperView);
assert indexOfWrapperView != -1;
ArrayList<Animator> animators = new ArrayList<Animator>();
mTargetWrapperView.getAnimationsForTransition(animators);
// Determine where the tops of each InfoBar will need to be.
int heightDifference = mTargetWrapperView.getTransitionHeightDifference();
int cumulativeTopStart = 0;
int cumulativeTopEnd = 0;
int cumulativeEndHeight = 0;
if (!infoBarsOnTop) {
if (heightDifference >= 0) {
// The current container is smaller than the final container, so the current 0
// coordinate will be >= 0 in the final container.
cumulativeTopStart = heightDifference;
} else {
// The current container is bigger than the final container, so the current 0
// coordinate will be < 0 in the final container.
cumulativeTopEnd = -heightDifference;
}
}
for (int i = 0; i < mContainer.getChildCount(); ++i) {
View view = mContainer.getChildAt(i);
// At this point, the View being transitioned in shouldn't have been added to the
// visible container, yet, and shouldn't affect calculations.
int startHeight = view.getHeight();
int endHeight = startHeight + (i == indexOfWrapperView ? heightDifference : 0);
int topStart = cumulativeTopStart;
int topEnd = cumulativeTopEnd;
int bottomStart = topStart + startHeight;
int bottomEnd = topEnd + endHeight;
if (topStart == topEnd && bottomStart == bottomEnd) {
// The View needs to stay put.
view.setTop(topEnd);
view.setBottom(bottomEnd);
view.setY(topEnd);
view.setTranslationY(0);
} else {
// A translation is required to move the View into place.
int translation = heightDifference;
if (infoBarsOnTop) translation *= -1;
boolean translateDownward = false;
if (topStart < topEnd) {
translateDownward = infoBarsOnTop;
} else if (topStart > topEnd) {
translateDownward = !infoBarsOnTop;
} else {
translateDownward = bottomEnd > bottomStart;
}
PropertyValuesHolder viewTranslation;
if (translateDownward) {
view.setTop(topEnd);
view.setBottom(bottomEnd);
view.setTranslationY(translation);
view.setY(topEnd + translation);
viewTranslation =
PropertyValuesHolder.ofFloat("translationY", translation, 0.0f);
} else {
viewTranslation =
PropertyValuesHolder.ofFloat("translationY", 0.0f, -translation);
}
animators.add(ObjectAnimator.ofPropertyValuesHolder(view, viewTranslation));
}
// Add heights to the cumulative totals.
cumulativeTopStart += startHeight;
cumulativeTopEnd += endHeight;
cumulativeEndHeight += endHeight;
}
// Lock the InfoBarContainer's size at its largest during the animation to avoid
// clipping issues.
final int oldContainerTop = mContainer.getTop();
final int oldContainerBottom = mContainer.getBottom();
final int newContainerTop;
final int newContainerBottom;
if (infoBarsOnTop) {
newContainerTop = oldContainerTop;
newContainerBottom = newContainerTop + cumulativeEndHeight;
} else {
newContainerBottom = oldContainerBottom;
newContainerTop = newContainerBottom - cumulativeEndHeight;
}
final int biggestContainerTop = Math.min(oldContainerTop, newContainerTop);
final int biggestContainerBottom = Math.max(oldContainerBottom, newContainerBottom);
mContainer.setTop(biggestContainerTop);
mContainer.setBottom(biggestContainerBottom);
// Set up and run all of the animations.
mAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mTargetWrapperView.startTransition();
mContainer.startTransition();
}
@Override
public void onAnimationEnd(Animator animation) {
mTargetWrapperView.finishTransition();
mContainer.finishTransition();
}
});
mAnimatorSet.playTogether(animators);
mAnimatorSet.setDuration(ANIMATION_DURATION_MS);
mAnimatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
mAnimatorSet.start();
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import org.chromium.content.common.CommandLine;
import org.chromium.sync.signin.AccountManagerHelper;
import org.chromium.sync.signin.ChromeSigninController;
/**
* Performs the actual login to the requried service.
*/
public class AutoLoginAccountDelegate implements AccountManagerCallback<Bundle> {
private static final String WEB_LOGIN_PREFIX = "weblogin:";
private final Activity mActivity;
private final AutoLoginProcessor mAutoLoginProcessor;
private final AccountManager mAccountManager;
private final Account mAccount;
private boolean mLogInRequested;
private String mAuthTokenType;
public AutoLoginAccountDelegate(Activity activity, AutoLoginProcessor autoLoginProcessor,
String realm, String account, String accountArgs) {
mActivity = activity;
mAutoLoginProcessor = autoLoginProcessor;
mAccountManager = AccountManager.get(activity);
mAccount = ChromeSigninController.get(activity).getSignedInUser();
mLogInRequested = false;
mAuthTokenType = WEB_LOGIN_PREFIX + accountArgs;
}
public boolean logIn() {
Log.i("AutoLoginAccountDelegate", "auto-login requested for "
+ (mAccount != null ? mAccount.toString() : "?"));
Account currentAccount = ChromeSigninController.get(mActivity).getSignedInUser();
if (mAccount == null || !mAccount.equals(currentAccount)) {
Log.i("InfoBar", "auto-login failed because account is no longer valid");
return false;
}
// The callback for this request comes in on a non-UI thread.
mAccountManager.getAuthToken(mAccount, mAuthTokenType, null, mActivity, this, null);
mLogInRequested = true;
return true;
}
String getAuthToken() {
return mAuthTokenType;
}
String getAccountName() {
return mAccount != null ? mAccount.name : "";
}
boolean loginRequested() {
return mLogInRequested;
}
boolean hasAccount() {
return mAccount != null;
}
@Override
public void run(AccountManagerFuture<Bundle> value) {
String result = null;
try {
result = value.getResult().getString(AccountManager.KEY_AUTHTOKEN);
} catch (Exception e) {
result = null;
}
final boolean success = result != null;
// Can't rely on the Bundle's auth token or account name as they might be null
// if this was a failed attempt.
if (mAutoLoginProcessor != null) {
mAutoLoginProcessor.processAutoLoginResult(getAccountName(), getAuthToken(),
success, result);
}
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.accounts.Account;
import android.app.Activity;
import android.util.Log;
import android.util.SparseArray;
import org.chromium.chrome.R;
import org.chromium.base.CalledByNative;
/**
* Java equivalent of the C++ AutoLoginDelegateAndroid.
*
* Offers functionality to log in using the account in the system and keeps track
* of all the native autologin infobars and their respective accounts.
*/
public class AutoLoginDelegate {
private final Activity mActivity;
private final AutoLoginProcessor mAutoLoginProcessor;
// indexed by nativeInfoBar, think of it as an efficient
// HashMap<nativeInfoBar, AutoLoginAccountDelegate>.
private final SparseArray<AutoLoginAccountDelegate> mAccountHelpers;
public AutoLoginDelegate(AutoLoginProcessor autoLoginProcessor, Activity activity) {
mActivity = activity;
mAutoLoginProcessor = autoLoginProcessor;
mAccountHelpers = new SparseArray<AutoLoginAccountDelegate>();
}
/**
* @return the account name of the device if any.
*/
@CalledByNative
String initializeAccount(int nativeInfoBar, String realm, String account, String args) {
AutoLoginAccountDelegate accountHelper =
new AutoLoginAccountDelegate(mActivity, mAutoLoginProcessor, realm, account, args);
if (!accountHelper.hasAccount()) {
return "";
}
mAccountHelpers.put(nativeInfoBar, accountHelper);
return accountHelper.getAccountName();
}
/**
* Log in a user to a given google service.
*/
@CalledByNative
boolean logIn(int nativeInfoBar) {
AutoLoginAccountDelegate account = mAccountHelpers.get(nativeInfoBar);
if (account == null || !account.logIn()) {
nativeLoginFailed(nativeInfoBar);
return false;
}
return true;
}
/**
* Clear account information for cancelled login requests.
*/
@CalledByNative
boolean cancelLogIn(int nativeInfoBar) {
mAccountHelpers.remove(nativeInfoBar);
return true;
}
/**
* Clear all infobars in the same tab and tells native to proceed with login if successful.
*/
public void dismissAutoLogins(String accountName, String authToken, boolean success,
String result) {
// Use a copy of the current active accounts so we can delete the
// original in the for loop.
SparseArray<AutoLoginAccountDelegate> accountInfo = mAccountHelpers.clone();
for (int i = 0; i < accountInfo.size(); i++) {
int infoBar = accountInfo.keyAt(i);
AutoLoginAccountDelegate delegate = accountInfo.get(infoBar);
if (!delegate.loginRequested()) {
nativeLoginDismiss(infoBar);
} else {
String accountAuthToken = delegate.getAuthToken();
if (accountAuthToken != null && accountAuthToken.equals(authToken)
&& delegate.loginRequested()) {
if (success) {
nativeLoginSuccess(infoBar, result);
} else {
nativeLoginFailed(infoBar);
}
}
}
mAccountHelpers.remove(infoBar);
}
}
private native void nativeLoginSuccess(int nativeAutoLoginInfoBarDelegateAndroid,
String result);
private native void nativeLoginFailed(int nativeAutoLoginInfoBarDelegateAndroid);
private native void nativeLoginDismiss(int nativeAutoLoginInfoBarDelegateAndroid);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
/**
* Process the result of an autologin.
*/
public interface AutoLoginProcessor {
/**
* Process the result of an autologin.
*
* @param accountName The name of the account request is being accessed for.
* @param authToken The authentication token access is being requested for.
* @param success Whether or not the authentication attempt was successful.
* @param result The resulting token for the auto login request
*/
public void processAutoLoginResult(
String accountName, String authToken, boolean success, String result);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.content.Context;
/**
* An infobar that presents the user with 2 buttons (typically OK, Cancel).
*/
public class ConfirmInfoBar extends TwoButtonInfoBar {
// Message to prompt the user.
private final String mMessage;
// Typically set to "OK", or some other positive action.
private final String mPrimaryButtonText;
// Typically set to "Cancel", or some other negative action.
private final String mSecondaryButtonText;
// Listens for when either of the buttons is clicked.
private final InfoBarListeners.Confirm mConfirmListener;
public ConfirmInfoBar(InfoBarListeners.Confirm confirmListener, int backgroundType,
int iconDrawableId, String message, String primaryButtonText,
String secondaryButtonText) {
this(0, confirmListener, backgroundType, iconDrawableId, message, primaryButtonText,
secondaryButtonText);
}
public ConfirmInfoBar(int nativeInfoBar, InfoBarListeners.Confirm confirmListener,
int backgroundType, int iconDrawableId, String message, String primaryButtonText,
String secondaryButtonText) {
super(confirmListener, backgroundType, iconDrawableId);
mMessage = message;
mPrimaryButtonText = primaryButtonText;
mSecondaryButtonText = secondaryButtonText;
mConfirmListener = confirmListener;
setNativeInfoBar(nativeInfoBar);
}
@Override
public CharSequence getMessageText(Context context) {
return mMessage;
}
@Override
public String getPrimaryButtonText(Context context) {
return mPrimaryButtonText;
}
@Override
public String getSecondaryButtonText(Context context) {
return mSecondaryButtonText;
}
@Override
public void onButtonClicked(boolean isPrimaryButton) {
if (mConfirmListener != null) {
mConfirmListener.onConfirmInfoBarButtonClicked(this, isPrimaryButton);
}
if (mNativeInfoBarPtr != 0) {
int action = isPrimaryButton ? InfoBar.ACTION_TYPE_OK : InfoBar.ACTION_TYPE_CANCEL;
nativeOnButtonClicked(mNativeInfoBarPtr, action, "");
}
}
@Override
public void onCloseButtonClicked() {
if (mNativeInfoBarPtr != 0) {
nativeOnCloseButtonClicked(mNativeInfoBarPtr);
}
super.onCloseButtonClicked();
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import org.chromium.base.CalledByNative;
import org.chromium.chrome.browser.ResourceId;
/**
* Provides JNI methods for ConfirmInfoBars
*/
public class ConfirmInfoBarDelegate {
private ConfirmInfoBarDelegate() {
}
@CalledByNative
public static ConfirmInfoBarDelegate create() {
return new ConfirmInfoBarDelegate();
}
/**
* Creates and begins the process for showing a ConfirmInfoBar.
* @param nativeInfoBar Pointer to the C++ InfoBar corresponding to the Java InfoBar.
* @param enumeratedIconId ID corresponding to the icon that will be shown for the InfoBar.
* The ID must have been mapped using the ResourceMapper class before
* passing it to this function.
* @param message Message to display to the user indicating what the InfoBar is for.
* @param buttonOk String to display on the OK button.
* @param buttonCancel String to display on the Cancel button.
*/
@CalledByNative
InfoBar showConfirmInfoBar(int nativeInfoBar, int enumeratedIconId, String message,
String buttonOk, String buttonCancel) {
int drawableId = ResourceId.mapToDrawableId(enumeratedIconId);
// Apparently, yellow was the popular choice at the time these InfoBars were implemented
// because they stuck out more (hence the BACKGROUND_TYPE_WARNING) default.
ConfirmInfoBar infoBar = new ConfirmInfoBar(nativeInfoBar, null,
InfoBar.BACKGROUND_TYPE_WARNING, drawableId, message, buttonOk, buttonCancel);
return infoBar;
}
}
\ No newline at end of file
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.FrameLayout;
import org.chromium.chrome.R;
import org.chromium.base.ApiCompatibilityUtils;
import java.util.ArrayList;
/**
* A wrapper class designed to:
* - consume all touch events. This way the parent view (the FrameLayout ContentView) won't
* have its onTouchEvent called. If it does, ContentView will process the touch click.
* We don't want web content responding to clicks on the InfoBars.
* - allow swapping out of children Views for animations.
*
* Once an InfoBar has been hidden and removed from the InfoBarContainer, it cannot be reused
* because the main panel is discarded after the hiding animation.
*/
public class ContentWrapperView extends FrameLayout {
private static final String TAG = "ContentWrapperView";
// Index of the child View that will get swapped out during transitions.
private static final int CONTENT_INDEX = 0;
private final int mGravity;
private final boolean mInfoBarsFromTop;
private final InfoBar mInfoBar;
private View mViewToHide;
private View mViewToShow;
/**
* Constructs a ContentWrapperView object.
* @param context The context to create this View with.
*/
public ContentWrapperView(Context context, InfoBar infoBar, int backgroundType, View panel,
boolean infoBarsFromTop) {
// Set up this ViewGroup.
super(context);
mInfoBar = infoBar;
mGravity = infoBarsFromTop ? Gravity.BOTTOM : Gravity.TOP;
mInfoBarsFromTop = infoBarsFromTop;
// Pull out resources we need for the backgrounds. Defaults to the INFO type.
int separatorBackground = R.color.infobar_info_background_separator;
int layoutBackground = R.drawable.infobar_info_background;
if (backgroundType == InfoBar.BACKGROUND_TYPE_WARNING) {
layoutBackground = R.drawable.infobar_warning_background;
separatorBackground = R.color.infobar_warning_background_separator;
}
// Set up this view.
Resources resources = context.getResources();
LayoutParams wrapParams = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
setLayoutParams(wrapParams);
ApiCompatibilityUtils.setBackgroundForView(this, resources.getDrawable(layoutBackground));
// Add a separator line that delineates different InfoBars.
View separator = new View(context);
separator.setBackgroundColor(resources.getColor(separatorBackground));
addView(separator, new LayoutParams(LayoutParams.MATCH_PARENT, getBoundaryHeight(context),
mGravity));
// Add the InfoBar content.
addChildView(panel);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return !mInfoBar.areControlsEnabled();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Consume all motion events so they do not reach the ContentView.
return true;
}
/**
* Calculates how tall the InfoBar boundary should be in pixels.
* XHDPI devices and above get a double-tall boundary.
* @return The height of the boundary.
*/
private int getBoundaryHeight(Context context) {
float density = context.getResources().getDisplayMetrics().density;
return density < 2.0f ? 1 : 2;
}
/**
* @return the current View representing the InfoBar.
*/
public boolean hasChildView() {
// If there's a View that can be replaced, there will be at least two children for the View.
// One of the Views will always be the InfoBar separator.
return getChildCount() > 1;
}
/**
* Detaches the View currently being shown and returns it for reparenting.
* @return the View that is currently being shown.
*/
public View detachCurrentView() {
assert getChildCount() > 1;
View view = getChildAt(CONTENT_INDEX);
removeView(view);
return view;
}
/**
* Adds a View to this layout, before the InfoBar separator.
* @param viewToAdd The View to add.
*/
private void addChildView(View viewToAdd) {
addView(viewToAdd, CONTENT_INDEX, new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, mGravity));
}
/**
* Prepares the animation needed to hide the current View and show the new one.
* @param viewToShow View that will replace the currently shown child of this FrameLayout.
*/
public void prepareTransition(View viewToShow) {
assert mViewToHide == null && mViewToShow == null;
// If it exists, the View that is being replaced will be the non-separator child and will
// we in the second position.
assert getChildCount() <= 2;
if (hasChildView()) {
mViewToHide = getChildAt(CONTENT_INDEX);
}
mViewToShow = viewToShow;
assert mViewToHide != null || mViewToShow != null;
assert mViewToHide != mViewToShow;
}
/**
* Called when the animation is starting.
*/
public void startTransition() {
if (mViewToShow != null) {
// Move the View to this container.
ViewParent parent = mViewToShow.getParent();
assert parent != null && parent instanceof ViewGroup;
((ViewGroup) parent).removeView(mViewToShow);
addChildView(mViewToShow);
// We're transitioning between two views; set the alpha so it doesn't pop in.
if (mViewToHide != null) mViewToShow.setAlpha(0.0f);
// Because of layout scheduling, we need to move the child Views downward before it
// occurs. Failure to do so results in the Views being located incorrectly during the
// first few frames of the animation.
if (mInfoBarsFromTop && getViewToShowHeight() > getViewToHideHeight()) {
getLayoutParams().height = getViewToShowHeight();
int translation = getTransitionHeightDifference();
for (int i = 0; i < getChildCount(); ++i) {
View v = getChildAt(i);
v.setTop(v.getTop() + translation);
v.setBottom(v.getBottom() + translation);
}
}
}
}
/**
* Called when the animation is done.
* At this point, we can get rid of the View that used to represent the InfoBar and re-enable
* controls.
*/
public void finishTransition() {
if (mViewToHide != null) {
removeView(mViewToHide);
}
getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
requestLayout();
mViewToHide = null;
mViewToShow = null;
mInfoBar.setControlsEnabled(true);
}
/**
* Returns the height of the View being shown.
* If no new View is going to replace the current one (i.e. the InfoBar is being hidden), the
* height is 0.
*/
private int getViewToShowHeight() {
return mViewToShow == null ? 0 : mViewToShow.getHeight();
}
/**
* Returns the height of the View being hidden.
* If there wasn't a View in the container (i.e. the InfoBar is being animated onto the screen),
* then the height is 0.
*/
private int getViewToHideHeight() {
return mViewToHide == null ? 0 : mViewToHide.getHeight();
}
/**
* @return the difference in height between the View being shown and the View being hidden.
*/
public int getTransitionHeightDifference() {
return getViewToShowHeight() - getViewToHideHeight();
}
/**
* Creates animations for transitioning between the two Views.
* @param animators ArrayList to append the transition Animators to.
*/
public void getAnimationsForTransition(ArrayList<Animator> animators) {
if (mViewToHide != null && mViewToShow != null) {
ObjectAnimator hideAnimator;
hideAnimator = ObjectAnimator.ofFloat((Object)mViewToHide, "alpha", 1.0f, 0.0f);
animators.add(hideAnimator);
ObjectAnimator showAnimator;
showAnimator = ObjectAnimator.ofFloat((Object)mViewToShow, "alpha", 0.0f, 1.0f);
animators.add(showAnimator);
}
}
/**
* Calculates a Rect that prevents this ContentWrapperView from overlapping its siblings.
* Because of the way the InfoBarContainer stores its children, Android will cause the InfoBars
* to overlap when a bar is slid towards the top of the screen. This calculates a bounding box
* around this ContentWrapperView that clips the InfoBar to be drawn solely in the space it was
* occupying before being translated anywhere.
* @return the calculated bounding box
*/
public Rect getClippingRect() {
int maxHeight = Math.max(getViewToHideHeight(), getViewToShowHeight());
return new Rect(getLeft(), getTop(), getRight(), getTop() + maxHeight);
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.content.Context;
import android.view.View;
import android.widget.ImageButton;
import org.chromium.chrome.R;
import com.google.common.annotations.VisibleForTesting;
import org.chromium.base.CalledByNative;
/**
* The base class for all InfoBar classes.
* Note that infobars expire by default when a new navigation occurs.
* Make sure to use setExpireOnNavigation(false) if you want an infobar to be sticky.
*/
public abstract class InfoBar implements InfoBarView {
private static final String TAG = "InfoBar";
/**
* Possible labels of all the infobar buttons.
*
* Make sure this set of values is aligned with the C++ correspondent in
* infobar_android.h
*/
public static final int ACTION_TYPE_NONE = 0;
// Confirm infobar
public static final int ACTION_TYPE_OK = 1;
public static final int ACTION_TYPE_CANCEL = 2;
// Translate infobar
public static final int ACTION_TYPE_TRANSLATE = 3;
public static final int ACTION_TYPE_TRANSLATE_SHOW_ORIGINAL = 4;
// Background types
public static final int BACKGROUND_TYPE_INFO = 0;
public static final int BACKGROUND_TYPE_WARNING = 1;
private final int mBackgroundType;
private final int mIconDrawableId;
private InfoBarListeners.Dismiss mListener;
private ContentWrapperView mContentView;
private InfoBarContainer mContainer;
private Context mContext;
private boolean mExpireOnNavigation;
private boolean mIsDismissed;
private boolean mControlsEnabled;
protected int mNativeInfoBarPtr;
// Used by tests to reference infobars.
private final int mId;
private static int sIdCounter = 0;
private static int generateId() {
return sIdCounter++;
}
/**
* @param listener Listens to when buttons have been clicked on the InfoBar.
* @param backgroundType Background type to use (INFO or WARNING).
* @param iconDrawableId ID of the resource to use for the Icon. If 0, no icon will be shown.
*/
public InfoBar(InfoBarListeners.Dismiss listener, int backgroundType, int iconDrawableId) {
mListener = listener;
mId = generateId();
mBackgroundType = backgroundType;
mIconDrawableId = iconDrawableId;
mExpireOnNavigation = true;
}
/**
* Stores a pointer to the native-side counterpart of this InfoBar.
* @param nativeInfoBarPtr Pointer to the NativeInfoBar.
*/
protected void setNativeInfoBar(int nativeInfoBarPtr) {
if (nativeInfoBarPtr != 0) {
// The native code takes care of expiring infobars on navigations.
mExpireOnNavigation = false;
mNativeInfoBarPtr = nativeInfoBarPtr;
}
}
/**
* Change the pointer to the native-side counterpart of this InfoBar. Native-side code is
* responsible for managing the cleanup of the pointer.
* @param nativeInfoBarPtr Pointer to the NativeInfoBar.
*/
protected void replaceNativePointer(int newInfoBarPtr) {
mNativeInfoBarPtr = newInfoBarPtr;
}
// Determine if the infobar should be dismissed when |url| is loaded. Calling
// setExpireOnNavigation(true/false) causes this method always to return true/false.
// For more control, subclasses can override this method and take the url into account.
public boolean shouldExpire(String url) {
return mExpireOnNavigation;
}
// Sets whether the bar should be dismissed when a navigation occurs.
public void setExpireOnNavigation(boolean expireOnNavigation) {
mExpireOnNavigation = expireOnNavigation;
}
/**
* @return true if this java infobar owns this {@code nativePointer}
*/
boolean ownsNativeInfoBar(int nativePointer) {
return mNativeInfoBarPtr == nativePointer;
}
/**
* @return whether or not the InfoBar has been dismissed.
*/
protected boolean isDismissed() {
return mIsDismissed;
}
/**
* Sets the Context used when creating the InfoBar.
*/
protected void setContext(Context context) {
mContext = context;
}
/**
* @return The Context used to create the InfoBar. This will be null until the InfoBar is added
* to the InfoBarContainer, and should never be null afterward.
*/
protected Context getContext() {
return mContext;
}
/**
* Creates the View that represents the InfoBar.
* @return The View representing the InfoBar.
*/
protected final View createView() {
assert mContext != null;
return new InfoBarLayout(mContext, this, mBackgroundType, mIconDrawableId);
}
/**
* Used to close an infobar from java. In addition to closing the infobar, notifies native
* that the bar needs closing.
*/
public void dismiss() {
if (closeInfoBar() && mNativeInfoBarPtr != 0) {
// We are being closed from Java, notify C++.
nativeOnInfoBarClosed(mNativeInfoBarPtr);
mNativeInfoBarPtr = 0;
}
}
/**
* Used to close an infobar from native.
*
* @return whether the infobar actually needed closing.
*/
@CalledByNative
public boolean closeInfoBar() {
if (!mIsDismissed) {
mIsDismissed = true;
if (!mContainer.hasBeenDestroyed()) {
// If the container was destroyed, it's already been emptied of all its infobars.
mContainer.removeInfoBar(this);
}
if (mListener != null) {
mListener.onInfoBarDismissed(this);
}
return true;
}
return false;
}
protected ContentWrapperView getContentWrapper(boolean createIfNotFound) {
if (mContentView == null && createIfNotFound) {
mContentView = new ContentWrapperView(getContext(), this, mBackgroundType,
createView(), getInfoBarContainer().areInfoBarsOnTop());
mContentView.setFocusable(false);
}
return mContentView;
}
protected InfoBarContainer getInfoBarContainer() {
return mContainer;
}
/**
* @return The content view for the info bar.
*/
public ContentWrapperView getContentWrapper() {
return getContentWrapper(true);
}
void setInfoBarContainer(InfoBarContainer container) {
mContainer = container;
}
public boolean areControlsEnabled() {
return mControlsEnabled;
}
@Override
public void setControlsEnabled(boolean state) {
mControlsEnabled = state;
// Handle the close button.
if (mContentView != null) {
View closeButton = mContentView.findViewById(R.id.infobar_close_button);
if (closeButton != null) closeButton.setEnabled(state);
}
}
@Override
public void onButtonClicked(boolean isPrimaryButton) {
}
@Override
public void onCloseButtonClicked() {
dismiss();
}
@Override
public void createContent(InfoBarLayout layout) {
}
@Override
public String getPrimaryButtonText(Context context) {
return null;
}
@Override
public String getSecondaryButtonText(Context context) {
return null;
}
/**
* Returns the id of the tab this infobar is showing into.
*/
public int getTabId() {
return mContainer.getTabId();
}
@VisibleForTesting
public int getId() {
return mId;
}
@VisibleForTesting
public void setDismissedListener(InfoBarListeners.Dismiss listener) {
mListener = listener;
}
protected native void nativeOnInfoBarClosed(int nativeInfoBarAndroid);
protected native void nativeOnButtonClicked(
int nativeInfoBarAndroid, int action, String actionValue);
protected native void nativeOnCloseButtonClicked(int nativeInfoBarAndroid);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
/**
* A collection of listeners for different infobar events.
*/
public class InfoBarListeners {
/**
* Called whenever an infobar is dismissed, either manually or as a side
* effect of a navigation, replacing the infobar...
*/
public interface Dismiss {
void onInfoBarDismissed(InfoBar infoBar);
}
public interface Confirm extends Dismiss {
/**
* Called whenever an infobar's confirm or cancel button is clicked.
*/
public void onConfirmInfoBarButtonClicked(
ConfirmInfoBar infoBar, boolean confirm);
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.content.Context;
/**
* Functions needed to display an InfoBar UI.
*/
public interface InfoBarView {
/**
* Prepare the InfoBar for display and adding InfoBar-specific controls to the layout.
* @param layout Layout containing all of the controls.
*/
public void createContent(InfoBarLayout layout);
/**
* Returns the message indicating what the InfoBar is informing or asking the user about.
* @param context Context to pull the string from.
* @return The string to display.
*/
public CharSequence getMessageText(Context context);
/**
* Returns text to display on the primary button indicating that some action will be taken.
* Setting this to null prevents the button from being created.
* @param context Context to pull the string from.
* @return The string to display.
*/
public String getPrimaryButtonText(Context context);
/**
* Returns text to display on the secondary button, typically indicating that some action will
* not be taken.
*
* Example text includes "Cancel" or "Nope". Setting this to null prevents the button from
* being created. It is illegal to have a secondary button without a primary button.
*
* @param context Context to pull the string from.
* @return The string to display.
*/
public String getSecondaryButtonText(Context context);
/**
* Take some action related to the close button being clicked.
*/
public void onCloseButtonClicked();
/**
* Performs some action related to either the primary or secondary button being pressed.
* @param isPrimaryButton True if the primary button was clicked, false otherwise.
*/
public void onButtonClicked(boolean isPrimaryButton);
/**
* Sets whether or not controls for this View should be clickable.
* @param state If set to false, controls cannot be clicked and will be grayed out.
*/
public void setControlsEnabled(boolean state);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.content.Context;
import android.widget.TextView;
import org.chromium.chrome.R;
/**
* A simple infobar that contains a message and a close icon on the right side.
* This is used only in the context of Java code and is not associated with any native
* InfoBarDelegate.
*/
public class MessageInfoBar extends InfoBar {
private CharSequence mTitle;
/**
* Creates and returns an infobar with a white background and a close button on the right.
* @param title the text displayed in the infobar
* @return the infobar.
*/
public static MessageInfoBar createInfoBar(CharSequence title) {
return new MessageInfoBar(null, 0, title, BACKGROUND_TYPE_INFO);
}
/**
* Creates and returns an infobar with a white background and a close button on the right.
* @param iconResourceId the icon shown on the right
* @param title the text displayed in the infobar
* @return the infobar.
*/
public static MessageInfoBar createInfoBar(int iconResourceId, CharSequence title) {
return new MessageInfoBar(null, iconResourceId, title, BACKGROUND_TYPE_INFO);
}
/**
* Creates a warning infobar, with a yellow background and a warning icon on the right.
* @param title the text displayed in the infobar
* @return the infobar.
*/
public static MessageInfoBar createWarningInfoBar(CharSequence title) {
return createWarningInfoBar(null, title);
}
/**
* Creates a warning infobar, with a yellow background and a warning icon on the right.
* @param listener an infobar dismissed listener
* @param title the text displayed in the infobar
* @return the infobar.
*/
public static MessageInfoBar createWarningInfoBar(InfoBarListeners.Dismiss listener,
CharSequence title) {
return new MessageInfoBar(listener, R.drawable.warning, title, BACKGROUND_TYPE_WARNING);
}
protected MessageInfoBar(InfoBarListeners.Dismiss listener, int iconResourceId,
CharSequence title, int backgroundType) {
super(listener, backgroundType, iconResourceId);
mTitle = title;
}
@Override
public CharSequence getMessageText(Context context) {
return mTitle;
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.infobar;
import android.content.Context;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.chromium.chrome.R;
/**
* An infobar that presents the user with up to 2 buttons.
*/
public abstract class TwoButtonInfoBar extends InfoBar {
public TwoButtonInfoBar(InfoBarListeners.Dismiss dismissListener, int backgroundType,
int iconDrawableId) {
super(dismissListener, backgroundType, iconDrawableId);
}
/**
* Creates controls for the current InfoBar.
* @param layout InfoBarLayout to find controls in.
*/
@Override
public void createContent(InfoBarLayout layout) {
Context context = layout.getContext();
layout.addButtons(getPrimaryButtonText(context), getSecondaryButtonText(context));
}
@Override
public void setControlsEnabled(boolean state) {
super.setControlsEnabled(state);
// Handle the buttons.
ContentWrapperView wrapper = getContentWrapper(false);
if (wrapper != null) {
Button primary = (Button) wrapper.findViewById(R.id.button_primary);
Button secondary = (Button) wrapper.findViewById(R.id.button_secondary);
if (primary != null) primary.setEnabled(state);
if (secondary != null) secondary.setEnabled(state);
}
}
}
...@@ -65,6 +65,10 @@ You are signing in with a managed account and giving its administrator control o ...@@ -65,6 +65,10 @@ You are signing in with a managed account and giving its administrator control o
<message desc="Message for the progress dialog shown while profile data is being wiped after signing out of an enterprise account" name="IDS_WIPING_PROFILE_DATA_MESSAGE"> <message desc="Message for the progress dialog shown while profile data is being wiped after signing out of an enterprise account" name="IDS_WIPING_PROFILE_DATA_MESSAGE">
Please wait... Please wait...
</message> </message>
<!-- InfoBar -->
<message desc="Accessibility label for the dismiss infobar Button" name="IDS_INFOBAR_CLOSE">
Close
</message>
</messages> </messages>
</release> </release>
<translations> <translations>
......
...@@ -3,10 +3,7 @@ ...@@ -3,10 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/translate/translate_infobar_delegate.h" #include "chrome/browser/translate/translate_infobar_delegate.h"
#include "chrome/browser/ui/auto_login_infobar_delegate.h"
#include "chrome/browser/ui/auto_login_infobar_delegate_android.h"
#include "printing/printing_context.h" #include "printing/printing_context.h"
#include "printing/printing_context_android.h" #include "printing/printing_context_android.h"
...@@ -17,38 +14,6 @@ ...@@ -17,38 +14,6 @@
class InfoBarService; class InfoBarService;
// AutoLoginInfoBarDelegatAndroid empty implementation for test_shell
// TODO(miguelg) remove once the AutoLoginInfoBar is upstreamed.
AutoLoginInfoBarDelegateAndroid::AutoLoginInfoBarDelegateAndroid(
InfoBarService* owner,
const AutoLoginInfoBarDelegate::Params& params)
: AutoLoginInfoBarDelegate(owner, params), params_() {}
AutoLoginInfoBarDelegateAndroid::~AutoLoginInfoBarDelegateAndroid() {}
bool AutoLoginInfoBarDelegateAndroid::Accept() {
return false;
}
bool AutoLoginInfoBarDelegateAndroid::Cancel() {
return false;
}
base::string16 AutoLoginInfoBarDelegateAndroid::GetMessageText() const {
return base::string16();
}
// static
bool AutoLoginInfoBarDelegateAndroid::Register(JNIEnv* env) {
return false;
}
// static
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
NOTREACHED() << "ConfirmInfoBar: InfoBarFactory should be used on Android";
return NULL;
}
// static // static
InfoBar* TranslateInfoBarDelegate::CreateInfoBar(InfoBarService* owner) { InfoBar* TranslateInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
return NULL; return NULL;
......
...@@ -36,11 +36,15 @@ ...@@ -36,11 +36,15 @@
#include "chrome/browser/ui/android/autofill/autofill_dialog_result.h" #include "chrome/browser/ui/android/autofill/autofill_dialog_result.h"
#include "chrome/browser/ui/android/autofill/autofill_popup_view_android.h" #include "chrome/browser/ui/android/autofill/autofill_popup_view_android.h"
#include "chrome/browser/ui/android/chrome_http_auth_handler.h" #include "chrome/browser/ui/android/chrome_http_auth_handler.h"
#include "chrome/browser/ui/android/infobar/confirm_infobar.h"
#include "chrome/browser/ui/android/infobar/infobar_android.h"
#include "chrome/browser/ui/android/infobar/infobar_container_android.h"
#include "chrome/browser/ui/android/javascript_app_modal_dialog_android.h" #include "chrome/browser/ui/android/javascript_app_modal_dialog_android.h"
#include "chrome/browser/ui/android/navigation_popup.h" #include "chrome/browser/ui/android/navigation_popup.h"
#include "chrome/browser/ui/android/ssl_client_certificate_request.h" #include "chrome/browser/ui/android/ssl_client_certificate_request.h"
#include "chrome/browser/ui/android/validation_message_bubble_android.h" #include "chrome/browser/ui/android/validation_message_bubble_android.h"
#include "chrome/browser/ui/android/website_settings_popup_android.h" #include "chrome/browser/ui/android/website_settings_popup_android.h"
#include "chrome/browser/ui/auto_login_infobar_delegate_android.h"
#include "components/autofill/core/browser/android/component_jni_registrar.h" #include "components/autofill/core/browser/android/component_jni_registrar.h"
#include "components/navigation_interception/component_jni_registrar.h" #include "components/navigation_interception/component_jni_registrar.h"
#include "components/web_contents_delegate_android/component_jni_registrar.h" #include "components/web_contents_delegate_android/component_jni_registrar.h"
...@@ -68,6 +72,7 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = { ...@@ -68,6 +72,7 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = {
autofill::AutofillDialogResult::RegisterAutofillDialogResult }, autofill::AutofillDialogResult::RegisterAutofillDialogResult },
{ "AutofillPopup", { "AutofillPopup",
autofill::AutofillPopupViewAndroid::RegisterAutofillPopupViewAndroid }, autofill::AutofillPopupViewAndroid::RegisterAutofillPopupViewAndroid },
{"AutoLoginDelegate", AutoLoginInfoBarDelegateAndroid::Register},
{ "BookmarksBridge", BookmarksBridge::RegisterBookmarksBridge }, { "BookmarksBridge", BookmarksBridge::RegisterBookmarksBridge },
{ "CertificateViewer", RegisterCertificateViewer }, { "CertificateViewer", RegisterCertificateViewer },
{ "ChromeBrowserProvider", { "ChromeBrowserProvider",
...@@ -76,6 +81,7 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = { ...@@ -76,6 +81,7 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = {
ChromeHttpAuthHandler::RegisterChromeHttpAuthHandler }, ChromeHttpAuthHandler::RegisterChromeHttpAuthHandler },
{ "ChromeWebContentsDelegateAndroid", { "ChromeWebContentsDelegateAndroid",
RegisterChromeWebContentsDelegateAndroid }, RegisterChromeWebContentsDelegateAndroid },
{"ConfirmInfoBarDelegate", RegisterConfirmInfoBarDelegate},
{ "ContentViewUtil", RegisterContentViewUtil }, { "ContentViewUtil", RegisterContentViewUtil },
{ "DevToolsServer", RegisterDevToolsServer }, { "DevToolsServer", RegisterDevToolsServer },
{ "InvalidationController", invalidation::RegisterInvalidationController }, { "InvalidationController", invalidation::RegisterInvalidationController },
...@@ -83,11 +89,13 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = { ...@@ -83,11 +89,13 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = {
{ "FieldTrialHelper", RegisterFieldTrialHelper }, { "FieldTrialHelper", RegisterFieldTrialHelper },
{ "ForeignSessionHelper", { "ForeignSessionHelper",
ForeignSessionHelper::RegisterForeignSessionHelper }, ForeignSessionHelper::RegisterForeignSessionHelper },
{"InfoBarContainer", RegisterInfoBarContainer},
{ "ShortcutHelper", ShortcutHelper::RegisterShortcutHelper }, { "ShortcutHelper", ShortcutHelper::RegisterShortcutHelper },
{ "IntentHelper", RegisterIntentHelper }, { "IntentHelper", RegisterIntentHelper },
{ "JavascriptAppModalDialog", { "JavascriptAppModalDialog",
JavascriptAppModalDialogAndroid::RegisterJavascriptAppModalDialog }, JavascriptAppModalDialogAndroid::RegisterJavascriptAppModalDialog },
{ "MostVisitedSites", RegisterMostVisitedSites }, { "MostVisitedSites", RegisterMostVisitedSites },
{"NativeInfoBar", RegisterNativeInfoBar},
{ "NavigationPopup", NavigationPopup::RegisterNavigationPopup }, { "NavigationPopup", NavigationPopup::RegisterNavigationPopup },
{ "OmniboxPrerender", RegisterOmniboxPrerender }, { "OmniboxPrerender", RegisterOmniboxPrerender },
{ "PersonalDataManagerAndroid", { "PersonalDataManagerAndroid",
......
...@@ -6,45 +6,10 @@ ...@@ -6,45 +6,10 @@
// needed to compile some tests. // needed to compile some tests.
#include "chrome/browser/android/tab_android.h" #include "chrome/browser/android/tab_android.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/translate/translate_infobar_delegate.h" #include "chrome/browser/translate/translate_infobar_delegate.h"
#include "chrome/browser/ui/auto_login_infobar_delegate.h"
#include "chrome/browser/ui/auto_login_infobar_delegate_android.h"
#include "printing/printing_context.h" #include "printing/printing_context.h"
#include "printing/printing_context_android.h" #include "printing/printing_context_android.h"
// AutoLoginInfoBarDelegatAndroid empty implementation for test_shell.
// TODO(miguelg) remove once the AutoLoginInfoBar is upstreamed.
AutoLoginInfoBarDelegateAndroid::AutoLoginInfoBarDelegateAndroid(
InfoBarService* owner,
const AutoLoginInfoBarDelegate::Params& params)
: AutoLoginInfoBarDelegate(owner, params), params_() {}
AutoLoginInfoBarDelegateAndroid::~AutoLoginInfoBarDelegateAndroid() {}
bool AutoLoginInfoBarDelegateAndroid::Accept() {
return false;
}
bool AutoLoginInfoBarDelegateAndroid::Cancel() {
return false;
}
base::string16 AutoLoginInfoBarDelegateAndroid::GetMessageText() const {
return base::string16();
}
// static
bool AutoLoginInfoBarDelegateAndroid::Register(JNIEnv* env) {
return false;
}
// static
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
NOTREACHED() << "ConfirmInfoBar: InfoBarFactory should be used on Android";
return NULL;
}
// static // static
InfoBar* TranslateInfoBarDelegate::CreateInfoBar(InfoBarService* owner) { InfoBar* TranslateInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
return NULL; return NULL;
......
dfalcantara@chromium.org
miguelg@chromium.org
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/auto_login_infobar_delegate_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_helper.h"
#include "base/android/jni_string.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/infobars/simple_alert_infobar_delegate.h"
#include "chrome/browser/ui/auto_login_infobar_delegate.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "jni/AutoLoginDelegate_jni.h"
#include "ui/base/l10n/l10n_util.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
AutoLoginInfoBarDelegateAndroid::AutoLoginInfoBarDelegateAndroid(
InfoBarService* owner,
const Params& params)
: AutoLoginInfoBarDelegate(owner, params), params_(params) {}
AutoLoginInfoBarDelegateAndroid::~AutoLoginInfoBarDelegateAndroid() {}
bool AutoLoginInfoBarDelegateAndroid::AttachAccount(
JavaObjectWeakGlobalRef weak_java_auto_login_delegate) {
weak_java_auto_login_delegate_ = weak_java_auto_login_delegate;
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm());
ScopedJavaLocalRef<jstring> jaccount =
ConvertUTF8ToJavaString(env, account());
ScopedJavaLocalRef<jstring> jargs = ConvertUTF8ToJavaString(env, args());
DCHECK(!jrealm.is_null() && !jaccount.is_null() && !jargs.is_null());
ScopedJavaLocalRef<jobject> delegate =
weak_java_auto_login_delegate_.get(env);
DCHECK(delegate.obj());
user_ = ConvertJavaStringToUTF8(
Java_AutoLoginDelegate_initializeAccount(env,
delegate.obj(),
reinterpret_cast<jint>(this),
jrealm.obj(),
jaccount.obj(),
jargs.obj()));
return !user_.empty();
}
string16 AutoLoginInfoBarDelegateAndroid::GetMessageText() const {
return l10n_util::GetStringFUTF16(IDS_AUTOLOGIN_INFOBAR_MESSAGE,
UTF8ToUTF16(user_));
}
bool AutoLoginInfoBarDelegateAndroid::Accept() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> delegate =
weak_java_auto_login_delegate_.get(env);
DCHECK(delegate.obj());
Java_AutoLoginDelegate_logIn(
env, delegate.obj(), reinterpret_cast<jint>(this));
// Do not close the infobar on accept, it will be closed as part
// of the log in callback.
return false;
}
bool AutoLoginInfoBarDelegateAndroid::Cancel() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> delegate =
weak_java_auto_login_delegate_.get(env);
DCHECK(delegate.obj());
Java_AutoLoginDelegate_cancelLogIn(
env, delegate.obj(), reinterpret_cast<jint>(this));
return true;
}
void AutoLoginInfoBarDelegateAndroid::LoginSuccess(JNIEnv* env,
jobject obj,
jstring result) {
if (owner()) {
content::WebContents* web_contents = owner()->web_contents();
if (web_contents) {
web_contents->Stop();
web_contents->OpenURL(content::OpenURLParams(
GURL(base::android::ConvertJavaStringToUTF8(env, result)),
content::Referrer(),
CURRENT_TAB,
content::PAGE_TRANSITION_AUTO_BOOKMARK,
false));
}
owner()->RemoveInfoBar(this);
}
}
void AutoLoginInfoBarDelegateAndroid::LoginFailed(JNIEnv* env, jobject obj) {
ScopedJavaLocalRef<jobject> delegate =
weak_java_auto_login_delegate_.get(env);
DCHECK(delegate.obj());
if (owner()) {
SimpleAlertInfoBarDelegate::Create(
owner(),
IDR_INFOBAR_WARNING,
l10n_util::GetStringUTF16(IDS_AUTO_LOGIN_FAILED),
false);
owner()->RemoveInfoBar(this);
}
}
void AutoLoginInfoBarDelegateAndroid::LoginDismiss(JNIEnv* env, jobject obj) {
if (owner())
owner()->RemoveInfoBar(this);
}
// Register Android JNI bindings.
bool AutoLoginInfoBarDelegateAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/android/infobar/confirm_infobar.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/logging.h"
#include "chrome/browser/android/resource_mapper.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "jni/ConfirmInfoBarDelegate_jni.h"
using base::android::ConvertUTF16ToJavaString;
using base::android::ScopedJavaLocalRef;
// static
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
return new ConfirmInfoBar(owner, this);
}
ConfirmInfoBar::ConfirmInfoBar(InfoBarService* owner, InfoBarDelegate* delegate)
: InfoBarAndroid(owner, delegate),
delegate_(delegate->AsConfirmInfoBarDelegate()),
java_confirm_delegate_() {}
ConfirmInfoBar::~ConfirmInfoBar() {}
ScopedJavaLocalRef<jobject> ConfirmInfoBar::CreateRenderInfoBar(JNIEnv* env) {
java_confirm_delegate_.Reset(Java_ConfirmInfoBarDelegate_create(env));
ScopedJavaLocalRef<jstring> ok_button_text =
ConvertUTF16ToJavaString(env, GetTextFor(InfoBarAndroid::ACTION_OK));
ScopedJavaLocalRef<jstring> cancel_button_text =
ConvertUTF16ToJavaString(env, GetTextFor(InfoBarAndroid::ACTION_CANCEL));
ScopedJavaLocalRef<jstring> message_text =
ConvertUTF16ToJavaString(env, GetMessage());
return Java_ConfirmInfoBarDelegate_showConfirmInfoBar(
env,
java_confirm_delegate_.obj(),
reinterpret_cast<jint>(this),
GetEnumeratedIconId(),
message_text.obj(),
ok_button_text.obj(),
cancel_button_text.obj());
}
void ConfirmInfoBar::ProcessButton(int action,
const std::string& action_value) {
DCHECK(action == InfoBarAndroid::ACTION_OK ||
action == InfoBarAndroid::ACTION_CANCEL);
if ((action == InfoBarAndroid::ACTION_OK) ? delegate_->Accept()
: delegate_->Cancel())
CloseInfoBar();
}
string16 ConfirmInfoBar::GetTextFor(ActionType action) {
int buttons = delegate_->GetButtons();
switch (action) {
case InfoBarAndroid::ACTION_OK:
if (buttons & ConfirmInfoBarDelegate::BUTTON_OK)
return delegate_->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK);
break;
case InfoBarAndroid::ACTION_CANCEL:
if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL)
return delegate_->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL);
break;
default:
break;
}
return string16();
}
string16 ConfirmInfoBar::GetMessage() {
return delegate_->GetMessageText();
}
// -----------------------------------------------------------------------------
// Native JNI methods for confirm delegate.
// -----------------------------------------------------------------------------
bool RegisterConfirmInfoBarDelegate(JNIEnv* env) {
return RegisterNativesImpl(env);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_ANDROID_INFOBAR_CONFIRM_INFOBAR_H_
#define CHROME_BROWSER_UI_ANDROID_INFOBAR_CONFIRM_INFOBAR_H_
#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "chrome/browser/ui/android/infobar/infobar_android.h"
class ConfirmInfoBarDelegate;
namespace gfx {
class Image;
}
// Implementation of InfoBar for confirm infobars, this currently
// includes, geolocation, popups..
class ConfirmInfoBar : public InfoBarAndroid {
public:
ConfirmInfoBar(InfoBarService* owner, InfoBarDelegate* delegate);
virtual ~ConfirmInfoBar();
private:
// InfoBar overrides.
virtual base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar(
JNIEnv* env) OVERRIDE;
virtual void ProcessButton(int action,
const std::string& action_value) OVERRIDE;
string16 GetTextFor(ActionType action);
string16 GetMessage();
ConfirmInfoBarDelegate* delegate_;
base::android::ScopedJavaGlobalRef<jobject> java_confirm_delegate_;
DISALLOW_COPY_AND_ASSIGN(ConfirmInfoBar);
};
// Registers native methods
bool RegisterConfirmInfoBarDelegate(JNIEnv* env);
#endif // CHROME_BROWSER_UI_ANDROID_INFOBAR_CONFIRM_INFOBAR_H_
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/android/infobar/infobar_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/strings/string_util.h"
#include "chrome/browser/android/resource_mapper.h"
#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_delegate.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "jni/InfoBar_jni.h"
namespace gfx {
class Image;
}
using base::android::AttachCurrentThread;
using base::android::JavaRef;
// static constants defined in infobar.h we don't really use them for anything
// but they are required. The values are copied from the GTK implementation.
const int InfoBar::kSeparatorLineHeight = 1;
const int InfoBar::kDefaultArrowTargetHeight = 9;
const int InfoBar::kMaximumArrowTargetHeight = 24;
const int InfoBar::kDefaultArrowTargetHalfWidth = kDefaultArrowTargetHeight;
const int InfoBar::kMaximumArrowTargetHalfWidth = 14;
const int InfoBar::kDefaultBarTargetHeight = 36;
InfoBarAndroid::InfoBarAndroid(InfoBarService* owner, InfoBarDelegate* delegate)
: InfoBar(owner, delegate),
delegate_(delegate) {
DCHECK(delegate_);
DCHECK(delegate_->owner());
}
InfoBarAndroid::~InfoBarAndroid() {}
void InfoBarAndroid::ReassignJavaInfoBar(InfoBarAndroid* replacement) {
DCHECK(replacement);
if (!java_info_bar_.is_null()) {
replacement->set_java_infobar(java_info_bar_);
java_info_bar_.Reset();
}
}
void InfoBarAndroid::set_java_infobar(const JavaRef<jobject>& java_info_bar) {
DCHECK(java_info_bar_.is_null());
java_info_bar_.Reset(java_info_bar);
}
bool InfoBarAndroid::HasSetJavaInfoBar() const {
return !java_info_bar_.is_null();
}
void InfoBarAndroid::OnButtonClicked(
JNIEnv* env, jobject obj, jint action, jstring action_value) {
DCHECK(delegate_);
std::string value = base::android::ConvertJavaStringToUTF8(env, action_value);
ProcessButton(action, value);
}
void InfoBarAndroid::OnCloseButtonClicked(JNIEnv* env, jobject obj) {
delegate_->InfoBarDismissed();
}
void InfoBarAndroid::OnInfoBarClosed(JNIEnv* env, jobject obj) {
java_info_bar_.Reset(); // So we don't notify Java.
if (owner())
RemoveSelf();
}
void InfoBarAndroid::CloseInfoBar() {
CloseJavaInfoBar();
if (owner())
RemoveSelf();
}
void InfoBarAndroid::CloseJavaInfoBar() {
if (!java_info_bar_.is_null()) {
JNIEnv* env = AttachCurrentThread();
Java_InfoBar_closeInfoBar(env, java_info_bar_.obj());
}
}
int InfoBarAndroid::GetEnumeratedIconId() {
DCHECK(delegate_);
return ResourceMapper::MapFromChromiumId(delegate_->GetIconID());
}
// -----------------------------------------------------------------------------
// Native JNI methods
// -----------------------------------------------------------------------------
// Register native methods
bool RegisterNativeInfoBar(JNIEnv* env) {
return RegisterNativesImpl(env);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_ANDROID_INFOBAR_INFOBAR_ANDROID_H_
#define CHROME_BROWSER_UI_ANDROID_INFOBAR_INFOBAR_ANDROID_H_
#include <string>
#include "base/android/jni_helper.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "chrome/browser/infobars/infobar.h"
class InfoBarDelegate;
class InfoBarService;
namespace gfx {
class Image;
}
class InfoBarAndroid : public InfoBar {
public:
// Make sure this set of values is aligned with the java constants defined in
// InfoBar.java
enum ActionType {
ACTION_NONE = 0,
// Confirm infobar
ACTION_OK = 1,
ACTION_CANCEL = 2,
// Translate infobar
ACTION_TRANSLATE = 3,
ACTION_TRANSLATE_SHOW_ORIGINAL = 4,
};
InfoBarAndroid(InfoBarService* owner, InfoBarDelegate* delegate);
virtual ~InfoBarAndroid();
// InfoBar
virtual base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar(
JNIEnv* env) = 0;
void set_java_infobar(const base::android::JavaRef<jobject>& java_info_bar);
bool HasSetJavaInfoBar() const;
// Tells the Java-side counterpart of this InfoBar to point to the replacement
// InfoBar instead of this one.
void ReassignJavaInfoBar(InfoBarAndroid* replacement);
void OnButtonClicked(JNIEnv* env, jobject obj,
jint action, jstring action_value);
void OnCloseButtonClicked(JNIEnv* env, jobject obj);
void OnInfoBarClosed(JNIEnv* env, jobject obj);
void CloseJavaInfoBar();
// Maps from a Chromium ID (IDR_TRANSLATE) to a enum value that Java code can
// translate into a Drawable ID using the ResourceId class.
int GetEnumeratedIconId();
// Acquire the java infobar from a different one.
// This is used to do in place replacements.
virtual void PassJavaInfoBar(InfoBarAndroid* source) {}
protected:
// Derived classes must implement this method to process the
// corresponding action.
virtual void ProcessButton(
int action, const std::string& action_value) = 0;
void CloseInfoBar();
private:
// The InfoBar's delegate.
InfoBarDelegate* delegate_;
base::android::ScopedJavaGlobalRef<jobject> java_info_bar_;
DISALLOW_COPY_AND_ASSIGN(InfoBarAndroid);
};
// Register the NativeInfoBar's native methods through jni
bool RegisterNativeInfoBar(JNIEnv* env);
#endif // CHROME_BROWSER_UI_ANDROID_INFOBAR_INFOBAR_ANDROID_H_
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/android/infobar/infobar_container_android.h"
#include "base/android/jni_android.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_delegate.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/ui/android/infobar/infobar_android.h"
#include "chrome/browser/ui/auto_login_infobar_delegate_android.h"
#include "content/public/browser/web_contents.h"
#include "jni/InfoBarContainer_jni.h"
using base::android::AttachCurrentThread;
using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;
using content::WebContents;
// InfoBarContainerAndroid
InfoBarContainerAndroid::InfoBarContainerAndroid(JNIEnv* env,
jobject obj,
jobject auto_login_delegate)
: InfoBarContainer(NULL),
weak_java_infobar_container_(env, obj),
weak_java_auto_login_delegate_(env, auto_login_delegate) {}
InfoBarContainerAndroid::~InfoBarContainerAndroid() {
RemoveAllInfoBarsForDestruction();
}
void InfoBarContainerAndroid::Destroy(JNIEnv* env, jobject obj) {
delete this;
}
// TODO(miguelg) Move this out of infobar container.
void InfoBarContainerAndroid::OnWebContentsReplaced(
WebContents* old_web_contents,
WebContents* new_web_contents) {
InfoBarService* new_infobar_service = NULL;
if (new_web_contents)
new_infobar_service = InfoBarService::FromWebContents(new_web_contents);
if (!new_infobar_service)
return;
ChangeInfoBarService(new_infobar_service);
}
// InfobarContainer
void InfoBarContainerAndroid::PlatformSpecificAddInfoBar(InfoBar* infobar,
size_t position) {
DCHECK(infobar);
InfoBarAndroid* android_bar = static_cast<InfoBarAndroid*>(infobar);
if (!android_bar) {
// TODO(bulach): CLANK: implement other types of InfoBars.
// TODO(jrg): this will always print out WARNING_TYPE as an int.
// Try and be more helpful.
NOTIMPLEMENTED() << "CLANK: infobar type "
<< infobar->delegate()->GetInfoBarType();
return;
}
if (infobar->delegate()->AsAutoLoginInfoBarDelegate()) {
AutoLoginInfoBarDelegateAndroid* auto_login_delegate =
static_cast<AutoLoginInfoBarDelegateAndroid*>(
infobar->delegate()->AsAutoLoginInfoBarDelegate());
if (!auto_login_delegate->AttachAccount(weak_java_auto_login_delegate_)) {
return;
}
}
AttachJavaInfoBar(android_bar);
}
void InfoBarContainerAndroid::AttachJavaInfoBar(InfoBarAndroid* android_bar) {
// Java infobar already set on the new bar, nothing to do.
if (android_bar->HasSetJavaInfoBar())
return;
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> java_infobar =
android_bar->CreateRenderInfoBar(env);
Java_InfoBarContainer_addInfoBar(
env, weak_java_infobar_container_.get(env).obj(), java_infobar.obj());
android_bar->set_java_infobar(java_infobar);
}
void InfoBarContainerAndroid::PlatformSpecificReplaceInfoBar(
InfoBar* old_infobar, InfoBar* new_infobar) {
InfoBarAndroid* new_android_bar = static_cast<InfoBarAndroid*>(new_infobar);
InfoBarAndroid* old_android_bar =
old_infobar != NULL ? static_cast<InfoBarAndroid*>(old_infobar) : NULL;
new_android_bar->PassJavaInfoBar(old_android_bar);
}
void InfoBarContainerAndroid::PlatformSpecificRemoveInfoBar(InfoBar* infobar) {
InfoBarAndroid* android_infobar = static_cast<InfoBarAndroid*>(infobar);
android_infobar->CloseJavaInfoBar();
base::MessageLoop::current()->DeleteSoon(FROM_HERE, infobar);
}
// -----------------------------------------------------------------------------
// Native JNI methods
// -----------------------------------------------------------------------------
static int Init(JNIEnv* env,
jobject obj,
jint native_web_contents,
jobject auto_login_delegate) {
InfoBarService* infobar_service = InfoBarService::FromWebContents(
reinterpret_cast<content::WebContents*>(native_web_contents));
InfoBarContainerAndroid* infobar_container =
new InfoBarContainerAndroid(env, obj, auto_login_delegate);
infobar_container->ChangeInfoBarService(infobar_service);
return reinterpret_cast<int>(infobar_container);
}
// Register native methods
bool RegisterInfoBarContainer(JNIEnv* env) {
return RegisterNativesImpl(env);
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_ANDROID_INFOBAR_INFOBAR_CONTAINER_ANDROID_H_
#define CHROME_BROWSER_UI_ANDROID_INFOBAR_INFOBAR_CONTAINER_ANDROID_H_
#include <map>
#include <string>
#include "base/android/jni_helper.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "chrome/browser/infobars/infobar_container.h"
class InfoBarAndroid;
class InfoBarDelegate;
class InfoBarService;
namespace content {
class WebContents;
}
class InfoBarContainerAndroid : public InfoBarContainer {
public:
InfoBarContainerAndroid(JNIEnv* env,
jobject infobar_container,
jobject auto_login_delegate);
void Destroy(JNIEnv* env, jobject obj);
JavaObjectWeakGlobalRef auto_login_delegate() const {
return weak_java_auto_login_delegate_;
}
JavaObjectWeakGlobalRef java_container() const {
return weak_java_infobar_container_;
}
// The prerender is swapping the web contents.
void OnWebContentsReplaced(content::WebContents* old_web_contents,
content::WebContents* new_web_contents);
private:
virtual ~InfoBarContainerAndroid() OVERRIDE;
// InfobarContainer
virtual void PlatformSpecificAddInfoBar(InfoBar* infobar, size_t position)
OVERRIDE;
virtual void PlatformSpecificRemoveInfoBar(InfoBar* infobar) OVERRIDE;
virtual void PlatformSpecificReplaceInfoBar(InfoBar* old_infobar,
InfoBar* new_infobar) OVERRIDE;
// Create the Java equivalent of |android_bar| and add it to the java
// container
void AttachJavaInfoBar(InfoBarAndroid* android_bar);
// We're owned by the java infobar, need to use a weak ref so it can destroy
// us.
JavaObjectWeakGlobalRef weak_java_infobar_container_;
JavaObjectWeakGlobalRef weak_java_auto_login_delegate_;
DISALLOW_COPY_AND_ASSIGN(InfoBarContainerAndroid);
};
// Register the InfoBarContainer's native methods through jni
bool RegisterInfoBarContainer(JNIEnv* env);
#endif // CHROME_BROWSER_UI_ANDROID_INFOBAR_INFOBAR_CONTAINER_ANDROID_H_
...@@ -3558,6 +3558,10 @@ ...@@ -3558,6 +3558,10 @@
'android/java/src/org/chromium/chrome/browser/UrlUtilities.java', 'android/java/src/org/chromium/chrome/browser/UrlUtilities.java',
'android/java/src/org/chromium/chrome/browser/ValidationMessageBubble.java', 'android/java/src/org/chromium/chrome/browser/ValidationMessageBubble.java',
'android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java', 'android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java',
'android/java/src/org/chromium/chrome/browser/infobar/AutoLoginDelegate.java',
'android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBarDelegate.java',
'android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java',
'android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java',
], ],
'variables': { 'variables': {
'jni_gen_package': 'chrome', 'jni_gen_package': 'chrome',
......
...@@ -75,6 +75,13 @@ ...@@ -75,6 +75,13 @@
'browser/ui/android/autofill/autofill_dialog_result.h', 'browser/ui/android/autofill/autofill_dialog_result.h',
'browser/ui/android/autofill/autofill_popup_view_android.cc', 'browser/ui/android/autofill/autofill_popup_view_android.cc',
'browser/ui/android/autofill/autofill_popup_view_android.h', 'browser/ui/android/autofill/autofill_popup_view_android.h',
'browser/ui/android/infobar/auto_login_infobar_delegate_android.cc',
'browser/ui/android/infobar/confirm_infobar.cc',
'browser/ui/android/infobar/confirm_infobar.h',
'browser/ui/android/infobar/infobar_android.cc',
'browser/ui/android/infobar/infobar_android.h',
'browser/ui/android/infobar/infobar_container_android.cc',
'browser/ui/android/infobar/infobar_container_android.h',
'browser/ui/android/certificate_viewer_android.cc', 'browser/ui/android/certificate_viewer_android.cc',
'browser/ui/android/chrome_http_auth_handler.cc', 'browser/ui/android/chrome_http_auth_handler.cc',
'browser/ui/android/chrome_http_auth_handler.h', 'browser/ui/android/chrome_http_auth_handler.h',
......
...@@ -12,4 +12,20 @@ ...@@ -12,4 +12,20 @@
--> -->
<dimen name="color_picker_gradient_margin">14.5dp</dimen> <dimen name="color_picker_gradient_margin">14.5dp</dimen>
</resources> <!-- Infobar dimensions -->
\ No newline at end of file <!-- Text size of the InfoBar message. -->
<dimen name="infobar_text_size">16sp</dimen>
<!-- Text size of text inside InfoBar buttons. -->
<dimen name="infobar_button_text_size">16sp</dimen>
<!-- Minimum dimension (height or width) of the upper row of an InfoBar. -->
<dimen name="infobar_min_size">60dp</dimen>
<!-- Margin between items in an InfoBar. -->
<dimen name="infobar_margin">10dp</dimen>
<!-- Left/right padding for infobar button text. -->
<dimen name="infobar_button_horizontal_padding">30dp</dimen>
<!-- Minimum height for a touch target. -->
<dimen name="infobar_touch_target_height">40dp</dimen>
<!-- Dimension (height or width) of the InfoBar icon. -->
<dimen name="infobar_icon_size">31dp</dimen>
</resources>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment