Don't trigger HW acceleration from Toasts on low-end devices.
BUG=520600 Review URL: https://codereview.chromium.org/1276523003 Cr-Commit-Position: refs/heads/master@{#343518}
This commit is contained in:
PRESUBMIT.py
chrome/android
java
src
org
chromium
chrome
browser
ChromeTabbedActivity.javaShortcutHelper.java
download
media
remote
nfc
ntp
preferences
toolbar
javatests
src
org
chromium
chrome
browser
hardware_acceleration
shell
java
src
org
chromium
chrome
content/public/android/java/src/org/chromium/content/browser
ui/android/java/src/org/chromium/ui
38
PRESUBMIT.py
38
PRESUBMIT.py
@ -1312,6 +1312,43 @@ def _CheckJavaStyle(input_api, output_api):
|
||||
black_list=_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
|
||||
|
||||
|
||||
def _CheckAndroidToastUsage(input_api, output_api):
|
||||
"""Checks that code uses org.chromium.ui.widget.Toast instead of
|
||||
android.widget.Toast (Chromium Toast doesn't force hardware
|
||||
acceleration on low-end devices, saving memory).
|
||||
"""
|
||||
toast_import_pattern = input_api.re.compile(
|
||||
r'^import android\.widget\.Toast;$')
|
||||
|
||||
errors = []
|
||||
|
||||
sources = lambda affected_file: input_api.FilterSourceFile(
|
||||
affected_file,
|
||||
black_list=(_EXCLUDED_PATHS +
|
||||
_TEST_CODE_EXCLUDED_PATHS +
|
||||
input_api.DEFAULT_BLACK_LIST +
|
||||
(r'^chromecast[\\\/].*',
|
||||
r'^remoting[\\\/].*')),
|
||||
white_list=(r'.*\.java$',))
|
||||
|
||||
for f in input_api.AffectedSourceFiles(sources):
|
||||
for line_num, line in f.ChangedContents():
|
||||
if toast_import_pattern.search(line):
|
||||
errors.append("%s:%d" % (f.LocalPath(), line_num))
|
||||
|
||||
results = []
|
||||
|
||||
if errors:
|
||||
results.append(output_api.PresubmitError(
|
||||
'android.widget.Toast usage is detected. Android toasts use hardware'
|
||||
' acceleration, and can be\ncostly on low-end devices. Please use'
|
||||
' org.chromium.ui.widget.Toast instead.\n'
|
||||
'Contact dskiba@chromium.org if you have any questions.',
|
||||
errors))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def _CheckAndroidCrLogUsage(input_api, output_api):
|
||||
"""Checks that new logs using org.chromium.base.Log:
|
||||
- Are using 'TAG' as variable name for the tags (warn)
|
||||
@ -1530,6 +1567,7 @@ def _AndroidSpecificOnUploadChecks(input_api, output_api):
|
||||
"""Groups checks that target android code."""
|
||||
results = []
|
||||
results.extend(_CheckAndroidCrLogUsage(input_api, output_api))
|
||||
results.extend(_CheckAndroidToastUsage(input_api, output_api))
|
||||
return results
|
||||
|
||||
|
||||
|
@ -22,7 +22,6 @@ import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.CommandLine;
|
||||
import org.chromium.base.MemoryPressureListener;
|
||||
@ -93,6 +92,7 @@ import org.chromium.content.common.ContentSwitches;
|
||||
import org.chromium.content_public.browser.LoadUrlParams;
|
||||
import org.chromium.ui.base.DeviceFormFactor;
|
||||
import org.chromium.ui.base.PageTransition;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* This is the main activity for ChromeMobile when not running in document mode. All the tabs
|
||||
@ -221,7 +221,7 @@ public class ChromeTabbedActivity extends ChromeActivity implements ActionBarDel
|
||||
public void didAddTab(Tab tab, TabLaunchType type) {
|
||||
if (type == TabLaunchType.FROM_LONGPRESS_BACKGROUND
|
||||
&& !DeviceClassManager.enableAnimations(getApplicationContext())) {
|
||||
Toast.makeText(getBaseContext(),
|
||||
Toast.makeText(ChromeTabbedActivity.this,
|
||||
R.string.open_in_new_tab_toast,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import android.graphics.Bitmap;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Base64;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.ApplicationStatus;
|
||||
import org.chromium.base.VisibleForTesting;
|
||||
@ -20,6 +19,7 @@ import org.chromium.chrome.browser.tab.Tab;
|
||||
import org.chromium.chrome.browser.webapps.WebappLauncherActivity;
|
||||
import org.chromium.content_public.browser.WebContents;
|
||||
import org.chromium.content_public.common.ScreenOrientationConstants;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.UUID;
|
||||
|
@ -13,7 +13,6 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.webkit.URLUtil;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.VisibleForTesting;
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
@ -26,6 +25,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector;
|
||||
import org.chromium.content.browser.ContentViewDownloadDelegate;
|
||||
import org.chromium.content.browser.DownloadInfo;
|
||||
import org.chromium.content_public.browser.WebContents;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
@ -19,7 +19,6 @@ import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.LongSparseArray;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.base.ThreadUtils;
|
||||
@ -29,6 +28,7 @@ import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl;
|
||||
import org.chromium.content.browser.DownloadController;
|
||||
import org.chromium.content.browser.DownloadInfo;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
2
chrome/android/java/src/org/chromium/chrome/browser/media/remote/AbstractMediaRouteController.java
2
chrome/android/java/src/org/chromium/chrome/browser/media/remote/AbstractMediaRouteController.java
@ -14,7 +14,6 @@ import android.support.v7.media.MediaRouteSelector;
|
||||
import android.support.v7.media.MediaRouter;
|
||||
import android.support.v7.media.MediaRouter.RouteInfo;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.cast.CastMediaControlIntent;
|
||||
|
||||
@ -24,6 +23,7 @@ import org.chromium.base.VisibleForTesting;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.ChromeSwitches;
|
||||
import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
@ -20,7 +20,6 @@ import android.support.v7.media.MediaRouter;
|
||||
import android.support.v7.media.MediaRouter.RouteInfo;
|
||||
import android.support.v7.media.MediaSessionStatus;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.cast.CastMediaControlIntent;
|
||||
|
||||
@ -30,6 +29,7 @@ import org.chromium.base.CommandLine;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.ChromeSwitches;
|
||||
import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -17,7 +17,6 @@ import android.support.v7.app.MediaRouteChooserDialogFragment;
|
||||
import android.support.v7.app.MediaRouteControllerDialogFragment;
|
||||
import android.support.v7.app.MediaRouteDialogFactory;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.cast.CastMediaControlIntent;
|
||||
|
||||
@ -28,6 +27,7 @@ import org.chromium.base.VisibleForTesting;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.ChromeSwitches;
|
||||
import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
|
@ -14,11 +14,11 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.ThreadUtils;
|
||||
import org.chromium.base.metrics.RecordUserAction;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
@ -12,13 +12,13 @@ import android.view.View.OnLongClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.ApiCompatibilityUtils;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.appmenu.ChromeAppMenuPropertiesDelegate;
|
||||
import org.chromium.chrome.browser.widget.TintedDrawable;
|
||||
import org.chromium.ui.base.DeviceFormFactor;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* The toolbar at the bottom of the new tab page. Contains buttons to open the bookmarks and
|
||||
|
@ -5,9 +5,9 @@
|
||||
package org.chromium.chrome.browser.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* Utilities and common methods to handle settings managed by policies.
|
||||
|
@ -19,7 +19,6 @@ import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
|
||||
@ -27,6 +26,7 @@ import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
|
||||
import org.chromium.chrome.browser.preferences.PreferencesLauncher;
|
||||
import org.chromium.ui.text.SpanApplier;
|
||||
import org.chromium.ui.text.SpanApplier.SpanInfo;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* The promo screen encouraging users to enable Data Saver.
|
||||
|
@ -23,7 +23,6 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckedTextView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
|
||||
@ -31,6 +30,7 @@ import org.chromium.chrome.browser.preferences.Preferences;
|
||||
import org.chromium.chrome.browser.signin.AccountManagementFragment;
|
||||
import org.chromium.sync.signin.ChromeSigninController;
|
||||
import org.chromium.ui.text.SpanApplier;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
|
@ -12,7 +12,6 @@ import android.preference.PreferenceFragment;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.help.HelpAndFeedback;
|
||||
@ -20,6 +19,7 @@ import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference;
|
||||
import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate;
|
||||
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* Fragment to keep track of the translate preferences.
|
||||
|
@ -19,7 +19,6 @@ import android.view.MenuItem;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference;
|
||||
@ -34,6 +33,7 @@ import org.chromium.chrome.browser.preferences.ProtectedContentResetCredentialCo
|
||||
import org.chromium.chrome.browser.widget.TintedDrawable;
|
||||
import org.chromium.content.browser.MediaDrmCredentialManager;
|
||||
import org.chromium.content.browser.MediaDrmCredentialManager.MediaDrmCredentialManagerCallback;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -17,7 +17,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.appmenu.AppMenuButtonHelper;
|
||||
@ -29,6 +28,7 @@ import org.chromium.chrome.browser.util.ViewUtils;
|
||||
import org.chromium.chrome.browser.widget.TintedImageButton;
|
||||
import org.chromium.chrome.browser.widget.ToolbarProgressBar;
|
||||
import org.chromium.ui.UiUtils;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* Layout class that contains the base shared logic for manipulating the toolbar component. For
|
||||
|
@ -10,19 +10,32 @@ import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import org.chromium.base.test.util.Restriction;
|
||||
import org.chromium.base.test.util.UrlUtils;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.tab.Tab;
|
||||
import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
|
||||
import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils;
|
||||
|
||||
/**
|
||||
* Tests that ChromeTabbedActivity is hardware accelerated only high-end devices.
|
||||
*/
|
||||
public class ChromeTabbedActivityHWATest extends ChromeTabbedActivityTestBase {
|
||||
|
||||
private static final String LINKED_URL = UrlUtils.encodeHtmlDataUri(
|
||||
"<html>"
|
||||
+ " <head>"
|
||||
+ " <title>Linked Page</title>"
|
||||
+ " </head>"
|
||||
+ " <body style='margin: 0em; background: #ff00ff;'></body>"
|
||||
+ "</html>");
|
||||
|
||||
private static final String LINK_ID = "testLink";
|
||||
private static final String URL = UrlUtils.encodeHtmlDataUri(
|
||||
"<html>"
|
||||
+ " <head>"
|
||||
+ " <title>Test Page</title>"
|
||||
+ " </head>"
|
||||
+ " <body style='margin: 0em; background: #ffff00;'></body>"
|
||||
+ " <a href='" + LINKED_URL + "' id='" + LINK_ID + "'>Test Link</a>"
|
||||
+ "</html>");
|
||||
|
||||
@Override
|
||||
@ -40,4 +53,16 @@ public class ChromeTabbedActivityHWATest extends ChromeTabbedActivityTestBase {
|
||||
public void testNoRenderThread() throws Exception {
|
||||
Utils.assertNoRenderThread();
|
||||
}
|
||||
|
||||
@Restriction(RESTRICTION_TYPE_LOW_END_DEVICE)
|
||||
@SmallTest
|
||||
public void testToastNoRenderThread() throws Exception {
|
||||
// Open link in new tab (shows 'Tab Opened In Background' toast)
|
||||
Tab tab = getActivity().getActivityTab();
|
||||
ContextMenuUtils.selectContextMenuItem(this, tab, LINK_ID,
|
||||
R.id.contextmenu_open_in_new_tab);
|
||||
getInstrumentation().waitForIdleSync();
|
||||
|
||||
Utils.assertNoRenderThread();
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
package org.chromium.chrome.browser.hardware_acceleration;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver.OnPreDrawListener;
|
||||
|
||||
@ -14,6 +15,7 @@ import org.chromium.base.SysUtils;
|
||||
import org.chromium.base.ThreadUtils;
|
||||
import org.chromium.chrome.browser.ChromeActivity;
|
||||
import org.chromium.content.browser.test.util.CallbackHelper;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@ -31,6 +33,11 @@ public class Utils {
|
||||
public static void assertHardwareAcceleration(ChromeActivity activity) throws Exception {
|
||||
assertActivityAcceleration(activity);
|
||||
assertChildWindowAcceleration(activity);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// Toasts are only HW accelerated on LOLLIPOP+
|
||||
assertToastAcceleration(activity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,12 +70,33 @@ public class Utils {
|
||||
});
|
||||
|
||||
listenerCalled.waitForCallback(0);
|
||||
assertAcceleration(accelerated);
|
||||
}
|
||||
|
||||
if (SysUtils.isLowEndDevice()) {
|
||||
Assert.assertFalse(accelerated.get());
|
||||
} else {
|
||||
Assert.assertTrue(accelerated.get());
|
||||
}
|
||||
private static void assertToastAcceleration(final ChromeActivity activity)
|
||||
throws Exception {
|
||||
final AtomicBoolean accelerated = new AtomicBoolean();
|
||||
final CallbackHelper listenerCalled = new CallbackHelper();
|
||||
|
||||
ThreadUtils.postOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// We are using Toast.makeText(context, ...) instead of new Toast(context)
|
||||
// because that Toast constructor is unused and is deleted by proguard.
|
||||
Toast toast = Toast.makeText(activity, "", Toast.LENGTH_SHORT);
|
||||
toast.setView(new View(activity) {
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
accelerated.set(isHardwareAccelerated());
|
||||
listenerCalled.notifyCalled();
|
||||
}
|
||||
});
|
||||
toast.show();
|
||||
}
|
||||
});
|
||||
|
||||
listenerCalled.waitForCallback(0);
|
||||
assertAcceleration(accelerated);
|
||||
}
|
||||
|
||||
private static void assertChildWindowAcceleration(final ChromeActivity activity)
|
||||
@ -93,7 +121,10 @@ public class Utils {
|
||||
});
|
||||
|
||||
listenerCalled.waitForCallback(0);
|
||||
assertAcceleration(accelerated);
|
||||
}
|
||||
|
||||
private static void assertAcceleration(AtomicBoolean accelerated) {
|
||||
if (SysUtils.isLowEndDevice()) {
|
||||
Assert.assertFalse(accelerated.get());
|
||||
} else {
|
||||
|
@ -18,7 +18,6 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.ApiCompatibilityUtils;
|
||||
import org.chromium.base.BaseSwitches;
|
||||
@ -62,6 +61,7 @@ import org.chromium.sync.signin.AccountManagerHelper;
|
||||
import org.chromium.sync.signin.ChromeSigninController;
|
||||
import org.chromium.ui.base.ActivityWindowAndroid;
|
||||
import org.chromium.ui.base.WindowAndroid;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* The {@link android.app.Activity} component of a basic test shell to test Chrome features.
|
||||
|
@ -10,12 +10,12 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
import org.chromium.content.R;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -7,11 +7,11 @@ package org.chromium.ui.base;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
import org.chromium.ui.R;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
/**
|
||||
* Simple proxy that provides C++ code with an access pathway to the Android
|
||||
|
@ -23,11 +23,11 @@ import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
import org.chromium.ui.VSyncMonitor;
|
||||
import org.chromium.ui.widget.Toast;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
|
185
ui/android/java/src/org/chromium/ui/widget/Toast.java
Normal file
185
ui/android/java/src/org/chromium/ui/widget/Toast.java
Normal file
@ -0,0 +1,185 @@
|
||||
// Copyright 2015 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.ui.widget;
|
||||
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.chromium.base.SysUtils;
|
||||
|
||||
/**
|
||||
* Toast wrapper, makes sure toasts don't trigger HW acceleration when created
|
||||
* from activities that are not HW accelerated.
|
||||
*
|
||||
* Can (and should) also be used for Chromium-related additions and extensions.
|
||||
*/
|
||||
public class Toast {
|
||||
|
||||
public static final int LENGTH_SHORT = android.widget.Toast.LENGTH_SHORT;
|
||||
public static final int LENGTH_LONG = android.widget.Toast.LENGTH_LONG;
|
||||
|
||||
private android.widget.Toast mToast;
|
||||
private ViewGroup mSWLayout;
|
||||
|
||||
public Toast(Context context) {
|
||||
this(context, new android.widget.Toast(context));
|
||||
}
|
||||
|
||||
private Toast(Context context, android.widget.Toast toast) {
|
||||
mToast = toast;
|
||||
|
||||
if (SysUtils.isLowEndDevice()
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|
||||
&& context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP
|
||||
&& isHWAccelerationDisabled(context)) {
|
||||
// Don't HW accelerate Toasts. Unfortunately the only way to do it is to make
|
||||
// toast.getView().getContext().getApplicationInfo().targetSdkVersion return
|
||||
// something less than LOLLIPOP (see WindowManagerGlobal.addView).
|
||||
mSWLayout = new FrameLayout(new ContextWrapper(context) {
|
||||
@Override
|
||||
public ApplicationInfo getApplicationInfo() {
|
||||
ApplicationInfo info = new ApplicationInfo(super.getApplicationInfo());
|
||||
info.targetSdkVersion = Build.VERSION_CODES.KITKAT;
|
||||
return info;
|
||||
}
|
||||
});
|
||||
|
||||
setView(toast.getView());
|
||||
}
|
||||
}
|
||||
|
||||
public android.widget.Toast getAndroidToast() {
|
||||
return mToast;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
mToast.show();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
mToast.cancel();
|
||||
}
|
||||
|
||||
public void setView(View view) {
|
||||
if (mSWLayout != null) {
|
||||
mSWLayout.removeAllViews();
|
||||
if (view != null) {
|
||||
mSWLayout.addView(view, WRAP_CONTENT, WRAP_CONTENT);
|
||||
mToast.setView(mSWLayout);
|
||||
} else {
|
||||
// When null view is set we propagate it to the toast to trigger appropriate
|
||||
// handling (for example show() throws an exception when view is null).
|
||||
mToast.setView(null);
|
||||
}
|
||||
} else {
|
||||
mToast.setView(view);
|
||||
}
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
if (mToast.getView() == null) {
|
||||
return null;
|
||||
}
|
||||
if (mSWLayout != null) {
|
||||
return mSWLayout.getChildAt(0);
|
||||
} else {
|
||||
return mToast.getView();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
mToast.setDuration(duration);
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return mToast.getDuration();
|
||||
}
|
||||
|
||||
public void setMargin(float horizontalMargin, float verticalMargin) {
|
||||
mToast.setMargin(horizontalMargin, verticalMargin);
|
||||
}
|
||||
|
||||
public float getHorizontalMargin() {
|
||||
return mToast.getHorizontalMargin();
|
||||
}
|
||||
|
||||
public float getVerticalMargin() {
|
||||
return mToast.getVerticalMargin();
|
||||
}
|
||||
|
||||
public void setGravity(int gravity, int xOffset, int yOffset) {
|
||||
mToast.setGravity(gravity, xOffset, yOffset);
|
||||
}
|
||||
|
||||
public int getGravity() {
|
||||
return mToast.getGravity();
|
||||
}
|
||||
|
||||
public int getXOffset() {
|
||||
return mToast.getXOffset();
|
||||
}
|
||||
|
||||
public int getYOffset() {
|
||||
return mToast.getYOffset();
|
||||
}
|
||||
|
||||
public void setText(int resId) {
|
||||
mToast.setText(resId);
|
||||
}
|
||||
|
||||
public void setText(CharSequence s) {
|
||||
mToast.setText(s);
|
||||
}
|
||||
|
||||
@SuppressLint("ShowToast")
|
||||
public static Toast makeText(Context context, CharSequence text, int duration) {
|
||||
return new Toast(context, android.widget.Toast.makeText(context, text, duration));
|
||||
}
|
||||
|
||||
@SuppressLint("ShowToast")
|
||||
public static Toast makeText(Context context, int resId, int duration)
|
||||
throws Resources.NotFoundException {
|
||||
return new Toast(context, android.widget.Toast.makeText(context, resId, duration));
|
||||
}
|
||||
|
||||
private static Activity getActivity(Context context) {
|
||||
while (context != null) {
|
||||
if (context instanceof Activity) {
|
||||
return (Activity) context;
|
||||
}
|
||||
if (!(context instanceof ContextWrapper)) {
|
||||
break;
|
||||
}
|
||||
context = ((ContextWrapper) context).getBaseContext();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isHWAccelerationDisabled(Context context) {
|
||||
Activity activity = getActivity(context);
|
||||
if (activity == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
ActivityInfo info = activity.getPackageManager().getActivityInfo(
|
||||
activity.getComponentName(), 0);
|
||||
return (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) == 0;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user